After using UART for so many years I am now exploring RS-232 with flow control. It's exciting but also the wiring can't be more confused. So I'm wondering, there's no hardware flow control on 328P, correct? Thanks.
there is not. but it can be added into HardwareSerial
Maybe de-assert some GPIO acting as DTR or RTS while in RX ISR? Since the hardware buffer is 1-byte deep, the only effective way I've found to receive high baudrate transmission on Arduino so far is to disable RX int and read status register in the main loop. I had to first send to arduino a request byte and wait for arduino to respond with response byte. When arduino noticed the request byte sitting in RX hardware buffer, it stops looping and waits in a while loop to repeatedly check uart status register for more. Then I packetize my transmission to arduino so each packet starts with total length. I send that packet to arduino, which is fast enough to receive repeatedly in a while loop without RX interrupts and return to main loop once expected amount is received.
Any comments? I could go a different route if there's a better one. I think hardware flow control probably only works between devices with hardware buffer, unless processing the received data takes very long time, like printing them to paper.
Or you could just implement buffering...
I normally use something like this
volatile uint8_t buffer[size]
volatile uint8_t counter = 0;
ISR(RX)
{
buffer[counter++] = USART_DATA;
if(buffer[counter-1] == SOME_TERMINATING_BYTE)
{
msgComplete = 1;
counter = 0;
}
}
void loop()
{
if(msgComplete)
{
msgComplete = 0;
// process data here
}
}
You can even implement double buffering where you copy the received buffer into another buffer and do your processing on that buffer, so your original buffer can still received data while you are processing the old data
liuzengqiang:
Maybe de-assert some GPIO acting as DTR or RTS while in RX ISR? Since the hardware buffer is 1-byte deep, the only effective way I've found to receive high baudrate transmission on Arduino so far is to disable RX int and read status register in the main loop. I had to first send to arduino a request byte and wait for arduino to respond with response byte. When arduino noticed the request byte sitting in RX hardware buffer, it stops looping and waits in a while loop to repeatedly check uart status register for more. Then I packetize my transmission to arduino so each packet starts with total length. I send that packet to arduino, which is fast enough to receive repeatedly in a while loop without RX interrupts and return to main loop once expected amount is received.Any comments? I could go a different route if there's a better one. I think hardware flow control probably only works between devices with hardware buffer, unless processing the received data takes very long time, like printing them to paper.
so this is an Arduino forum. so we can discus the Serial classes in the core like HardwareSerial or CDC implementation. HardwareSerial has buffers. the SAMD core has a similar class as AVR HardwareSerial class but there it implements receive flow control (it doesn't use the RX flow control of the SERCOM).
Thanks both. In my one part of my project, serial class won't be useful because and ISR needs the uart to send messages out on a timely manner. In another part I could use serial class because the main loop is using uart. I was playing with ESP32 uarts and was able to get its software and hardware flow control working. It's a pretty thing but still no substitute to packetizing data with a header that tells the length of the packet. I'm interested in samd but maybe after I understand more about ESP32. They are probably comparable in order of magnitude of speed, memory?
esp32 has UART flow control
Juraj:
esp32 has UART flow control
Yes, I have understood hardware flow control better now. ESP32 has two pins RTS and CTS for flow control in both directions. I used those pins in place of DTR and DSR that the actual device I am interacting with is using. It works. Thanks.