Start a new topic
Solved

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

greeting 

Vic

I had a system crash so will be a while before I can upload. However I think it is related to this post. http://support.iteadstudio.com/support/discussions/topics/1000068204?page=1

  

// 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"

//PID
//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;
//pump
int pumpPin = D0;
int pumpState = 0;

// DS18B20 Thermometer Stuff
#define ONE_WIRE_BUS D1
#define TEMPERATURE_PRECISION 12
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[] =
{
    &disPump,
    &disSet,
    &b1,
    &disPIDSet,
    NULL
};

void setup()
{
    
    //Pump setup
    pinMode(pumpPin,OUTPUT);
    pinMode(D7,OUTPUT);
    digitalWrite(pumpPin,LOW);
    
    //PID
    //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.SetOutputLimits(0,100);
    myPID.SetTunings(Kp, Ki, Kd);
    myPID.SetSampleTime(10000);  //sets the period, in Milliseconds. 10 sec.
    myPID.SetMode(PID::AUTOMATIC);

    //PWM
    pinMode(PWMPin, OUTPUT);
    // DS18B20
    sensors.begin();
    sensors.setResolution(mashInThermometer, TEMPERATURE_PRECISION);
    sensors.setResolution(mashOutThermometer, TEMPERATURE_PRECISION);
    sensors.setResolution(mashThermometer, TEMPERATURE_PRECISION);
    sensors.setResolution(HLThermometer, TEMPERATURE_PRECISION);
    sensors.setWaitForConversion(false); 
    sensors.requestTemperatures(); 
  display.start();
    
    
    //spark function setup
    // SPARK FUNCTION SET UP
    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
    ThingSpeak.begin(client);
    thing.start();
   
   
    
    /* Set the baudrate which is for debug and communicate with Nextion screen. */
    nexInit();
    /* 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.
         */
    nexLoop(nex_listen_list);
    
    
    //PID compute  
    input = mashTempF;
    myPID.Compute();
    if (mashInTempF<setPoint+20)  // safty check to turn off RIMM if output greater than 20 degrees over setpoint.
    {    
        analogWrite(PWMPin,(output*2.55));
    }
    else
    {
         output = 0;
         analogWrite(PWMPin,output);
    }

}



//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
// SPARK FUNCTION PIDset
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);
    Serial.println(Kp);
    Serial.println(Ki);
    Serial.println(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)
    {
        pumpS("1");
        disPump.setText("On");
    }
    else
    {
        pumpS("0");
        disPump.setText("Off");
    }
}

/*
 * Slider component pop callback function.
  */
void TempSetPopCallback(void *ptr)
{
    
    dbSerialPrintln("tempsetPopCallback");
    uint32_t number = 0;
    char temp[10] = {0};
    n0.getValue(&number);
    utoa(number, temp, 10);
    gsetT(temp);
}

void updateDisplay()  //updates display and calls for temp update.  must be greater than 750ms
{
    Serial.println("updateDisplay called");
    disSetTemp.setValue(setPoint);
    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.
    sensors.requestTemperatures();  
    disPIDOut.setValue(output);
}

void loadPIDSet(void *ptr)  //loads PID values from memory to display
{
   Serial.print("load PIDSet called: ");
   disKp.setText(String(Kp,2)); 
   disKi.setText(String(Ki,2)); 
   disKd.setText(String(Kd,2)); 
}

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);
   PIDSet(temp);
   
}

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

  

HMI

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.  

Hi,


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.

HMI
(1.59 MB)
ino
(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)

    {

        updateDisplay();

        lastUpdate = millis();

    }

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

setBaudrate(115200);

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

http://support.iteadstudio.com/support/discussions/topics/11000001276

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;

   sendCurrentPageId(&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 http://support.iteadstudio.com/support/discussions/topics/11000001697

Thanks to Justin Sykes idea

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