RTS/CTS in QSerialPort
-
I'm trying to understand how harware handshaking using RTS/CTS works. The end application is a PC app that communicates with a PIC using RS232 to send large-ish chunks of binary data. As the PIC does not have enough memory for a buffer that can hold all the data, it needs to be able to start/stop the PC from sending.
To understand the handshaking, I compiled the QSerialPort 'terminal' app and run that on the PC, with a FTDI cable connected to the USB port. Looking at the signals at the other end, RX/TX are fine. RTS is and output from the PC terminal and stays at 0v all the time. CTS is an input to the PC terminal.
I'd expect that when the terminal wants to send data, it should send RTS low (logic 1) which tells the PIC to be ready to receive data. When ready, the PIC responds by pulling its CTS line low (logic 1) and the terminal sends data.
But this doesn't happen - the RTS line never changes state. It's as if flow control was ignored.
Am I missing something? Why does the terminal have a RTS/CTS handshake option if it does nothing?
-
I'm trying to understand how harware handshaking using RTS/CTS works. The end application is a PC app that communicates with a PIC using RS232 to send large-ish chunks of binary data. As the PIC does not have enough memory for a buffer that can hold all the data, it needs to be able to start/stop the PC from sending.
To understand the handshaking, I compiled the QSerialPort 'terminal' app and run that on the PC, with a FTDI cable connected to the USB port. Looking at the signals at the other end, RX/TX are fine. RTS is and output from the PC terminal and stays at 0v all the time. CTS is an input to the PC terminal.
I'd expect that when the terminal wants to send data, it should send RTS low (logic 1) which tells the PIC to be ready to receive data. When ready, the PIC responds by pulling its CTS line low (logic 1) and the terminal sends data.
But this doesn't happen - the RTS line never changes state. It's as if flow control was ignored.
Am I missing something? Why does the terminal have a RTS/CTS handshake option if it does nothing?
@KeithS Just a comment - I have been "analysing" "terminal" for different reason...
The actual interaction - send serial data - is done in "console"
and RS232 data flow option is set in "settings".If set , RTS is "ASSERTED" ( FANCY WORD) For POSTING IT to / TOWARDS the RECEIVER....
If THERE IS no RECEIVER ATTACHED , as in my case , - I have a piece of test hardware ( LED's ) connected to the actual serial port - there IS NO CTS "ASSERTED" HENCE console DOES NOT SEND ANY DATA.
That is expected behaviour - in my case.Currently I see no code which actually stops the DATA sending...
and that may be the reason why you do not see interaction between RTS and CTS.
I am trying to find the actual "terminal" code processing RTS /CTS.
-
@KeithS Just a comment - I have been "analysing" "terminal" for different reason...
The actual interaction - send serial data - is done in "console"
and RS232 data flow option is set in "settings".If set , RTS is "ASSERTED" ( FANCY WORD) For POSTING IT to / TOWARDS the RECEIVER....
If THERE IS no RECEIVER ATTACHED , as in my case , - I have a piece of test hardware ( LED's ) connected to the actual serial port - there IS NO CTS "ASSERTED" HENCE console DOES NOT SEND ANY DATA.
That is expected behaviour - in my case.Currently I see no code which actually stops the DATA sending...
and that may be the reason why you do not see interaction between RTS and CTS.
I am trying to find the actual "terminal" code processing RTS /CTS.
@AnneRanch
Here is my attempt to isolate code which processes RTS/CTS.
This line stops the actual sending data ......
emit getData(e->text().toLocal8Bit());
when the RTS/CTS option is selected.
how does it check RTS / CTS is unknown ....
// starts proceasing console void ORIGINAL_TERMINAL_Console::keyPressEvent(QKeyEvent *e) { #ifdef OPEN_PORT text ="#ifdef OPEN_PORT"; text += " TASK 1st keyPressEvent "; text += Q_FUNC_INFO; text += " @ line # "; text += QString ::number(__LINE__); qDebug()<< text; #endif switch (e->key()) { case Qt::Key_Backspace: case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up: case Qt::Key_Down: break; default: if (m_localEchoEnabled) { // echo #ifdef OPEN_PORT text ="#ifdef OPEN_PORT"; text += " TASK 2nd echo ..."; qDebug()<< text; #endif QPlainTextEdit::keyPressEvent(e); } #ifdef OPEN_PORT text ="#ifdef OPEN_PORT"; text += " TASK 3rd send ..."; //text += getData(e->text()); // .toLocal8Bit()); //text += QPlainTextEdit::keyPressEvent(e); //text += getData(e->text()); qDebug()<< text; #endif // convert aCSII TO X BITS FORMAT ?? #ifdef OPEN_PORT text ="#ifdef OPEN_PORT"; text += " TASK START 4th convert aCSII TO X BITS FORMAT ?? and send it "; //text += getData(e->text()); // .toLocal8Bit()); //text += QPlainTextEdit::keyPressEvent(e); //text += getData(e->text()); qDebug()<< text; #endif //for (;;) { emit getData(e->text().toLocal8Bit()); #ifdef OPEN_PORT text ="#ifdef OPEN_PORT"; text += " TASK END 5th data send ...."; //text += getData(e->text()); // .toLocal8Bit()); //text += QPlainTextEdit::keyPressEvent(e); //text += getData(e->text()); qDebug()<< text; #endif } } }
-
I'm trying to understand how harware handshaking using RTS/CTS works. The end application is a PC app that communicates with a PIC using RS232 to send large-ish chunks of binary data. As the PIC does not have enough memory for a buffer that can hold all the data, it needs to be able to start/stop the PC from sending.
To understand the handshaking, I compiled the QSerialPort 'terminal' app and run that on the PC, with a FTDI cable connected to the USB port. Looking at the signals at the other end, RX/TX are fine. RTS is and output from the PC terminal and stays at 0v all the time. CTS is an input to the PC terminal.
I'd expect that when the terminal wants to send data, it should send RTS low (logic 1) which tells the PIC to be ready to receive data. When ready, the PIC responds by pulling its CTS line low (logic 1) and the terminal sends data.
But this doesn't happen - the RTS line never changes state. It's as if flow control was ignored.
Am I missing something? Why does the terminal have a RTS/CTS handshake option if it does nothing?
A transmitter asserts its RTS line, which signals the receiver “Can I send some data”? If the receiver is in a position to receive the data it will assert its CTS line, i.e. – “Yes you can start sending”.
Asserted (logic 1) == voltage between -15 and -3V wrt common ground.
Not Asserted (logic 0) == voltage between +3 and +15V wrt common ground.
An "RS232" signal at 0V is out-of-range.The default flow control setting in QSerialPort is QSerialPort::NoFlowControl. That is quite acceptable in many circumstances. If you want hardware flow control then you need to change this from default. Both ends have to be similarly configured.
One possible wrinkle is that not all USB-Serial adapters support hardware flow control or do not fully support RS232 signal levels (i.e use 0 and 5V TTL levels).
Is your PIC interfacing through a MAX232, or the like, to get better RS232 levels?
-
I've tried various things. Initially I had a terminal emulator called 'Serial' running on a Macbook Pro, and connected to the PIC board via a USB-to-RS232 cable. The PIC board used MAX232 to convert levels to TTL.
The terminal emulator was set to 115200 baud, no parity, 1 stop bit and could talk to the PIC and back sucessfully. I then set it to hardware flow control using RTS/CTS.
This as mentioned above allowed driving the CTS input to the terminal, but RTS from the terminal stayed at a logic '1' (that's -ve in RS232 levels).
I then tried using the Qt 'terminal' example with hardware flow control on; same result.
I also tried using a FTDI cable from Mac to PIC, dispensing with the MAX232 as the FTDI chip in the cable does all the level conversion. No difference. And finally I tried a ft232 board (a 'Moyina usb to serial board' from Amazon, again no difference.
All the time I was expecting the terminal to assert RTS before sending data. But nothing, nada, nich. It just stays at logic 1. Is this because the terminal is ready for receiving data (and its unlikely to not be in that position, unless I try and send large amounts of data back from the PIC - I suppose I could try that?). It's a pity that the Qt documentation give no indication of what protocol is being used when RTS/CTS flow control is enabled.
-
I've tried various things. Initially I had a terminal emulator called 'Serial' running on a Macbook Pro, and connected to the PIC board via a USB-to-RS232 cable. The PIC board used MAX232 to convert levels to TTL.
The terminal emulator was set to 115200 baud, no parity, 1 stop bit and could talk to the PIC and back sucessfully. I then set it to hardware flow control using RTS/CTS.
This as mentioned above allowed driving the CTS input to the terminal, but RTS from the terminal stayed at a logic '1' (that's -ve in RS232 levels).
I then tried using the Qt 'terminal' example with hardware flow control on; same result.
I also tried using a FTDI cable from Mac to PIC, dispensing with the MAX232 as the FTDI chip in the cable does all the level conversion. No difference. And finally I tried a ft232 board (a 'Moyina usb to serial board' from Amazon, again no difference.
All the time I was expecting the terminal to assert RTS before sending data. But nothing, nada, nich. It just stays at logic 1. Is this because the terminal is ready for receiving data (and its unlikely to not be in that position, unless I try and send large amounts of data back from the PIC - I suppose I could try that?). It's a pity that the Qt documentation give no indication of what protocol is being used when RTS/CTS flow control is enabled.
OK, " we " have a RTS/CTS defined .
That in my opinion is not the issue.As bad as "terminal" is not documented , it is also not the issue here.
The code posted demonstrate the sequence of outputting / showing/ displaying the ASCII character in "console" .
Since this GROUP ( "we ") is actuality using "terminal" ,
can "'we" make a group effort to find HOW / where is "terminal" code implementing RTS/CTS ?I do not see it in "console". The last line of code just stops output when "RTS/CTS" flow is implemented.
Eventually, after all this is resolved , I like to be able to "emulate CTS " thus bypassing the hardware - for test purpose,
Actually I like to see the code - in "console" referencing "Settings p = m_settings->settings();"