Hi, I am currently using a basic Nextion display with an Arduino Uno. I am creating a data logging module for upto 4 sensors.
The following image shows the screen accessed for displaying/logging:
The code, including parts of @PerryBebbington s introduction to Nextion tutorial, reads the data from a sensor and displays it as it should, however upon pressing start, I cannot stop the following 'while' loop effectively when 'II' is pressed on the screen.
while (Graph_pauseState != 1)
I have had to put in a delay to allow enough time for the 'II' button on screen to be recognised and break out of the loop.
This works, however it is not effective and I know the delay is blocking the program somewhat.
Full code below:
/*Changelog:
-18/07/2022: Starting to add analog input to test printing to Nextion.
-20/07/2022: Added graph display data and botton to start and pause waveform. Added sensor state for start and pause conditions
*/
enum pages {page0, page1, page2, noOfPages};
enum HMIData {spare, page, type, index, data0, data1};
int sample;
int Graph_startState = 0; // variable for reading the Nextion start button state
int Graph_pauseState = 0; // variable for reading the Nextion pause button state
int h;
int m;
int s;
int dd;
int mm;
int yy;
int sensor0 = A0;
int v;
int readingScaled;
String dc;
String ddi;
String mmi;
String yyi;
String dat;
String tim;
String hc;
String hi;
String mi;
String si;
#include <SoftwareSerial.h>
#include <SPI.h>
#include <DS3231.h>
SoftwareSerial Serial2(2, 3); // RX, TX
DS3231 rtc(SDA, SCL);
void setup() {
Serial2.begin(9600);
Serial.begin(9600);
rtc.begin();
pinMode(A0, INPUT_PULLUP);
pinMode(sensor0, INPUT);
}
//************************************************************ main************************************************
void loop() {
clock_run();
HMI_read();
}
//************************************************************ main************************************************
//This displays the clock
void HMI_display_clock() {
dat = rtc.getDateStr();
tim = rtc.getTimeStr();
Serial2.print(F("t1.txt=\""));
Serial2.print(rtc.getTimeStr());
endLine(); // Sends 0xff 0xff 0xff, which tell the Nextion that it has a complete string of data
Serial2.print(F("t2.txt=\""));
Serial2.print(tim);
endLine();
Serial2.print(F("t3.txt=\""));
Serial2.print(dat);
endLine();
Serial2.print(F("t4.txt=\""));
Serial2.print(dat);
endLine();
Serial2.print(F("t5.txt=\""));
Serial2.print(rtc.getTemp());
Serial2.print(F("C"));
endLine();
}
//This displays the page number
void HMI_display_page(uint8_t page) {
// Serial2.print(F("t0.txt=\""));
// Serial2.print(F("This is page "));
// Serial2.print(page);
// endLine();
// Serial.println("Page");
}
void HMI_P1_display_slider(uint8_t slider_d1, uint8_t slider_d0) {
uint16_t slider_val = (slider_d1 << 8 | slider_d0);
//This displays byte 1 of the slider value in HEX
Serial2.print(F("t2.txt=\""));
Serial2.print(slider_d1, HEX);
endLine();
Serial.println("slider 1" + slider_d1);
//This displays byte 0 of the slider value in HEX
Serial2.print(F("t3.txt=\""));
Serial2.print(slider_d0, HEX);
endLine();
Serial.println("slider 2 " + slider_d0);
//This displays the complete slider value in decimal
Serial2.print(F("t4.txt=\""));
Serial2.print(slider_val);
endLine();
Serial.println("slider 3" + slider_val);
}
//HMI_read takes the data sent from the Nextion to the Serial2 port and processes it depending on what has been sent
//There are 3 levels of nested switch statements corresponding to the page, the type of object and the index of the object.
void HMI_read() {
#define read_data_size 10 //Size of buffer use to receive data from Nextion (The string sent from nextiojn is 10 long)
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.
// Serial.println("rec");
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) { //This reads the 5th section of the Nextion string/HEX value
switch (HMI_read_data[page]) { //The page the data has come from
/* ---------- Page 0 ----------*/
case page0 :
switch (HMI_read_data[type]) { //Data from the page itself, this is the post initialisation request to update the page, which displays the page number
case 0:
HMI_display_page(HMI_read_data[index]); //Select a page
break;
}
/* ---------- Page 1 ----------*/
case page1 :
switch (HMI_read_data[type]) { //Data from the page itself, this is the post initialisation request to update the page, which displays the page number
case 0:
HMI_display_page(HMI_read_data[index]); //Select a page
break;
case 1: //In this demonstration case 1 is a button for setting the clock (This points to the 4th section of the Nextion Hex)
values();
v = HMI_read_data[index];
modRt(v); //move the next bit to a function
switch (HMI_read_data[index]) { //HMI_read_data[index] is the index of the type of button, so 0 to 5 as there are 6 buttons for setting the clock. Each case is a different button. (index in this case refers to the 5th section of HEX)
case 0:
Serial.println("clock set Hour + pushed");
h++;
if (h > 23) {
h = 0;
}
rtc.setTime(h, m, s);
break;
case 1:
Serial.println("clock set Hour - pushed");
h--;
if (h < 0) {
h = 23;
}
rtc.setTime(h, m, s);
break;
case 2:
Serial.println("clock set Min + pushed");
m++;
if (m > 59) {
m = 0;
}
rtc.setTime(h, m, s);
break;
case 3:
Serial.println("clock set Min - pushed");
m--;
if (m < 0) {
m = 59;
}
rtc.setTime(h, m, s);
break;
case 4:
Serial.println("clock set Sec + pushed ");
s++;
if (s > 59) {
s = 0;
}
rtc.setTime(h, m, s);
break;
case 5:
Serial.println("clock set Sec - pushed ");
s--;
if (s < 0) {
s = 59;
}
rtc.setTime(h, m, s);
break;
case 6:
Serial.println("date set day + pushed");
dd++;
if (dd > 31) {
dd = 1;
}
rtc.setDate(dd, mm, yy);
break;
case 7:
Serial.println("date set day - pushed");
dd--;
if (dd < 1) {
h = 31;
}
rtc.setDate(dd, mm, yy);
break;
case 8:
Serial.println("date set month + pushed");
mm++;
if (mm > 12) {
mm = 1;
}
rtc.setDate(dd, mm, yy);
break;
case 9:
Serial.println("date set month - pushed");
mm--;
if (mm < 1) {
mm = 12;
}
rtc.setDate(dd, mm, yy);
break;
case 10: //REMEMBER IN HEX e.g. 10 = 16 in HEX and A5 in HEX = 10 in DEC
Serial.println("date set year + pushed");
yy++;
if (yy > 2099) {
yy = 0;
}
rtc.setDate(dd, mm, yy);
break;
case 11: //
Serial.println("date set year - pushed");
yy--;
if (yy < 0) {
yy = 2099;
}
rtc.setDate(dd, mm, yy);
break;
}
HMI_display_clock();
break;
}
break;
/* ---------- Page 2 ----------*/
case page2: //Case 2 means the data has come from page 2
switch (HMI_read_data[type]) {
case 0: //Data from the page itself, this is the post initialisation request to update the page, which displays the page number
HMI_display_page(HMI_read_data[index]);
break;
case 1: //Data from the Sensors on page 2
switch (HMI_read_data[index]) { //HMI_read_data[index] is the index of the type of button, so 0 to 5 as there are 6 buttons for setting the clock. Each case is a different button. (index in this case refers to the 5th section of HEX)
case 0:
break;
case 1: //Graph start button
Graph_pauseState = 0;
Serial.println(Graph_pauseState);
Sensor_read();
break;
}
}
break;
}
}
++HMI_read_data_i;
if (HMI_read_data_i >= read_data_size) {
HMI_read_data_i = read_data_size - 1;
}
}
}
void clock_run() {
static unsigned long previousMillis;
unsigned long currentMillis = millis();
const unsigned long interval = 500;
if (currentMillis - previousMillis >= interval) {
previousMillis += interval;
HMI_display_clock();
}
}
void Sensor_read() { //Called when entering a page requiring sensor data to be printed.
//for (int sample = 0; sample <= 1000; sample++) {// number of samples
while (Graph_pauseState != 1) {// number of samples
//----------------------------------------------------------------------------------
#define read_data_size 10 //Size of buffer use to receive data from Nextion (The string sent from nextiojn is 10 long)
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.
// Serial.println("rec");
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) { //This reads the 5th section of the Nextion string/HEX value
switch (HMI_read_data[page]) { //The page the data has come from
/* ---------- Page 2 ----------*/
case page2: //Case 2 means the data has come from page 2
switch (HMI_read_data[type]) {
case 0: //Data from the page itself, this is the post initialisation request to update the page, which displays the page number
HMI_display_page(HMI_read_data[index]);
break;
case 1: //Data from the Sensors on page 2
switch (HMI_read_data[index]) { //HMI_read_data[index] is the index of the type of button, so 0 to 5 as there are 6 buttons for setting the clock. Each case is a different button. (index in this case refers to the 5th section of HEX)
case 2: //Graph pause button
Graph_pauseState = 1;
Serial.println(Graph_pauseState);
break;
}
}
break;
}
}
++HMI_read_data_i;
if (HMI_read_data_i >= read_data_size) {
HMI_read_data_i = read_data_size - 1;
}
}
int sensor0Read = analogRead(sensor0);
Serial2.print("add 9,0,");
readingScaled = map(sensor0Read, 0, 1200, 2, 198);
Serial2.print(readingScaled);
Serial.println(sensor0Read);
Serial2.print(F("\xFF\xFF\xFF"));
Serial2.print(F("sense0.txt=\""));
Serial2.print(sensor0Read);
endLine();
clock_run();
delay(125);
//-----------------------------------------------------------------------------------
}
}
void endLine() {
Serial2.print(F("\""));
Serial2.print(F("\xFF\xFF\xFF"));
}
void values() {
hc = rtc.getTimeStr();
hi = hc.substring(0, 2);
mi = hc.substring(3, 5);
si = hc.substring(6, 8);
h = hi.toInt();
m = mi.toInt();
s = si.toInt();
dc = rtc.getDateStr();
ddi = dc.substring(0, 2);
mmi = dc.substring(3, 5);
yyi = dc.substring(6, 10);
dd = ddi.toInt();
mm = mmi.toInt();
yy = yyi.toInt();
}
int modRt(int vu) {
Serial.println(vu);
}
Could someone please advise on a method of breaking out of this loop?
Cheers.