11 years, 8 months ago.

RS485 with mbed microcontroller. Not receiving any data

I'm trying to communicate with the energy meter (MODBUS protocol) via SIPEX SP485CS chip. I'm unable to receive any data from the energy meter. I can confirm that all my hardware is working correctly as i have extra for each component. I'm not sure if is the connection or the program's problem. The program will stop after the printf("Getting data\n");. I'm always getting a 3.3V reading from Tx pin28 while 0V reading from Rx pin27, is this normal?

#include "mbed.h" 

Serial RS485(p28,p27); // Tx, Rx
DigitalOut ho(p26);

int regvalue[9];
int main()
{
    printf("Starting\n");
    RS485.baud(9600);
    while(1) {
        RS485.baud(9600);
        printf("Starting\n");
        ho = 1;                  // 3.3V output from digital out pin
        RS485.putc(0x01);   // slave add
        RS485.putc(0x04);   // function code
        RS485.putc(0x00);   // Hi PDU add
        RS485.putc(0x48);   // low PDU add
        RS485.putc(0x00);   // Hi N reg 
        RS485.putc(0x02);   // Lo N reg
        RS485.putc(0xf1);   // Hi CRC
        RS485.putc(0xdd);   // Lo CRC
        wait_ms(200);         // Silent interval
        printf("Getting data\n");
        ho = 0;                  // 0V output from digital out pin
        for (int count = 0; count < 8; count++) {
            regvalue[count] = RS485.getc(); // Retrieving received register from modbus
            printf("%X - ", regvalue[count]);
        }
        printf("Done\n");
        wait_ms(1000);
    }
} 

/media/uploads/weebeng/123.png

7 Answers

10 years, 2 months ago.

Hello; parity bits, stop bits, data bits are set, and most importantly how to have the slave ID?

11 years, 8 months ago.

0V on RX is not correct, this signal should normally be high (may need a pullup) when idle (transmit mode) and pulse low when actually receiving data.

Indeed, or maybe A and B are connected wrong?

posted by Erik - 28 Mar 2013
11 years, 8 months ago.

Try swapping A and B, not all manufacturers agree which is D+ and D-. You may need to add bias resistors at the termination to ensure correct idle states. It is a good idea to add a ground connection as well.

It is really useful to have a scope to look at the data lines...

Your energy meter may not be on address 1. I assume your request has a valid CRC...

5 years, 11 months ago.

Hi, I am using STM32f4 board, my slave id is 112

RS485.putc(0x70); slave add

I am also having the same problem.

Can I use this library for stm32f4 board or it is for a specific controller.

Thank you.

10 years, 4 months ago.

i notice that your crc bytes are wrong and they should be in order such that the Least Signficant Byte is placed first into the packet

7 years, 11 months ago.

Even i am Facing the same Problem...I tried every solution posted here..None of them worked...if anyone of you have got output using above code or similar..please let me know...I am Using FRDM-KL25Z board with RS485 board...

7 years, 11 months ago.

Viral - RS485 can be a complex setup so please confirm the following:

1) How many RS485 nodes are in your setup ? Recommend that you start with a single RS485 node and your FRDM board only.

2) Proper termination ? You must apply a 120 ohm termination on the FRDM board and also a 120 ohm termination on the external single RS485 node. This termination is often a 1/4 watt resistor across the D+ and D- lines. For RS485, you must apply a 120 ohm termination at the start of the RS485 chain and also at the end of the RS485 chain. No termination on the nodes between the first and last RS485 node.

3) Which RS485 transceiver is being used by your project ? Is it fail-safe biased ? If not, then you must consider to add additional pull-up and pull-down resistors to shift the idle state for the RS485 wiring away from the 0 volts. Otherwise you can lead to oscillations and just wrong values for the received data. Best to use fail safe biased transceivers to start with for such projects. For example Maxim, Intersil offer such parts - not 100% sure on Exar line at this time. If you do apply external biasing resistors then you must calculate the respective values based on the number of RS485 nodes. Some excellent articles on the net on this topic and yes you can apply a general range of values but keep in mind that the resistor values will impact the overall max number of RS485 nodes.

4) How many nodes do you plan to use in your setup ? If under 32 then almost any transceiver is fine (aside from the fail safe requirement which is recommended) - but many are now 1/8th load devices so you could consider upto 256 RS485 nodes if all such transceivers are the same 1/8th load devices.

5) Recommend you try the following idea - use a single RS485 node and alter your s/w to force the DE (driver enable) on the FRDM board to be ACTIVE (most likely ACTIVE HIGH) -> now when you transmit, the local RS485 transceiver will be fixed to be in transmit mode. On the remote RS485 node, wire up to DISABLE the RS485 transmitted so that the remote RECEIVER is always listening. Assuming you are use a HD (half duplex = 2 wire) interconnect. Now when the FRDM transmits data, the remote unit should be listening - verify this to be solid. Then reverse this setup and confirm that you are able to receive the data from the remote RS485 node. This is effectively a 2 wire RS422 setup but used often to test the wiring between nodes.

6) Is your external RS485 noisy ? If dealing with perhaps motor controllers, etc. then consider to have RS485 isolators between the FRDM and this RS485 setup. Otherwise, ground loops and/or surges can cause failures of the same setup. This is a topic on its own but many good notes on the subject.

7) You can also consider to source a low cost USB / PCIe RS485 adapter to validate that your host is not the issue and even to consider 2 of such adapters so you can xmit and receive between 2 PCs to improve your understanding of the RS485 operation. 2 adapters + 2 wires (+ ground) and you should be able to chat between the 2 PCs in Teraterm or similar. Be sure your baud rates match between the host and remote RS485 nodes.

Check that you are pinging your external remote single node at the proper RS485 node address - often, this is the key mistake.

Share more details if you are still stuck like post your code, wiring diagram, RS485 node details.

Edit:

The RS485 RO of the transceiver MUST have a pull-up to 3v3. This is so when the RS485 receiver is DISABLED - will be when you are transmitting then the RO pin cannot float. The pull-up will be used to park the RO pin. Otherwise the FRDM board and/or remote RS485 node can see false start bits and enter into chaos land. Be sure to have a pull-up on the FRDM RO pin and also a pull-up on the remote RS485 node's RO pin.