The register size is normally 16bits but many devices use 2 successive registers to holde a 32 bit value. You have to interpret the data returned to convert it into the correct format (byte order etc may differ from the Rabbits so you need to know what the order is).
I’ve written test code very similar to yours and am debugging it at the moment. I get the TX: message and am not yet receiving any response but the RS485 adapter on my PC is seeing my request and the electricity meters response in my test setup so I am just going through the receive side of things now to see what is missing.
I changed my slave for another plant. When I run my program, I have the same thing as you now …
Tx: 05 03 10 00 00 02 4F C1
With the statement:
main ()
{int i;
RegsValue double [50];
serine ();
MBM_ReadRegs i = (005, & RegsValue [0], 0x1000, 2); / / read reg 0
if (i == 0)
printf ("Connect OK “);
else printf (“Connection Not OK”);
printf (”% d,% d \ n ", RegsValue [0], RegsValue [1]);
while (1);
}
/* START FUNCTION DESCRIPTION ********************************************
MBM_Send_ADU
SYNTAX: int MBM_Send_ADU ( char *Packet, int ByteCount );
DESCRIPTION: Transmit a Modbus packet to a “downstream” device.
Calculate the CRC and append to the packet.
There is a 50msec timeout hard coded in this function.
PARAMETER1: address of packet - must have two byte pad at end for
inclusion of CRC word
PARAMETER2: number of bytes in the packet
RETURN VALUE: MB_SUCCESS
Note: these functions do NOT implement the Modbus protocol delay of
3.5 byte times.
END DESCRIPTION **********************************************************/
/*** BeginHeader MBM_Send_ADU /
int MBM_Send_ADU(char Packet, int ByteCount);
/* EndHeader */
_modbus_dbg
int MBM_Send_ADU(char *Packet, int ByteCount)
{
unsigned CRCvalue;
unsigned long Endtime;
int i;
// insert CRC
CRCvalue = MODBUS_CRC ( Packet, ByteCount );
Packet[ByteCount+1] = CRCvalue; // store low byte
Packet[ByteCount] = CRCvalue>>8; // store high byte
ByteCount+=2; // adjust for CRC
Just did some quick tests and the timeout is definetly a problem in my case. I’m using a Femto D4 electricity meter for my tests and if I set the timeout to 50ms I don’t read the response, at 100ms I get the response about 75% of the time and at 150ms I always get the response.
Checking with a scope I see that the meter is responding between 80ms and 120ms after receiving the request. I don’t think it is exactly a speed demon!
The test application itself has the #use modbus_master.lib statement. I didn’t post this code as it is not that much different to yours.
The ser485TX/RX functions are supplied by the BLxS2xx.lib library. You don’t actually need these in your code or the brdinit function as they are in the RCM39xx.lib file. All you need to do is have #use bl39xx.lib at the top of your program and they should be linked in.
When I run the program step by step, he stops at the following statement:
while (serCrdUsed ()! = ByteCount);
As if serCrdUsed () was always different from ByteCount …
This should be in the samples\RCM3900 folder. The name is RCM39XX.LIB
Idea of using the serCrdUsed value is that when the RS485 lines are set correctly, each byte transmitted by the RCM3900 is also received by the controller because the RS485 tranceiver is wired up with a single enable which means the RX line is active when TX mode is selected.
This code uses the count of bytes received to see when all the data has been trensmitted. If your RS485 lines are not switching correctly then this will mean no data received back. Other things which can break this logic are shorts or execssive loading on the RS485 line, bad line bias and so on which stop the data from being received correctly.
The MS/TP code in the BACnet stack uses the serXsending function to determine when all the RS485 data has been transmitted and you might be able to port that function from the DC10.66 RS232.LIB to the DC9.62 RS232.LIB if you want a safe mechanism for determining the end of data transmission.