Reading the Plantower PMS7003 particle sensor (Unrealistic high values)

I am trying to read the Plantower PMS7003 and DHT22 (Relative Humidity and Temperature) sensors using ESP32 and upload the data to 2 Thingspeak channels using WiFi. After several readings, the code breaks and give unrealistic high values. I used the code below.

#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
#include <SoftwareSerial.h>

// WiFi credentials
const char* ssid = "";
const char* password = "";

// ThingSpeak API keys for two channels
const char* apiKey1 = "QX32BBO6UXGWWMCM"; // Channel 1
const char* apiKey2 = "F9PRN6I4UBSG94YF"; // Channel 2

// Define pins and type for DHT22
#define DHTPIN 22          // GPIO pin connected to the DHT22 data pin
#define DHTTYPE DHT22      // DHT22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);

// PMS7003 sensor serial connection
SoftwareSerial pmsSerial(17, 16);

// Variables for tracking measurements
unsigned long previousMillis = 0; // Stores last time data was read
const unsigned long interval = 60000; // 1 minute interval for reading data
int measurementCount = 0;  // Counter to track the number of measurements
const int maxMeasurements = 7;  // Reset sensor after 7 measurements

void setup() {
  // Start serial communication for debugging
  Serial.begin(115200);
  
  // Start PMS sensor communication at 9600 baud
  pmsSerial.begin(9600);

  // Initialize DHT22
  dht.begin();

  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("...");
  }
  Serial.println(" Connected!");
}

struct pms7003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};

struct pms7003data data;

void loop() {
  // Check if 1 minute has passed since the last reading
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; // Reset the timer

    if (readPMSdata(&pmsSerial)) {
      Serial.println();
      Serial.println("---------------------------------------");
      Serial.print("PM 1.0: "); Serial.print(data.pm10_standard);
      Serial.print("\tPM 2.5: "); Serial.print(data.pm25_standard);
      Serial.print("\tPM 10: "); Serial.println(data.pm100_standard);
      Serial.println("---------------------------------------");

      // Increment the measurement counter
      measurementCount++;

      // If 7 measurements have been taken, reset the sensor and flush the buffer
      if (measurementCount >= maxMeasurements) {
        resetSensor();
        measurementCount = 0;  // Reset the counter
      }
    } else {
      Serial.println("Failed to read PMS7003 data.");
    }

    // Read data from DHT22
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();

    if (isnan(humidity) || isnan(temperature)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    Serial.print("Humidity: "); Serial.print(humidity);
    Serial.print(" %\tTemperature: "); Serial.print(temperature); Serial.println(" °C");

    // Send data to ThingSpeak, split across two channels
    if (WiFi.status() == WL_CONNECTED) {
      // Upload the first set of fields to Channel 1
      HTTPClient http1;
      String url1 = "http://api.thingspeak.com/update?api_key=" + String(apiKey1) +
                    "&field1=" + String(data.pm10_standard) +
                    "&field2=" + String(data.pm25_standard) +
                    "&field3=" + String(data.pm100_standard) +
                    "&field4=" + String(data.pm10_env) +
                    "&field5=" + String(data.pm25_env) +
                    "&field6=" + String(data.pm100_env);
                    
      http1.begin(url1);

      int httpCode1 = http1.GET();
      if (httpCode1 > 0) {
        Serial.printf("Data sent to Channel 1, code: %d\n", httpCode1);
      } else {
        Serial.printf("Failed to send data to Channel 1, error: %s\n", http1.errorToString(httpCode1).c_str());
      }
      http1.end();

      // Upload the remaining fields to Channel 2
      HTTPClient http2;
      String url2 = "http://api.thingspeak.com/update?api_key=" + String(apiKey2) +
                    "&field1=" + String(humidity) +
                    "&field2=" + String(temperature) +
                    "&field3=" + String(data.particles_03um) +
                    "&field4=" + String(data.particles_05um) +
                    "&field5=" + String(data.particles_10um) +
                    "&field6=" + String(data.particles_25um) +
                    "&field7=" + String(data.particles_50um) +
                    "&field8=" + String(data.particles_100um);
      http2.begin(url2);

      int httpCode2 = http2.GET();
      if (httpCode2 > 0) {
        Serial.printf("Data sent to Channel 2, code: %d\n", httpCode2);
      } else {
        Serial.printf("Failed to send data to Channel 2, error: %s\n", http2.errorToString(httpCode2).c_str());
      }
      http2.end();
    } else {
      Serial.println("WiFi not connected, data not sent.");
    }
  }
}

boolean readPMSdata(Stream *s) {
  if (!s->available()) {
    Serial.println("No data available from PMS7003.");
    return false;
  }

  uint8_t firstByte = s->peek();
  Serial.print("First byte: "); Serial.println(firstByte, HEX); // Debug output
  if (firstByte != 0x42) { 
    Serial.println("First byte is not 0x42, discarding data.");
    s->read(); 
    return false; 
  }

  if (s->available() < 32) {
    Serial.print("Not enough data available. Bytes available: ");
    Serial.println(s->available());
    return false;
  }

  uint8_t buffer[32];
  uint16_t sum = 0;
  s->readBytes(buffer, 32);

  // Calculate checksum and print buffer for debugging
  for (uint8_t i = 0; i < 30; i++) {
    sum += buffer[i];
    Serial.print(buffer[i], HEX); Serial.print(" ");
  }
  Serial.println();

  uint16_t buffer_u16[15];
  for (uint8_t i = 0; i < 15; i++) {
    buffer_u16[i] = (buffer[2 + i * 2] << 8) | buffer[2 + i * 2 + 1];
  }

  // Copy buffer to data struct
  memcpy((void *)&data, (void *)buffer_u16, sizeof(data));

  // Checksum validation
  Serial.print("Checksum Expected: "); Serial.println(data.checksum, HEX);
  Serial.print("Checksum Calculated: "); Serial.println(sum, HEX);
  if (sum != data.checksum) {
    Serial.println("Checksum failure");
    return false;
  }
  return true;
}

void resetSensor() {
  // Put the PMS7003 sensor to sleep and then wake it up again
  Serial.println("Resetting PMS7003...");
  pmsSerial.write(0x42); // Command to wake up the sensor
  pmsSerial.write(0x4D); // Command to sleep the sensor
  delay(3000);  // Wait for sensor to sleep
  pmsSerial.write(0x42);  // Wake up the sensor
  pmsSerial.write(0x4D);  // Command to wake the sensor
  delay(30000); // Allow time for the sensor to stabilize after wake-up
  Serial.println("Sensor reset complete.");
}