Problems using Nextion display

Hello!

I am currently stuck with my project because of a bug that I can't manage to fix... The project is a microbalance with two arduino unos where each one count the frequency of a cuartz crystal and an arduino mega that gets the frequency values through I2c from these. The arduino mega also has installed a sht85 T&H sensor a DS3231 RTC a SD card module to store data and a NEXTION display to interface with the device and show all the information.

So for interfacing with the nextion i have been using @PerryBebbington code. In the code every time you change page on the nextion it sends a message with the page to what you have changed so the micorcontroller knows at what page is the nextion at all moments. The problem that I am having is that sometimes I get weird page numbers when I shouldn't. On the project I have a total of 19 pages and for example I change to page 2 and the active_page variable is displayed as 255 or I go page 8 and active_page displays 26. This happens when the screen shuts down after some time and you touch the screen again to light up then the active_page variable goes to 134.

Has anyone had a simillar problem or know what can be causing this problem?

{Impatient drumming of fingertips on desk}

Was expecting this :sweat_smile:, just uploaded it

Sounds a little like not handling sleep/wake-up messages from the Nextion properly.

I will not put that stuff on my computer,
if you want me to have a look at it, you should post the sketch in code tags.

Now I was going to connect a logic analizer that just got to see the messages that are being sent


#include <SD.h>
#include <SPI.h>
#include <EEPROM.h>
#include "RTClib.h"
#include "SHTSensor.h"
#include <Wire.h>

enum pages { page0 = 0, page1,
             page2,
             page3,
             page4,
             page5,
             page6,
             page7,
             page8,
             page9,
             page10,
             page11,
             page12,
             page13,
             page14,
             page15,
             page16,
             page17,
             page18,
             page19,
             noOfPages };
enum HMIData { space,
               numBytes,
               page,
               type,
               index,
               data0,
               data1 };
enum action { change_Date,
              change_Units,
              send_Mesurements,
              debug_State,
              Silver_Coupon_First_Mesurement,
              Copper_Coupon_First_Mesurement,
              standby_state };
enum temperatureUnits { Celsius = 0,
                        Farenheit,
                        Kelvin };
enum pressureUnits { Bar,
                     Atm,
                     Pascals,
                     Psi,
                     mmHg };
const char startOfNumberDelimiter = '<';
const char changeDateDelimiter = ')';
const char yearNow = 'y';
const char monthNow = 'M';
const char dayNow = 'd';
const char minuteNow = 'm';
const char hourNow = 'h';
const char secondNow = 's';
const char endOfTemperatureDelimiter = '@';
const char endOfHumidityDelimiter = '%';
const char endOfSilverDelimiter = '=';
const char endOfCopperDelimiter = 'C';
const char endOfFirstSilverDelimiter = 'o';
const char endOfFirstCopperDelimiter = '$';
const char endMessageDelimiter = '>';

uint8_t active_Tunit = 0;
uint8_t active_Punit = 0;
uint8_t active_page = 0;
bool pageChanged = false;
bool  clock_flag= false;
bool  corrosion_flag= false;
bool writeSD = false;
bool file_exists = false;
bool pageUpdated[noOfPages];
bool j = true;
char printBuffer[25];

const uint8_t minBufferSize = 33;
const uint8_t pinCS = 53;
unsigned int year, month, day, hour, minute, second;
unsigned int cyear, cmonth, cday, chour, cminute, csecond;
unsigned int syear, smonth, sday, shour, sminute, ssecond;
unsigned int corrosion_rate_silver;
unsigned int corrosion_rate_copper;
unsigned int cumulative_corrosion_silver[600];
unsigned int cumulative_corrosion_copper[600];
long Uncorrected_Copper_Frequency;
long Uncorrected_Silver_Frequency;
long Initial_Copper_Frequency = 0;
long Initial_Silver_Frequency = 0;
long previous_Copper_Frequency = 0;
long previous_Silver_Frequency = 0;
float Copper_CC;
float Silver_CC;
long ICF2;
long ISF2;
float Corrected_Copper_Frequency;
float Corrected_Silver_Frequency;
unsigned int clock_period = 1000;
unsigned int corrosion_period = 6000;
char newDateBuffer[30];
char dateBuffer[13];
char hourBuffer[8];
char tempBuffer[20];
char humBuffer[10];
char pressureBuffer[20];
char SilverLifeBuffer[10];
char CopperLifeBuffer[10];

String FileName;
RTC_DS3231 rtc;
SHTSensor sht;
float h = 0.0f;
float t = 0.0f;

union Buffer {
  unsigned long longNumber;
  byte longBytes[4];
};

Buffer buffer;

const int Initial_Copper_Address = 0;
const int Initial_Silver_Address = 4;
int T, H;
int T1, T2;
int H1, H2;
int fileNumber = 0;
int Temperature_Frequency_Correction;
int copperLife, silverLife;
Sd2Card card;
SdVolume volume;

unsigned long currentMillis_clock = 0;
unsigned long currentMillis_corrosion = 0;
unsigned long EEPROMReadlong(long address);
void EEPROMWritelong(int address, unsigned long value);

byte incremental_corrosion_silver[600];
byte incremental_corrosion_copper[600];
byte plotTValues[600];
byte plotHValues[600];
int plotValuesPointer = 0;
int silver_Corrosion_Pointer = 0;
int copper_Corrosion_Pointer = 0;

String NextionOutput;
int GraphMeT;
int GraphMeH;
int z = 0;

File root;
File myFile;
File information;

void setup() {

  initialization();
  
 }

void loop() {
  HMI_read();
  HMI_serial_print();
  flag_update();
  calculations();
  
}

/*------------------------------------------------------------- NEXTION INTERFACING FUNCTIONS -------------------------------------------------------------*/
void HMI_read() {
#define read_data_size 33                        //Size of buffer use to receive data from Nextion
  static uint8_t HMI_read_data[read_data_size];  //This is a temporary buffer to hold the data from the display. Space for 10 bytes although this demonstration only uses 6 bytes
  static uint8_t HMI_read_data_i;                //This is a count of how many bytes have been received from the display.
  static uint8_t a5count;                        //0xa5 repeated 3 times is used as a start indicator, this is a count of how many times it has been received.
  uint8_t readtemp;                              //This is to hold the last received byte to ensure that it is only read from the receive buffer once.


  while (Serial2.available() > 0) {  //Read every byte in the receive buffer
    readtemp = Serial2.read();
    if (readtemp == 0xa5) {  //Count the number of times 0xa5 has been received
      ++a5count;
      if (a5count > 2) {
        a5count = 0;
        HMI_read_data_i = 0;
      }
    } else {
      a5count = 0;
    }
    HMI_read_data[HMI_read_data_i] = readtemp;

    if (HMI_read_data_i >= 5) {
      if (HMI_read_data_i >= HMI_read_data[numBytes]) {
        HMI_read_data_i = 0;

        active_page = (HMI_read_data[page]);  // Sets the current page to the page the data came from

        switch (HMI_read_data[page]) {  // HMI_read_data[1] contains the page the data has come from
          /* --------------- Page 0 ---------------*/
          case page0:  // The data has come from page 0
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);

                break;
              case 1:
                active_page = 0;
                switch (HMI_read_data[index]) {
                }
                break;
            }
            break;
          /* --------------- Page 1 ---------------*/
          case page1:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                break;
            }
            break;
          /* --------------- Page 2 ---------------*/
          case page2:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                break;
            }
            break;
          /* --------------- Page 3 ---------------*/
          case page3:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                break;
            }
            break;
          /* --------------- Page 4 ---------------*/
          case page4:
            switch (HMI_read_data[type]) {
              case 0:

                active_Tunit = HMI_read_data[data0];
                break;
              case 1:

                active_Punit = HMI_read_data[data0];
                break;
            }
            break;
          /* --------------- Page 5 ---------------*/
          case page5:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                break;
            }
            break;
          /* --------------- Page 6 ---------------*/
          case page6:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                break;
            }
            break;
          /* --------------- Page 7 ---------------*/
          case page7:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);

                break;
              case 1:
                sprintf(printBuffer, "%s", (HMI_read_data + 5));
                char* ptr;
                day = atoi(strtok(printBuffer, "<"));
                month = atoi(strtok(NULL, "<"));
                year = atoi(strtok(NULL, "<"));
                hour = atoi(strtok(NULL, "<"));
                minute = atoi(strtok(NULL, "<"));
                rtc.adjust(DateTime(year, month, day, hour, minute, 0));
                pageUpdated[page7] = true;

                break;
            }
            break;
          /* --------------- Page 8 ---------------*/
          case page8:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                break;
            }
            break;
          /* --------------- Page 9 ---------------*/
          case page9:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:

                break;
            }
            break;
          /* --------------- Page 10 ---------------*/
          case page10:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:
                switch (HMI_read_data[index]) {
                  case 0:
                    create_file();
                    SD.begin(53);
                    root = SD.open("/");
                    printDirectory(root, 0);
                    break;
                  case 1:
                    delete_file();
                    SD.begin(53);
                    root = SD.open("/");
                    printDirectory(root, 0);
                    break;
                }

                break;
            }
            break;
          /* --------------- Page 11 ---------------*/
          case page11:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                break;
              case 1:

                break;
            }
            break;
          /* --------------- Page 16 ---------------*/
          case page16:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                Serial2.print(F("t3.txt=\""));
                Serial2.print("COUPON CALIBRATION IS TAKING PLACE PLEASE");
                Serial2.print(F("\r\n"));
                Serial2.print("             WAIT FOR NEW INSTRUCTIONS");
                Serial2.print("\"");
                Serial2.print("\xff\xff\xff");
                Serial2.print("PBarSilver.val=");
                Serial2.print(0);
                Serial2.print("\xff\xff\xff");
                Serial2.print(F("PerSilver.txt=\""));
                Serial2.print(" Starting... ");
                Serial2.print("\"");
                Serial2.print("\xff\xff\xff");
                delay(300);
                for (int i = 0; i <= 100; i++) {
                  Serial2.print("PBarSilver.val=");
                  Serial2.print(i);
                  Serial2.print("\xff\xff\xff");
                  Serial2.print(F("PerSilver.txt=\""));
                  Serial2.print(i);
                  Serial2.print(" %");
                  Serial2.print("\"");
                  Serial2.print("\xff\xff\xff");
                  delay(150);
                  if (i == 35) {
                    Silver_Frequency_Request();
                    delay(10);
                    Read_T_and_H();
                    calculate_T_H_P();
                    frequecy_Temperature_Correction();
                    long ISF = Corrected_Silver_Frequency;
                    EEPROMWritelong(Initial_Silver_Address, ISF);
                  }
                }

                sday = day;
                shour = hour;
                sminute = minute;
                ssecond = second;
               
                silver_Corrosion_Pointer = 0;
                previous_Silver_Frequency = Corrected_Silver_Frequency;
                memset(incremental_corrosion_silver,0,sizeof(incremental_corrosion_silver));
                

                Serial2.print(F("t3.txt=\""));
                Serial2.print("CALIBRATION COMPLETE, CLICK FINISH BUTTON");
                Serial2.print("\"");
                Serial2.print("\xff\xff\xff");
                break;
              case 1:

                break;
            }
            break;
          /* --------------- Page 19 ---------------*/
          case page19:
            switch (HMI_read_data[type]) {
              case 0:
                change_active_page(HMI_read_data[data0]);
                Serial2.print(F("t3.txt=\""));
                Serial2.print("COUPON CALIBRATION IS TAKING PLACE PLEASE");
                Serial2.print(F("\r\n"));
                Serial2.print("             WAIT FOR NEW INSTRUCTIONS");
                Serial2.print("\"");
                Serial2.print("\xff\xff\xff");
                Serial2.print("PBarCopper.val=");
                Serial2.print(0);
                Serial2.print("\xff\xff\xff");
                Serial2.print(F("PerCopper.txt=\""));
                Serial2.print(" Starting... ");
                Serial2.print("\"");
                Serial2.print("\xff\xff\xff");

                for (int i = 0; i <= 100; i++) {
                  Serial2.print("PBarCopper.val=");
                  Serial2.print(i);
                  Serial2.print("\xff\xff\xff");
                  Serial2.print(F("PerCopper.txt=\""));
                  Serial2.print(i);
                  Serial2.print(" %");
                  Serial2.print("\"");
                  Serial2.print("\xff\xff\xff");
                  delay(150);
                  if (i == 35) {
                    Copper_Frequency_Request();
                    delay(10);
                    Read_T_and_H();
                    calculate_T_H_P();
                    frequecy_Temperature_Correction();
                    long ICF = Corrected_Copper_Frequency;
                    EEPROMWritelong(Initial_Copper_Address, ICF);
                  }
                }
                cday = day;
                chour = hour;
                cminute = minute;
                csecond = second;

                copper_Corrosion_Pointer = 0;
                previous_Copper_Frequency = Corrected_Copper_Frequency;
                memset(incremental_corrosion_copper,0,sizeof(incremental_corrosion_copper));

                Serial2.print(F("t3.txt=\""));
                Serial2.print("CALIBRATION COMPLETE, CLICK FINISH BUTTON");
                Serial2.print("\"");
                Serial2.print("\xff\xff\xff");

                break;
              case 1:

                break;
            }
            break;
          /* --------------- PInvalid ---------------*/
          default:

            break;
        }
      }
    }
    ++HMI_read_data_i;
    if (HMI_read_data_i >= read_data_size) {
      HMI_read_data_i = read_data_size - 1;
    }
  }
}

void change_active_page(uint8_t page) {
  active_page = page;
  pageChanged = true;
  switch (page) {
    case page0:
      break;
    case page1:
      break;
    case page2:
      break;
    case page3:
      break;
    case page4:
      break;
    case page5:
      break;
    case page6:
      break;
    case page7:
      break;
    case page8:
      break;
    case page9:
      break;
    case page10:
      break;
    case page11:
      break;
    case page16:
      break;
    case page19:
      break;
  }
}

void HMI_serial_print() {
  if (Serial2.availableForWrite() > minBufferSize) {
    switch (active_page) {
      case page0:
        HMI_serial_print_p0();
        break;
      case page1:
        HMI_serial_print_p1();
        break;
      case page2:
        HMI_serial_print_p2();
        break;
      case page3:
        HMI_serial_print_p3();
        break;
      case page4:
        HMI_serial_print_p4();
        break;
      case page5:
        break;
      case page6:
        HMI_serial_print_p6();
        break;
      case page7:
        HMI_serial_print_p7();
        break;
      case page8:
        HMI_serial_print_p8();
        break;
      case page9:
        HMI_serial_print_p9();
        break;
      case page10:
        HMI_serial_print_p10();
        break;
      case page11:
        HMI_serial_print_p11();
        break;
      case page16:
        break;
      case page19:
        break;
    }
  }
}

void HMI_serial_print_p0() {
  if (pageChanged) {
    pageChanged = false;
    displayCurrentDate();
    display_T_H_P();
    display_coupon_life();
    display_corrosion_rate();
  }
  if (pageUpdated[page0]) {
    pageUpdated[page0] = false;
    displayCurrentDate();
    display_T_H_P();
    display_coupon_life();
    display_corrosion_rate();
  }
}

void HMI_serial_print_p1() {
  if (pageChanged) {
    pageChanged = false;
  }
  if (pageUpdated[page1]) {
    pageUpdated[page1] = false;
  }
}

void HMI_serial_print_p2() {
  if (pageChanged) {
    pageChanged = false;
  }
  if (pageUpdated[page2]) {
    pageUpdated[page2] = false;
  }
}

void HMI_serial_print_p3() {
  if (pageChanged) {
    pageChanged = false;
  }
  if (pageUpdated[page3]) {
    pageUpdated[page3] = false;
  }
}

void HMI_serial_print_p4() {
  if (pageChanged) {
    pageChanged = false;
  }
  if (pageUpdated[page4]) {
    pageUpdated[page4] = false;
  }
}

void HMI_serial_print_p5() {
  if (pageChanged) {
    pageChanged = false;
  }
  if (pageUpdated[page5]) {
    pageUpdated[page5] = false;
  }
}

void HMI_serial_print_p6() {
  if (pageChanged) {
    pageChanged = false;
    print_freq();
  }
  if (pageUpdated[page6]) {
    pageUpdated[page6] = false;
    print_freq();
  }
}

void HMI_serial_print_p7() {
  if (pageChanged) {
    pageChanged = false;
    displayNewDate();
  }
  if (pageUpdated[page7]) {
    pageUpdated[page7] = false;
    displayNewDate();
  }
}

void HMI_serial_print_p8() {
  if (pageChanged) {
    pageChanged = false;
    print_SD_menu();
  }
  if (pageUpdated[page8]) {
    pageUpdated[page8] = false;
    print_SD_menu();
    SD_card_check();
  }
}

void HMI_serial_print_p9() {
  if (pageChanged) {
    pageChanged = false;
    print_SD_info();
  }
  if (pageUpdated[page9]) {
    pageUpdated[page9] = false;
    print_SD_info();
  }
}

void HMI_serial_print_p10() {
  if (pageChanged) {
    SD.begin(53);
    root = SD.open("/");
    printDirectory(root, 0);
    pageChanged = false;
  }
  if (pageUpdated[page10]) {

    SD.begin(53);
    root = SD.open("/");
    printDirectory(root, 0);
    pageUpdated[page10] = false;
  }
}

void HMI_serial_print_p11() {
  if (pageChanged) {
    pageChanged = false;
    Plot_All_values_TandH();
  }
  if (pageUpdated[page11]) {
    TandH_plot();
    pageUpdated[page11] = false;
  }
}

/*------------------------------------------------------------- DISPLAY ON NEXTION INTERFACING FUNCTIONS -------------------------------------------------------------*/

void displayNewDate() {
  sprintf(newDateBuffer, "(%02d/%02d/%d  %02d:%02d)", day, month, year, hour, minute);
  Serial2.print(F("newdate.txt=\""));
  Serial2.print(newDateBuffer);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}
void displayCurrentDate() {
  snprintf(dateBuffer, 11, "%02d/%02d/%d", day, month, year);
  Serial2.print(F("date.txt=\""));
  Serial2.print(dateBuffer);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");

  snprintf(hourBuffer, 6, "%02d:%02d", hour, minute);
  Serial2.print(F("hour.txt=\""));
  Serial2.print(hourBuffer);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}     
 void display_T_H_P() {

  //SEND TEMPERATURE

  unsigned int P1, P2;
  float p = 1.45;
  switch (active_Punit) {
    case Bar:
      Serial2.print(F("press1.txt=\""));
      Serial2.print(pressureBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
    case Atm:
      Serial2.print(F("press1.txt=\""));
      Serial2.print(pressureBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
    case Pascals:
      Serial2.print(F("press1.txt=\""));
      Serial2.print(pressureBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
    case Psi:
      Serial2.print(F("press1.txt=\""));
      Serial2.print(pressureBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
    case mmHg:
      Serial2.print(F("press1.txt=\""));
      Serial2.print(pressureBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
  }

  switch (active_Tunit) {
    case Celsius:
      Serial2.print(F("temp1.txt=\""));
      Serial2.print(tempBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
    case Farenheit:
      Serial2.print(F("temp1.txt=\""));
      Serial2.print(tempBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;

    case Kelvin:
      Serial2.print(F("temp1.txt=\""));
      Serial2.print(tempBuffer);
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      break;
  }
  //SEND HUMIDITY
  Serial2.print(F("humi1.txt=\""));
  Serial2.print(humBuffer);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}
void display_corrosion_rate() {
  switch (corrosion_rate_silver) {
    case 0:
      Serial2.print(F("CRS.txt=\""));
      Serial2.print("CORROSION RATE : G1");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRS.pco=2024");
      Serial2.print("\xff\xff\xff");
      break;
    case 1:
      Serial2.print(F("CRS.txt=\""));
      Serial2.print("CORROSION RATE : G2");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRS.pco=65504");
      Serial2.print("\xff\xff\xff");
      break;
    case 2:
      Serial2.print(F("CRS.txt=\""));
      Serial2.print("CORROSION RATE : G3");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRS.pco=64520");
      Serial2.print("\xff\xff\xff");
      break;
    case 3:
      Serial2.print(F("CRS.txt=\""));
      Serial2.print("CORROSION RATE : GX");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRC.pco=63488");
      Serial2.print("\xff\xff\xff");
      break;
  }

  switch (corrosion_rate_copper) {
    case 0:
      Serial2.print(F("CRC.txt=\""));
      Serial2.print("CORROSION RATE : G1");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRS.pco=2024");
      Serial2.print("\xff\xff\xff");
      break;
    case 1:
      Serial2.print(F("CRC.txt=\""));
      Serial2.print("CORROSION RATE : G2");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRS.pco=65504");
      Serial2.print("\xff\xff\xff");
      break;
    case 2:
      Serial2.print(F("CRC.txt=\""));
      Serial2.print("CORROSION RATE : G3");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRS.pco=64520");
      Serial2.print("\xff\xff\xff");
      break;
    case 3:
      Serial2.print(F("CRC.txt=\""));
      Serial2.print("CORROSION RATE : GX");
      Serial2.print("\"");
      Serial2.print("\xff\xff\xff");
      Serial2.print("CRC.pco=63488");
      Serial2.print("\xff\xff\xff");
      break;
  }
  Serial2.print(F("Acopper.txt=\""));
  Serial2.print(incremental_corrosion_copper[copper_Corrosion_Pointer]);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");

  Serial2.print(F("Asilver.txt=\""));
  Serial2.print(incremental_corrosion_silver[silver_Corrosion_Pointer]);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}
void display_coupon_life() {

  Serial2.print(F("CLP.txt=\""));
  Serial2.print(CopperLifeBuffer);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print("CLPB.val=");
  Serial2.print(copperLife);
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("SLP.txt=\""));
  Serial2.print(SilverLifeBuffer);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print("SLPB.val=");
  Serial2.print(silverLife);
  Serial2.print("\xff\xff\xff");
}
void print_freq() {
  Serial2.print(F("d1.txt=\""));
  Serial2.print("Uncorrected Copper Frequency = ");
  Serial2.print(Uncorrected_Copper_Frequency);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("d2.txt=\""));
  Serial2.print("Corrected Copper Frequency = ");
  Serial2.print(Corrected_Copper_Frequency);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("d3.txt=\""));
  Serial2.print("Uncorrected Silver Frequency = ");
  Serial2.print(Uncorrected_Silver_Frequency);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("d4.txt=\""));
  Serial2.print("Corrected Silver Frequency = ");
  Serial2.print(Corrected_Silver_Frequency);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("d5.txt=\""));
  Serial2.print("Initial Copper Frequency = ");
  Serial2.print(ICF2);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("d6.txt=\""));
  Serial2.print("Initial Silver Frequency = ");
  Serial2.print(ISF2);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}
void initialization() {
  Wire.begin();
  rtc.begin();
  sht.init();
  SD_card_initialization();
  Serial2.begin(115200);
  pinMode(13, INPUT);
   //long f = EEPROMReadlong(Initial_Copper_Address);
  //if (f == -1) EEPROMWritelong(Initial_Copper_Address, 0);
  //f = EEPROMReadlong(Initial_Silver_Address);
  //if (f == -1) EEPROMWritelong(Initial_Silver_Address, 0);
}

/*------------------------------------------------------------- ARDUINO MEGA INTERFACING FUNCTIONS -------------------------------------------------------------*/

void flag_update() {

  if (millis() > currentMillis_clock + clock_period) {
    currentMillis_clock = millis();
    DateTime now = rtc.now();
    save_TandH_values();   
    Read_Date(now);    
    Read_T_and_H();
    Page_Updates();
    print_to_SD();
    //if(active_page > noOfPages) active_page = 0;
    clock_flag = true;    
   
  } 
  
  else if (millis() > currentMillis_corrosion + corrosion_period) {
    currentMillis_corrosion = millis();
    Silver_Frequency_Request();
    Copper_Frequency_Request();
        
    copper_Corrosion_Pointer++;
    silver_Corrosion_Pointer++;    
    if(copper_Corrosion_Pointer > 600) copper_Corrosion_Pointer = 0;
    if(silver_Corrosion_Pointer > 600) silver_Corrosion_Pointer = 0;
        
    corrosion_flag = true;
  }
}
void Page_Updates(){
  if (active_page == 0) pageUpdated[page0] = true; 
  else if (active_page == 6) pageUpdated[page6] = true;
  else if (active_page == 8) pageUpdated[page8] = true;
  else if (active_page == 9) pageUpdated[page9] = true;
  else if (active_page == 10) pageUpdated[page10] = true; 
  else if (active_page == 11) pageUpdated[page11] = true; 

   Serial2.print(F("t0.txt=\""));
    Serial2.print(active_page);
    Serial2.print("\"");
    Serial2.print("\xff\xff\xff");
  
}
void Read_Date(DateTime date) {
  year = date.year();
  month = date.month();
  day = date.day();
  hour = date.hour();
  minute = date.minute();
  second = date.second();
}
void Read_T_and_H() {
  sht.readSample();
  t = (sht.getTemperature());
  h = (sht.getHumidity());
}
void Copper_Frequency_Request() {
  Wire.requestFrom(9, 4);
  if (Wire.available() > 0) {

    buffer.longBytes[0] = Wire.read();
    buffer.longBytes[1] = Wire.read();
    buffer.longBytes[2] = Wire.read();
    buffer.longBytes[3] = Wire.read();
  }
  Uncorrected_Copper_Frequency = buffer.longNumber;
}
void Silver_Frequency_Request() {
  Wire.requestFrom(8, 4);

  if (Wire.available() > 0) {

    buffer.longBytes[0] = Wire.read();
    buffer.longBytes[1] = Wire.read();
    buffer.longBytes[2] = Wire.read();
    buffer.longBytes[3] = Wire.read();
  }

  Uncorrected_Silver_Frequency = buffer.longNumber;
}
/*------------------------------------------------------------- DEBUGGING SECUENCE OF SENSORS AND SYSTEMS -------------------------------------------------------------*/

void SD_card_initialization() {
  pinMode(pinCS, OUTPUT);
  digitalWrite(pinCS, HIGH);

  if (!SD.begin(pinCS)) {
    Serial2.print(F("d1.txt=\""));
    Serial2.print("Unable to initialize SD");
    Serial2.print("\"");
    Serial2.print("\xff\xff\xff");
    return;
  }
  Serial2.print(F("d1.txt=\""));
  Serial2.print("SD initialization correct");
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}

/*------------------------------------------------------------- SECURE CARD (SD) INTERFACING FUNCTIONS -------------------------------------------------------------*/

void print_SD_menu() {

  Serial2.print(F("sd_menu_header.txt=\""));
  Serial2.print("INFORMATION WINDOW");
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");

  if (!card.init(SPI_HALF_SPEED, pinCS) ) {
    Serial2.print(F("sd_menu.txt=\""));
    Serial2.print("PLEASE INTRODUCE AN SD CARD");
    Serial2.print("\"");
    Serial2.print("\xff\xff\xff");
  } else {
    Serial2.print(F("sd_menu.txt=\""));
    Serial2.print("SD INITIALIZATION CORRECT:");
    Serial2.print(F("\r\n"));
    Serial2.print("YOU CAN CHECK SD INFORMATION");
    Serial2.print(F("\r\n"));
    Serial2.print("OR CREATE AND DELETE FILES");
    Serial2.print("\"");
    Serial2.print("\xff\xff\xff");
  }
}
void SD_card_check() {
  if (digitalRead(13) == HIGH && active_page == 8) print_SD_menu();
}
void print_SD_info() {

  SD.begin(53);
  root = SD.open("/");
  printDirectory(root, 0);

  Serial2.print(F("sdInfo.txt=\""));
  Serial2.print("CARACTERISTICS:");
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
  Serial2.print(F("sdInfo2.txt=\""));
  Serial2.print("FILES:");
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");



  if (!card.init(SPI_HALF_SPEED, pinCS) ) {
    Serial2.print(F("sdFeedback.txt=\""));
    Serial2.print("Please introduce an SD card");
    Serial2.print("\"");
    Serial2.print("\xff\xff\xff");
  } else if (card.init(SPI_HALF_SPEED, pinCS)) {
    //SD card info print
    !volume.init(card);
    Serial2.print(F("sdFeedback.txt=\""));
    Serial2.print(F("Card Type: "));
    switch (card.type()) {
      case SD_CARD_TYPE_SD1:
        Serial2.print(F("SD1"));
        break;
      case SD_CARD_TYPE_SD2:
        Serial2.print(F("SD2"));
        break;
      case SD_CARD_TYPE_SDHC:
        Serial2.print(F("SDHC"));
        break;
      default:
        Serial2.print("Unknown");
    }
    Serial2.print(F("\r\n"));
    Serial2.print(F("Volume type is: "));
    Serial2.print(volume.fatType());
    Serial2.print(F(" FAT"));
    uint32_t n = volume.clusterCount();
    Serial2.print(F("\r\n"));
    Serial2.print(F("Clusters: "));
    Serial2.print(n);
    Serial2.print(F("\r\n"));
    Serial2.print(F("Total Blocks: "));
    Serial2.print((volume.blocksPerCluster() * volume.clusterCount()));
    Serial2.print(F("\r\n"));
    uint32_t volumesize;
    volumesize = volume.blocksPerCluster();  // clusters are collections of blocks
    volumesize *= volume.clusterCount();     // we'll have a lot of clusters
    volumesize /= 2;

    Serial2.print("Volume size (Kb):  ");
    Serial2.print(volumesize = volumesize / 1024);
    Serial2.print(F("\r\n"));
    Serial2.print("Volume size (Gb):  ");
    Serial2.print((float)volumesize / 1024.0);
    Serial2.print(F("\""));
    Serial2.print("\xFF\xFF\xFF");
  }
}
void printDirectory(File dir, int counter) {

  String entryName;
  int entrySize;

  while (true) {

    File entry = dir.openNextFile();

    if (!entry || dir.size() <= 0) {

      break;
    }

    if (!entry.isDirectory() && counter == 0) {

      entryName += (String)entry.name() + "           " + (String)entry.size() + (String) "\r\n";
    }

    else {
      printDirectory(entry, counter + 1);
    }
    entry.close();
  }
  Serial2.print(F("sdFeedback2.txt=\""));
  Serial2.print(entryName);
  Serial2.print("\"");
  Serial2.print("\xff\xff\xff");
}
void create_file() {
  long ICF2 = EEPROMReadlong(Initial_Copper_Address);
  long ISF2 = EEPROMReadlong(Initial_Silver_Address);
  FileName = "FILE" + String(fileNumber) + ".csv";
  fileNumber++;
  myFile = SD.open(FileName, FILE_WRITE);
  myFile.println("MICROBALANCE CORROSION MONITOR INFORMATION");
  myFile.println("Timestamp,Temperature,Humidity,Copper_Frequency,Silver_Frequency,CCF,CSF");
  myFile.close();
}
void delete_file() {
  SD.remove(FileName);
  if (fileNumber > 0) {
    fileNumber--;
  }
  FileName = "FILE" + String(fileNumber) + ".csv";
}
void print_to_SD() {
  myFile = SD.open(FileName, FILE_WRITE);
  float Ht, Tt;
  float Ht1, Ht2, Tt1, Tt2;
  Ht1 = H1;
  Ht2 = H2;
  Tt1 = T1;
  Tt2 = T2;
  Ht = Ht1 + Ht2 / 100;
  Tt = Tt1 + Tt2 / 100;
  String Timestamp = (String)hour + ":" + (String)minute + "  " + (String)day + "/" + (String)month + "/" + (String)year;
  String INFO_COLLECTION = Timestamp + "," + (String)Tt + "," + (String)Ht + "," + (String)Corrected_Copper_Frequency + "," + (String)Corrected_Silver_Frequency + "," + (String)Copper_CC + "," + (String)Silver_CC;
  myFile.println(INFO_COLLECTION);
  myFile.close();
}
void EEPROMWritelong(int address, unsigned long value) {

  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);

  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);
}
unsigned long EEPROMReadlong(int address) {
  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);

  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

/*------------------------------------------------------------- CALCULATION  FUNCTIONS -------------------------------------------------------------*/

void calculations() {
  if (clock_flag== true) {
    calculate_T_H_P();    
    clock_flag = false;
  }
  if(corrosion_flag == true){
    calculate_cumulative_corrosion();
    calculate_incremental_corrosion();
    calculate_coupon_life();
    calculate_corrosion_rate();
    corrosion_flag =false;
  }
}
void calculate_incremental_corrosion(){

  incremental_corrosion_silver[silver_Corrosion_Pointer] = previous_Silver_Frequency - Corrected_Silver_Frequency;
  incremental_corrosion_copper[copper_Corrosion_Pointer] = previous_Copper_Frequency - Corrected_Copper_Frequency;
  
  if( (incremental_corrosion_silver[silver_Corrosion_Pointer] - incremental_corrosion_silver[silver_Corrosion_Pointer - 1]) > 20) incremental_corrosion_silver[silver_Corrosion_Pointer] = incremental_corrosion_silver[silver_Corrosion_Pointer - 1];
  if( (incremental_corrosion_copper[copper_Corrosion_Pointer] -  incremental_corrosion_copper[copper_Corrosion_Pointer - 1]) > 20)  incremental_corrosion_copper[copper_Corrosion_Pointer] =  incremental_corrosion_copper[copper_Corrosion_Pointer - 1];
  
  previous_Copper_Frequency = Corrected_Copper_Frequency;
  previous_Silver_Frequency = Corrected_Silver_Frequency;
}
void calculate_T_H_P() {
  unsigned int P1, P2;
  float p = 1.45;
  switch (active_Punit) {
    case Bar:
      p = p * 1.01325;
      P1 = int(p);
      P2 = int((p - P1) * 100);
      snprintf(pressureBuffer, 20, "%d,%02d Bar", P1, P2);
      break;
    case Atm:
      P1 = int(p);
      P2 = int((p - P1) * 100);
      snprintf(pressureBuffer, 20, "%d,%02d Atm", P1, P2);
      break;
    case Pascals:
      p = p * 101325;
      P1 = int(p);
      P2 = int(((p - P1) * 100), 2);
      snprintf(pressureBuffer, 20, "%02d,%02d Pa", P1, P2);
      break;
    case Psi:
      p = p * 14, 696;
      P1 = int(p);
      P2 = int((p - P1) * 100);
      snprintf(pressureBuffer, 20, "%02d,%02d PSI", P1, P2);
      break;
    case mmHg:
      p = p * 760;
      P1 = int(p);
      P2 = int((p - P1) * 100);
      snprintf(pressureBuffer, 20, "%02d,%02d mmHg", P1, P2);
      break;
  }

  switch (active_Tunit) {
    case Celsius:
      T1 = int(t);
      T2 = int((t - T1) * 100);
      snprintf(tempBuffer, 20, "%02d,%02d %sC", T1, T2, "\xB0");
      break;
    case Farenheit:
      float tfaren = ((t * 1.8) + 32);
      T1 = int(tfaren);
      T2 = int((tfaren - T1) * 100);
      snprintf(tempBuffer, 10, "%02d,%02d F", T1, T2);
      break;
    case Kelvin:
      t = (t + 273);
      T1 = int(t);
      T2 = int((t - T1) * 100);
      snprintf(tempBuffer, 10, "%02d,%02d K", T1, T2);
      break;
  }
  //SEND HUMIDITY
  H1 = int(h);
  H2 = int((h - H1) * 100);
  snprintf(humBuffer, 10, "%02d,%02d %%", H1, H2);
}
void calculate_cumulative_corrosion() {
  frequecy_Temperature_Correction();
  ICF2 = EEPROMReadlong(Initial_Copper_Address);
  ISF2 = EEPROMReadlong(Initial_Silver_Address);
  Copper_CC = ICF2 - Corrected_Copper_Frequency;
  Silver_CC = ISF2 - Corrected_Silver_Frequency;
  cumulative_corrosion_copper[copper_Corrosion_Pointer] = int(Copper_CC);
  cumulative_corrosion_silver[silver_Corrosion_Pointer] = int(Silver_CC);
}
void calculate_coupon_life() {

  copperLife = map(Corrected_Copper_Frequency, ICF2, (ICF2 + 4000), 100, 0);
  if (ICF2 == 0 || copperLife < 0) copperLife = 0;
  if (copperLife > 100) copperLife = 100;
  snprintf(CopperLifeBuffer, 10, "%d %%", copperLife);

  silverLife = map(Corrected_Silver_Frequency, ISF2, (ISF2 + 4000), 100, 0);
  if (ISF2 == 0 || silverLife < 0) silverLife = 0;
  if (silverLife > 100) silverLife = 100;
  snprintf(SilverLifeBuffer, 10, "%d %%", silverLife);
}
void calculate_corrosion_rate() {

  if (day == sday + 1 && hour == shour && minute >= sminute) {
    long CSC = Corrected_Silver_Frequency - ISF2;
    if (CSC < 7) {
      corrosion_rate_silver = 0;
    } else if (CSC < 30) {
      corrosion_rate_silver = 1;
    } else if (CSC < 64) {
      corrosion_rate_silver = 2;
    } else if (CSC > 64) {
      corrosion_rate_silver = 3;
    }
  }

  if (day == cday + 1 && hour == chour && minute >= cminute) {
    long CCC = Corrected_Copper_Frequency - ICF2;
    if (CCC < 7) {
      corrosion_rate_copper = 0;
    } else if (CCC < 30) {
      corrosion_rate_copper = 1;
    } else if (CCC < 64) {
      corrosion_rate_copper = 2;
    } else if (CCC > 64) {
      corrosion_rate_copper = 3;
    }
  }
}
void frequecy_Temperature_Correction() {

  float FreqCorr = (32.5 - (5 / 4) * t);
  Corrected_Silver_Frequency = Uncorrected_Silver_Frequency + FreqCorr;
  Corrected_Copper_Frequency = Uncorrected_Copper_Frequency + FreqCorr;
}

/*------------------------------------------------------------- PLOTTING  FUNCTIONS -------------------------------------------------------------*/

void save_TandH_values() {

  plotTValues[plotValuesPointer] = T1 * 2;
  plotHValues[plotValuesPointer] = H1;
  plotValuesPointer++;
  if (plotValuesPointer == 600) {
    plotValuesPointer = 0;
  }
}
void TandH_plot() {
  GraphMeT = T1 * 2;
  GraphMeT = map(GraphMeT, 0, 100, 0, 255);
  NextionOutput = "add 2,0," + String(GraphMeT);
  Serial2.print(NextionOutput);
  Serial2.print("\xFF\xFF\xFF");
  GraphMeH = H1;
  GraphMeH = map(GraphMeH, 0, 100, 0, 255);
  NextionOutput = "add 2,1," + String(GraphMeH);
  Serial2.print(NextionOutput);
  Serial2.print("\xFF\xFF\xFF");
}
void Plot_All_values_TandH() {
  for (int t = 0; t < 600; t++) {
    uint8_t temp;
    temp = map(plotTValues[t], 0, 100, 0, 255);
    NextionOutput = "add 2,0," + String(temp);
    Serial2.print(NextionOutput);
    Serial2.print("\xFF\xFF\xFF");

    uint8_t hum;
    hum = map(plotHValues[t], 0, 100, 0, 255);
    NextionOutput = "add 2,1," + String(hum);
    Serial2.print(NextionOutput);
    Serial2.print("\xFF\xFF\xFF");
  }
}

Thank you.

That allows even mobile users to see your sketch. :grinning:

1 Like

Your 'decoding' of the Nextion messages seems very strange to me.

You have tons of named constants, but use a literal here.
What's special about 0xA5?

I used the guide from here Using Nextion displays with Arduino to do the decoding , and the 0xa5 for what i understood is just the number that the guide creator decided to use, nothing in special with it.

It is because I use 0xa5 in my code as a means to start a message from the Nextion to the processor. This goes right back to my initial experiments with a Nextion and a PIC, I wanted some kind of start marker for messages that wasn't the 0xff that Nextion use as a message terminator. The only reason for 0xa5 is it has a lot of transitions from 1 to 0 and 0 to 1, unlike 0xff, which has no transitions.

@evansg124
I'll have a look at your code in a bit if @Whandall doesn't give you a solution first.

So you are not using the Nextion framing at all?

I will not be able to really help, because my Nextions don't compose their own messages.

The communication is strange enough out of the box,
I did not want to add more stuff to the list of possible messages.

He's not if he uses my methods. I completely avoided the Nextion official stuff and did my own thing. Judging by the comments I've read since about the Nextion official library I made the right choice.

Yes I am using @PerryBebbington method to comunicate with Nextion. I Just connected a logic analizer and I just saw something really weird at some point Nextion is sending 15 times to the arduino the message "26" "255" "255" "255". Here is a picture.

The fact that the Nextion library is absolute crap (and their support is snarky and greedy),
should not lead to reinventing the communication protocol, IMHO.

The built-in stuff is hard to switch off totally,
here you have a case, where that hurts the communication.

Please attach your HMI file. If Discourse doesn't like it please put it in a zip file.

looking at the Nextion guide I found this :


which is the "26" "255" "255" "255", however I don't get why it sends this message...

Perhaps.

However, that's not what happened. I started using Nextions before I had any involvement with Arduino. I set out to write from scratch something that would work in C on a PIC with what I knew at the time. Some time later I joined this web site, started using Arduinos in my projects and discovered no one was providing help for Nextion displays. I modified the methods I'd created to work with Arduino (mostly I no longer had to deal with the serial port hardware) and created the tutorial. Only after all that did I discover that folk don't like the official Nextion library or their support.

Ok, nobody would come up with three 0xFF as a delimiter from scratch. :grinning:

So I can not be of much help here, sorry.

I have seen unexplained 0x1A errors too, maybe that is just something that can happen.

Thanks for the HMI file.

As it is a rather large configuration please can you indicate exactly what you have to do to get the response you are getting? I could spend hours looking for it and not see it!

Thanks,