Problem with sensor timing

Hi,

I’ve got a problem with my air quality sensor. I used a sample code from manufacturer’s site (link) and tried to modify it to suit my needs. I would like to read data from the sensor every 20 sec and pass it to the other board. I’ve got a problem with precision and it’s very important to me since I’d like to send average value every 60th received data package via SMS (exactly every 20 minutes). I’m completely new to Arduino. Thanks for any help in advance.

#include <ESP8266WiFi.h>
#include <Wire.h>

#define LENG 31   //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];

int PM2_5Value=0;        
int PM10Value=0;         

char toSend [10];

void setup()
{
  Serial.begin(9600);   //use serial0
  Serial.setTimeout(1500);    //set the Timeout to 1500ms, longer than the data transmission periodic time of the sensor
  Wire.begin(D1, D2);  
}

void loop()
{
  if(Serial.find(0x42)){    //start to read when detect 0x42
    Serial.readBytes(buf,LENG);

    if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        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 
      }           
    } 
  }

  static unsigned long OledTimer=millis();  
    if (millis() - OledTimer >=20000) 
    {
      OledTimer=millis(); 
      
      Serial.print("PM2.5: ");  
      Serial.print(PM2_5Value);
      Serial.println(" ug/m3");     
      
      Serial.print("PM10:  ");  
      Serial.print(PM10Value);
      Serial.println(" ug/m3");   

      sprintf (toSend, "%d,%d", PM2_5Value, PM10Value);
      Serial.print("Ready to send: .");
      Serial.print(toSend);
      Serial.println(".");
      Serial.print("\n");
      Wire.beginTransmission(8); 
      Wire.write(toSend);           
      Wire.endTransmission();    
      memset(toSend, 0, 10);
    }  
}

char checkValue(unsigned char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;

  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;
 
  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data 
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[11]<<8) + thebuf[12]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[13]<<8) + thebuf[14]); //count PM10 value of the air detector module  
  return PM10Val;
}
#define LENG 31   //0x42 + 31 bytes equal to 32 bytes

0x42 + 31 is 97, not 32.

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[11]<<8) + thebuf[12]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

That is NOT what that code does. The function name leaves a lot to be desired, since it does not reflect what the function actually does.

I’ve got a problem

You forgot to tell us what the problem is.

There's no problem with the part of the code responsible for reading sensor values since it's a part of the manufacturer's sample code. It works like a charm. The only problem I have is that the timer is not accurate enough and I receive data slightly delayed. It takes more than 20 sec I wanted.

The only problem I have is that the timer is not accurate enough

You'd be wrong there. The problem is that you have blocking code. When that blocking code is running, like Serial.find() twiddling its thumbs waiting for a 0x42 to arrive, other code can't run.

Get rid of all blocking code.

If there is serial data to read, read ONE byte. Is it a 0x42? If so, then you can wait for the rest of the data. If not, do not sit there with your thumb up your a** waiting for more data. Do something else. Like, check the time. Oh, my god, I'm late...

What a silly mistake. I did everything as you said and now the timing problem is completely gone. Thanks for your time and help.