Hello, I need help, I am new to nextion screens and data storage, I am doing a monitoring project where I measure gas concentrations, for now I can read the values and send them to the nextion screen, I also save the data in matrices from time to time, the problem is that I don't know how to graph that data, I attach my code, I hope your help.
CODE_SENSORS1.ino (5,1 KB)
#include <Arduino.h>
#include "MHZ19.h"
#include <Adafruit_ADS1X15.h>
#include <Wire.h>
#include <RTClib.h> // Librería para el RTC DS3231
#include <HardwareSerial.h>
RTC_DS3231 rtc; // Crear una instancia del RTC
Adafruit_ADS1115 ads;
#define PinMQ4 0 // Canal A0 del ADS1115 para MQ4 (Metano)
#define PinMQ7 1 // Canal A1 del ADS1115 para MQ7 (Monóxido de Carbono)
#define PinMQ8 2 // Canal A2 del ADS1115 para MQ8 (Hidrógeno)
#define NEXTION_SERIAL Serial2
// Tx pin which the MHZ19 Rx pin is attached to // Device to MH-Z19 Serial baudrate (should not be changed)
MHZ19 myMHZ19; // Constructor for library
HardwareSerial mySerial(1); // On ESP32 we do not require the SoftwareSerial library, since we have 2 USARTS available
int CO_ppm;
int H2_ppm;
int CH4_ppm;
int CO2;
int minutes;
int hours;
String receivedData = "Z";
// We store the last 24 hours sensor values in arrays - store value each 15 minutes so for 24 hours we need 96 bytes.
// We must use bytes and can't increse the storing to let's say 5 mins because the Arduino Pro Mini has a limited dynamic memory
uint8_t COData[96] = {};
uint8_t CH4Data[96] = {};
uint8_t CO2Data[96] = {};
uint8_t H2Data[96] = {};
unsigned long sensorReadTimer = 0;
bool shouldStoreData = false;
void setup() {
NEXTION_SERIAL.begin(9600); // (Uno example) device to MH-Z19 serial start
mySerial.begin(9600, SERIAL_8N1, 18, 19);
myMHZ19.begin(mySerial); // *Serial(Stream) reference must be passed to library begin().
myMHZ19.autoCalibration(); // Turn auto calibration ON (OFF autoCalibration(false))
ads.begin();
Wire.begin(); // Iniciar la comunicación I2C para el RTC
rtc.begin(); // Iniciar el RTC
// Ajustar la hora y fecha del RTC si es necesario
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
void loop() {
DateTime now = rtc.now(); // Obtener la fecha y hora actual del RTC
if (millis() - sensorReadTimer >= 8000) {
CO2 = myMHZ19.getCO2();
int16_t rawMQ4 = ads.readADC_SingleEnded(PinMQ4);
int16_t rawMQ7 = ads.readADC_SingleEnded(PinMQ7);
int16_t rawMQ8 = ads.readADC_SingleEnded(PinMQ8);
float MQ4_RS = (float)(65535 - rawMQ4) / rawMQ4;
float MQ7_RS = (float)(65535 - rawMQ7) / rawMQ7;
float MQ8_RS = (float)(65535 - rawMQ8) / rawMQ8;
float MQ4_R0 = 10.80; // Valor de resistencia R0 para el sensor MQ4 (calibrar según el sensor)
float MQ7_R0 = 1.20; // Valor de resistencia R0 para el sensor MQ7 (calibrar según el sensor)
float MQ8_R0 = 0.90; // Valor de resistencia R0 para el sensor MQ8 (calibrar según el sensor)
// Calcular las concentraciones en ppm utilizando las relaciones RS/R0
float CH4_ppm = pow(10, ((log10(MQ4_RS / MQ4_R0) - (0.9873)) / 2.6386));
int CO_ppm = pow(10, ((log10(MQ7_RS / MQ7_R0) - (-1.4065)) / 2.0162));
float H2_ppm = pow(10, ((log10(MQ8_RS / MQ8_R0) - (-0.7152)) / 2.9891));
String dia = String(now.day());
String mes = String(now.month());
String anio = String(now.year());
// Enviar los datos a la pantalla Nextion
NEXTION_SERIAL.print("t0.txt=\"CH4:" + String(CH4_ppm)+"ppm\"");
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.print("t1.txt=\"CO:" + String(CO_ppm)+"ppm\"");
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.print("t2.txt=\"H2:" + String(H2_ppm)+"ppm\"");
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.print("t4.txt=\"Fecha:"+dia + "/" + mes + "/" + anio + "\"");
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.print("n0.val=");
NEXTION_SERIAL.print(CO2);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
NEXTION_SERIAL.write(0xFF);
sensorReadTimer = millis(); // Reiniciar el temporizador de lecturas de sensores
}
// Comprobar si ha pasado 5 minutos desde la última vez que se almacenaron los datos
if (now.minute() % 2 == 0 && now.second() == 0) {
shouldStoreData = true;
}
// Almacenar los datos en las matrices cuando corresponda
if (shouldStoreData) {
storeData(); // Llamar a la función para almacenar datos en las matrices
shouldStoreData = false; // Reiniciar la bandera
}
}
void storeData() {
// Storing current sensor values into arrays
memmove(COData, &COData[1], sizeof(COData));
COData[sizeof(COData) - 1] = map(CO_ppm, 0, 1000, 0, 255);
memmove(CH4Data, &CH4Data[1], sizeof(CH4Data));
CH4Data[sizeof(CH4Data) - 1] = map(CH4_ppm, 0, 500, 0, 255);
memmove(CO2Data, &CO2Data[1], sizeof(CO2Data));
CO2Data[sizeof(CO2Data) - 1] = map(CO2, 0, 5000, 0, 255);
memmove(H2Data, &H2Data[1], sizeof(H2Data));
H2Data[sizeof(H2Data) - 1] = map(H2_ppm, 0, 500, 0, 255);
}