[tutorial] ESP32+TFT + light splitting prism to realize transparent small TV

[tutorial] realizing transparent small TV with ESP32+TFT + beam splitter prism (completed)


Say in front

  • It mainly refers to the HoloCubic of Zhi Huijun and the transparent watch tutorial of Wangzai father's creation society. https://mp.weixin.qq.com/s/Pkq7gmrbVfeZjG7krhSlTg
  • Video tutorial for this article: https://www.bilibili.com/video/BV1C54y1E72e

1. Materials

  • ESP32 + TFT + spectroscopic prism material:

    devicesize
    ESP32 development board (Lexin ESP-WROOM-32 module)54.9mm×27.9mm
    HD SPI TFT color screen (8 pin)1.44 "26.5mm × 25.5mm
    Splitting prism semi transparent and semi reflective 1:125.4mm×25.4mm
  • A treasure link:

    https://m.tb.cn/h.4zJX7F9?sm=4420ad Goouuu-ESP32 module development board wireless WiFi + Bluetooth 2 in 1 dual core CPU
    https://m.tb.cn/h.4zJXVqe?sm=704883 HD SPI1 44 inch TFT display color screen OLED LCD st7735
    Splitting prism: https://m.tb.cn/h.4zFqoKL?sm=9cef79 Spectroscopic prism 25.4mm experimental teaching instrument semi transparent and semi reflective 1:1 spectroscopic image spectroscopic projection prism, pay attention to be 1:1

  • ESP8266 + OLED + spectroprism material:

    devicesize
    ESP8266 development board (ESP-01S recommended)24.82mm×14.81mm
    OLED screen monochrome (four pin)23.45mm×23.45mm
    Splitting prism semi transparent and semi reflective 1:125mm×25mm
    ESP8266 serial port Downloader-
    3.7V lithium battery 300mAh-
    1A lithium battery charging protection board (Type-C charging port)-
    switch-
  • ESP32 and ESP8266 are very cost-effective Wi Fi modules, which are very suitable for DIY projects in the field of Internet of things. Both chips belong to 32-bit processors. ESP32 is a dual core CPU, while ESP8266 is a single core processor, which can easily remotely control and monitor the device through Wi Fi or Bluetooth (ESP32).
  • ESP32 is the successor to ESP8266. It adds an additional CPU core, faster Wi Fi, more GPIO, and supports Bluetooth 4.2 and Bluetooth low power consumption. In addition, the ESP32 is equipped with a touch sensing pin.

2. EPS32 hardware connection mode

  • EPS32 and TFT color screen wiring diagram:

3. Construction of Arduino + esp32 development environment

  • Download arduino1.0 from the official website eight point one five https://www.arduino.cc/en/software (it is recommended not to download the 2.0 beta version, which may cause problems).

  • Install ESP32 development kit, file - > Preferences - > add development board manager input https://dl.espressif.com/dl/package_esp32_index.json

    Then restart Arduino, tools - > development board - > development board manager, and search for ESP32 download

    The download speed of this method is very slow. Generally, the following methods are used:

  • The ESP32 configuration can be directly completed by referring to the Espressif file in the folder to the Arduino installation directory / hardware.

  • Tools - > development board select the development board of ESP32, and set the download speed to 921600 and the frequency to 80MHZ.

  • So far, Arduino and ESP32 development environments have been built.

The following is an official routine to verify whether there is a problem and whether the program can be downloaded.

  • Open the official example of the file: ChipID to obtain the chip ID number of the development board.

  • Click the burn button to see that the burn is 100% complete below. Note that when Connect is prompted below, the development board needs to manually press the boot button to burn (pit stepping record. At first, I thought the board was broken QAQ)

  • Click the serial port monitor in the upper right corner to see the ID number of ESP32 chip. Prove that the environment is built successfully!

4. TFT_ Installation and basic use of ESPI Library

  • The ESP32 package of this document already has TFT_ The ESPI library, if downloaded by yourself, needs to be downloaded from the library management.

  • Open \Arduino\hardware\espressif\esp32\libraries\TFT_ < user under ESPI_ Setup. h> File, in many driver files, select the driver ST7735, and comment out other unused files. (the in the folder is modified. If the TFT screen driver is the same as mine, select ST7735)

  • Then set the color and size of the screen. We set the width of the screen to 128 × 128. There are two types of screen colors: RGB and BGR. TFT is BGR by default. Our pictures are generally RGB, which will be described in detail in the picture display tutorial later.

      ![Insert picture description here](https://img-blog.csdnimg.cn/b076800c49ae4a9ea990a26d95305086.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMTgxNTky,size_16,color_FFFFFF,t_70#pic_center)
    
  • The following line of code cancels the annotation to solve the problem of screen display offset. It is mainly driven by 7735. A pattern line appears at the bottom and right of the screen, and there is no color display. The reason is that the screen origin (0, 0) is offset. Just cancel the annotation of this line of code. (it took a long time to find out the pit stepping record. I thought the TFT screen was broken. QAQ)

  • Next is the setting of SPI pin, which can be set according to the pin in the figure below, which is consistent with the previous ESP32 connection.

  • The following is the frequency setting, which can be set according to the following figure.

  • Write the following code to the new file:

    #include <SPI. h> / / import library
    #include <TFT_eSPI.h> 
      
    TFT_eSPI tft = TFT_eSPI(); 
    
    void setup() {
      // put your setup code here, to run once:
      tft.init();                               //initialization
      tft.fillScreen(TFT_BLACK);                //screen color
      tft.setCursor(10, 10, 1);                 //Set the starting coordinates (10, 10), font size 2
      tft.setTextColor(TFT_YELLOW);             //Set the text color to white
      tft.setTextSize(2);                       //Set text size (1 ~ 7)
      tft.println("TFT_Text");                  //display text
      tft.fillCircle(30,30,10,TFT_BLUE);        //Draw a circle
      tft.drawLine(10,50, 118, 50, TFT_WHITE);  //Draw a line
      tft.drawPixel(70,70,TFT_RED);             //Draw point
      tft.setTextColor(TFT_WHITE,TFT_BLUE);     //Set text color and background color
      tft.setCursor(10, 80, 1);                 //Set the starting coordinates (10, 10), font size 2
      tft.println("TFT_Text");                  //display text
    }
    void loop() {
      // put your main code here, to run repeatedly:
    }
    
  • Burn according to the previous steps, and the results are shown in the following figure:

  • TFT common function prototype:

    tft.init(); tft initialization

    tft.fillScreen(Color); color can be built-in, or you can set the screen color yourself

    tft.setCursor(X, Y, L); Set the starting coordinates (X, Y), L-size font L:0~6

    tft.setTextColor(Color); Set text color

    tft.setTextSize(S); Set text size S:(1~7)

    tft.println(Str); Display text string, only English characters can be displayed, and Chinese characters will be shown in a detailed tutorial later (you need to build your own Chinese character library to display)

    tft.fillCircle(X,Y,R,Color); Draw a circle with (x, Y) as the center and R as the radius.

    tft.drawLine(X1,Y1, X2, Y2, Color); Draw a line, starting point (x1, Y1), ending point (X2, Y2).

    tft.drawPixel(X,Y,Color); Draw point (x, y)

    tft.setTextColor(fg,bg); Set the text color FG and background color BG.

5. TFT displays Chinese characters

  • Create a new font file myfont H is used to store Chinese character font data. By converting each Chinese character into a corresponding hexadecimal number, any Chinese words or sentences can be displayed. In fact, displaying Chinese characters or pictures takes up the running memory of the single chip microcomputer. We need to define these unchanged data as immutable const type, because the variables modified with const, In hardware, it will be saved in ROM, namely "program memory", and the RAM space of "random access memory" for calculation is much smaller than ROM.

  • Define the display size of each Chinese character as 16 × 16 pixels in myfont Write the following code in H:

    #include <pgmspace.h>
    const unsigned char hz_zhou PROGMEM[] =
    {
    	0x00,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x2F,0xE8,0x21,0x08,0x21,0x08,0x3F,0xF8,
    	0x20,0x08,0x27,0xC8,0x24,0x48,0x24,0x48,0x27,0xC8,0x40,0x08,0x40,0x28,0x80,0x10/*"Week ", 0*/
    };
    const unsigned char hz_Mon PROGMEM[] =
    {
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,
    	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00/*"One ", 1*/
    };
    
    ...
    ...
    ... // Omit the rest of the font data
    
    struct FNT_HZ // Chinese font data structure
    {
      char  Index[4];	// Chinese character internal code index, such as "medium", under UTF-8 coding, each Chinese character occupies 3 bytes, and the fourth is the terminator 0
      const unsigned char* hz_Id;  // Dot matrix code data, which stores the corresponding dot matrix sequence after the internal code. Each word requires a dot matrix sequence of 32 bytes
      unsigned char hz_width;    //Sequence length
    };
    
    //Define structure array
    PROGMEM const FNT_HZ hanzi[] =
    {
      {"week", hz_zhou,16}, {"one", hz_Mon,16}, {"two", hz_Tue,16}, {"three", hz_Wed,16}, {"four", hz_Thu,16},
      {"five", hz_Fri,16}, {"six", hz_Sat,16}, {"day", hz_Sunday,16}, {"Sunny", hz_sun,16}, {"Yin", hz_cloudy,16},
      {"rain", hz_rain,16}, {"snow", hz_snow,16}, {"many", hz_duo,16}, {"cloud", hz_yun,16}, {"Promise",hz_xu,16}, {"Chang", hz_chang, 16},
      {"east", hz_dong,16}, {"west", hz_xi,16}, {"south", hz_nan,16}, {"north",hz_bei,16}, {"wind", hz_feng, 16}
    };
    
    
  • Open the font modeling software pctolcd2002 Exe, set the following options:

  • Then enter the Chinese characters to be retrieved at the bottom, click generate font, you can copy them, define the Chinese character array in the above way, and store these font patterns for use.

  • The following is the method of importing font and displaying Chinese characters on TFT screen:

    /*******************Single Chinese character display****************/
    void showMyFont(int32_t x, int32_t y, const char c[3], uint32_t color) { 
      for (int k = 0; k < 25; k++)// Adjust the number of cycles according to the number of words in the font
        if (hanzi[k].Index[0] == c[0] && hanzi[k].Index[1] == c[1] && hanzi[k].Index[2] == c[2])
        { 
            tft.drawBitmap(x, y, hanzi[k].hz_Id, hanzi[k].hz_width, 16, color);
        }
    }
    /*******************Whole sentence Chinese character display****************/
    void showMyFonts(int32_t x, int32_t y, const char str[], uint32_t color) { //Display the whole sentence of Chinese characters. The font is relatively simple. The up, down, left and right output is realized in the function
      int x0 = x;
      for (int i = 0; i < strlen(str); i += 3) {
        showMyFont(x0, y, str+i, color);
        x0 += 17;
      }
    }
    
    showMyFonts(40, 50, "Zhou Riqing", TFT_YELLOW); //"Sunny Sunday" is displayed at (40, 50)
    

6. TFT display picture (including dynamic picture)

  • Also create a new picture file pic h. Store the data of the image model in the same way, for example:

    #include <pgmspace.h>
    
    const uint16_t weather0[0x1000] PROGMEM ={
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0010 (16)
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    ...
    ...
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0FE0 (4064)
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0FF0 (4080)
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x1000 (4096)
    };
    
    const uint16_t weather1[0x1000] PROGMEM ={...};
    
    const uint16_t weather2[0x1000] PROGMEM ={...};
    
    const uint16_t weather3[0x1000] PROGMEM ={...};
    
  • Image modeling method: Open image modeling software imageconverter565 Exe, Open image select the image file to be converted, you can see the pixel size, select Arduino, and save as c documents.

  • Change it to const uint16_t Name[ ] PROGMEM ={...} In the same way as the font, it is stored in the program memory.

  • The following procedure can be used to display the picture on the TFT screen:

    tft.setSwapBytes(true);              // RGB - > BGR add this sentence to display the color correctly.
    tft.pushImage(4, 4, 120, 120, Name); // Display Name picture 128 at (4,4) × 128 pixels
    
  • For the display of dynamic photos, the dynamic photos are divided into several frames. In the loop function, define a global variable i to control the number of frames displayed. Each time you run loop to display one frame of photos and delay, the display of dynamic photos can be completed.

    #include <pgmspace.h>
    
    //Each frame of astronaut's photo, a total of nine frames
    const uint16_t astronaut1[0x1000] PROGMEM ={
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0010 (16)
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,   // 0x0020 (32)
    ...
    ...
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
    const uint16_t astronaut2[0x1000] PROGMEM ={...};
    const uint16_t astronaut3[0x1000] PROGMEM ={...};
    const uint16_t astronaut4[0x1000] PROGMEM ={...};
    const uint16_t astronaut5[0x1000] PROGMEM ={...};
    const uint16_t astronaut6[0x1000] PROGMEM ={...};
    const uint16_t astronaut7[0x1000] PROGMEM ={...};
    const uint16_t astronaut8[0x1000] PROGMEM ={...};
    const uint16_t astronaut9[0x1000] PROGMEM ={...};
    
    //Defines an array of pointers for astronaut photos
    const uint16_t* Astronaut [] PROGMEM = {astronaut1,astronaut2,astronaut3,astronaut4,astronaut5,astronaut6,astronaut7,astronaut8,astronaut9};
    
    int i = 0;
    void loop{
        tft.setSwapBytes(true);             //Change the picture color from RGB - > BGR
        tft.pushImage(10, 55,  64, 64, Astronaut[i]); // (10,55) display 64 ×  64 pixel picture
        delay(100);							//delayed
        i+=1;								//Next frame
        if(i>8){i=0;}							
    }
    

7. TFT image setting + beam splitting prism

  • Light splitting prism is an optical element used to separate the horizontal polarization and vertical polarization of light. It is composed of two prisms, with a multilayer structure plated in the middle, in which the transmission and reflection are 1:1.

  • It looks upside down, which requires us to set the screen to mirror display in the program.

  • Open the file E:\Arduino\hardware\espressif\esp32\libraries\TFT_eSPI\TFT_Drivers\ST7735_Rotation.h

    rotation = m % 5; // Limit the range of values to 0-4
    
      writecommand(TFT_MADCTL);
      switch (rotation) {
        case 0:
         if (tabcolor == INITR_BLACKTAB) {
           writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
         } else if(tabcolor == INITR_GREENTAB2) {
           ...
           ...
           ...
          _width  = _init_height;
          _height = _init_width;
          break;
             
        /****Add case4**********/     
        case 4:
           	writedata(0x39);  // Set mirror rotation
            _width  = _init_width;
          	_height = _init_height;
          break;
      }
    
    
  • Then set the image in the Setup() function in the code, so that the TFT screen will display the image.

    void setup()
    {
        tft.init();                         //Initialize display register
        tft.fillScreen(TFT_WHITE);          //screen color
        tft.setTextColor(TFT_BLACK);        //Set font color black
        tft.setCursor(15, 30, 1);           //Set the text start coordinates (15,30) and font size 1
        tft.setTextSize(1);
        
        tft.setRotation(4);    //Set display mirror + rotate 90 °
    }
    

8. NTP acquisition time

  • Network Time Protocol (NTP) is a protocol used to synchronize the computer's time. It can enable the computer to synchronize its server or clock source (such as quartz clock, GPS, etc.). It can provide high-precision time correction, and the error with the standard time is less than 1ms. Standard time comes from atomic clock, satellite, observatory, etc.

  • We want to get the current date and time from the NTP server. The commonly used NTP servers are as follows:

    pool.ntp.org     		 # Foreign NTP server, domestic address: CN pool. ntp. org
    ntp.aliyun.com   		 # Alibaba cloud
    time1.cloud.tencent.com  # tencent
    time.google.com 		 # Google
    ntp.tuna.tsinghua.edu.cn # Tsinghua University
    ntp.sjtu.edu.cn  		 # Shanghai Jiaotong University
    ntp.fudan.edu.cn		 # Fudan University 
    
  • Install NTPClient and Wifi libraries in Arduino and search in tools - > library management tool. If I used the ESP32 package I shared at that time, there was one that came with it, so I don't need to download it.

  • Now open the official routine, file - > routine - > NtpClient - > basic, and make the following modifications:

    #include <NTPClient.h>
    #include <WiFi.h> // for WiFi shield
    #include <WiFiUdp.h>
    const char *ssid    = "   ";  //wifi account
    const char *password = "   ";  //wifi password
    WiFiUDP ntpUDP;
    NTPClient timeClient(ntpUDP,"ntp.aliyun.com");  //NTP server address
    void setup(){
      Serial.begin(115200);
      //Connect wifi
      WiFi.begin(ssid, password);
      while ( WiFi.status() != WL_CONNECTED ) {
        delay ( 500 );
        Serial.print ( "." );
      }
      timeClient.begin();
    }
    void loop() {
      timeClient.update();
      //Print time
      Serial.println(timeClient.getFormattedTime());
      delay(1000);
    }
    
  • After downloading, we checked the print results through the serial port monitor and found that the time printed was not synchronized with the time displayed on the computer, with a difference of 8 hours. Because of the time zone, our location is East Zone 8, so we need to synchronize with the time of East Zone 8, and make the following modifications:

    void setup(){
      Serial.begin(115200);
      //Connect wifi
      WiFi.begin(ssid, password);
      while ( WiFi.status() != WL_CONNECTED ) {
        delay ( 500 );
        Serial.print ( "." );
      }
      timeClient.begin();
      timeClient.setTimeOffset(28800);  // +Zone 1 offset 3600, + Zone 8: 3600 × 8 = 28800  
    }
    
  • The following is the code for obtaining the specific year, month, day, week, hour and minute:

    timeClient.update();
        unsigned long epochTime = timeClient.getEpochTime();
        Serial.print("Epoch Time: ");
        Serial.println(epochTime);
        //Print time
        int currentHour = timeClient.getHours();
        Serial.print("Hour: ");
        Serial.println(currentHour);
        int currentMinute = timeClient.getMinutes();
        Serial.print("Minutes: ");
        Serial.println(currentMinute);
        int weekDay = timeClient.getDay();
        Serial.print("Week Day: ");
        Serial.println(weekDay);
        //Convert epochTime to adult month day
        struct tm *ptm = gmtime ((time_t *)&epochTime);
        int monthDay = ptm->tm_mday;
        Serial.print("Month day: ");
        Serial.println(monthDay);
        int currentMonth = ptm->tm_mon+1;
        Serial.print("Month: ");
        Serial.println(currentMonth);
        delay(1000);
    

  • Epoch Time: in fact, it refers to a specific time: 1970-01-01 00:00:00, that is, 0:00:00 world standard time on January 1, 1970. Taking this time as the starting point, the value is increased by 1 every past second. You can calculate the Gregorian calendar time and date (excluding leap seconds).

  • You can use the method provided in the NTP library file to directly calculate the date, week and other data. After obtaining the time data, you can display the time data on the TFT color screen only according to the method of displaying text and Chinese characters described above.

9. Weather information acquisition

  • The weather sense is adopted Com official API, this is selected because it provides users with free weather live and the weather in the next three days, which is completely enough for our project. First register and log in, click console - > free version.

  • You can view your public key and private key in the basic information. The private key is used for API access.

  • Click document - > V3 version document - > weather live. Here are the specific interface address, parameter description and return result description.

  • Weather API: https://api.seniverse.com/v3/weather/now.json?key= Your private key & location = query City Pinyin & language = zh Hans & unit = C

  • Weather API for the current day + the next 3 days: https://api.seniverse.com/v3/weather/daily.json?key= Your private key & location = query City Pinyin & language = zh Hans & unit = C & start = 0 & days = 5

  • Life index API: https://api.seniverse.com/v3/life/suggestion.json?key= Your private key & location = query City Pinyin & language = zh Hans

  • Let's take the actual weather in Shanghai as an example and enter the above website directly on the website. The returned results are as follows:

    {
    	"results":[
    		{
    			"location":
    			{
    				"id":"WTW3SJ5ZBJUY",
    				"name":"Shanghai",
    				"country":"CN",
    				"path":"Shanghai,Shanghai,country",
    				"timezone":"Asia/Shanghai",
    				"timezone_offset":"+08:00"},
    			"now":
    			{
    				"text":"Yin",
    				"code":"9",
    				"temperature":"28"
    			},
    			"last_update":"2021-07-28T11:25:27+08:00"
    		}
    	]
    }
    
  • You can see that the returned data format is json. We use the Http protocol to access this API to obtain json data in the program, and install the httpclient Library in Arduino to send requests and establish connections. Install the arduino json library for json data parsing.

    #include <WiFi. h> / / WiFi Library
    #include <ArduinoJson. h> / / JSON Library
    #include <HTTPClient. h> / / HTTP Library
    const char* ssid    = "  ";  //wifi account
    const char* password = "  ";  //wifi password
    const char* host = "api.seniverse.com";  //Xinzhi weather server address
    String now_address="",now_time="",now_temperature="";//Used to store the string obtained from the message
    void setup()
    {
      Serial.begin(115200);
      // Connect network
      WiFi.begin(ssid, password);
      //Waiting for wifi connection
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected"); //Connection succeeded
      Serial.print("IP address: ");    //Print IP address
      Serial.println(WiFi.localIP());
    }
    void loop()
    {
        //Create TCP connection
        WiFiClient client;
        const int httpPort = 80;
        if (!client.connect(host, httpPort))
        {
          Serial.println("connection failed");  //Network request unresponsive print connection failed
          return;
        }
        //URL request address
        String url ="/v3/weather/now.json?key=SeAeuMjbRTJo4I_ZN&location=shanghai&language=zh-Hans&unit=c";
        //Send network request
        client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                  "Host: " + host + "\r\n" +
                  "Connection: close\r\n\r\n");
        delay(5000);
        //Define the answer variable to store the data returned after requesting the network server
        String answer;
        while(client.available())
        {
          String line = client.readStringUntil('\r');
          answer += line;
        }
        //Disconnect server
      client.stop();
      Serial.println();
      Serial.println("closing connection");
    //Get data in json format
      String jsonAnswer;
      int jsonIndex;
      //Find a useful return data location i don't go back
      for (int i = 0; i < answer.length(); i++) {
        if (answer[i] == '{') {
          jsonIndex = i;
          break;
        }
      }
      jsonAnswer = answer.substring(jsonIndex);
      Serial.println();
      Serial.println("JSON answer: ");
      Serial.println(jsonAnswer);
    }
    

  • The following is the code for processing json data. How to extract the weather string we need from json data and use the official json processing website: arduinojson.org Click Assistant to make the following settings:

  • Click Next - > json to copy the json code just obtained:

  • Then go to the next step and give the code for parsing json data as follows:

  • Copy it to the main program, where the second line of input is modified to the previously returned json data, and the code for judging error can be removed, because the json data we obtained earlier must be correct.

    #include <WiFi. h> / / WiFi Library
    #include <ArduinoJson. h> / / JSON Library
    #include <HTTPClient. h> / / HTTP Library
    
    const char *ssid     = "HUAWEI-86BPKD";
    const char *password = "changgebaitong";
    
    const char* host = "api.seniverse.com";  //Xinzhi weather server address
    String now_address="",now_weather="",now_temperature="";//Used to store the string obtained from the message
    void setup()
    {
      Serial.begin(115200);
      // Connect network
      WiFi.begin(ssid, password);
      //Waiting for wifi connection
      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected"); //Connection succeeded
      Serial.print("IP address: ");    //Print IP address
      //Serial.println(WiFi.localIP());
    }
    void loop()
    {
        //Create TCP connection
        WiFiClient client;
        const int httpPort = 80;
        if (!client.connect(host, httpPort))
        {
          Serial.println("connection failed");  //Network request unresponsive print connection failed
          return;
        }
        //URL request address
        String url ="/v3/weather/now.json?key=SeAeuMjbRTJo4I_ZN&location=shanghai&language=zh-Hans&unit=c";
        //Send network request
        client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                  "Host: " + host + "\r\n" +
                  "Connection: close\r\n\r\n");
        delay(5000);
        //Define the answer variable to store the data returned after requesting the network server
        String answer;
        while(client.available())
        {
          String line = client.readStringUntil('\r');
          answer += line;
        }
        //Disconnect server
        client.stop();
        Serial.println();
        Serial.println("closing connection");
        //Get data in json format
        String jsonAnswer;
        int jsonIndex;
        //Find a useful return data location i don't go back
        for (int i = 0; i < answer.length(); i++) {
          if (answer[i] == '{') {
            jsonIndex = i;
            break;
          }
        }
        jsonAnswer = answer.substring(jsonIndex);
        Serial.println();
        Serial.println("JSON answer: ");
        Serial.println(jsonAnswer);
      
    
    StaticJsonDocument<512> doc;
    
    deserializeJson(doc, jsonAnswer);
    
    JsonObject results_0 = doc["results"][0];
    
    JsonObject results_0_location = results_0["location"];
    
    const char* results_0_location_name = results_0_location["name"]; // "Shanghai"
    
    JsonObject results_0_now = results_0["now"];
    const char* results_0_now_text = results_0_now["text"]; // "Yin"
    //const char* results_0_now_code = results_0_now["code"]; // "9"
    const char* results_0_now_temperature = results_0_now["temperature"]; // "28"
    now_address = results_0_location_name;
    now_weather = results_0_now_text;
    now_temperature = results_0_now_temperature;
    Serial.print("Now address:");
    Serial.println(now_address);
    Serial.print("Now weather:");
    Serial.println(now_weather);
    Serial.print("Now temperature:");
    Serial.println(now_temperature);
    }
    

  • After getting these strings and displaying Chinese characters in combination with the previous tutorial TFT, you can display weather information anywhere on the screen.

ending

  • So far, all the knowledge has been covered. The project can be completed by integrating all the above contents. For the specific code, please refer to the transparent screen INO, any questions or questions can be raised in the comment area. Thank you.

Tags: arduino ESP32

Posted by andremta on Tue, 11 Jan 2022 09:04:11 +1030