Nextion Display + ESP32

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

  }

I do not know Nextion, but you can warm up the graphing by using a serial monitor. Here is an example of multiple variable inputs simulating your data changes. The output is a vertical text plotter. You can increase the number of analog inputs just by adding a call to the plotter.

[edit] many changes/improvements[/edit]...

// textplot

#define analogInputs 4 // number of analog inuts
int POT[analogInputs] = {A0, A1, A2, A3}; // analog inputs

#define DELAY   100     // delay between analog read
#define MININ   0       // analog input minimum value
#define MAXIN   1023    // analog input maximum balue
#define MINOUT  0       // analog input re-mapped minimum value 
#define MAXOUT  15      // analog input re-mapped maximum value
#define PLOTGAP MAXOUT  // width of each plot to maintain formatting

void setup() {
  Serial.begin(115200); // start serial monitor

  for (int i = 0; i < analogInputs; i++)
   pinMode(POT[i], INPUT); // configure analog input pin

}

void loop() {
  for (int i = 0; i < analogInputs; i++)
   plotter(POT[i]); // label and plot

  Serial.print("\n"); // end of plotter line
  delay(DELAY);
}

void plotter(int input) {
  // map the analog input to a plotable range
  int value = analogRead(input);
  int output = (map(value, MININ, MAXIN, MINOUT, MAXOUT));

  if (input == 14) // Analog pin A0 is Arduino pin 14
    Serial.print("|");
  Serial.print(input-13); // translate 14, 15, 16, 17 to 1, 2, 3, 4
  Serial.print("=");
  spacePad(value);
  Serial.print(value);
  Serial.print("|");

  // plot the data
  for (int i = 0; i < output; i++)
    Serial.print(" ");
  Serial.print("*");

  // add a gap before next plot line
  for (int i = 0; i < PLOTGAP - output; i++)
    Serial.print(" ");
  Serial.print("|");
}

void spacePad (int value) {
  if (value < 1000)
    Serial.print(" ");
  if (value < 100)
    Serial.print(" ");
  if (value < 10)
    Serial.print(" ");
}

I'm on holiday at the moment so no access to my PC, which makes it difficult to help. In the Nextion IDE there is an object for a graph, sorry I can't remember what it's called. Look it up and look at the Nextion instruction set on the Nextion web site. Also look at my Nextion tutorial at the top of the Display category of the forum. If you are still struggling by Sunday put your best effort here and remind me, I'll have a look.

Hi Perry, nothing appears in your tutorial about the waveform, which is what it's called, I tried the nextion instruction set steps but I haven't succeeded, there are no clear examples, for now at least I just want to graph the values in time real

1 Like

I realise this, but I was hoping you'd learn something from the tutorial and have a go. Look at Instruction Set - Nextion and look at the 'add' instruction. You can use that to add data points to a waveform.

I suggest you start a new sketch and a new Nextion configuration. Put just a waveform object on the Nextion and use the new sketch to practice sending data to it. The only code I have for a Nextion waveform is written for a PIC and it way too complex to show to a beginner, in any case it does not conform to the Arduino IDE requirements.

I am not familiar with the ESP32, but your code appears to show you are using 3 serial ports, my limited understanding of the ESP32 is that it has one serial port for the USB connection and one presented on the pins for other uses. I'm sure it does not have 3. (Or maybe I am misunderstanding your code).

Please, if someone reading this understands the ESP32 will you reply about the use of serial ports, even if you know nothing about the Nextion?

Hello Perry, I told you that I can now graph the values but for now only in real time, I would like to know how I would do it with the data stored in the array, I saw that with the addt but I still can't understand it

Using addt is on my to do list, probably will be for some time yet. I've not worked out exactly how to use it and I have concerns about it because if you tell it you are going to send 96 points to the waveform but for some reason only send 95 then you are stuck because the Nextion will just sit there waiting for the next one that it's never going to get.

If you have the data in an array then you need to:
Keep a count of how many points you have sent. If you have an array with 96 elements then you need to count from 0 to 95. Use if to see if there's another to send
Use Serial.available to see if there is enough space in the serial buffer to add more data, so maybe:

 if (still some points to send) {
     if (Serial.available > 15) {
        // Code to send the next point
     }
 }

Please make an attempt at this in a new sketch that just works with the Nextion, I want to see your attempt please.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.