mbed-modbus-RTU (modbus slave to control 6 LEDs)

Dependencies:   Modbus nvt_rs485

Fork of NuMaker-mbed-modbus-sample by Nuvoton

main.cpp

Committer:
rkuo2000
Date:
2017-01-05
Revision:
6:7fb2dc9292b7
Parent:
5:3e19326b47f7

File content as of revision 6:7fb2dc9292b7:

//
// modbus RTU sample code
// 
// EVB : NuMaker-PFM-NUC472
// Connections:
// D0 & D1 : to USB-to-UART (PC running modbus master software simulator)
// D2 ~ D7 : to external LEDs
//
// if choose on-board RS485, then go to Modbus/portserial.cpp line#38
// Modify '//#define DEF_RS485_PORT 1' to '#define DEF_RS485_PORT 1'
//
// PC modbus master command = Write Single Register
// ID = 1, Func = 6, Addr = 4, Data = 0x003F (6 bits for 6 LEDs)
//
/* ----------------------- System includes --------------------------------*/
#include "mbed.h"
#include "rtos.h"
/*----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"

/* ----------------------- Defines ------------------------------------------*/
#define MODBUS_BAUDRATE 9600
// Sharing buffer index
enum {                      // Modbus Slave Address
  eData_MBInCounter,        // 0: In  Counter
  eData_MBOutCounter,       // 1: Out Counter
  eData_MBError,            // 2: Error code
  eData_DI,                 // 3: DI
  eData_DO,                 // 4: DO = LED[x]
  eData_RGB,                // 5: DO = RGB LED
  eData_MBResistorVar,      // 6: Variable Resistor
  eData_TemperatureSensor,  // 7: Temperature Sensor
  eData_Cnt                 
} E_DATA_TYPE;

#define REG_INPUT_START 1
#define REG_INPUT_NREGS eData_Cnt
#define SLAVE_ID 0x01
/* ----------------------- Static variables ---------------------------------*/
static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS];

DigitalOut led1(LED1);  // For temperature worker.
DigitalOut led2(LED2);  // For Modbus worker.
DigitalOut led3(LED3);  // For Holder CB

#define DEF_LED_NUM 6
#if defined(TARGET_NUMAKER_PFM_NUC472)
DigitalOut LED[DEF_LED_NUM] = { PF_9, PF_10, PC_10, PC_11, PA_10, PA_9 } ;
#elif defined(TARGET_NUMAKER_PFM_M453)
DigitalOut LED[DEF_LED_NUM] = { PC_6, PC_7, PC_11, PC_12, PC_13, PC_14 } ;
#endif

void light_leds()
{
    int i=0;
    USHORT usOutValue = usRegInputBuf[eData_DO];
    for ( i=0; i<DEF_LED_NUM ; i++)        
        if((usOutValue&(0x01<<i)) !=0) LED[i]=1;
        else                           LED[i]=0;
}

/* ----------------------- Start implementation -----------------------------*/
int
main( void )
{
    eMBErrorCode    eStatus;
    
    // Initialise some registers
    for (int i=0; i<REG_INPUT_NREGS; i++)
         usRegInputBuf[i] = 0x0;

    light_leds(); // Control LEDs
        
    printf("\n\r");
    //printf("We will set modbus slave ID-%d(0x%x) for the device.\r\n", usSlaveID, usSlaveID );
    printf("modbus master  : %d bps  \r\n", MODBUS_BAUDRATE);
    printf("modbus slave ID: %d      \r\n", SLAVE_ID, SLAVE_ID );
    printf("\r\n");
    printf("To control modbus slave LEDs, use modbus poll\r\n");
    printf("command: ID= %d, Func = 6, Addr = %d, Data = LED[x] -- Write Single Register\r\n", SLAVE_ID, eData_DO);

    /* Enable the Modbus Protocol Stack. */
    if ( (eStatus = eMBInit( MB_RTU, SLAVE_ID, 0, MODBUS_BAUDRATE, MB_PAR_NONE )) !=  MB_ENOERR )
        goto FAIL_MB;
    else if ( (eStatus = eMBEnable(  ) ) != MB_ENOERR )
        goto FAIL_MB_1;
    else {
        for( ;; )
        {
            xMBPortSerialPolling();           
            if ( eMBPoll( ) != MB_ENOERR ) break;
        }       
    }    
    
FAIL_MB_1:
    eMBClose();    
    
FAIL_MB:
    for( ;; )
    {
        led2 = !led2;
        Thread::wait(200);
    }
}

eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;
    
    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInputStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
 
    return eStatus;
}
 
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;
     
    usRegInputBuf[eData_MBInCounter]++;
    usRegInputBuf[eData_MBOutCounter]++;
        
    if (eMode == MB_REG_READ)
    {
        printf("modbus : MB REG READ...\r\n");
        if( ( usAddress >= REG_INPUT_START )
            && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
        {
            iRegIndex = ( int )( usAddress - usRegInputStart );
            while( usNRegs > 0 )
            {
                *pucRegBuffer++ =
                    ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
                *pucRegBuffer++ =
                    ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
                iRegIndex++;
                usNRegs--;
            }
        }
    }
 
    if (eMode == MB_REG_WRITE)
    {
        printf("modbus : MB REG Write...\r\n");
        if( ( usAddress >= REG_INPUT_START )
            && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
        {
            iRegIndex = ( int )( usAddress - usRegInputStart );            
            while( usNRegs > 0 )
            {
                usRegInputBuf[iRegIndex] =  ((unsigned int) *pucRegBuffer << 8) | ((unsigned int) *(pucRegBuffer+1));                
                pucRegBuffer+=2;
                iRegIndex++;
                usNRegs--;
            }                     
            light_leds(); // Control LEDs
        }
    }
 
    led3=!led3;
        
    return eStatus;
}
 
 
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
               eMBRegisterMode eMode )
{
    return MB_ENOREG;
}
 
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    return MB_ENOREG;
}