Teensy 3.2 w/ Sparkfun RS485 breakout and USB converter

Status
Not open for further replies.

TimSco

Member
Hi All,

I have a problem that I am trying to troubleshoot.

My project calls for listening to RS422 packets from a pre-existing device on my Teensy 3.2, so I have the Sparkfun RS485 breakout (https://www.sparkfun.com/products/10124), and this works for me fine.

But I want to emulate the RS422 packets for ease of programming. So I have the Sparkfun USB to RS485 converter (https://www.sparkfun.com/products/9822), and I have a terminal on my computer imitating the packets and sending them to the Teensy (via the USB to rs485 converter to the RS485 to TTL breakout). It may seem a little absurd, as I could just use the USB serial instead of this unnecessary conversion. But I want to hot swap my prototype between the two situations. And I also want to emulate the hardware serial limitations and program flow.

But there is something with my configuration that causes the Teensy to stop receiving bytes after the first few, or not receive any.

I don't think there is anything wrong with the Arduino code or the TTL converter config. But I must not have correctly interfaced the USB to RS485. The connections are straightforward (see attached)

I'm using CoolTerm on my mac, and the terminal allows me change RTS, CTS, DTR etc. I'm not sure if it is something to do with that, I've done a fair bit of trial and error there.

I can send a hex string of EE EE EE, and the teensy will reply via USB serial that it has received EE EE EE and a 0, if I send any less or more bytes it doesn't work, and then I can't go back to sending three bytes. If I reboot Teensy it will go back and be able to do the same. This would suggest a code problem, but testing shows it isn't. The RS485 breakout is powered from Teensy and I think the reboot resets it. But none of it makes sense really, It's just so weird!

If anyone has any leads or suggestions that would be much appreciated!

The code is so basic, straight from an example, and works in my other HW serial setup. I'm quite confident there is no errors, but I've attached regardless.


void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial1.begin(9600);
while(!Serial.dtr());
Serial.println("Ready");

}

void loop() {
// put your main code here, to run repeatedly:
int incomingByte;


if(Serial1.available() > 0) {
incomingByte = Serial1.read();
Serial.print("UART received: ");
Serial.println(incomingByte, HEX);
}

}



20170322_150336.jpg
 
Just for testing: try changing your main loop to:

Code:
if(Serial1.available() > 0) {
  incomingByte = Serial1.read();
  if(incomingByte > 0){
    Serial.print("UART received: ");
    Serial.println(incomingByte, HEX);
  }
  else{
    Serial1.flush();
  }
}
 
Just for testing: try changing your main loop to:

Code:
if(Serial1.available() > 0) {
  incomingByte = Serial1.read();
  if(incomingByte > 0){
    Serial.print("UART received: ");
    Serial.println(incomingByte, HEX);
  }
  else{
    Serial1.flush();
  }
}

Thanks for suggestion!

I tried it, no luck unfortunately. I get the same behaviour.

I think the Teensy is running ok. When I remove the power to the RS485 to TTL module with my sketch running, the Teensy will happily receive garbage like FF or close to.. As I believe this would simulate the line being pulled low and constantly sending 1's?? and there is no buffering issues with this.
 
Again others know a lot more about this than me, but if it were me, I would try something like:

Connect the RTS pin to an IO pin (i.e. not GND). Example pin 2

I would then use the transmitterEnable call of the Serial port. i.e. something like:

Code:
void setup() {
// put your setup code here, to run once:
    Serial.begin(9600);
    Serial1.begin(9600);
    pinMode(2, OUTPUT);
    Serial1.transmitterEnable(2);
    while(!Serial.dtr());
    Serial.println("Ready");

}

void loop() {
    // put your main code here, to run repeatedly:
    int incomingByte;


    if(Serial1.available() > 0) {
        incomingByte = Serial1.read();
        Serial.print("UART received: ");
        Serial.println(incomingByte, HEX);
    }

}

Again warning I have not use used this board nor have I actually used RS485, but have done similar for half duplex support (AX Servo support)
 
Connect the RTS pin to an IO pin (i.e. not GND). Example pin 2

Thanks Kurt.
I think setting an IO pin low is essentially the same as my setup, I don't need to ever change data direction.

Because my USB to RS485 converter has TTL level TX-O and RX-I connections straight from the FTDI chip. I'm just going to plug that directly into Teensy. The fact that RS 422/485 in not involved right now is moot. I know I have the rs485 transceiver working in the actual set up.

So I'll proceed like this. Although I'm still curious to why the previous config didn't work, if anyone else has any suggestions!
 
You are probably correct, about the direction pin... The other thing I would check is are TX and RX pins connected to the right pins on the Teensy?

Also sometimes when all else fails I try swapping them... That is sometimes hard to know what sometimes the docs can be confusing, on what is TX and what is RX, i.e. on this board I am assuming that the TX pin is the output of this device which should connect to the RX of the Teensy (pin 0) and the RX pin of this chip ... Should connect to PIN 1 the Teensy...

Like always sometimes showing picture of your actual hookup helps...
 
Although I'm still curious to why the previous config didn't work

RS485 usually involves half-duplex communication.

The 8 pin chip has a pair of signals to enable the driver (when high) and enable the receiver (when low). Normally those are connected together, so each side can decide to only transmit or to only listen. Hardware can also be configured to receive while transmitting, or to totally disable the chip, but those are generally not done. Normally the 2 control pins are wired together, so a single digital signal controls if the chip transmits or receives.

Obviously things only work when one side is listening while the other is sending. If both sides try to transmit at the same moment, neither hears the other's data. Communicating reliably with this limitation requires careful design so both sides follow a clear protocol to know when they can transmit. Many schemes exist, but the most common is a query-response protocol where one side is the "master" that sends the queries and other other side is the "slave" which only answers queries and never initiates communication itself.

When you just connect the TX pin to the RX pin and vise-versa, things are much easier. If both sides happen to send at the same time, each will hear the other because data can flow in both directions at the same time. You don't need to adhere to a strict protocol of who gets to transmit when with this wiring.

So my guess as to "why the previous config didn't work", assuming the hardware really was connected properly (a pretty big "if"), would be lack of a strict protocol to control when each side transmits to the other.
 
As a RS-485 veteran and having used many USB-to-RS485 and RS-485-to-TTL converter chips, I can attest that many of those devices often take a more liberal approach to the specs. That's why I'm not surprised you receive a 0 after your valid message bytes. I often had to implement a routine that eats those bytes when I run into these kinds of problems. It's caused by the transceiver asserting the output lines when it really shouldn't, leading to Teensy (or other UARTS) to think it's receiving something. I painstakingly found this out after hooking up a scope with UART decoding capabilities on the TTL lines and actually seeing this behaviour on screen. That's why I recommended the flush().

It still bugs me why it would make your basic sketch hang though. I would try replacing the USB-to-RS485 converter with another Teensy and a similar RS485 transceiver. Also, does the same behaviour happen when you don't connect grounds?
 
Last edited:
Status
Not open for further replies.
Back
Top