11 years, 3 months ago.

Not able to receive character (RS485)

Hi !

I am using this library to communicate over a RS485 bus with a device. I used pin 9 and 10 (tx,rx) and 19 and 20 as digital outputs for RE and DE.

The transceiver I am using is: ADM3491EARZ

I connected pin 9 to DI, pin 10 to RO, pin 19 to /RE and pin 20 to DE. In order to test the communication I connected the outputs of the transceiver (A, B, Z and Y) to a USB/RS485 cable and connected it to my laptop.

COM3 : mbed COM4 : USB/RS485 Cable

Following happens:

I am using hterm to read the inputs on my pc. I am able to send strings ("Hallo World") over RS485 to COM4.

But unfortunately I am not able to send a character from COM4 over RS485 to COM3 (mbed). It doesn't even wait for any inputs when executing "char rx = rs485.getc()", it directly assigns '\0' to rx....

#include "mbed.h"


Serial rs485(p9, p10);  // tx, rx
Serial pc(USBTX, USBRX);

DigitalOut re_not(p19);
DigitalOut de(p20);

DigitalOut led1(LED1); //transmit mode
DigitalOut led2(LED2); //receive mode

int main() {
    
    char rx;
    
    re_not = 1;
    de = 1;
    led1 = 1;
    
    rs485.printf("Hello World\n"); //print string to device - WORKS
    wait(0.25);
    
    while(1)
    {
        pc.printf("Press a button to continue\n");
        pc.getc();
        if(rs485.readable()) {
            re_not = 0;
            de     = 0;
            pc.printf("readable!\n");
            rx = rs485.getc();            
            pc.printf("read: %c", rx);
            wait(0.25);
        }
        re_not = 1;
        de = 1;
    }
}

I really hope somebody of you guys can help me out...I'm really stuck for so many hours on this issue.... :/

Question relating to:

يجب تحويل اشارة من ثنائي القطب الي احادي القطب بواسطة MAX 232

posted by dark watch 09 Dec 2015

5 Answers

11 years, 3 months ago.

Erik is absolutely right. You cannot have rs485.readable() returning true while your RS485 transceiver is not in listening mode. Normally you should write your program in a way that the RS485 receiver is active and driver inactive by default. Only when you want to send something via RS485, you briefly deactivate the receiver and activate the driver before the print statements and put it back into listening mode just after the print statements. You will probably have to make sure that all the bytes to send have actually copletely left the UART shift register, before putting the RS485 transceiver back in listening mode again after the print statements. This can be done like this:

while (!(LPC_UARTx->LSR & (1 << 6))); wait until TEMT (transmitter empty) Bit turns 1 (see LPC17xx user manual page 307)

Best regards
Nenad

Accepted Answer

Agreed , but then what is wrong with this code

try1.c

#include "mbed.h" 

Serial PC(USBTX , USBRX);
Serial RS485(p28,p27); // Tx, Rx
DigitalOut txen(p26);
DigitalOut rs485_txen(LED1);
unsigned char regvalue[9];
int main()
{
    rs485_txen= 1 ;
    RS485.baud(19200);
    RS485.format(8,SerialBase::Even,1);
    while(1) {
        rs485_txen = !rs485_txen ;    
        txen = 1;
        RS485.putc(0x02);   // slave add
        RS485.putc(0x03);   // function code
        RS485.putc(0x0F);   // Hi PDU add
        RS485.putc(0x3C);   // low PDU add
        RS485.putc(0x00);   // Hi N reg 
        RS485.putc(0x02);   // Lo N reg
        RS485.putc(0x07);   // Hi CRC
        RS485.putc(0x20);   // Lo CRC
        txen = 0;                  // 0V output from digital out pin

        for (int count = 0; count <9; count++) {
            regvalue[count] = RS485.getc(); 
            // Retrieving received register from modbus
            //printf("%X - ", regvalue[count]);  //debugging 
        }
    
    }
} 
posted by Abhinav Jadon 07 Jul 2014
10 years, 1 month ago.

use Ethernet connection for Rs 485

RS485 is completely unrelated to ethernet. You need Serial (ie: UART) connected to a 485 transceiver, which also required DigitalOuts to set it correctly to transmitting or receiving.

posted by Erik - 18 Feb 2014
11 years ago.

Hi Davor, Your code was clear ad simple but please could you just clarify what the fix was.,

LPC_PINCON->PINMODE0 &= (1 << 2);

LPC_PINCON->PINMODE0 &= (1 << 3);

Are there internal pulls ups in the mbed?

John

11 years, 3 months ago.

Okay, I fixed it now.

I had to enable the internal pullups für RX.

    LPC_PINCON->PINMODE0 &= ~(1 << 2);
    LPC_PINCON->PINMODE0 &= ~(1 << 3);

But the problem is not completely solved....

It works only under the condition that I remove "if(rs485.readable())" because the query is never true....

As it works now, I am using it without the query before I read.

Is there a better way to solve this problem?

Hi Davor, Please can you clarify what the fix was Are there internal pullups that need tobe enabled?

Thanks John

posted by John Chilvers 11 Mar 2013

Hi John. I really apologize for not replying you earlier. Yes, I had to enable internal pullups. I guess this is just due to the RS485 transceiver I was using. It may be different with other devices. Furthermore my readable() was always "false" due to wrong states of my enable signals (As Erik and Nenad suggested (cheers guys!))

posted by Student Project 10 May 2013
11 years, 3 months ago.

I would assume it can't be readable until re_not and de are zero, so I think you should move them before the readable check. Although it is probably just as easy without the readable check, since now it will wait until it gets a new char, otherwise it will immediatly restart if there isnt a new char. So then you need to put a wait statement after you make re_not and de zero, during which a new char can be received, and then you can check if it is readable. Then it probably is simpler to just wait using getc() until there is a new char.