How to implement software flow control using easytransfer

Status
Not open for further replies.

Gibbedy

Well-known member
I have a teensy 3.2 with audio adapter doing peak and fft analysis and sending this data to another teensy 3.2 over half duplex rs485 with an octows2811 adapter to use this data to update some pretty lights.

Without any flow control, I'm having to adjust the frequency with which i send my fft/peak data depending on the work load of my octows2811 teensy eg.
if octows2811 teensy is controlling 27 leds I can send it a 131 byte easytransfer message 115 times a second.
if octows2811 teensy is controlling 216 leds I can send it a 131 byte eastransfer message 50 times a second.
I assume buffer on octows2811 teensy is being filled.

In this case I'm not sending anything from the octows2811 teensy to the audio adapter teensy, so I believe I could just create an easyTransfer message with say a bool for send 1 update.

Is this how it should be done?

Can it just be done with a hardware method of another wire and a gpio pin either end?
Would that work reliably/as reliable as an RS485 link alone. What i mean is I have chosen rs485 because i need greater range than rs232. Do I loose any magic of rs485 if I do this?

Thanks.
 
Why limit yourself to software flow control? The Teensy 3.2 does have hardware flow control:

  • https://www.pjrc.com/teensy/td_uart.html;
  • For Serial1, pins 18 and 20 can be used for CTS (clear to send);
  • For Serial2, pin 23 can be used for CTS;
  • For Serial3, pin 14 can be used for CTS;
  • Any digital pin can be used for RTS (release to send);
  • For high speed operation, you want to use either Serial1 or Serial2, both of which have hardware FIFO queues.
 
Why limit yourself to software flow control?

Will adding a wire or two for hardware flow control work at high speed over 1km of rs485 connection with same noise immunity?

I'll probably be running nowhere near that distance,but don't want to have any weird comms issues later.

I don't understand electronics well enough, but I assume rs485 balanced line or whatever it's called does something.
 
I could be wrong, but I believe the issue is the receiving teensy is not clearing buffer quick enough as it does more work (more leds).
 
you could also put 100ohm resistors in series to prevent ringing, as close to the outputs of the devices
 
Generally half duplex communication is done using a protocol specifically designed for half duplex. As far as I know, EasyTransfer doesn't implement such a protocol.

Most of these protocols designate one device as the master. It sends queries to the other device(s). The slave devices listen for queries and reply, but they never transmit unless they've received a query instructing them to do so. This sort of communication assures that no 2 devices will try to transmit at the same time. With half duplex RS485, you need that.

Usually flow control isn't needed with such half duplex protocols. Typically the queries and responses are short enough to fit into the serial buffers. The design where each slave only sends a small reply in response to each limited size query inherently gives you a sort of flow control. Neither side transmits too much at once, due to the design of the protocol and limited size of the messages.

If you want to do full duplex with full rts/cts flow control, you're going to need 8 signal wires (4 pairs) plus ground for the communication. A shielded CAT6 cable could work well. Of course, each side will need 2 transmitters and 2 receivers. That's a lot more wires and hardware than half duplex, but it will let you just use the communication channel as ordinary high speed serial with full automatic flow control. Maybe the simplicity and improved performance of the software side is worth all that extra hardware?
 
Thanks for clearing that up.
I think I'll leave it for now as half duplex one way communication with no flow control and just lower the number of samples/second I send depending on testing.
 
I think of Easy Transfer as a STRUCT wrapper to transport a variety of variables. It doesn't do anything re: CTS/RTS, you have to implement that yourself. However, I really appreciate how easy Mr. Porter's library makes it to share variables among compatible MCU's.

Even better, Paul has been nice enough to make hardware CTS and RTS easily accessible for most serial channels on the Teensy 3 series, as long as you use the right pin for CTS (they are reserved, see Mr. Meissners list above or the Teensy UART page for all compatible models, plus code examples). Once enabled, hardware CTS and RTS take care of that part of signalling, allowing for much reliable operation at high baud rates than otherwise possible.

As mentioned by Paul, to implement CTS/RTS connections with RS485, you will have to reserve a pair of RS485 channels, one for CTS, one for RTS. Not sure that's worth the effort, but it is doable. As suggested by Paul, I use ethernet wiring for RS485 because it's good for high speed, twisted, inexpensive, and available in a variety of lengths.

I'm in the process of implementing a full-duplex channels for RS485 here, where the master is the only one to talk to all the slaves and the slaves share a communications line back to the master. I don't need super fast speeds that CTS/RTS enables with RS485, so I use two pairs of wires in the CAT5e for bus power while the other two pair carry the RS485 signals (A,B,Y,Z).

Where I am using CTS/RTS, however, is with XBee transmissions, allowing the radios ample opportunity to signal when thy are ready for the next bit of data since the buffers are limited, etc.
 
Last edited:
I've re-read posts a few times.
Can I confirm that:
For full duplex rs485 link each teensy needs 4xttl to rs485 converters. These will be for Tx/Rx/cts/rts.
 
I've re-read posts a few times.
Can I confirm that: For full duplex rs485 link each teensy needs 4xttl to rs485 converters. These will be for Tx/Rx/cts/rts.

For full duplex with RTS/CTS, you will need 4 pairs of wire. I would implement it with two full-duplex RS485 chips (i.e. IL83071, among many others). One chip dedicated to UART/Serial, the other to CTS/RTS. Or, buy a single full-duplex RS485 chip with 2/2 channels for each end. Digikey lists 86 with varying stats. Don't forget about termination...
 
You are transmitting a tiny amount of data. Requiring hardware flow control seems crazy to me.

Increase the serial buffer size, so that a few messages fit and don't call easytransfer, when no entire message is available (check SerialX.available()) - it just pointlessly wastes time busy-waiting for the message to trickle in.

Transmitting / receiving data takes little CPU time (if you are not busy-waiting). If your receiving Teensy can't handle all the data, just selectively throw some away and don't bother adjusting the sending rate.
 
You are transmitting a tiny amount of data. Requiring hardware flow control seems crazy to me.
I believe I require hardware flow control because my receiving teensy is clearing the rx buffer slower than the sending teensy is filling it. This is perhaps because I'm doing something crazy on the receiving teensy. Edit: did test and doing 13ms worth of octows2811 is enough to overflow my Serial buffer before Easytransfer gets there once per loop.

Increase the serial buffer size, so that a few messages fit and don't call easytransfer, when no entire message is available (check SerialX.available()) - it just pointlessly wastes time busy-waiting for the message to trickle in.

I call "receiveData()" on my Easytransfer object every loop as per Bill Porters example. I would expect recieveData() not to work as you say. If you've looked at this before please post the details as I'm not able to understand the receiveData() code at my skill level. Edit: did a test and I'm not seeing this. Easytransfer processes whatever is in the serial buffer each time receiveData() is called. On the occasion where this is less than a full 130byte message it completes it on the next loop. my loop time never varies from 13ms in any case. (13ms is octows2811's leds.show() time)

My receiving teensy's buffer was increased to 255 but I'm only ever going to fit 1 130 byte message in my buffer at once.

Transmitting / receiving data takes little CPU time (if you are not busy-waiting). If your receiving Teensy can't handle all the data, just selectively throw some away and don't bother adjusting the sending rate.

My recieving teensy is processing whatever data is available every loop. If that is the same data for 1/2/3 loops it doesn't care. No more or less time is spent processing my audio data.
I'm pretty sure my issue is that my receiving teensy/Easytransfer is not emptying rx buffer quick enough. This is most likely a problem with my code blocking.

Pretty simple to test this and I'll have fun doing it.
Thanks.

edit: from testing, I'm beginning to see your loop time of your rx teensy or your data rate of the tx teensy has to be pretty small to avoid filling 255byte buffer. So I either make sure I can control these for every new light sequence i add to my project, or I put in flow control of some sort to save me thinking about it.
 
Last edited:
Status
Not open for further replies.
Back
Top