Modbus RTU

A

Thread Starter

AJ

Hey,

I am trying to get my HMI to display integer values that the PIC18F4550 micro calculates using RS232 and Modbus RTU. I am new to Modbus and am trying to learn the protocols. I am thinking I need to set the Micro as the master and the HMI as the slave. So I send the this packet:<pre>
3.5 Character Start bit at 38K4 baud rate
TXREG = 0x01; //Addresses the HMI as address 1
TXREG = 0x02; //Tells HMI to read registers
TXREG = 4; //Data to send to HMI as a test
crc = CRC16 ();
if (crc = 1) //Data is ok
{
3.5 Character Stop bit at 38K4 baud rate
return;
}
if (crc = 0) //Data is not ok
{
modbus(); //Go through routine again
}</pre>
I am wondering, how do I store the integer value that I want to display on the HMI in an address in the Micro that the Modbus RTU recognizes (40001 and up). Would I put the integer value that I want displayed in the data part of the packet?

I am also wondering, will the HMI send a confirmation value back saying it got the data?

Thanks for any help!

AJ
 
B

Bruce Durdle

Depending on the HMI, you are probably better to use the HMI as the master and the MCU as the slave.

Allocate a series of registers in the MCU as "addresses" - so locations 160 and 161 could be Holding Register (4)00001, 162 and 163 (4)0002 etc. Assign these Holding Register addresses in the HMI to the tags - the HMI will then take care of the message structure. Your MCU has to reply to the message from the +HMI by constructing the necessary reply message and inserting the appropriate values of data from the Holding Register array you have defined.

I have software for an 18F4xxx MCU if you are interested - email me direct at bmdurdle at clear dot net dot nz.

Cheers,
Bruce.
 
Hey,

thanks for putting that code available, it will fit my project nicely. I am unsure of this code though:<pre>
void readRegResponse(void) //response for modbus 03 function (read registers)
{
unsigned char i;
T.bytes.lowByte = buffer[3];
T.bytes.highByte = buffer[2];
T.integer*=2;
buffer[2] = buffer[5]*2;
for (i=0; i<buffer[2]; i++)
{
startI2C();
writeI2C(0xA0);
writeI2C(T.bytes.highByte);
writeI2C(T.bytes.lowByte);
stopI2C();
startI2C();
writeI2C(0xA1);
RCEN = 1;
buffer[i+3] = readI2C();
RCEN = 0;
T.integer++;
}
CRC16(buffer[2]+3,0);
for (i=0; i<buffer[2] + 5; i++)
writeRS(buffer);
}</pre>
I understand that the packet is stored in buffer[] array, and that the data is stored in separate device that is accessed via I2C, but I'm unsure of what is being done in this function (I was expecting there to be a modbus frame to be passed back to the HMI with 3.5 char start time,etc.).
 
Top