RCM 3900 modbus

When I run the program step by step … I do not go through the functions and MBM_Send_ADU MBM_Rcv_Resp …

More if I MBM_ReadRegs i = (07, & RegsValue [0], 0xC55E, 2);
and I print RegsValue [30], I -7012 … instead of 0 …

I really really do not see why not …

I have a question!
The values ​​in the registers are double words … and my regValue [] is declared int … This can cause errors?


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.


Can you paste your program … Perhaps with your own I would find my mistake …

Thank you Peter

I’ll do so when I have it all working. Probably tomorrow as I have to finish up early today.


Okay, thanks Peter :smiley:

Hey Peter, I have something new: D

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);

We are not far to get there!

I got the transmit and receive working with the following:

/*** BeginHeader */
// Normal MBUS debug printing

#define _modbus_dbg debug
#define _modbus_dbg nodebug

/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************

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


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 */
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

for(i=0; i

Another thing to note is that this code does not support broadcast messages properly as it always looks for a response.


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!


It is good if it works for you. : D

But I do not understand, you do not define ser485Tx () and ser485Rx () in your program … and you have not used modbus_master.lib!


Thank you

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 …

Okok i want to test with bl39xx.lib but i dont have this in my file… where is it??

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.



How do I configure my BrdInit enabled RCM3900 for my RS485 ports?? (P c)
I think my error comes from there?

Thank you all