Help Nextion display - temperature / humidity with photon

Hi everybody,
I’m trying to display the temperature and the humidity values from my sensors on the Nextion display but the code I found doesn’t work and it’s complicated to find something for Photon.

I found some things, but the code doesn’t works (all the videos are for arduino)…



My display is plug like this :
+5v --> VIN
TX --> TX
RX --> RX
GND --> GND
It’s a simple 3.2" Nextion display (same one the first video).

And here is my code, I have 4 temperature sensor plus 1 humidity sensor.

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



////// LIBRARIES ///////
#include <Adafruit_DHT.h>



////// TEMPERATURE ///////
int chaudHaut = A0;
int chaudBas = A1;
int froidHaut = A2;
int froidBas = A3;

double tempChaudHaut = 0.0;
double tempChaudBas = 0.0;
double tempFroidHaut = 0.0;
double tempFroidBas = 0.0;



////// HUMIDITY ///////
#define DHTPIN A4
#define DHTTYPE DHT11
int humidity;
DHT dht(DHTPIN, DHTTYPE);



////// RELAYS ///////



////// DISPLAY ///////
NexText txt_tempch = NexText(0, 4, "tempch");
NexText txt_humi = NexText(0, 8, "humi");

char buffer[100] = {0};
char buffer2[100] = {0};





void setup() {
    
    ////// TEMPERATURE ///////
    Particle.variable("tempch", &tempChaudHaut, DOUBLE);
    Particle.variable("tempcb", &tempChaudBas, DOUBLE);
    Particle.variable("tempfh", &tempFroidHaut, DOUBLE);
    Particle.variable("tempfb", &tempFroidBas, DOUBLE);
    
    pinMode(chaudHaut, INPUT);
    pinMode(chaudBas, INPUT);
    pinMode(froidHaut, INPUT);
    pinMode(froidBas, INPUT);
    
    
    
    
    ////// HUMIDITY ///////
    dht.begin();
    
    
    
    ////// DISPLAY ///////
    nexInit();
}






void loop() {
    /////////////////////////////////////////////////////////////// TEMPERATURE ///////////////////////////////////////////////////////////////
    ////////// Sonde chaud haut //////////
    int readingCH = analogRead(chaudHaut);
    double voltageCH = (readingCH * 3.3) / 4095.0;
    tempChaudHaut = (voltageCH - 0.5) * 100;
  
  
    ////////// Sonde chaud bas //////////
    int readingCB = analogRead(chaudBas);
    double voltageCB = (readingCB * 3.3) / 4095.0;
    tempChaudBas = (voltageCB - 0.5) * 100;
  
  
    ////////// Sonde froid haut //////////
    int readingFH = analogRead(froidHaut);
    double voltageFH = (readingFH * 3.3) / 4095.0;
    tempFroidHaut = (voltageFH - 0.5) * 100;
  
  
    ////////// Sonde froid bas //////////
    int readingFB = analogRead(froidBas);
    double voltageFB = (readingFB * 3.3) / 4095.0;
    tempFroidBas = (voltageFB - 0.5) * 100;
    
    
    
    
    /////////////////////////////////////////////////////////////// HUMIDITY ///////////////////////////////////////////////////////////////
    humidity = dht.getHumidity();
    Spark.publish("humidity", String(humidity) + "%");
    delay(3000000);
    
    
    
    
    /////////////////////////////////////////////////////////////// RELAYS ///////////////////////////////////////////////////////////////
    
    
    
    
    /////////////////////////////////////////////////////////////// DISPLAY ///////////////////////////////////////////////////////////////
    txt_tempch.setText(buffer);
    txt_humi.setText(buffer2);
    
}

If somebody can help that would be great, that driving me crazy.
All the best

This isn't a helpful symptom description.
What exactly does not work?
Did you look at any of the demos provided with the (Particle ported) library?

Thank you for your reply.
I meant that the temperature of the interface I have made on the nextion editor doesn’t change.

Yes, I took a look on the examples but I don’t understand everything, and I didn’t see how to use the value from sensors, all the examples that use text or number use button to change it.

And with my project, I am trying to getback the datas from the sensors (using the same delays) to display it on the screens.

The second video is exactly what I am trying to do, but when I use its code nothing happend on the screen and if I use it alone without my code, the IDE tell me that there is some problems with the library.

Thank you again for your help :slight_smile:

So you have waited 50 minutes to see whether the screen updates after you saw the published event in the cloud?

And where exactly are you feeding the new data into the strings (buffer[] & buffer2[]) you send to the display?

I know it's long, but obviously no, I didn't wait 50min... it's just because I don't need to have an update every seconds.

That's what I don't understand. How and where should I write which value should modify which text from the interface.
It's the first time I use one of these screen, so, I don't understand many things, sorry.
The buffer and buffer2 are from the code found on the first video, but I don't know what does it mean.

Actually with this code you aren't updating the screen at all for the first 50 minutes. You read the sensors and then you wait 50 minutes before you would show these readings on the screen.
But not even then your code would do anything useful on the screen because you'd just write an empty string to the txt_ components on your screen.

For testing, reduce the delay to 10000 (10 sec) and put that at the end of loop().

And to actually get some text displayed do this

    snprintf(buffer, sizeof(buffer), "%.1f °C", tempChaudHaut);
    snprintf(buffer2, sizeof(buffer2), "%3d %%", humidity);
    txt_tempch.setText(buffer);
    txt_humi.setText(buffer2);

Actually the first two lines of the code above haven't got anything to do with the display. This would be common practice for any program that needs a numeric value wrapped up as a text.
Only the latter two lines cause the transfer of the strings to the display.

And to be up to date with syntax, change this in setup() too

    Particle.variable("tempch", tempChaudHaut);
    Particle.variable("tempcb", tempChaudBas);
    Particle.variable("tempfh", tempFroidHaut);
    Particle.variable("tempfb", tempFroidBas);

BTW, the sample you got the buffer variables from, also fills these buffers with strings like this

    // Conversao dos valores de inteiro para string
    memset(buffer, 0, sizeof(buffer));
    itoa(temp, buffer, 10);
    memset(buffer2, 0, sizeof(buffer2));
    itoa(umid, buffer2, 10);

Thank you again for your reply. Actually everything works fine for the sensors, i’m just trying to display the temperature and the humidity on the screen, and I tried you code, but it give me an error in the library ITEADLIB_Nextion :

lib/ITEADLIB_Nextion/src/NexHardware.cpp:189: undefined reference to nexSerial' lib/ITEADLIB_Nextion/src/NexHardware.cpp:260: undefined reference tonexSerial’
lib/ITEADLIB_Nextion/src/NexHardware.cpp:276: undefined reference to `nexSerial’

But maybe I don’t understand something, i’m quiet a newbie in Arduino and I don’t understand the syntax of the display…

That's where I'd repeat what I said earlier

This ported library needs to be used just a bit differently than the original in order to support a custom serial interface and not just the one hardcoded in the original lib.

Thank you for your help.
I finally display the values (thanks to you :slight_smile:) , but I should use two different way, one for temperature, and another for humidity:

snprintf(buffer3, sizeof(buffer3), "%.1f", tempFroid);
t2.setText(buffer3);
    
t3.setText(buffer4);
int humi = dht.getHumidity();
memset(buffer4, 0, sizeof(buffer4));
itoa(humi, buffer4, 10);

If I use the same way for humidity and temperature, the temperature is print in the humidity field.
And I also should add this command: USARTSerial& nexSerial = Serial1; before the setup, otherwise I had some errors with the library (ITEADLIB_Nextion.h)

But now, I have a different problem. I wanted to use and print the time on the display, so I took a look on the particle documentation: https://docs.particle.io/reference/firmware/photon/#timestr- an when I use and print Time.now(); on the screen, it works well, but I have something like that: 1400647897 that’s apparently normal, but I don’t know how to read or change that (I tried some thing found in the documentation like:

Time.zone(-4);
or
Time.format(time, TIME_FORMAT_ISO8601_FULL);

but nothing works and I don’t really know where to place it and where to find the time zone for my country).

So I use two int, one for the minutes and one for the hour, displayed in two different field on my Nextion. It works fine, but I have two hours less than the hour in my country, and the time change about every 20 minutes and I don’t know why. Here the code for the time (placed in the void loop();

t4.setText(buffer5);
memset(buffer5, 0, sizeof(buffer5));
itoa(hourTime, buffer5, 10);

t8.setText(buffer6);
memset(buffer6, 0, sizeof(buffer6));
itoa(minuteTime, buffer6, 10);

Thank you again for your help.

First, why on earth are you sending the buffer to the display before you actually put your string into it?

And for the time I’d do something like this

  tTime.setText((const char*)Time.format("%T"));

To select any other format have a look here
http://www.cplusplus.com/reference/ctime/strftime/

Simply because, as I said I don't know what this thing is made for and I didn't find something clear on internet and also because i'm quite new in Arduino.

Thanks for the time, I'll try that, but where should I put that, and how could I print that in a field on the display ? Like that ?

t12.setText(buffer9);
memset(buffer9, 0, sizeof(buffer9));
itoa(tTime, buffer9, 10);

OK then, simplified: The setText() method of the Nextion library just passes the string you provide via the parameter to the display where the current contents of that variable will be copied over for display.
So in order to have this method display the current value of your numeric value, you'd need to convert the numeric into string and copy into the buffer before you pass it to the display.

memset(buffer9, 0, sizeof(buffer9));
itoa(tTime, buffer9, 10);
t12.setText(buffer9);

But since you only use the buffer temporarily, there is no point in having several buffer1, buffer2, ...
Just have one and reuse it.
And I much prefer snprintf() over itoa() and its likes for the flexibility.

  char    buffer[64];
  double temp = 12.3;
  double hum = 67.8;

  snprintf(buffer, sizeof(buffer), "Temperature: %4.1f °C", temp);
  tTemp.setText(buffer);

  snprintf(buffer, sizeof(buffer), "Humidity: %4.1f %%", hum);
  tHum.setText(buffer);

  snprintf(buffer, sizeof(buffer), "%s", (const char*)Time.format("%T"));
  tTime.setText(buffer);
1 Like

Thank you for your explanation, that really helped me, and now, the time is working well !
But I would try the same way for the date, but it’s don’t seem to be that easy.

snprintf(buffer, sizeof(buffer), "%x", (const char*)Time.day("%D"));
t10.setText(buffer);

This is what I tried for the date, but I have this error:

../wiring/inc/spark_wiring_time.h:52:17: error: initializing argument 1 of 'static int TimeClass::day(time_t)' [-fpermissive] static int day(time_t t); // the day for the given time ^
But in the line 52 I just have this:

NexText t3 = NexText(0, 7, "t3"); // humidity

And it worked fine before I change that, I used this way:

t10.setText(buffer2); memset(buffer2, 0, sizeof(buffer2)); itoa(day, buffer2, 10);

But I should use 3 paragraphes like this one, one for the day, one for the month and the last for the year. I’m pretty sure there is another way to do so, but I didn’t find it in the Particle’s documentation. Just found the command for the day/monrh/year. If you could help me for this part as well :slight_smile:

Obviously, I try many thing, and I make some research before asking you, I don’t here without searching.

Thank you again

First it would be "%s" not "%x" and you still want Time.format("%D") and not Time.day("%D") for the date.

  snprintf(buffer, sizeof(buffer), "%s", (const char*)Time.format("%D"));

But if you only want the number of the day, you’d use

  snprintf(buffer, sizeof(buffer), "%d", Time.day());
1 Like

Amazing, it works really nice, that’s perfect.
Now I have to find the way to fade-in and fade-out a white led strip when the hour of the photon is reached and normally thanks to you, everything is done.

If you have some tips for the led strips thats will be amazing, I already did it with an arduino uno, but when I use the same way, the led strip just bright and there is no fade in.
Im using a FQP50N06L transistor to drive it, but on the Uno there is PWM digital pin, but I don’t know where are they on the Photon.

Obviously the first place to look for such info would be the docs
https://docs.particle.io/reference/firmware/photon/#input-output

1 Like

Thank you for the link, I didn’t find that when I searched.
I could modify the led strip intensity Using the analogWrite, but I wanted to make a fade-in when the hour is reached, but everything I found make the led “breathing”, so it fade-in and then fade-out etc. and I can’t make the led stay on with the fade-in when the time is reached and the stay off with the fade-out when the time is reached as well.

int led = 9;
int brightness = 0;
int fadeAmount = 5;
 
void setup() {
  pinMode(led, OUTPUT);
}
 
void loop() {
  analogWrite(led, brightness);
 
  brightness = brightness + fadeAmount;
 
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }
  delay(30);
}

I know this code will make the led “breathing” I tried to modify it, but I couldn’t modify it to keep the led in after the fade-in

Do you know how I could keep the led on after the fade-in ?

Hi @lxnr-p
The experts here will possibly give you a better answer (I am a novice too):
But you could try:

Note: You will need to reset brightness to zero when LEDs are turned off to repeat the process.

(This should ramp brightness up by "5" on each loop of 30 (milliseconds) - so should reach 255 in 255/5 x 30ms about 1.5 seconds.)

Note: In the original code once the 255 value got reached, the fade amount got reversed to -5 and the brightness value stepped back to zero, where it swapped fade amount to +5 and so it went on).

1 Like

I’d do something like this

const int led    = D0;
int   fadeStep   = 0;
int   brightness = 0;

int setFadeStep(String cmd) {
  return (fadeStep = cmd.toInt());
}

void setup() {
  pinMode(led, OUTPUT);
  Particle.function("setFadeStep", setFadeStep);
}
 
void loop() {
  static uint32_t msDelay = 0;

  if (millis() - msDelay < 30) return;  // non-blocking "delay" 
  msDelay = millis();

  if(fadeStep != 0) {
    brightness += fadeStep;
    brightness = constrain(brightness, 0, 255);
    analogWrite(led, brightness);
 
    if (brightness == 0 || brightness == 255) {
      fadeStep = 0;
    }
  }
}

You can start a fade-in with sending a positive number to setFadeStep and a fade out with a negative.

But this hasn’t got anything to do with the topic title, right?

And I’m pretty sure there is no GPIO pin with the number 9 on any Particle device.

int led = 9;

Hence I opted for D0 :wink:

1 Like

Thank you for your reply, I finally could fade-in the leds :slight_smile:

But I still have a problem with the hour. There is still two hours less than in my country (France), how and where I can change that?
I tried some things found in the particle documentation, but it doesn’t works…