karser/KarserDSM501

Incorrect values.

Opened this issue · 9 comments

Hello. I came across your library and an example for taking readings from the dsm501 sensor. Your example is the best. But here's the problem when I add mqtt to your example. All indications become incorrect. I guess the problem is in time. But I can't figure out how to solve it.

Do you use delays? Can you maybe show the code? What device is it btw?

#include "AGS02MA.h"
#include <Wire.h>
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>

#define WIFI_SSID "NETGEAR"
#define WIFI_PASSWORD "14117687"

// Raspberry Pi Mosquitto MQTT Broker
#define MQTT_HOST IPAddress(192, 168, 31, 145)
// For a cloud MQTT broker, type the domain name
//#define MQTT_HOST "example.com"
#define MQTT_PORT 1883

// Temperature MQTT Topics
#define MQTT_PUB_TEMP "esp32/ags02ma/tvoc"

float ppm25;
#define DUST_SENSOR_PIN_PM10 5 //Must be the pins that
#define DUST_SENSOR_PIN_PM25 2 //support interrupts

#define INTERVAL_COUNTDOWN 1000
#define INTERVAL_READ 30000

#include <KarserDSM501.h>
// ISRs forward declaration
void pm10_handleInterrupt();
void pm25_handleInterrupt();
// init pm10 and pm25 instances
KarserDSM501 pm10(DUST_SENSOR_PIN_PM10, pm10_handleInterrupt);
KarserDSM501 pm25(DUST_SENSOR_PIN_PM25, pm25_handleInterrupt);
// handle ISRs
void pm10_handleInterrupt() { pm10.handleInterrupt(); }
void pm25_handleInterrupt() { pm25.handleInterrupt(); }

unsigned long timer = 0;
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;

unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 1000; // Interval at which to publish sensor readings

void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}

void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
void onMqttPublish(uint16_t packetId) {
Serial.print("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}

void setup() {
Serial.begin(115200);
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));

WiFi.onEvent(WiFiEvent);

mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
// If your broker requires authentication (username and password), set them below
mqttClient.setCredentials("mqtt", "mqtt");
connectToWifi();
}

void loop() {

if (!pm10.isReady() && (millis() >= timer + INTERVAL_COUNTDOWN)) {
Serial.println("DSM501 warm up: " + String(pm10.getReadyCountdown()));
timer += INTERVAL_COUNTDOWN;

} else if (millis() >= timer + INTERVAL_READ) {
timer += INTERVAL_READ;
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(pm25.readPM()).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_PUB_TEMP, packetIdPub1);
Serial.printf("Message: %.2f \n", String(pm25.readPM()));
}
}

I'm not selenium in programming. I have one sample, I connect different sensors in the image and likeness.

Are you Russian? then you can use Russian, it will be easier this way

Let's stick to English since this might help somebody else.

Try commenting out this line
//uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(pm25.readPM()).c_str());
and check if the pm25 value is correct in console.
So that you will figure out if the issue happens during publishing or setup.

I've done it before. It doesn't help. I completely removed everything from the "void loop", leaving only your code. And still the values are not correct. I think the problem is connecting to wi-fi and to the mqtt server. Somewhere in this place there is a delay that causes the pulses to be counted incorrectly.

I have now tried another example. And the same thing, after I add the code to send to the mqtt server, the values begin to be incorrect. Apparently I turned to the wrong address(

If interrupts don't work during wi-fi connection you probably should split this task into 2 boards so that pulses will be counted uninterruptedly. I'm wondering if ATTINY13 can handle this task.

in general, have examples on esp8266 with sending to the mqtt server. But they are too sophisticated. They are on platform.io and there is a lot of excess, for example, temperature sensors. It takes a very long time to clean all this.