Variable in void loop() problem

Hi everyone,

my name is Peter - I´m an electronics technician and relatively new to Arduino. The program that I´d like you to review was written for displaying weatherdata (airpressure, humidity, temperature) from a BME280 sensor in the serial monitor which works fine! Later I decided to show the weatherdata on a 2.2" TFT-Display and that´s where my problems started :-(((
The variable "weatherdata" in void(loop) contains the values that I want to show but of course its local and only known in "void loop() - but I need the content of "weatherdata" in "void showTemperature()"!!!!
As said before I come from another programming language and starting out is always difficult!!
I would really appreciate your expert advice :slight_smile: :slight_smile: :slight_smile:
Here´s the sketch:

/* Hardware:   [NodeMCU, TFT 2.2" Display] - [ArduinoUno, Ethernetshield, Router]
 * Captures weatherdata from local WLAN (Arduino Webserver) and shows it on a TFT 2.2" Display
 * 
 *
 *  
 *
 */

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#define USE_SERIAL Serial
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9340.h" 
#include "SPI.h"

ESP8266WiFiMulti WiFiMulti;

//Pinout for Display

#define TFT_CS D0   // GPIO 16 
#define TFT_RST 10  // D12 GPIO10 
#define TFT_DC D1   // GPIO 5
#define TFT_MOSI D7 // GPIO 13
#define TFT_CLK D5  // GPIO 14
#define TFT_MISO D6 // GPIO 12

Adafruit_ILI9340 tft = Adafruit_ILI9340(TFT_CS, TFT_DC, TFT_RST);


#define ROTATION_NO 0
#define ROTATION_90 1
#define ROTATION_180 2
#define ROTATION_270 3

//**************************************

String weatherdata; 

//**************************************

void setup() {

    USE_SERIAL.begin(115200);
   // USE_SERIAL.setDebugOutput(true);

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);}
    

WiFi.mode(WIFI_STA);

WiFiMulti.addAP("DLINK", "C63SxIpdTT");


tft.begin();
 
 tft.setRotation( ROTATION_270);
 tft_printFrame();
 tft_printCaption();
tft_showData();

}
//Void setup()end

void tft_printCaption(void)
{
 tft.setTextColor(ILI9340_WHITE); 
 tft.setCursor( 10,55);
 tft.setTextSize(2); 
 tft.print("Bodentemperatur in ");
 tft.setTextSize(1); 
 tft.print("O");
 tft.setTextSize(3); 
 tft.print("C");
 tft.setTextSize(2); 
 tft.setCursor( 50,15);
 tft.print("             HPascal");
 tft.setTextSize(2); 
 tft.setCursor( 10,210);
tft.print("                Prozent");

}

void tft_printFrame( )
{
 tft.fillScreen(ILI9340_BLACK);
 tft.drawRoundRect(1, 0, tft.width()-1,40, 10, ILI9340_BLUE);
 tft.drawRoundRect(1, 50, tft.width()-1,135, 10, ILI9340_GREEN);
 tft.drawRoundRect(0, 200, tft.width()-1, 40, 10, ILI9340_RED);
 }

void tft_showData()
{

tft.setTextSize(10); 
tft.setTextColor(ILI9340_YELLOW, ILI9340_BLACK ); 
tft.setCursor(20,90);
tft.print(weatherdata);
//USE_SERIAL.println(weatherdata);
}


void loop(void) {
   
// wait for WiFi connection
    if((WiFiMulti.run() == WL_CONNECTED)) {

        HTTPClient http;

        USE_SERIAL.print("[HTTP] begin...\n");
       
        // configure traged server and url
        http.begin("http://192.168.1.17/?mode=text"); //HTTP to Plaintext

        USE_SERIAL.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int httpCode = http.GET();

        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                weatherdata = http.getString();// This variable contains airpressure, humidity and temperature

                USE_SERIAL.println(weatherdata);
            }
        } 
        
        else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());}
        

        http.end();
    }

}

A quick fix would seem to be to declare weatherdata as a global variable rather than it being local to loop().

A more correct solution would be to pass weatherdata to the showTemperature() function

Hello UKHeliBob,

thanks for your quick answer - I would prefer passing weatherdata to the showTemperature() function - but how exactly is this done?? That´s a quite amateurish question I know - sorry for that!
I already tried declaring weatherdata global but failed - that´s obviously not so simple!! Maybe you can take me a bit further!!!

thanks

I already tried declaring weatherdata global but failed

Looking at your code again I see that weatherdata is already declared as global so is available throughout the program. What exactly happens with the code in your original post ?
What do you see when you Serial.print() weatherdata in loop() ?

What type of variable does tft.print() take ? Should it be a string (lowercase s) or a String (uppercase S) ?

I´m seeing this on the serial monitor!!!

19.1
50.0
1023.0

This is because of the line "http.begin("http://192.168.1.17/?mode=text"); //HTTP to Plaintext". Before i added "/?mode=Text" I saw the whole HTML Code! There were upper and lower case letters!
I´m not sure what you mean with "What exactly happens with the code in your original post ?"

Try placing the cursor in the Source Code Window in the IDE and using Ctrl-T. This will reformat your code to a more standard C style that is easier for people to read.

I´m not sure what you mean with "What exactly happens with the code in your original post ?"

What do you see on the LCD ?

I see nothing on the LCD :frowning: - when I apply "USE_SERIAL.println(weatherdata);" in "void showTemperature()" and comment it out in "void loop()" it´s just the same - nothing on the serial monitor!!!! That´s the real problem - I should have told you from the start!!! Typical me :-((((
@econjack
Ok

Here´s the reformatted Code:

/* Hardware:   [NodeMCU, TFT 2.2" Display] - [ArduinoUno, Ethernetshield, Router]
   Captures weatherdata from local WLAN (Arduino Webserver) and shows it on a TFT 2.2" Display
*/

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#define USE_SERIAL Serial
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9340.h"
#include "SPI.h"

ESP8266WiFiMulti WiFiMulti;

//Pinout for Display

#define TFT_CS D0   // GPIO 16 
#define TFT_RST 10  // D12 GPIO10 
#define TFT_DC D1   // GPIO 5
#define TFT_MOSI D7 // GPIO 13
#define TFT_CLK D5  // GPIO 14
#define TFT_MISO D6 // GPIO 12

Adafruit_ILI9340 tft = Adafruit_ILI9340(TFT_CS, TFT_DC, TFT_RST);


#define ROTATION_NO 0
#define ROTATION_90 1
#define ROTATION_180 2
#define ROTATION_270 3

//**************************************

String weatherdata;

//**************************************

void setup() {

  USE_SERIAL.begin(115200);
  // USE_SERIAL.setDebugOutput(true);

  USE_SERIAL.println();
  USE_SERIAL.println();
  USE_SERIAL.println();

  for (uint8_t t = 4; t > 0; t--) {
    USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
    USE_SERIAL.flush();
    delay(1000);
  }


  WiFi.mode(WIFI_STA);

  WiFiMulti.addAP("DLINK", "C63SxIpdTT");


  tft.begin();

  tft.setRotation( ROTATION_270);
  tft_printFrame();
  tft_printCaption();
  tft_showData();

}
//Void setup()end

void tft_printCaption(void)
{
  tft.setTextColor(ILI9340_WHITE);
  tft.setCursor( 10, 55);
  tft.setTextSize(2);
  tft.print("Bodentemperatur in ");
  tft.setTextSize(1);
  tft.print("O");
  tft.setTextSize(3);
  tft.print("C");
  tft.setTextSize(2);
  tft.setCursor( 50, 15);
  tft.print("             HPascal");
  tft.setTextSize(2);
  tft.setCursor( 10, 210);
  tft.print("                Prozent");

}

void tft_printFrame( )
{
  tft.fillScreen(ILI9340_BLACK);
  tft.drawRoundRect(1, 0, tft.width() - 1, 40, 10, ILI9340_BLUE);
  tft.drawRoundRect(1, 50, tft.width() - 1, 135, 10, ILI9340_GREEN);
  tft.drawRoundRect(0, 200, tft.width() - 1, 40, 10, ILI9340_RED);
}

void tft_showData()
{

  tft.setTextSize(10);
  tft.setTextColor(ILI9340_YELLOW, ILI9340_BLACK );
  tft.setCursor(20, 90);
  tft.print(weatherdata);
  //USE_SERIAL.println(weatherdata);
}


void loop(void) {

  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    USE_SERIAL.print("[HTTP] begin...\n");

    // configure traged server and url
    http.begin("http://192.168.1.17/?mode=text"); //HTTP to Plaintext

    USE_SERIAL.print("[HTTP] GET...\n");
    // start connection and send HTTP header
    int httpCode = http.GET();

    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK) {
        weatherdata = http.getString();// This variable contains airpressure, humidity and temperature

        USE_SERIAL.println(weatherdata);
      }
    }

    else {
      USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }


    http.end();
  }

}

That´s the real problem - I should have told you from the start!!!

It would have saved time.

Do you get any output on the LCD from a simple "Hello World" program ?
Has the LCD module got a contrast pot on the back by any chance ?

I do get an output from such a program and I can assure you that the display is working in my circuit and is properly connected cause hardware is a thing that I am good at!!
The module has no contrast - it´s in front of me - shining bright and it shows the frames that are declared in void setup()!!

As an experiment try printing some fixed text instead of weatherdata on the TFT. Does it work ?

It does - look at the attached picture!!!!! :frowning: :frowning: :frowning: :frowning:

So, to summarise :

Serial.print(weatherdata);

Shows the correct data

tft.print("Some characters");

Shows the correct text
but

tft.print(weatherdata);

prints nothing

Is the summary correct ?

Earlier in the thread you said

I´m seeing this on the serial monitor!!!

19.1

50.0
1023.0

Is that what you expected to see and if so, how should it be displayed on the TFT bearing in mind the comment that says the weatherdata variable contains 3 data items

Another experiment
Try this

        weatherdata = http.getString();// This variable contains airpressure, humidity and temperature
        USE_SERIAL.print(">");
        USE_SERIAL.print(weatherdata);
        USE_SERIAL.println("<");

Now what do you see in the serial monitor ?

By the way, what's with all of the USE_SERIAL stuff when you might just as well just type Serial ?

Serial.print(weatherdata);


Shows the correct data

tft.print("Some characters");

Shows the correct text

but tft.print(weatherdata);


prints nothing

Is the summary correct ?

YES!!!!

Is that what you expected to see and if so, how should it be displayed on the TFT bearing in mind the comment that says the weatherdata variable contains 3 data items

Yes that is also correct - it contains 3 data items but that can´t be the reason that absolutely nothing is displayed - I would expect a garbled display or something like that but not nothing!!!

>19.1
50.0
1023.0

<

This is what I see on the serial monitor after implementing your code!

By the way, what's with all of the USE_SERIAL stuff when you might just as well just type Serial ?

Changed it a minute ago!! - I watched several tutorials - maybe they weren´t the right ones :frowning:

>19.1

50.0
1023.0

<

This is what I see on the serial monitor after implementing your code!
[/quote]
Note the 2 blank lines at the end of the data output before the >

I suspect that the text on the TFT is wrapping back to the start of the same line and that all you are seeing are the blank lines, hence no text is displayed.  Try

[code]
  tft.setTextWrap(false);  //add this line
  tft.setCursor(20, 90);
  tft.print(weatherdata);



in your program to turn off text wrapping but don't expect 3 lines of data, plus blank lines, to fit properly

I tried your code - it´s still the same - no output on the display! Maybe I should bring another example to make things a bit clearer!

void tft_showData()
{

  tft.setTextSize(10);
  tft.setTextColor(ILI9340_YELLOW, ILI9340_BLACK );
  tft.setTextWrap(false);
  tft.setCursor(20, 90);
  tft.print(weatherdata);
  }

No output on the display!! When I put "Serial.print(weatherdata);" into "void tft_showData()" and uncomment it in "void loop()" there is also no output on the serial monitor!!

void tft_showData()
{

  tft.setTextSize(10);
  tft.setTextColor(ILI9340_YELLOW, ILI9340_BLACK );
  tft.setTextWrap(false);
  tft.setCursor(20, 90);
  tft.print(weatherdata = "test");
  }

"test" is shown on the display!!!
As far as I´m concerned this means that the content of the variable "weatherdata" from "void loop()" is unknown in "void tft_showData()". So how can I pass weatherdata to the "showData()" function??

As far as I´m concerned this means that the content of the variable "weatherdata" from "void loop()" is unknown in "void tft_showData()". So how can I pass weatherdata to the "showData()"

I think that your conclusion is wrong. weatherdata is a global variable so does not need to be passed to the function. It is, however, a String rather than a string. Does the library work with Strings I wonder ? Try converting weatherdata to string before printing it. I believe that the String library has a toCharArray() function or something of a similar name.

What do you see if you Serial.print() weatherdata within the tft_showData() function ?

 What do you see if you Serial.print() weatherdata within the tft_showData() function ?

I see none of the three values on the serial monitor - that´s where my point comes from!!! But I´m trying to implement what you suggest!

Hold on a minute.

Look at the only place that you call tft_showdata() from

Shouldn't you call it from loop() at some time ?