Start a new topic

Touch event missed on button press

I am using the Nexition 3.5" display connected to a Photon.  In my project I have a button that sends an event to the Photon on press release. I have noticed that the event is missed some of the time.  When watching the serial debug I can see the event is never received by the Photon.  On a subsequent press of the button it will be captured and received by the Photon. Anyone else experience this type of intermittent behavior?  Is the nex_listen i the main loop extremely timing sensitive?  

Hoi Justin,

like uploading the HMI and sketch can be looked at.

so an answer can not. there's more info needed



I had a system crash so will be a while before I can upload. However I think it is related to this post.


// This #include statement was automatically added by the Particle IDE.
#include "ITEADLIB_Nextion/ITEADLIB_Nextion.h"

// This #include statement was automatically added by the Particle IDE.
#include "ThingSpeak/ThingSpeak.h"

// This #include statement was automatically added by the Particle IDE.
#include "pid/pid.h"

// This #include statement was automatically added by the Particle IDE.
#include "spark-dallas-temperature/spark-dallas-temperature.h"

// This #include statement was automatically added by the Particle IDE.
#include "OneWire/OneWire.h"

#include "math.h"

//Define Variables we'll be connecting to
double input, output, setPoint, Kp, Ki, Kd;

//Specify the links and initial tuning parameters
PID myPID(&input, &output, &setPoint, Kp, Ki, Kd, PID::DIRECT);

// PWM
int PWMPin = A4;
int pumpPin = D0;
int pumpState = 0;

// DS18B20 Thermometer Stuff
#define ONE_WIRE_BUS D1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress mashInThermometer = { 0x28, 0xFF, 0x46, 0xC6, 0x03, 0x15, 0x02, 0x46 };  //Change to match actual device
DeviceAddress mashOutThermometer = {0x28, 0xFF, 0x3A, 0xC4, 0x03, 0x15, 0x02, 0x0D };
DeviceAddress mashThermometer = { 0x28, 0xFF, 0x35, 0xCB, 0x03, 0x15, 0x02, 0xF8 };
DeviceAddress HLThermometer = { 0x28, 0xFF, 0x93, 0xFF, 0x04, 0x15, 0x03, 0x35 };
double mashInTempF = -1;  
double mashOutTempF = -1;
double mashTempF = -1;
double HLTempF = -1;
Timer display(1000, updateDisplay);  //display refresh and temperature read.

// Functions declare.
void update18B20Temp(DeviceAddress deviceAddress, double &tempF);

int pumpS (String x);
int gsetT (String y);
int PIDSet(String y);

//void updateDisplay();
//void thingspaekUpdate();

//Thingspeak setup 
unsigned long myChannelNumber = 58086;
const char * myWriteAPIKey = "XXXXXXXXXXX";
TCPClient client;
Timer thing(30000, thingspeakUpdate);  // once per 30 sec

// Display setup
     * Declare a button object [page id:0,component id:1, component name: "b0"].
NexButton disSet = NexButton(2,13, "disSet");
NexButton disPump = NexButton(1, 3, "disPump");
NexButton b1 = NexButton(2, 3, "PIDTune");
NexButton disPIDSet = NexButton(3, 1, "disPIDSet");
char buffer[100] = {0};
NexText disMash = NexText(1, 1, "disMash");
NexText disMashIn = NexText(1, 5, "disMashIn");
NexText disMashOut = NexText(1, 7, "disMashOut");
NexText disHL = NexText(1, 9, "disHL");
NexText disKp = NexText(3, 7, "disKp");
NexText disKi = NexText(3, 8, "disKi");
NexText disKd = NexText(3, 9, "disKd");

NexNumber disSetTemp = NexNumber(1, 11, "disSetTemp");
NexNumber disPIDOut = NexNumber(2, 12, "disPIDOut");
NexNumber n0 = NexNumber(2, 11, "n0");

    * Register a button object to the touch event list.
NexTouch *nex_listen_list[] =

void setup()
    //Pump setup
    //initialize the variables we're linked to

    setPoint = 100;

    //turn the PID on
    EEPROM.get(10, Kp);
    EEPROM.get(20, Ki);
    EEPROM.get(30, Kd);
    myPID.SetTunings(Kp, Ki, Kd);
    myPID.SetSampleTime(10000);  //sets the period, in Milliseconds. 10 sec.

    pinMode(PWMPin, OUTPUT);
    // DS18B20
    sensors.setResolution(mashInThermometer, TEMPERATURE_PRECISION);
    sensors.setResolution(mashOutThermometer, TEMPERATURE_PRECISION);
    sensors.setResolution(mashThermometer, TEMPERATURE_PRECISION);
    sensors.setResolution(HLThermometer, TEMPERATURE_PRECISION);
    //spark function setup
    Particle.function("pumpSwitch", pumpS); // expects a 0 for off and a 1 for on.  Will fail with any other string content.
    Particle.function("getsetTemp", gsetT); //expects a string of integer that is the set temp float *10 to remove the decimal.
    Particle.function("PIDset", PIDSet); //sends pxx.xxixx.xxdxx.xx in a string

    //spark variable setup
    Particle.variable("mashInTemp", &mashInTempF, DOUBLE);
    Particle.variable("mashOutTemp", &mashOutTempF, DOUBLE);
    Particle.variable("mashTemp", &mashTempF, DOUBLE);
    Particle.variable("HLTemp", &HLTempF, DOUBLE);
    Particle.variable("pumpState", &pumpState, INT);     // Spark variable: 0 = Off, 1 = On.
    Particle.variable("Setpoint", &setPoint, DOUBLE);  //  Setpoint for the PID controller.  May not be needed as the function may be able to retrun the value.
    Particle.variable("Pidout", &output, DOUBLE);
    //Thingspeak init
    /* Set the baudrate which is for debug and communicate with Nextion screen. */
    /* Register the pop event callback function of the current button component. */
    disPump.attachPop(pumpPopCallback, &disPump);
    disSet.attachPop(TempSetPopCallback, &disSet);
    b1.attachPop(loadPIDSet, &b1);
    disPIDSet.attachPop(updatePIDSet, &disPIDSet);
    dbSerialPrintln("setup done");

    Serial.begin(9600);   // open serial over USB
    // On Windows it will be necessary to implement the following line:
    // Make sure your Serial Terminal app is closed before powering your Core
    // Now open your Serial Terminal, and hit any key to continue!
 //while(!Serial.available()) SPARK_WLAN_Loop();


void loop()
         * When a pop or push event occured every time,
         * the corresponding component[right page id and component id] in touch event list will be asked.
    //PID compute  
    input = mashTempF;
    if (mashInTempF<setPoint+20)  // safty check to turn off RIMM if output greater than 20 degrees over setpoint.
         output = 0;


//FUNCTION to read temp from Dallas temp
void update18B20Temp(DeviceAddress deviceAddress, double &tempF)
  double tempTemp = sensors.getTempF(deviceAddress);
 if (tempTemp > -100)
  tempF = tempTemp;

//Spark Function to turn pump on or off
// SPARK FUNCTION pumpSwitch
int pumpS (String x)                               // String x will be a 0 for relay off; a 1 for relay on)
    int tempValue = x.toInt();                  // Extract integer
    if (tempValue == 0)
        pumpState = 0;                                 // Set for relay off
        digitalWrite(pumpPin, LOW);                          // Switch relay off
        digitalWrite(D7, LOW);                          // Turn on Spark blue LED
    else if (tempValue == 1)
       pumpState = 1;                                  // Set for relay on
       digitalWrite(pumpPin, HIGH);                         // Switch relay on
       digitalWrite(D7, HIGH);                         // Turn off Spark blue LED
    return pumpState;

//Spark Function to updated PID temperature setpoint
// SPARK FUNCTION getsetTemp
int gsetT (String y)                               // String y will contain the set temperature as an int.
    int tempValue1 = y.substring(0).toInt();           
    setPoint = tempValue1;
    return -1;

//Spark Function to get PID settings
int PIDSet (String y)                               // String y  or format pxx.xxixx.xxdxx.xx where xx.xx contain float values
    Kp = y.substring(y.indexOf("Kp")+2, y.indexOf("Ki")).toFloat();           // converts part of string to float
    Ki = y.substring(y.indexOf("Ki")+2, y.indexOf("Kd")).toFloat();
    Kd = y.substring(y.indexOf("Kd")+2).toFloat();
    EEPROM.put(10, Kp);
    EEPROM.put(20, Ki);
    EEPROM.put(30, Kd);
    myPID.SetTunings(Kp, Ki, Kd);
    return -1;

 * Button component pop callback function.
void pumpPopCallback(void *ptr)
    dbSerialPrintln("Pump PopCallback");
    memset(buffer, 0, sizeof(buffer));
    /* Get the text value of button component [the value is string type]. */
    if (pumpState == 0)

 * Slider component pop callback function.
void TempSetPopCallback(void *ptr)
    uint32_t number = 0;
    char temp[10] = {0};
    utoa(number, temp, 10);

void updateDisplay()  //updates display and calls for temp update.  must be greater than 750ms
    Serial.println("updateDisplay called");
    update18B20Temp(mashInThermometer, mashInTempF);
    disMashIn.setText(String(mashInTempF,1)); //Send temp to nextion display.
    update18B20Temp(mashOutThermometer, mashOutTempF);
    disMashOut.setText(String(mashOutTempF,1)); //Send temp to nextion display.
    update18B20Temp(mashThermometer, mashTempF);
    disMash.setText(String(mashTempF,1)); //Send temp to nextion display.
    update18B20Temp(HLThermometer, HLTempF);
    disHL.setText(String(HLTempF,1)); //Send temp to nextion display.

void loadPIDSet(void *ptr)  //loads PID values from memory to display
   Serial.print("load PIDSet called: ");

void updatePIDSet(void *ptr)  //reads PID values from display and generates a string to send to PIDSet funcion to save to EEPROM.
   Serial.print("updatepidsety called: ");
   String temp = "Kp";
   memset(buffer, 0, sizeof(buffer));
   disKp.getText(buffer, sizeof(buffer));
   temp += String(buffer);
   temp += "Ki";
   memset(buffer, 0, sizeof(buffer));
   disKi.getText(buffer, sizeof(buffer));
   temp += String(buffer);
   temp += "Kd";
   memset(buffer, 0, sizeof(buffer));
   disKd.getText(buffer, sizeof(buffer));
   temp += String(buffer);

void thingspeakUpdate()
    Serial.println("thingspeak update called");
    float f1 = (float) mashInTempF;
    float f2 = (float) mashOutTempF;
    float f3 = (float) mashTempF;
    // Then you write the fields that you've set all at once.
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);  



Sorry I don't think this was the right way to post the Photon code but this is the Photon code and the HMI file.  You will see I have timers in my code that call functions at 1 sec and 30 seconds.  The PID lib executes every 10 seconds.  This will cause variation in the timing of the main loop execution.  


i have the simular problem. When the screen is not pressed really hard than i get an error back from the libary but i can see for example changes on the lcd.

(1.59 MB)
(16.1 KB)

I figured out my touch response problems.  In my code I use a timer to call the screen update once per second.  The library does not handle the asynchronous code flow and will miss data on the serial interface. I removed the timer and put a time check in the main loop.  

if ((millis() - lastUpdate) > displayUpdate)



        lastUpdate = millis();


This one change made a huge improvement on performance.  I also changed the serial baud rate with the following command in setup.   


I did not change the delays in the library as suggested in this post but that may help even more.

I also modified the screen update routine with a case statement using the sendcurrentpage function so I am only updating the current page.  My thought is this will avoid delays do to err timeouts when the code tries to write to objects not on the current page.  

uint8_t pageCurrent;


   switch(pageCurrent) {

      case 1 :

Now my screen response is smooth.  

1 person likes this
@justin sykes i am have the same problem as you. i will try your suggestion and let u know the result. Thanks man

here is a post i create to get the page number

Thanks to Justin Sykes idea

As the user has located a solution, this will now be marked as solved.