I am interfacing PM2.5 dust sensor with esp32 and sending data to Thingspeak Platform but the serial monitor shows "Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled."
#include "AHT20.h"// Including library for dht
#include <Adafruit_DPS310.h>
#include <MechaQMC5883.h>
#include <WiFi.h>
#include <Wire.h>
#include <Arduino.h>
#include <EEPROM.h>
#include "sensirion_common.h"
#include "sgp30.h"
#include <Seeed_HM330X.h>
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL_OUTPUT SerialUSB
#else
#define SERIAL_OUTPUT Serial
#endif
HM330X sensor;
static uint8_t buf[30];
#define DPS310_CS 10
#define LOOP_TIME_INTERVAL_MS 1000
#define BASELINE_IS_STORED_FLAG (0X55)
String apiKey = "5F8X1NH7JVS2X4CY"; // Enter your Write API key from ThingSpeak
const char *ssid = "HUAWEI-TBxY"; // replace with your wifi ssid and wpa2 key
const char *pass = "G7494ajE";
const char *server = "api.thingspeak.com";
AHT20 AHT;
float humi, temp;
Adafruit_DPS310 dps;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 1000; // the debounce time; increase if the output flickers
int pinInterrupt = 32;
int Count=0;
float s;
float orint_c;
MechaQMC5883 qmc;
uint16_t pm1_0;
uint16_t pm2_5;
uint16_t pm10_0;
WiFiClient client;
void onChange()
{
if ( digitalRead(pinInterrupt) == LOW )
Count++;
}
void setup()
{
Wire.begin();
Serial.begin(9600);
delay(10);
Serial.println("AHT20 DEMO");
AHT.begin();
//for pressure
Serial.println("DPS310");
//if (! dps.begin_I2C()) { // Can pass in I2C address here
//if (! dps.begin_SPI(DPS310_CS)) { // If you want to use SPI
// Serial.println("Failed to find DPS");
//while (1) yield();
//}
Serial.println("DPS OK!");
dps.configurePressure(DPS310_64HZ, DPS310_64SAMPLES);
//dps.configureTemperature(DPS310_64HZ, DPS310_64SAMPLES);
//for speed
pinMode( pinInterrupt, INPUT_PULLUP);// set the interrupt pin
attachInterrupt( digitalPinToInterrupt(pinInterrupt), onChange, FALLING);//Enable Interrupt
//for wane
qmc.init();
qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
//FOR VOC
s16 err;
u16 scaled_ethanol_signal, scaled_h2_signal;
/*For wio link!*/
#if defined(ESP32)
pinMode(15, OUTPUT);
digitalWrite(15, 1);
Serial.println("Set wio link power!");
delay(500);
#endif
/* Init module,Reset all baseline,The initialization takes up to around 15 seconds, during which
all APIs measuring IAQ(Indoor air quality ) output will not change.Default value is 400(ppm) for co2,0(ppb) for tvoc*/
//while (sgp_probe() != STATUS_OK) {
//Serial.println("SGP failed");
//while (1);
//}
/*Read H2 and Ethanol signal in the way of blocking*/
err = sgp_measure_signals_blocking_read(&scaled_ethanol_signal,
&scaled_h2_signal);
if (err == STATUS_OK) {
Serial.println("get ram signal!");
} else {
Serial.println("error reading signals");
}
// err = sgp_iaq_init();
set_baseline();
//
//for pm2.5
if (sensor.init()) {
SERIAL_OUTPUT.println("HM330X init failed!!");
while (1);
}
Serial.println("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
}
void loop()
{
int x,y,z;//variables for direction
sensors_event_t temp_event, pressure_event;//Pressure sensor variables
AHT20();
Speed();
//pressure calculation
while (!dps.temperatureAvailable() || !dps.pressureAvailable()) {
return; // wait until there's something to read
}
dps.getEvents(&temp_event, &pressure_event);
Serial.print(F("Pressure = "));
Serial.print(pressure_event.pressure);
Serial.println("hPa");
// direction calculation
//qmc.read(&x,&y,&z);
//orint_c = atan2(y, x);
//orint_c = transform(orint_c);
//Serial.println(orint_c);
//if(orint_c>=0 && orint_c<=40)
//Serial.println("NE");
//VOC and eCO2 calculation
s16 err = 0;
u16 tvoc_ppb, co2_eq_ppm;
err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);
if (err == STATUS_OK) {
Serial.print("tVOC Concentration:");
Serial.print(tvoc_ppb);
Serial.println("ppb");
Serial.print("CO2eq Concentration:");
Serial.print(co2_eq_ppm);
Serial.println("ppm");
} else {
Serial.println("error reading IAQ values\n");
}
store_baseline();
//AQI Calculations
if (sensor.read_sensor_value(buf, 29)) {
SERIAL_OUTPUT.println("HM330X read result failed!!");
}
parse_result_value(buf);
parse_result(buf);
SERIAL_OUTPUT.println("");
//pm1_0 = sensor.std.getPM1();
Serial.println(pm1_0);
delay(5000);
//pm2_5 = sensor.std.getPM25();
Serial.println(pm2_5);
delay(5000);
//pm10_0 = sensor.atm.getPM10();
Serial.println(pm10_0);
delay(5000);
delay(20);
if (client.connect(server,80)) // "184.106.153.149" or api.thingspeak.com
{
String postStr = apiKey;
postStr +="&field1=";
postStr += String(temp);
postStr +="&field2=";
postStr += String(humi*100);
postStr += "\r\n\r\n";
postStr +="&field3=";
postStr += String(pressure_event.pressure);
postStr += "\r\n\r\n";
postStr +="&field4=";
postStr += String(s);
postStr += "\r\n\r\n";
postStr +="&field5=";
postStr += String(tvoc_ppb);
postStr += "\r\n\r\n";
postStr +="&field6=";
postStr += String(co2_eq_ppm);
postStr += "\r\n\r\n";
postStr +="&field7=";
postStr += String(pm2_5);
postStr += "\r\n\r\n";
//postStr +="&field5=";
//postStr += String(orint_c);
//postStr += "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
delay(1000); // wait 2s for next reading
}
client.stop();
Serial.println("Waiting...");
// thingspeak needs minimum 15 sec delay between updates
delay(15000);
}
//*****temperature and humidity calculation*****//
void AHT20(void)
{
int ret = AHT.getSensor(&humi, &temp);
if(ret) // GET DATA OK
{
Serial.print("humidity: ");
Serial.print(humi*100);
Serial.print("%\t temerature: ");
Serial.println(temp);
}
else // GET DATA FAIL
{
Serial.println("GET DATA FROM AHT20 FAIL");
}
}
//*****windspeed calculation*****//
void Speed(void)
{
if ((millis() - lastDebounceTime) > debounceDelay) {
lastDebounceTime = millis();
s=((Count*8.75)*0.036);
Serial.print("Wind Speed=");
Serial.print(s);
Count=0;
Serial.println("km/h");
}
}
//*****for wind direction*****//
/*float transform(float c){
if(c < 0)
c += 2*PI;
if(c > 2*PI)
c -= 2*PI;
c = orint_c*180/PI;
return c;
}*/
//*****functions for VOC*****//
void array_to_u32(u32* value, u8* array) {
(*value) = (*value) | (u32)array[0] << 24;
(*value) = (*value) | (u32)array[1] << 16;
(*value) = (*value) | (u32)array[2] << 8;
(*value) = (*value) | (u32)array[3];
}
void u32_to_array(u32 value, u8* array) {
if (!array) {
return;
}
array[0] = value >> 24;
array[1] = value >> 16;
array[2] = value >> 8;
array[3] = value;
}
/*
Reset baseline per hour,store it in EEPROM;
*/
void store_baseline(void) {
static u32 i = 0;
u32 j = 0;
u32 iaq_baseline = 0;
u8 value_array[4] = {0};
i++;
Serial.println(i);
if (i == 3600) {
i = 0;
if (sgp_get_iaq_baseline(&iaq_baseline) != STATUS_OK) {
Serial.println("get baseline failed!");
} else {
Serial.println(iaq_baseline, HEX);
Serial.println("get baseline");
u32_to_array(iaq_baseline, value_array);
for (j = 0; j < 4; j++) {
EEPROM.write(j, value_array[j]);
Serial.print(value_array[j]);
Serial.println("...");
}
EEPROM.write(j, BASELINE_IS_STORED_FLAG);
}
}
delay(LOOP_TIME_INTERVAL_MS);
}
/* Read baseline from EEPROM and set it.If there is no value in EEPROM,retrun .
Another situation: When the baseline record in EEPROM is older than seven days,Discard it and return!!
*/
void set_baseline(void) {
u32 i = 0;
u8 baseline[5] = {0};
u32 baseline_value = 0;
for (i = 0; i < 5; i++) {
baseline[i] = EEPROM.read(i);
Serial.print(baseline[i], HEX);
Serial.print("..");
}
Serial.println("!!!");
if (baseline[4] != BASELINE_IS_STORED_FLAG) {
Serial.println("There is no baseline value in EEPROM");
return;
}
/*
if(baseline record in EEPROM is older than seven days)
{
return;
}
*/
array_to_u32(&baseline_value, baseline);
sgp_set_iaq_baseline(baseline_value);
Serial.println(baseline_value, HEX);
}
//PM2.5 Functions//
const char* str[] = {"sensor num: ", "PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
"PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
"PM10 concentration(Atmospheric environment,unit:ug/m3): ",
};
HM330XErrorCode print_result(const char* str, uint16_t value) {
if (NULL == str) {
return ERROR_PARAM;
}
SERIAL_OUTPUT.print(str);
SERIAL_OUTPUT.println(value);
return NO_ERROR;
}
HM330XErrorCode parse_result(uint8_t* data) {
uint16_t value = 0;
if (NULL == data) {
return ERROR_PARAM;
}
for (int i = 1; i < 8; i++) {
value = (uint16_t) data[i * 2] << 8 | data[i * 2 + 1];
print_result(str[i - 1], value);
if ( i == 2 ) {
pm1_0 = value;
}
if ( i == 3 ) {
pm2_5 = value;
}
if ( i == 4 ) {
pm10_0 = value;
}
}
return NO_ERROR;
}
HM330XErrorCode parse_result_value(uint8_t* data) {
if (NULL == data) {
return ERROR_PARAM;
}
for (int i = 0; i < 28; i++) {
SERIAL_OUTPUT.print(data[i], HEX);
SERIAL_OUTPUT.print(" ");
if ((0 == (i) % 5) || (0 == i)) {
SERIAL_OUTPUT.println("");
}
}
uint8_t sum = 0;
for (int i = 0; i < 28; i++) {
sum += data[i];
}
if (sum != data[28]) {
SERIAL_OUTPUT.println("wrong checkSum!!");
}
SERIAL_OUTPUT.println("");
return NO_ERROR;
}
The pasted code is for a complete weather station but when I add PM2.5 the serial monitor shows something like:
