start serial.read when start byte received

Hello,

I have one issue communicating over serial with a dust sensor.
Here is the datasheet of the dust sensor:
Datasheet

The sensor is sending 24 bytes over serial every few seconds.
I started with fetching the data this way:

while (serial_pm.available()<24) {} // Wait 'till there are 24 Bytes waiting
   
for(int n=0; n<24; n++) {
   PMvalues[n] = serial_pm.read(); // Then: Get them.
   Serial.print(PMvalues[n]);
   Serial.print("  ");
}

This was working fine before adding other sensors to the setup and using the standby-mode of the dust sensor. Then the output sometimes didn't start with the start character. In example instead of getting:

66 77 0 20 0	26 0 33 0 33 0 26 0 33 0 33 0 0 0 0 0	85 1 176

I got something like this:

33 0 0 0 0 0 85 1 146 66 77 0 20 0 19 0	25 0 33 0 19 0 25

So I have to change the code that it is working like this: "When receiving the start byte 0x42, then start reading 24 bytes."
My approach was the following, not very elegant, I know:

    int start = 0;
    int check = 0;
    int countread = 0;
    int value = 0;

    while (serial_pm.available()>0 && check==0) {
      value = serial_pm.read();
      if (value == 66) {
        start = 1;
        Serial.println("start");
      }
      if (start==1) {
        PMvalues[countread] = value;
        Serial.print(PMvalues[countread]);
        Serial.print(" ");
        countread++;
      }
      if (countread == 24) {
        check = 1;
        Serial.println();
      }
    }

This didn't work very well. At the beginning I receive full 24 bytes correctly, but after that most of the time the output is something like "-1 -1".
I think I have some misunderstand in how the serial.read is working..

Any suggestions?

Any suggestions?

Yes

while (serial_pm.available()<24) {} // Wait 'till there are 24 Bytes waiting

Scrap your code and start again

Never wait in a loop in this way as it creates a blocking function. Yore waiting for input from your sensor without being able to do anything else.

See Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Mark

You have the hang of it but there is an implicit, double negative condition, which often trips people up.

IF a packet is not being assembled
AND the incoming byte is not a start of packet marker,
THEN discard the incoming byte.

This is off the top of my head but hopefully you will see the general idea

void loop() {
    const uint8_t PACKET_START = 66;
    const uint8_t PACKET_TERM = 255;
    const uint8_t PACKET_LENGTH = 24;
    
    boolean collectPacket = false;
    boolean packetAvailable = false;
   
    uint8_t packetLength = 0;
    uint8_t packet[PACKET_LENGTH +1];

    //read the serial buffer
    while( serial_pm.available() ) {
        char ch = serial_pm.read();
        if(!collectPacket) {                    //start of packet
            collectPacket = (ch == PACKET_START);
            packetAvailable = false;
            packetLength = 0;
        }

        if(collectPacket) {                     //collect packet data
            packet[packetLength++] = ch;
            packet[packetLength] = PACKET_TERM;
        }
        
        if(packetLength == PACKET_LENGTH) {     //finalise 
            collectPacket = false;
            packetAvailable = true;
        }
    }

    if(packetAvailable) {
        Serial.println(F("Packet Available"));
    }
}

So I have to change the code that it is working like this: "When receiving the start byte 0x42, then start reading 24 bytes."

When the start byte arrives, you read AND STORE the data (the next 24 bytes, anyway). Prior to that happening, you just read the data (and discard it).

If you use this idea, the code is pretty simple. Robin2 has a good tutorial on reading serial data, including using start and end markers. The end marker can be a unique value OR can be assumed when some number of bytes has been received.

https://forum.arduino.cc/index.php?topic=288234.0