stm32duino / Arduino_Core_STM32

STM32 core support for Arduino
https://github.com/stm32duino/Arduino_Core_STM32/wiki
Other
2.81k stars 967 forks source link

Improving Serial reliability on STM32F401 #1104

Closed mrguen closed 4 years ago

mrguen commented 4 years ago

A program is sending a lot of data continuously over Serial. But there is a relatively frequent problem of data communication. Usually some data get truncated/concatenated. This is particularly problematic when 2 data get concatenated.

Here is what it produces when printing "TEST_" in loop:

TEST TEST TEST_ TESTTEST TEST TEST

I was annoyed by this problem because I tried to use the Serial Plotter and that renders the plotting useless (because of autoscale).

I thought the problem was due to my program running too many interrupts. Indeed the problem is worse in my original program that uses ADC, timers, interrupts, DMA etc. But this very simple program still produces data concatenation once a while:

void setup() {
  Serial.begin(9600);
  while(!Serial);
}

void printLoop() {

   for (uint16_t i = 0; i < 4096; i++)
  {
      Serial.println("TEST_");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  printLoop();
  delay(100);

}

Communication problems are reduced if adding while(!Serial); before sending each data but there are still some data concatenation errors.

This was tested on two different STM32F401RCT6 based board, using two different USB cables under Windows and Ubuntu (using the board "CoreBoard F401RCT6" (Also a little "bug": I can't select Generic F401RC" in the list that is too long (Ubuntu system display))

I wonder if there is a way to improve Serial communication? There might be a bug? Or should I use other CDC settings.

I used

fpistm commented 4 years ago

So , to be more precise you have an issue with Serial over USB.

Communication problems are reduced if adding while(!Serial); before sending each data but there are still some data concatenation errors.

Right. This is described here: https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial

I wonder if there is a way to improve Serial communication? There might be a bug? Or should I use other CDC settings.

Did you try with other console than the one form Arduino ?

I've tested your sketch and I did not seen your issue. On host side, USB drivers use a buffer this can be one of the root cause for your issue.

mrguen commented 4 years ago

@fpistm

Thanks. Thi seems to be related to the USB configuration of the device on the PC side.

Disabling the USB FIFO buffer under Windows 10 reduced the problem. But data corruption, even though rare is still present. Example

08:37:34.370 -> 2620.0000000000 08:37:34.404 -> 2782.0000000000 08:37:34.404 -> 2939.0000000000 08:37:34.404 -> 3055.0000000000 08:37:34.438 -> 3203.0000000000 08:37:34.438 -> 3425.0000000000 08:37:34.438 -> 3508.0000000000 08:37:34.438 -> 08:37:34.438 -> 04096696.0000000000 08:37:34.472 -> 727.0000000000 08:37:34.472 -> 788.0000000000 08:37:34.507 -> 834.0000000000 08:37:34.507 -> 830.0000000000 08:37:34.507 -> 946.0000000000 08:37:34.507 -> 1068.0000000000 08:37:34.542 -> 1187.0000000000

It might happen less often but when displaying sequences of thousands of measurements in the serial plotter, it is still a visible problem. SerialPlotterNoBuffer "Regular rendering" with visibly many other problems (related to DMA or ADC, I don't know yet)

SerialPlotterNoBuffer-2 Here above the effect of concatenation with the auto scale

So I tried other settings like flux control, and it was worse.

The device is recognized as a STMicroelectronics Virtual COM Port. It this correct?

fpistm commented 4 years ago

The device is recognized as a STMicroelectronics Virtual COM Port. It this correct?

Yes it is correct.

There is several thing to take into account, on which kind of prot you connect your board? USB 1.2, 2.0,... If you wrote too many data it is possible you loose some data. Try to decrease data.

Unfortunately I have no more clue for you on this.

fpistm commented 4 years ago

Note: You can try the master of the core. The F4 and the USBD middleware has been updated.

mrguen commented 4 years ago

@fpistm With this configuration

I did not see data concatenation anymore.

Under VirtualBox/Ubuntu: still get these errors, probably due to extra latency because of the virtual machine. Very few errors after adding while(!Serial); before sending.

fpistm commented 4 years ago

Fine, if it's solved your issue.

mrguen commented 4 years ago

Well I spoke too early. Still a few errors.

fpistm commented 4 years ago

Well,by experience, this often related to USB host side and the huge part of the USB is related to the USBD middleware which I do not maintains. You can try to reproduce with an example from the cube and submit an issue on the dedicated repo.

mrguen commented 4 years ago

I also wonder what is the exact baud rate? I suppose data is accumulating somewhere because there is a considerable lag between changing the input and seeing the data plotted. Then suddenly there is a data concatenation error (maybe an overflow, because it seems quite periodic) I could not see a difference when changing Serial.begin(9600) to Serial.begin(250000). I can't see a visible effect on lag when changing this value in the Serial monitor neither. To the difference of usual Arduino board a different setting of board rate in the Monitor and begin() does not produce gibberish values.

fpistm commented 4 years ago

With USB CDC baudrate has no effect

mrguen commented 4 years ago

Ok, so how can we increase the througput and/or take a snapshot of data?

fpistm commented 4 years ago

If the bottleneck is on USB host side then you will not be able to change that, I guess. You can try to debug but you will be on your own for this. The USB FS has a 64 bytes packet size so as said before, if you send too much data without being able to read it on host side then you would probably lost data.

fpistm commented 4 years ago

I close this as mainly linked to USB host side bottleneck and not reproduced.