Serial.print displaying in the wrong order (Pro-Micro)

I have pared my code down to the minimum to reproduce the problem
and this is a test case for the error.

I am using a Chinese clone of a Pro-Micro and the Arduino 1.6.4 IDE,
the ProMicro identifies itself as a Leonardo and is compiled using the
standard Leonardo core shipped with Arduino 1.6.4

Connect pin 0 to pin 1 (RX to TX loop back) and connect the ProMicro
to the computer using the USB and use the monitor to see the output.

The sketch should print the following
a-z count 1-9 count.
The output on the monitor is not in the same order.
f-z 1-5 count 6-9 a-e count
ie the count is delayed in a core buffer somehow possibly critical
timing in the Serial1 drivers, I do not see any missing volatiles in
the core. Note the printout is in HEX to see any smilie faces, there
are none, only occasional -1’s possibly caused by under runs or over runs.

No bytes are lost just the order is wrong.

(when starting up lots of -1 errors are returned from UART then it stabilizes)

I won’t admit to having started programming on Analogue patch panels 40
years ago in case this is a simple typo, however I think in that time I
have mastered the print statement :slight_smile:

void setup() {

  // Serial connection over UART for test output
  Serial.begin(115200);
  while (!Serial) ;


  // The following delay is so the ProMicro does not brick itself
  // just plug the USB in at same time as doing upload.
  // If it does get bricked 1 sec after starting an upload
  // short rst to gnd. It may take a few tries

  delay(5000); //This is so the ProMicro does not brick itself

  Serial1.begin(9600, SERIAL_8N1);
  while (!Serial1);

}


int count = 0;

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

  // print a to z
  for (i = 'a'; i <= 'z'; i++) {
    Serial1.write(i);
    result1 = Serial1.read();
    Serial.println(result1, HEX);
    //delay 100 no different
  }
  //delay(1000); // no different
  //print a count
  Serial.print (count, DEC);
  Serial.println("##");
  //print 1 to9
  for (i = '1'; i <= '9'; i++) {
    Serial1.write(i);
    result1 = Serial1.read();
    Serial.println(result1, HEX);
    //delay 100 no different
  }
  //delay(1000); // no different

  // print a count
  Serial.print (count, DEC);
  Serial.println("**");
  count++;

  //hang around to see the monitor output
  delay(5000);

}
  for (i = 'a'; i <= 'z'; i++) {
    Serial1.write(i);
    result1 = Serial1.read();
    Serial.println(result1, HEX);
    //delay 100 no different
  }

I’d sorta expect that to print (on the serial monitor)

FFFFFFFF
FFFFFFFF
FFFFFFFF
FFFFFFFF
   :
FFFFFFFF

Ie, all the Serial1.write() calls would complete before the millisecond it takes for the ‘a’ to loop back over the 9600bps real serial port, so the Serial1.read() would keep returning -1 (“no data present”)
That doesn’t seem to be quite what’s happening (I tried the code on a MEGA), but… You’ll definitely get out-of-sync, and then since you’re only reading one character for each character you output, you’ll stay out of sync.

You can probably see things more clearly by having the serial1.read code read as much as is available (here’s what I get on the mega)

0##
0**    [Nothing at all was read for the entire first set of outputs!]
 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 49 50 51 52 53 54 55 56 57 97
1##
1**
 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 49 50 51 52 53 54 55 56 57 97
2##
2**
 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 49 50 51 52 53 54 55 56 57 97
3##
3**
 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 49 50 51 52 53 54 55 56 57 97
4##
4**
 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 49 50 51 52 53 54 55 56 57 97
5##
5**
void setup() {

  // Serial connection over UART for test output
  Serial.begin(115200);
  while (!Serial) ;
  // The following delay is so the ProMicro does not brick itself
  // just plug the USB in at same time as doing upload.
  // If it does get bricked 1 sec after starting an upload
  // short rst to gnd. It may take a few tries

  delay(5000); //This is so the ProMicro does not brick itself
  Serial1.begin(9600, SERIAL_8N1);
  while (!Serial1);
}
int count = 0;

void flush1()
{
  int c;
  byte someprinted = 0;
  while ((c = Serial1.read()) > 0) {
    Serial.print(" ");
    Serial.print(c, DEC);
    someprinted = 1;
  }
  if (someprinted) {
    Serial.println();
  }
}
void loop() {
  // put your main code here, to run repeatedly:
  int result1;
  int i;

  // print a to z
  for (i = 'a'; i <= 'z'; i++) {
    Serial1.write(i);
    flush1();
    //delay 100 no different
  }
  //delay(1000); // no different
  //print a count
  Serial.print (count, DEC);
  Serial.println("##");
  //print 1 to9
  for (i = '1'; i <= '9'; i++) {
    Serial1.write(i);
    flush1();
    //delay 100 no different
  }
  //delay(1000); // no different

  // print a count
  Serial.print (count, DEC);
  Serial.println("**");
  count++;

  //hang around to see the monitor output
  delay(5000);

}

Thanks so much for trying this. You are correct that in my simplifiction I had unintentioanally forced one read for one write. Buying a MEGA was going to be my next step, but I see the original problem exists on a MEGA as well.

I would have expected the output to be

... 122 ##1
49 ... 57 **1
97 ...

but the MEGA prints all the letters then the numbers then the two count statements. So things are still out of order but differently. From the results of the MEGA I would say the problem is not in the serial driver but in the flushing of some internal buffer used to create the strings it is probably not a coincidence that there appear to be 128 characters printed.

SOLVED

As westfw pointed out in simplifying the test I had limited the program to one read for one write. This still did not solve the order problem, but pointed me in the right direction. I am writing at 9600 baud and reading at 115200 baud so I am attempting to read long before the write transmission has completed. By adding a flush() command after the write, the program has to wait for I/O completion before trying to read. This solves the order problem, which was created by some messages going via the rs232 while others were generated locally and were thus much faster.