The issue was that you are not allowed to block shared resources (like
Serial1) in a software timer.
Moving that stuff into
serialEvent1() isn't really anything other than having the same code inside
loop() since these "events" are no real events, but just a synchronous function that's called between iterations of
But this will still have impact on the execution speed of
loop() whereas this (untested) code would be non-blocking
int bufIndex = -1; // current index in message buffer (-1 indicates not started)
int b = 0;
// when not already started a message, flush everything up to first 'B'
while (bufIndex < 0 && (b = Serial1.read()) >= 0 && b != 'B') Particle.process();
// if we got a start byte start a new message
if ('B' == b) bufIndex = 0; // had en error here, hence the following discussion (if (`B` = b) caused the problem)
// fill all available bytes into open message buffer
while (0 <= bufIndex && bufIndex < sizeof(buf) && Serial1.available())
buf[bufIndex++] = Serial1.read();
if (bufIndex == sizeof(buf))
if(buf == 0x4d && checkValue(buf,LENG))
PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
bufIndex = -1; // mark as treated and ready for next message
The reason why software timers are not impacted by a blocking app code is that these are handled by RTOS, which executes them "asynchronously" to the main application.
If you add a D7 blink code like
digitalWrite(D7, (millis() >> 2) & 0x88); to
loop() you should see frequent glitches in the pattern when your code blocks, but with the above, these glitches should be less noticeable.