为什么ESP8266会挂在这部分代码中?

时间:2017-08-03 18:52:08

标签: c++ arduino infinite-loop esp8266 arduino-esp8266

这是让我麻烦的代码:

void PMS5003::processDataOn(HardwareSerial &serial) {
  unsigned long timeout = millis();
  int count = 0;
  byte incomeByte[NUM_INCOME_BYTE];
  boolean startcount = false;
  byte data;
  while (1){
    yield();
    ESP.wdtFeed();
    if ((millis() - timeout) > 3000){
      //ptrSerial.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 {
    //ptrSerial.println("#[exception] PM2.5 Sensor CHECKSUM ERROR!");
    pm1 = -1;
    pm25 = -1;
    pm10 = -1;
  }
  return;
}
经过几天的工作,ESP8266正悬在这里。我认为这与if ((millis() - timeout) > 3000){有关。

我应该注意什么? millis()溢出了吗?或者减法可能有问题?

@edit

你可以在这里看到我打印DEBUG: 32的一行 - 这是我在终端上看到的最后一件事:

ParticulateMatterMeasurements measurePM() {
    ParticulateMatterMeasurements measurements;
    for (int laserRestartCount = 0; laserRestartCount < 3; laserRestartCount++) {
        Serial.println("DEBUG: 31");
        for (int getMeasurementCount = 0; getMeasurementCount < 10; getMeasurementCount++) {
            Serial.println("DEBUG: 32");
            yield();
            measurements = getMeasurements();
            if (measurements.getAreValid()) {
                return measurements;
            } else {
                delay(2000);
            }
        }
        if (!measurements.getAreValid()) {
            Serial.println("DEBUG: 33");
            restartPMSensor();
        } else {
            break;
        }
        yield();
    }
    if (!measurements.getAreValid()) {
        Serial.println("Restarting ESP (laser error)...");
        ESP.restart();
    }
}

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;
}

@ EDIT2

我的loop方法:

void loop() {
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    Serial.println("DEBUG: 16");
    restartEspIfNotConnected();
    Serial.println("DEBUG: 17");
    AllMeasurements measurements = measureAllParameters();
    Serial.println("DEBUG: 18");
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    sendMeasurementsToBackupServer(getQueryParametersString(measurements));
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    Serial.println("DEBUG: 19");
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    int statusCode = sendMeasurementsToServer(getQueryParametersString(measurements));
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    Serial.println("DEBUG: 20");
    if (statusCode < 0) {
        Serial.println("DEBUG: 21");
        Serial.println(statusCode);
        sendingErrorCounter++;
    } else {
        Serial.println("DEBUG: 22");
        sendingErrorCounter = 0;
    }
    Serial.println("DEBUG: 23");
    if (sendingErrorCounter >= 10) {
        Serial.println("DEBUG: 24");
        ESP.restart();
    }
    Serial.println("DEBUG: 25");
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    sendRssi();
    Serial.println("DEBUG: 26");
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
    checkUpdates();
    Serial.println("DEBUG: 27");
    Serial.printf("Heap: %u\n", ESP.getFreeHeap());
}

@ EDIT3

花了一些时间,但我更接近这个bug。 ESP8266挂在一个我永远不会怀疑的地方。

以下是其他代码:

struct Color {
    double r;
    double g;
    double b;
    Color(double r, double g, double b) : r(r), g(g), b(b) {}
    Color() {}
};

Color green(0, 1024, 0);
Color greenYellow(512, 1024, 0);
Color yellow(1024, 1024, 0);
Color orange(1024, 200, 0);
Color red(1024, 0, 0);
Color blue(0, 0, 1024);
Color white(1024, 1024, 1024);
Color black(0, 0, 0);
Color currentColor;

AllMeasurements measureAllParameters() {
    AllMeasurements allMeasurements;
    double PM25[10], PM1[10], PM10[10];
    double calculatedMedianPm25[6];
    double calculatedMedianPm1[6];
    double calculatedMedianPm10[6];
    bool measureNow = true;
    double bmpTemp[5], dhtTemp[5], humidity[5], bmpPressure[5];
    double bmpTempMedian[6], dhtTempMedian[6], humidityMedian[6], pressureMedian[6];
    int dhtTempSize = 0;
    int humiditySize = 0;
    int dhtTempMedianSize = 0;
    int humidityMedianSize = 0;
    for (int b = 0; b < 6; b++) {
        Serial.println("DEBUG: 28");
        yield();
        int reading = 0;
        for (int i = 0; i < 10; i++) {
            Serial.println("DEBUG: 29");
            yield();
            if (measureNow) {
                BmpMeasurements bmpMeasurements = getMeasurementsFromBmpSensor();
                bmpTemp[reading] = bmpMeasurements.getTemperature();
                bmpPressure[reading] = bmpMeasurements.getPressure();
                double temp = dht.readTemperature(false);
                double hum = dht.readHumidity();
                if (!isnan(temp) && !isnan(hum)) {
                    dhtTemp[dhtTempSize] = temp;
                    humidity[humiditySize] = hum;
                    dhtTempSize++;
                    humiditySize++;
                }
                reading++;
                measureNow = false;
            } else {
                measureNow = true;
            }
            Serial.println("DEBUG: 29.0");
            ParticulateMatterMeasurements measurements = measurePM();
            Serial.println("DEBUG: 29.1");
            PM1[i] = measurements.getPM01Value();
            Serial.println("DEBUG: 29.2");
            PM25[i] = measurements.getPM25Value();
            Serial.println("DEBUG: 29.3");
            PM10[i] = measurements.getPM10Value();
            Serial.println("DEBUG: 29.4");
            delay(1000);
            Serial.println("DEBUG: 29.5");
        }
        Serial.println("DEBUG: 29.6");
        if (isBMP || isBMP280) {
            Serial.println("DEBUG: 29.7");
            pressureMedian[b] = median(bmpPressure, 5);
            Serial.println("DEBUG: 29.8");
            bmpTempMedian[b] = median(bmpTemp, 5);
            Serial.println("DEBUG: 29.9");
        }
        Serial.println("DEBUG: 29.10");
        if (dhtTempSize > 0) {
            Serial.println("DEBUG: 29.11");
            dhtTempMedian[dhtTempMedianSize] = median(dhtTemp, dhtTempSize);
            Serial.println("DEBUG: 29.12");
            dhtTempMedianSize++;
            Serial.println("DEBUG: 29.13");
            dhtTempSize = 0;
            Serial.println("DEBUG: 29.14");
        }
        Serial.println("DEBUG: 29.15");
        if (humiditySize > 0) {
            Serial.println("DEBUG: 29.16");
            humidityMedian[humidityMedianSize] = median(humidity, humiditySize);
            Serial.println("DEBUG: 29.17");
            humidityMedianSize++;
            Serial.println("DEBUG: 29.18");
            humiditySize = 0;
            Serial.println("DEBUG: 29.19");
        }
        Serial.println("DEBUG: 29.20");
        calculatedMedianPm25[b] = median(PM25, 10);
        Serial.println("DEBUG: 29.21");
        changeLedsColorSmoothlyByPM(calculatedMedianPm25[b]);
        Serial.println("DEBUG: 29.22");
        calculatedMedianPm1[b] = median(PM1, 10);
        Serial.println("DEBUG: 29.23");
        calculatedMedianPm10[b] = median(PM10, 10);
        Serial.println("DEBUG: 29.24");
    }
    Serial.println("DEBUG: 30");
    if (isBMP || isBMP280) {
        allMeasurements.averagePressure = average(pressureMedian, 6);
        allMeasurements.averageBmpTemp = average(bmpTempMedian, 6);
    }
    allMeasurements.averageDhtTemp = average(dhtTempMedian, dhtTempMedianSize);
    allMeasurements.averageHumidity = average(humidityMedian, humidityMedianSize);
    allMeasurements.averagePm1 = average(calculatedMedianPm1, 6);
    allMeasurements.averagePm25 = average(calculatedMedianPm25, 6);
    allMeasurements.averagePm10 = average(calculatedMedianPm10, 6);
    return allMeasurements;
}

void changeLedsColorSmoothlyByPM(const double pm25) {
    Serial.println("DEBUG: Leds.1");
    if (pm25 <= 26.6) {
        Serial.println("DEBUG: Leds.2");
        changeColorSmoothly(currentColor, green, 1000);
        Serial.println("DEBUG: Leds.3");
        currentColor = green;
        Serial.println("DEBUG: Leds.4");
        setLedsColorTo(GREEN);
        Serial.println("DEBUG: Leds.5");
    } else if (pm25 <= 44.24) {
        Serial.println("DEBUG: Leds.6");
        changeColorSmoothly(currentColor, greenYellow, 1000);
        Serial.println("DEBUG: Leds.7");
        currentColor = greenYellow;
        Serial.println("DEBUG: Leds.8");
    } else if (pm25 <= 73.63) {
        Serial.println("DEBUG: Leds.9");
        changeColorSmoothly(currentColor, yellow, 1000);
        Serial.println("DEBUG: Leds.10");
        currentColor = yellow;
        Serial.println("DEBUG: Leds.11");
    } else if (pm25 <= 138.29) {
        Serial.println("DEBUG: Leds.12");
        changeColorSmoothly(currentColor, orange, 1000);
        Serial.println("DEBUG: Leds.13");
        currentColor = orange;
        Serial.println("DEBUG: Leds.14");
    } else if (pm25 > 138.29) {
        Serial.println("DEBUG: Leds.15");
        changeColorSmoothly(currentColor, red, 1000);
        Serial.println("DEBUG: Leds.16");
        currentColor = red;
        Serial.println("DEBUG: Leds.17");
        setLedsColorTo(RED);
        Serial.println("DEBUG: Leds.18");
    }
    Serial.println("DEBUG: Leds.19");
}

void changeColorSmoothly(Color oldColor, Color newColor, int timeInMillis) {
    Serial.println("DEBUG: change.1");
    Color currentColor;
    currentColor = oldColor;
    for (int i=0; i<timeInMillis; i++) {
        currentColor.r += (newColor.r-oldColor.r)/timeInMillis;
        currentColor.g += (newColor.g-oldColor.g)/timeInMillis;
        currentColor.b += (newColor.b-oldColor.b)/timeInMillis;
        analogWrite(4, (int) currentColor.r);
        analogWrite(2, (int) currentColor.g);
        analogWrite(15, (int) currentColor.b);
        delay(1);
    }
    Serial.println("DEBUG: change.2");
}

我在终端上看到的最后一件事是DEBUG: change.1。因此,ESP8266在changeColorSmoothly方法内挂起。有什么想法,为什么它挂在那里?

@ edit4

哎呀,我超过了analogWrite()的价值限制吗?这可能是问题吗?

@ edit5

我使用新固件升级了设备,但仍然有一些设备挂起。

0 个答案:

没有答案