Serial Flow Control (Handshaking)

Dear friends,

I am trying to develop a USB Plotter based on "Motori the Ploter" (Motöri the Plotter), running on board Uno or Mega1280.
The main problem I am facing now is the Serial Flow Control, because arduino must receive USB bytes (HPGL), process the bytes and move the motors according to the HPGL instruction (sometimes motors can take 10 seconds to draw a long line), but the PC is sending the complete USB data to Arduino and arduino just read the firsts 64 bytes. The other bytes are just lost.
I would like arduino to receive only one byte and somehow the PC should stop sending a new byte until the PC to receive a command in order to send a new byte, example:

if (Serial.available() > 0) {
char c = (char)Serial.read();
Serial.write(0x13); //XOFF
...
HPGL parser
Motors moving
...
} else {
Serial.write(0x13); //XON
}

Is there any way to solve flow control on USB?

Thank you very much.

Eduardo Marzolla

What's sending the commands to the Arduino? That will need to be adapted to wait until the Arduino is ready for the next command. In principle though what you have suggested should be workable.

Hi,

Attached is my project.

I made a very simple code in order to test it:

void loop() {

  if (Serial.available() > 0) 
  {
    Serial.write(0x13); //sends the XOFF
    delay(100);
    char c = (char)Serial.read();
    delay(5000); //this line represents the motor moving from point A to point B and taking 5 seconds
  } else 
  {
  Serial.write(0x11); //sends the XON
  }
}

In order to test this code:

  1. On the Windows Device Manager, setup the COM4 to 9600N1, FlolCOntrol Xon/Xoff too
  2. Open Tera Terminal (application like hyperterminal) and configure the port to COM4 (my USB port), 9600N1, FlolCOntrol Xon/Xoff
  3. On Tera Terminal, send a text file with 1000 bytes
    Only the firsts 64 bytes are received on Arduino

My desire is:
1 - Arduino to receive one (or few) bytes and sends a XOFF to the PC (Windows is set to software flow control)
2 - Arduino would process the received bytes (e.g. moving motors)
3 - After processing the bytes, Arduino would send a XON to the PC
4 - PC would send one (or few) bytes again and loop this sequence

Do you know what I am doing wrong?

Thanks

marzollaplotterv1.h (2.75 KB)

marzollaplotterv1.ino (17.1 KB)

I think the problem is that when you are sending your XONs repeatedly, the first 64 (I think) fill up the serial tx buffer, so while they are being sent the Serial.write function blocks the processor until there's space in the buffer for the next character. When you receive a character it tries to send the XOFF, but the tx buffer is still full with the XONs, so it will have to wait for all of these to be sent before the XOFF actually gets sent. Because your PC hasn't received the XOFF yet it will still be sending characters, and I'm sure it will be no surprise that it takes just as long to fill up the rx buffer as it takes to empty the tx buffer. You then are only reading one character from the rx buffer, and the loop starts again, the tx buffer fills up (this will probably happen faster than the processor can even send a single byte), however this time because the rx buffer is already full (only one character was read out of it last time) the old data gets written over and lost.

The main thing I think you need to fix is that you should only send an XON every few seconds, to stop the Tx buffer filling up (don't use delay though, look at blink without delay for how to do this properly). Also in your parsing section read all of the data, not just a single character. Now that I look at it I think you may indirectly do this anyway, but I would add a command buffer in your code and you can keep filling with the serial data until you get a command, then send the XOFF, process it, send an XON etc.

Hi,
I tested your suggestion and the same happened (attached is the source).
I don't know if Tera Terminal (Windows) is identifying the 0x13 (XOFF) and 0x11 (XON) Arduino is sending.
Please let me know if someone has the solution.

Thx,

Eduardo

marzollaplotterv1.h (2.75 KB)

marzollaplotterv1.ino (17.2 KB)

The source you've attached doesn't seem to implement either of the changes I suggested. If it still isn't working I would try a different terminal program, or even better, build your own specific application to do this.

Hi
I have the same problem. After sending Xoff Arduino NANO receives one byte or nothing. Program process data and sends XOn, and gets next 63 byte from hardware buffer. Rest data are lost. I suspect that problem is with software on PC. Terminal (I use Hercules) sends data in the pocket. After receiving Xoff terminal software stops transmission no exactly in that moment but after sending the whole packet for example 4 kB. So SRAM buffer should be greater then terminal pocket.

Try another terminal program (I have had success using RealTerm with xon/xoff; see Reading instructions from a file - #11 by sterretje - Project Guidance - Arduino Forum but don't ask why I implemented what was implemented).