Go Down

Topic: Problems with Serial communication (Read 1 time) previous topic - next topic



I have the following issues with the Serial communication.

My program receives a protocol with a certain specification. Hence I am able to detect some errors in the transmission.

In particular, I am controlling a LED Strip by means of the Fast_SPI Library. The protocol contains the RGB data, is approx 30 bytes in length. The processing of the protocol is started as soon as the if(Serial.available>0) in my while(true) is true. The processing itself mainly consists of several if-clauses and the transfer of the Serial buffer (using Serial.read()) into an array.

To smoothen the colour transition I included a time triggered function. Specifically, every 30 ms a volatile boolean is set to true

Code: [Select]


Another if-clause in the while(true) loop checks if this flag is true and begins to calculate the final colour by mixing the current colour with the data last received

Code: [Select]

for (int i=0; i<NUM_LEDS; i++)

Now, what strikes me, is that the implemented check on transmission errors often returns that the last byte had not been received. This only occurs if I have turned on the timer interrupt and the subsequent colour mixture.

Imho, the time-trigger should not affect the reception of the Serial data since it only changes one flag. And the colour mixture can be interrupted by the Serial interrupt anyways...

Thank you in advance!

Nick Gammon

You need to show all your code. It isn't possible to see what the problem is from what you posted.


The Serial library uses a buffer of 64 bytes, so your 30 bytes should be no problem.

As soon as Serial.available() returns a value (the number of received bytes in the buffer) the recption of data is still going on. If you process it right away, you are processing data that is still being received.


Thanks so far.

Yeah the buffer size is not a problem, I even extended it to 256 bytes. Also right now I am using a short delay, but I wanted to try to avoid that by using an if(Serial.available()>=protocolSize ). But since it doesn't get the whole Serial data properly, it wouldn't be reliable this way.

I actually  would like to avoid posting my whole code here since it is a part of a prototypical concept.. hope you understand.

Albeit, I made a mistake in my starting post. Indeed my program returns me that the last byte couldn't be found. But my error-catch is working the way, that it should be actually: Protocol didn't have specified length. Sorry for the confusion. Indeed I can see on my LED-Strip that the specific End Byte has been received.

So, in my case the triggering of the colour smoothing using a timer ISR obviously blocks the correct Serial Data reception, bytes in between are dropped. Anyone an idea why?

Nick Gammon

A timer ISR should not block serial data reception at all, unless you are doing a ridiculously large amount of stuff in it, which it appears not.

You should not need delays, short or not.

Sorry I can't help more debugging code that I can't see.


Too bad, but I understand....

But just for my understanding. In general, it shouldn't be any problem to receive serial data at a baud rate of 115200 while simultaneously every 30 ms a Timer-ISR is running which only sets one flag, right? Do I actually need a cli() ... sei() when I reset my volatile flag? Or is it impossible that the ISR coincidentally corrupts the flag when it is triggered at this specific moment?

Thank you very much in advance

Nick Gammon

The change to the flag should be atomic, as that is storing a single byte.

And the colour mixture can be interrupted by the Serial interrupt anyways...

Yes, but how long does it take? If it was half-way through doing it and another interrupt occurred it would "miss" the second one, because it would finish the first and clear the flag.

Nick Gammon

To smoothen the colour transition I included a time triggered function. Specifically, every 30 ms a volatile boolean is set to true

I think the issue of timing would go away if you simply tested in the main loop if 30 mS has elapsed, and if so, do another calculation. I don't really see what the timer interrupt is adding, as you are testing a flag anyway. If you are testing a flag, why not just test the time itself?


That was a valuable hint. Thank you Nick.

At the beginning I wanted to put the "push the data to the LED-Strip" into the ISR as well, when I realised that this one command takes quite some time (4 ms for 32 LEDs). Hence I ended up polling the flag and didn't realize I can poll the time directly as well. Not it also works better.

Although I still don't get why the ISR which changes only one flag already leads to Serial Rx errors..

Nick Gammon

It wouldn't, normally. But the secret part of your code may do things that have a side effect.

Go Up