带有ESP8266的PMS5003 - 许多校验和错误

时间:2017-09-26 13:53:05

标签: c++ checksum esp8266 uart arduino-esp8266

我有一个ESP8266通过(硬件)UART连接到PMS5003颗粒物传感器。 从PMS5003读取时,我收到了很多校验和错误。

这是我用来与PMS5003沟通的图书馆:

PMS5003.cpp

#include "PMS5003.h"
void PMS5003::processDataOn(HardwareSerial &serial) {
  unsigned long timeout = millis();
  int count = 0;
  byte incomeByte[NUM_INCOME_BYTE];
  boolean startcount = false;
  byte data;
  int timeoutHops = 0;
  while (1){
    if (((millis() - timeout) > 1000) && (timeoutHops == 0)) {
      timeoutHops = 1;
      yield();
      ESP.wdtFeed();
    }
    if (((millis() - timeout) > 2000) && (timeoutHops == 1)) {
      timeoutHops = 2;
      yield();
      ESP.wdtFeed();
    }
    if ((millis() - timeout) > 3000){
      Serial.println("SENSOR-ERROR-TIMEOUT");
      break;
    }
    if (serial.available()){
      data = serial.read();
      if (data == CHAR_PRELIM && !startcount) {
        startcount = true;
        count++;
        incomeByte[0] = data;
      } else if (startcount) {
        count++;
        incomeByte[count - 1] = data;
        if (count >= NUM_INCOME_BYTE){
          break;
        }
      }
    }
  }
  unsigned int calcsum = 0;
  unsigned int exptsum;
  for (int i = 0; i < NUM_DATA_BYTE; i++) {
    calcsum += (unsigned int)incomeByte[i];
  }
  exptsum = ((unsigned int)incomeByte[CHECK_BYTE] << 8) + (unsigned int)incomeByte[CHECK_BYTE + 1];
  if (calcsum == exptsum) {
    pm1 = ((unsigned int)incomeByte[PM1_BYTE] << 8) + (unsigned int)incomeByte[PM1_BYTE + 1];
    pm25 = ((unsigned int)incomeByte[PM25_BYTE] << 8) + (unsigned int)incomeByte[PM25_BYTE + 1];
    pm10 = ((unsigned int)incomeByte[PM10_BYTE] << 8) + (unsigned int)incomeByte[PM10_BYTE + 1];
  } else {
    Serial.println("#[exception] PM2.5 Sensor CHECKSUM ERROR!");
    pm1 = -1;
    pm25 = -1;
    pm10 = -1;
  }
  return;
}

int PMS5003::getPM1() {
  return pm1;
}

int PMS5003::getPM25() {
  return pm25;
}

int PMS5003::getPM10() {
  return pm10;
}

PMS5003.h

#ifndef _PMS_5003_H
#define _PMS_5003_H

#include <Wire.h>
#include <Arduino.h>

#define VERSION 0.2
#define Sense_PM        6
#define NUM_INCOME_BYTE 32
#define CHAR_PRELIM     0x42
#define NUM_DATA_BYTE   29
#define CHECK_BYTE      30
#define PM1_BYTE        10
#define PM25_BYTE       12
#define PM10_BYTE       14

class PMS5003 {
public:
    //void processData(int *PM1, int *PM25, int *PM10);
    void processDataOn(HardwareSerial &serial);
    int getPM1();
    int getPM25();
    int getPM10();
private:
    int pm1;
    int pm25;
    int pm10;
};
#endif

以下是我如何使用它:

struct ParticulateMatterMeasurements {
private:
    bool _areValid = false;
    int PM01Value = 0;
    int PM25Value = 0;
    int PM10Value = 0;
public:
    void setAreValid(bool _areValid) {
        ParticulateMatterMeasurements::_areValid = _areValid;
    }

    bool getAreValid() const {
        return _areValid;
    }

    int getPM01Value() const {
        return PM01Value;
    }

    void setPM01Value(int PM01Value) {
        ParticulateMatterMeasurements::PM01Value = PM01Value;
    }

    int getPM25Value() const {
        return PM25Value;
    }

    void setPM25Value(int PM25Value) {
        ParticulateMatterMeasurements::PM25Value = PM25Value;
    }

    int getPM10Value() const {
        return PM10Value;
    }

    void setPM10Value(int PM10Value) {
        ParticulateMatterMeasurements::PM10Value = PM10Value;
    }
};

ParticulateMatterMeasurements getMeasurements() {
    ParticulateMatterMeasurements measurements;
    measurements.setAreValid(false);
    pms5003.processDataOn(Serial);
    measurements.setPM01Value(pms5003.getPM1());
    measurements.setPM25Value(pms5003.getPM25());
    measurements.setPM10Value(pms5003.getPM10());
    if (measurements.getPM01Value() != -1 && measurements.getPM25Value() != -1 && measurements.getPM10Value() != -1) {
        measurements.setAreValid(true);
    }
    return measurements;
}

问题是我得到了很多校验和错误。在60次测量期间,我得到了大约100个:#[exception] PM2.5 Sensor CHECKSUM ERROR!

这可能是什么问题?

@edit

我进行了测试,打印PMS5003发送到ESP8266的内容。看起来有时候不会发送作为最后一个字节的校验和。相反,我通常会66,但我有时会看到66 77而不是最后2个字节。

66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 201 2 216 0 86 0 8 0 3 0 1 145 0 3 172 
16
66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 201 2 216 0 86 0 8 0 3 0 1 145 0 3 172 
16
66 77 0 28 0 14 0 18 0 22 0 14 0 18 0 22 10 32 2 239 0 93 0 9 0 3 0 1 145 0 3 45 
18
66 77 0 28 0 14 0 18 0 22 0 14 0 18 0 22 10 32 2 239 0 93 0 9 0 3 0 1 145 0 3 66 
18
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 17 0 20 0 13 0 17 0 20 10 50 2 231 0 88 0 9 0 3 0 1 145 0 3 42 
17
66 77 0 28 0 12 0 16 0 20 0 12 0 16 0 20 9 225 2 208 0 90 0 8 0 3 0 1 145 0 3 190 
16
66 77 0 28 0 13 0 17 0 21 0 13 0 17 0 21 9 225 2 208 0 90 0 8 0 3 0 1 145 0 3 196 
17
66 77 0 28 0 12 0 15 0 17 0 12 0 15 0 17 9 249 2 211 0 76 0 5 0 0 0 0 145 0 3 188 
15
66 77 0 28 0 12 0 15 0 17 0 12 0 15 0 17 9 249 2 211 0 76 0 5 0 0 0 0 145 0 3 188 
15
66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 210 2 188 0 70 0 5 0 0 0 0 145 0 3 118 
15
66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 210 2 188 0 70 0 5 0 0 0 0 145 0 3 118 
15
66 77 0 28 0 13 0 16 0 17 0 13 0 16 0 17 9 198 2 183 0 78 0 5 0 0 0 0 145 0 3 115 
16
66 77 0 28 0 13 0 16 0 17 0 13 0 16 0 17 9 198 2 183 0 78 0 5 0 0 0 0 145 0 3 66 
16
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 12 0 16 0 18 0 12 0 16 0 18 9 234 2 195 0 87 0 8 0 1 0 0 145 0 3 176 
16
66 77 0 28 0 12 0 16 0 18 0 12 0 16 0 18 9 234 2 195 0 87 0 8 0 1 0 0 145 0 3 176 
16
66 77 0 28 0 12 0 15 0 17 0 12 0 15 0 17 9 186 2 184 0 77 0 6 0 1 0 0 145 0 3 101 
15
66 77 0 28 0 13 0 16 0 18 0 13 0 16 0 18 9 186 2 184 0 77 0 6 0 1 0 0 145 0 3 107 
16
66 77 0 28 0 13 0 16 0 18 0 13 0 16 0 18 9 186 2 184 0 77 0 6 0 1 0 0 145 0 3 107 
16
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 165 2 180 0 76 0 6 0 1 0 0 145 0 3 83 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 165 2 180 0 76 0 6 0 1 0 0 145 0 3 83 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 156 2 186 0 76 0 6 0 1 0 0 145 0 3 80 
17
66 77 0 28 0 12 0 16 0 17 0 12 0 16 0 17 9 156 2 186 0 76 0 6 0 1 0 0 145 0 3 66 
16
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 12 0 16 0 17 0 12 0 16 0 17 9 249 2 200 0 67 0 6 0 1 0 0 145 0 3 172 
16
66 77 0 28 0 12 0 16 0 17 0 12 0 16 0 17 9 249 2 200 0 67 0 6 0 1 0 0 145 0 3 172 
16
66 77 0 28 0 12 0 16 0 17 0 12 0 16 0 17 9 231 2 197 0 73 0 7 0 1 0 0 145 0 3 158 
16
66 77 0 28 0 12 0 16 0 17 0 12 0 16 0 17 9 231 2 197 0 73 0 7 0 1 0 0 145 0 3 158 
16
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 243 2 194 0 73 0 7 0 1 0 0 145 0 3 173 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 243 2 194 0 73 0 7 0 1 0 0 145 0 3 173 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 231 2 190 0 70 0 8 0 1 0 0 145 0 3 155 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 231 2 190 0 70 0 8 0 1 0 0 145 0 3 155 
17
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 10 65 2 219 0 68 0 7 0 1 0 0 145 0 3 66 
17
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 10 65 2 219 0 68 0 7 0 1 0 0 145 0 3 18 
17
66 77 0 28 0 13 0 18 0 20 0 13 0 18 0 20 10 86 2 218 0 79 0 11 0 2 0 0 145 0 3 58 
18
66 77 0 28 0 13 0 18 0 20 0 13 0 18 0 20 10 86 2 218 0 79 0 11 0 2 0 0 145 0 3 58 
18
66 77 0 28 0 13 0 18 0 19 0 13 0 18 0 19 10 86 2 216 0 76 0 8 0 1 0 0 145 0 3 47 
18
66 77 0 28 0 13 0 18 0 19 0 13 0 18 0 19 10 86 2 216 0 76 0 8 0 1 0 0 145 0 3 47 
18
66 77 0 28 0 14 0 18 0 20 0 14 0 18 0 20 10 212 2 250 0 75 0 8 0 1 0 0 145 0 3 210 
18
66 77 0 28 0 14 0 18 0 20 0 14 0 18 0 20 10 212 2 250 0 75 0 8 0 1 0 0 145 0 3 210 
18
66 77 0 28 0 12 0 17 0 20 0 12 0 17 0 20 10 137 2 234 0 86 0 10 0 1 0 0 145 0 3 126 
17
66 77 0 28 0 12 0 17 0 20 0 12 0 17 0 20 10 137 2 234 0 86 0 10 0 1 0 0 145 0 3 126 
17
66 77 0 28 0 12 0 17 0 20 0 12 0 17 0 20 10 137 2 234 0 86 0 10 0 1 0 0 145 0 3 66 
17
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 164 2 240 0 95 0 10 0 1 0 0 145 0 3 178 
19
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 164 2 240 0 95 0 10 0 1 0 0 145 0 3 178 
19
66 77 0 28 0 13 0 19 0 21 0 13 0 19 0 21 10 110 2 223 0 95 0 10 0 1 0 0 145 0 3 105 
19
66 77 0 28 0 13 0 19 0 21 0 13 0 19 0 21 10 110 2 223 0 95 0 10 0 1 0 0 145 0 3 105 
19
66 77 0 28 0 13 0 19 0 21 0 13 0 19 0 21 10 128 2 227 0 101 0 10 0 1 0 0 145 0 3 133 
19
66 77 0 28 0 13 0 19 0 21 0 13 0 19 0 21 10 128 2 227 0 101 0 10 0 1 0 0 145 0 3 133 
19
66 77 0 28 0 14 0 20 0 24 0 14 0 20 0 24 10 158 2 254 0 106 0 13 0 4 0 0 145 0 3 211 
20
66 77 0 28 0 13 0 19 0 23 0 13 0 19 0 23 10 158 2 254 0 106 0 13 0 4 0 0 145 0 3 205 
19
66 77 0 28 0 13 0 19 0 23 0 13 0 19 0 23 10 212 3 10 0 107 0 12 0 4 0 0 145 0 3 66 
19
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 14 0 20 0 24 0 14 0 20 0 24 10 212 3 10 0 107 0 12 0 4 0 0 145 0 3 22 
20
66 77 0 28 0 14 0 20 0 24 0 14 0 20 0 24 10 236 3 11 0 109 0 13 0 4 0 0 145 0 3 50 
20
66 77 0 28 0 14 0 20 0 24 0 14 0 20 0 24 10 236 3 11 0 109 0 13 0 4 0 0 145 0 3 50 
20
66 77 0 28 0 15 0 20 0 23 0 15 0 20 0 23 10 254 3 29 0 105 0 9 0 3 0 0 145 0 3 77 
20
66 77 0 28 0 15 0 20 0 23 0 15 0 20 0 23 10 254 3 29 0 105 0 9 0 3 0 0 145 0 3 77 
20
66 77 0 28 0 14 0 19 0 22 0 14 0 19 0 22 11 22 3 40 0 99 0 9 0 3 0 0 145 0 2 101 
19
66 77 0 28 0 14 0 19 0 22 0 14 0 19 0 22 11 22 3 40 0 99 0 9 0 3 0 0 145 0 2 101 
19
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 149 3 6 0 93 0 8 0 3 0 0 145 0 2 184 
19
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 149 3 6 0 93 0 8 0 3 0 0 145 0 2 66 
19
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 14 0 18 0 20 0 14 0 18 0 20 10 140 3 2 0 77 0 5 0 3 0 0 145 0 2 148 
18
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 10 140 3 2 0 77 0 5 0 3 0 0 145 0 2 142 
17
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 10 104 2 251 0 77 0 5 0 3 0 0 145 0 3 98 
17
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 10 104 2 251 0 77 0 5 0 3 0 0 145 0 3 98 
17
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 10 104 2 251 0 77 0 5 0 3 0 0 145 0 3 98 
17
66 77 0 28 0 13 0 18 0 20 0 13 0 18 0 20 10 116 3 11 0 77 0 8 0 3 0 0 145 0 2 134 
18
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 116 3 11 0 77 0 8 0 3 0 0 145 0 2 140 
19
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 137 3 18 0 76 0 7 0 3 0 0 145 0 2 166 
19
[update] This is the newest version.
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 10 137 3 18 0 76 0 7 0 3 0 0 145 0 2 166 
19
66 77 0 28 0 12 0 17 0 18 0 12 0 17 0 18 10 77 2 241 0 77 0 5 0 0 0 0 145 0 3 66 
17
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 12 0 17 0 18 0 12 0 17 0 18 10 77 2 241 0 77 0 5 0 0 0 0 145 0 3 54 
17
66 77 0 28 0 13 0 18 0 19 0 13 0 18 0 19 10 32 2 224 0 80 0 6 0 0 0 0 145 0 3 2 
18
66 77 0 28 0 13 0 18 0 19 0 13 0 18 0 19 10 32 2 224 0 80 0 6 0 0 0 0 145 0 3 2 
18
66 77 0 28 0 13 0 19 0 19 0 13 0 19 0 19 10 47 2 240 0 81 0 5 0 0 0 0 145 0 3 35 
19
66 77 0 28 0 12 0 18 0 18 0 12 0 18 0 18 10 47 2 240 0 81 0 5 0 0 0 0 145 0 3 29 
18
66 77 0 28 0 14 0 20 0 20 0 14 0 20 0 20 10 173 3 6 0 90 0 6 0 1 0 1 145 0 2 202 
20
66 77 0 28 0 14 0 20 0 20 0 14 0 20 0 20 10 173 3 6 0 90 0 6 0 1 0 1 145 0 2 202 
20
66 77 0 28 0 14 0 21 0 21 0 14 0 21 0 21 10 233 3 24 0 90 0 9 0 1 0 1 145 0 3 31 
21
66 77 0 28 0 13 0 19 0 22 0 13 0 19 0 22 10 242 3 25 0 84 0 12 0 4 0 2 145 0 3 38 
19
66 77 0 28 0 13 0 19 0 22 0 13 0 19 0 22 10 242 3 25 0 84 0 12 0 4 0 2 145 0 3 38 
19
66 77 0 28 0 13 0 19 0 22 0 13 0 19 0 22 10 242 3 25 0 84 0 12 0 4 0 2 145 0 3 66 
19
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 15 0 20 0 23 0 15 0 20 0 23 11 79 3 40 0 88 0 9 0 4 0 2 145 0 2 156 
20
66 77 0 28 0 15 0 20 0 23 0 15 0 20 0 23 11 79 3 40 0 88 0 9 0 4 0 2 145 0 2 156 
20
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 11 67 3 38 0 83 0 9 0 4 0 2 145 0 2 129 
19
66 77 0 28 0 14 0 19 0 21 0 14 0 19 0 21 11 67 3 38 0 83 0 9 0 4 0 2 145 0 2 129 
19
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 11 58 3 43 0 82 0 8 0 4 0 2 145 0 2 121 
18
66 77 0 28 0 15 0 19 0 22 0 15 0 19 0 22 11 58 3 43 0 82 0 8 0 4 0 2 145 0 2 127 
19
66 77 0 28 0 15 0 19 0 21 0 15 0 19 0 21 11 31 3 37 0 79 0 7 0 4 0 2 145 0 2 88 
19
66 77 0 28 0 15 0 19 0 21 0 15 0 19 0 21 11 31 3 37 0 79 0 7 0 4 0 2 145 0 2 88 
19
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 10 203 3 11 0 84 0 8 0 4 0 2 145 0 2 66 
18
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 10 203 3 11 0 84 0 8 0 4 0 2 145 0 2 235 
18
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 10 197 3 5 0 84 0 9 0 4 0 2 145 0 2 224 
18
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 10 197 3 5 0 84 0 9 0 4 0 2 145 0 2 224 
18
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 10 179 3 8 0 81 0 8 0 3 0 1 145 0 2 203 
18
66 77 0 28 0 14 0 18 0 21 0 14 0 18 0 21 10 179 3 8 0 81 0 8 0 3 0 1 145 0 2 203 
18
66 77 0 28 0 14 0 17 0 20 0 14 0 17 0 20 10 98 2 243 0 75 0 8 0 3 0 1 145 0 3 90 
17
66 77 0 28 0 14 0 17 0 20 0 14 0 17 0 20 10 98 2 243 0 75 0 8 0 3 0 1 145 0 3 90 
17
66 77 0 28 0 14 0 17 0 19 0 14 0 17 0 19 10 116 2 246 0 77 0 5 0 3 0 1 145 0 3 108 
17
66 77 0 28 0 14 0 17 0 19 0 14 0 17 0 19 10 116 2 246 0 77 0 5 0 3 0 1 145 0 3 66 
17
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 14 0 17 0 19 0 14 0 17 0 19 10 74 2 232 0 80 0 3 0 1 0 1 145 0 3 51 
17
66 77 0 28 0 14 0 17 0 19 0 14 0 17 0 19 10 74 2 232 0 80 0 3 0 1 0 1 145 0 3 51 
17
66 77 0 28 0 14 0 17 0 19 0 14 0 17 0 19 10 74 2 232 0 80 0 3 0 1 0 1 145 0 3 51 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 246 2 220 0 79 0 3 0 1 0 1 145 0 3 205 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 246 2 220 0 79 0 3 0 1 0 1 145 0 3 205 
17
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 9 255 2 222 0 82 0 6 0 1 0 1 145 0 3 224 
17
66 77 0 28 0 13 0 17 0 19 0 13 0 17 0 19 9 255 2 222 0 82 0 6 0 1 0 1 145 0 3 224 
17
66 77 0 28 0 14 0 18 0 20 0 14 0 18 0 20 10 89 2 242 0 85 0 6 0 1 0 1 145 0 3 88 
18
66 77 0 28 0 14 0 18 0 20 0 14 0 18 0 20 10 89 2 242 0 85 0 6 0 1 0 1 145 0 3 66 
18
#[exception] PM2.5 Sensor CHECKSUM ERROR!

一段时间后,我得到更多错误:

66 77 0 28 0 13 0 17 0 66 77 0 28 0 13 0 17 0 17 0 13 0 17 0 17 9 129 2 177 0 65 0 
7168
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 17 0 17 0 66 77 0 28 0 13 0 17 0 17 0 13 0 17 0 17 9 129 2 177 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 17 0 17 0 66 77 0 28 0 12 0 16 0 16 0 12 0 16 0 16 9 186 2 186 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 12 0 16 0 16 0 12 0 16 0 16 9 186 2 186 0 67 0 6 0 0 0 0 145 0 3 92 
16
66 77 0 28 0 12 0 16 0 16 0 12 0 16 0 16 9 174 2 193 0 62 0 5 0 0 0 0 145 0 3 81 
16
66 77 0 28 0 13 0 17 0 17 0 13 0 17 0 17 9 174 2 193 0 62 0 5 0 0 0 0 145 0 3 87 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 180 2 197 0 62 0 6 0 1 0 1 145 0 3 102 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 180 2 197 0 62 0 6 0 1 0 1 145 0 3 102 
17
66 77 0 28 0 13 0 17 0 18 0 13 0 17 0 18 9 165 2 190 0 62 0 6 0 1 0 1 145 0 3 80 
17
66 77 0 28 0 13 0 17 0 66 77 0 28 0 13 0 16 0 18 0 13 0 16 0 18 9 135 2 182 0 65 0 
7168
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 16 0 18 0 66 77 0 28 0 13 0 16 0 18 0 13 0 16 0 18 9 135 2 182 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 16 0 18 0 13 0 16 0 18 9 117 2 180 0 64 0 3 0 2 0 1 145 0 3 20 
16
66 77 0 28 0 13 0 16 0 18 0 66 77 0 28 0 13 0 16 0 18 0 13 0 16 0 18 9 117 2 180 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 12 0 15 0 17 0 12 0 15 0 17 9 153 2 196 0 64 0 3 0 2 0 1 145 0 3 66 
15
66 77 0 28 0 12 0 15 0 17 0 12 0 15 0 17 9 153 2 196 0 64 0 3 0 2 0 1 145 0 3 66 
15
[update] This is the newest version.
66 77 0 28 0 12 0 16 0 19 0 12 0 16 0 19 9 162 2 206 0 71 0 6 0 5 0 2 145 0 3 105 
16
66 77 0 28 0 13 0 17 0 20 0 13 0 17 0 20 9 162 2 206 0 71 0 6 0 5 0 2 145 0 3 111 
17
66 77 0 28 0 13 0 16 0 19 0 13 0 16 0 19 9 123 2 189 0 74 0 6 0 5 0 2 145 0 3 54 
16
66 77 0 28 0 13 0 16 0 66 77 0 28 0 12 0 16 0 20 0 12 0 16 0 20 9 54 2 166 0 76 0 
7168
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 12 0 16 0 20 0 12 0 16 0 20 9 54 2 166 0 76 0 7 0 6 0 2 145 0 2 222 
16
66 77 0 28 0 11 0 15 0 19 0 66 77 0 28 0 11 0 15 0 19 0 11 0 15 0 19 9 21 2 166 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 11 0 15 0 19 0 66 77 0 28 0 12 0 16 0 20 0 12 0 16 0 20 9 21 2 166 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 120 2 189 0 83 0 9 0 6 0 1 145 0 3 65 
16
66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 120 2 189 0 83 0 9 0 6 0 1 145 0 3 65 
16
66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 186 2 198 0 74 0 9 0 5 0 1 145 0 3 130 
16
66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 186 2 198 0 74 0 9 0 5 0 1 145 0 3 130 
16
66 77 0 28 0 13 0 15 0 19 0 13 0 15 0 19 9 171 2 184 0 74 0 9 0 5 0 1 145 0 3 97 
15
66 77 0 28 0 13 0 15 0 66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 198 2 190 0 77 0 
7168
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 16 0 20 0 13 0 16 0 20 9 198 2 190 0 77 0 8 0 5 0 1 145 0 3 136 
16
66 77 0 28 0 13 0 16 0 19 0 66 77 0 28 0 13 0 16 0 19 0 13 0 16 0 19 9 225 2 190 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!
66 77 0 28 0 13 0 17 0 20 0 13 0 17 0 20 10 23 2 214 0 81 0 9 0 3 0 0 145 0 2 246 
17
66 77 0 28 0 13 0 17 0 20 0 13 0 17 0 20 10 23 2 214 0 81 0 9 0 3 0 0 145 0 2 246 
17
66 77 0 28 0 13 0 17 0 20 0 13 0 17 0 20 10 23 2 214 0 81 0 9 0 3 0 0 145 0 2 246 
17
66 77 0 28 0 13 0 17 0 20 0 66 77 0 28 0 13 0 17 0 20 0 13 0 17 0 20 10 98 2 234 0 
19712
#[exception] PM2.5 Sensor CHECKSUM ERROR!

32字节后新行中的孤独数字是PM2.5的值,它不应该变高。但是,它有时会很高,有时候校验和不正确。

我想知道为什么情况会随着时间而变化......也许我可以继续以某种方式重置UART?

2 个答案:

答案 0 :(得分:1)

对于未通过校验和测试的每个数据包,您会在中间或末尾找到CHAR_PRELIM(66)。这意味着传感器偶尔会丢弃数据包并导致错位。

一种解决方案是每次读取66时重新启动数据包读取。这段代码应该这样做:

更新:根据@ sawdust的评论,6677的存在应该用作开始条件,因为它可能是66单独出现在数据中。另一个考虑因素是使用第3和第4个字节提供的数据包长度,而不是假设长度为32.希望这些改进使代码更耐用。

size_t length;
incomingByte[0] = 66; // the first two bytes are always known
incomingByte[1] = 77;

... 

if (serial.available()) {
  if (serial.read() == 66 && serial.read() == 77)
    incomingByte[2] = serial.read(); // length high byte
    incomingByte[3] = serial.read(); // length low byte
    int length = (incomingByte[2] << 8) + incomingByte[3];

    // starting at index 4, read `length` bytes
    serial.readBytes(incomingByte + 4, length);
    break;
  }
}

// when the code breaks out of the while(1) loop, you still need to evaluate the checksum.

根据this source定义的协议,数据包长度固定为32字节,因此编码帧长度(字节3和4)应始终等于0 28(32字节 - 2个起始字节 - 2帧长度字节= 28)。

但是,这段代码甚至可以用于可变长度的数据包(感谢@sawdust)。

公平警告:我没有其中一个传感器,所以显然我没有测试过这个,但概念仍然存在。

我认识到这段代码不会解决被删除字符的问题,因为它只是忽略了不完整的数据包,你仍然依赖于有效性校验和。

最后,我觉得有趣的是校验和失败的原因是因为在这些情况下甚至没有收到校验和字节

希望这有帮助!

更新#2 这或多或少都是修正后的答案。

使用此代码读取数据包,保证以下标准(由协议定义):

  1. 数据包以[66 77]
  2. 开头
  3. 数据包包含32个字节
  4. 开始条件[66 77]永远不会出现在数据包正文中。
  5. 这是代码。我设法将其减少到几个if语句

    void PMS5003::processDataOn(HardwareSerial &serial) {
        bool possibleStart = false;
        incomeByte[0] = 66;
        incomeByte[1] = 77;
        uint8_t count = 0;
    
        ...
    
        while (1) {
            ...
    
            if (serial.available()) {    
                uint8_t c = serial.read();
    
                if (possibleStart) {
                    possibleStart = false;
                    if (c == 77) count = 2;
                }
                if (c == 66) possibleStart = true;
    
                if (count >= 2) incomeByte[count++] = c;
                if (count == NUM_DATA_BYTE) break;      
            }
        }
    
        // at this point, incomeByte must:\
        // > begin with [66 77]
        // > contain 32 bytes
        // > not contain [66 77] anywhere after the first two bytes
        // > therefore, it is guaranteed to contain a checksum
    
        // now is the right time to evaluate the checksum.
        // I expect all of the checksums to match, but you might as well check
    }
    

    在发布时,OP已经编写了满足要求的解决方案。我发布这个是因为我相信这个代码通过更简洁,更具可读性/声明性来改进OP,并且希望更容易管理。

    此代码还可用作通用解决方案,其中两个字符定义启动条件,前提是数据包长度已知或可以测定

答案 1 :(得分:0)

虽然数据损坏的原因仍然存在,但这是我设法实现的解决方法:

  1. 我正在检查校验和,如果不正确,那么:
  2. 我在整个数据中寻找66 77。当我找到它时:
  3. 我正在检查在接下来的16个字节中是否有另一个66 77。如果找不到:
  4. 我假设距离66 77 10-15个字节的值是我正在寻找的值(PM1,PM2.5,PM10)。
  5. 以下是代码:

    void PMS5003::processDataOn(HardwareSerial &serial) {
      unsigned long timeout = millis();
      int count = 0;
      byte incomeByte[NUM_INCOME_BYTE];
      boolean startcount = false;
      byte data;
      int timeoutHops = 0;
      while (1){
        if (((millis() - timeout) > 1000) && (timeoutHops == 0)) {
          timeoutHops = 1;
          yield();
          ESP.wdtFeed();
        }
        if (((millis() - timeout) > 2000) && (timeoutHops == 1)) {
          timeoutHops = 2;
          yield();
          ESP.wdtFeed();
        }
        if ((millis() - timeout) > 3000) {
          yield();
          ESP.wdtFeed();
          Serial.println("SENSOR-ERROR-TIMEOUT");
          break;
        }
        if (serial.available()) {
          data = serial.read();
          if (data == CHAR_PRELIM && !startcount) {
            startcount = true;
            count++;
            incomeByte[0] = data;
          } else if (startcount) {
            count++;
            incomeByte[count - 1] = data;
            if (count >= NUM_INCOME_BYTE){
              break;
            }
          }
        }
      }
      unsigned int calcsum = 0;
      unsigned int exptsum;
      for (int a = 0; a < NUM_INCOME_BYTE; a++) {
        Serial.print((unsigned int)incomeByte[a]);
        Serial.print(" ");
      }
      Serial.println();
      Serial.println(((unsigned int)incomeByte[PM25_BYTE] << 8) + (unsigned int)incomeByte[PM25_BYTE + 1]);
      for (int i = 0; i < NUM_DATA_BYTE; i++) {
        calcsum += (unsigned int)incomeByte[i];
      }
      exptsum = ((unsigned int)incomeByte[CHECK_BYTE] << 8) + (unsigned int)incomeByte[CHECK_BYTE + 1];
      if (calcsum == exptsum) {
        pm1 = ((unsigned int)incomeByte[PM1_BYTE] << 8) + (unsigned int)incomeByte[PM1_BYTE + 1];
        pm25 = ((unsigned int)incomeByte[PM25_BYTE] << 8) + (unsigned int)incomeByte[PM25_BYTE + 1];
        pm10 = ((unsigned int)incomeByte[PM10_BYTE] << 8) + (unsigned int)incomeByte[PM10_BYTE + 1];
      } else {
        Serial.println("#[exception] PM2.5 Sensor CHECKSUM ERROR!");
        pm1 = -1;
        pm25 = -1;
        pm10 = -1;
        for (int a = 0; a < NUM_INCOME_BYTE; a++) {
          bool valid = true;
          if (((unsigned int)incomeByte[a] == 66) && ((unsigned int)incomeByte[a+1] == 77)) {
            if (a+16 < NUM_INCOME_BYTE) {
              for (int b = a+1; b < a+15; b++) {
                if (((unsigned int)incomeByte[b] == 66) && ((unsigned int)incomeByte[b+1] == 77)) {
                  valid = false;
                  break;
                }
              }
              if (valid) {
                pm1 = ((unsigned int)incomeByte[a+10] << 8) + (unsigned int)incomeByte[a+11];
                pm25 = ((unsigned int)incomeByte[a+12] << 8) + (unsigned int)incomeByte[a+13];
                pm10 = ((unsigned int)incomeByte[a+14] << 8) + (unsigned int)incomeByte[a+15];
                Serial.println("valid: ");
                Serial.print(pm1);
                Serial.print(" ");
                Serial.print(pm25);
                Serial.print(" ");
                Serial.print(pm10);
                Serial.println();
                break;
              }
            }
          }
        }
      }
      return;
    }
    

    理论上,它可能产生误报或否定,但在实践中,它只是有效。

    66 77 0 28 0 12 0 15 0 17 0 12 0 15 0 17 9 102 2 176 66 77 0 28 0 12 0 15 0 16 0 12 
    15
    #[exception] PM2.5 Sensor CHECKSUM ERROR!
    valid: 
    12 15 17
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 114 2 175 0 73 0 4 0 1 0 0 145 0 3 12 
    15
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 114 2 175 0 73 0 4 0 1 0 0 145 0 3 12 
    15
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 141 2 190 0 72 0 3 0 1 0 0 145 0 3 52 
    15
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 141 2 190 0 72 0 3 0 1 0 0 145 0 3 52 
    15
    66 77 0 28 0 12 0 16 0 16 0 12 0 16 0 16 9 198 2 202 0 75 0 3 0 0 0 0 145 0 3 125 
    16
    66 77 0 28 0 12 0 16 0 16 0 66 77 0 28 0 12 0 16 0 16 0 12 0 16 0 16 9 198 2 202 0 
    19712
    #[exception] PM2.5 Sensor CHECKSUM ERROR!
    valid: 
    12 16 16
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 174 2 199 0 71 0 3 0 0 0 0 145 0 3 92 
    15
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 174 2 199 0 71 0 3 0 0 0 0 145 0 3 92 
    15
    66 77 0 28 0 12 0 15 0 16 0 12 0 15 0 16 9 174 2 199 66 77 0 28 0 13 0 16 0 16 0 13 
    15
    #[exception] PM2.5 Sensor CHECKSUM ERROR!
    valid: 
    12 15 16
    66 77 0 28 0 13 0 16 0 16 0 13 0 16 0 16 9 213 2 205 0 72 0 3 0 0 0 0 145 0 3 142 
    16
    66 77 0 28 0 13 0 16 0 16 0 13 0 16 0 16 9 213 2 205 0 72 0 3 0 0 0 0 145 0 3 142 
    16
    66 77 0 28 0 13 0 16 0 17 0 13 0 16 0 17 9 207 2 208 0 83 0 6 0 1 0 0 145 0 3 156 
    16
    66 77 0 28 0 13 0 16 0 17 0 13 0 16 0 17 9 207 2 208 0 83 0 6 0 1 0 0 145 0 3 156 
    16
    66 77 0 28 0 13 0 17 0 17 0 13 0 17 0 17 9 159 2 202 0 87 0 5 0 1 0 0 145 0 3 107 
    17
    66 77 0 28 0 13 0 17 0 17 0 66 77 0 28 0 13 0 17 0 17 0 13 0 17 0 17 9 159 2 202 0 
    19712
    #[exception] PM2.5 Sensor CHECKSUM ERROR!
    valid: 
    13 17 17