GUI-O Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login

    Episode 5: Humidity and temperature reader

    Scheduled Pinned Locked Moved
    GUI-O Application Tutorial Series
    1
    1
    382
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • K
      kl3m3n
      last edited by kl3m3n

      I will be using a DHT11 sensor to read and display humidity and ambient temperature. Using a drop-down selector, the indicators for each quantity can be shown or hidden.

      I will be using GUI-O IoT (MQTT) connection, but the example can be easily be ported to other connection types.

      Software prerequisites:

      • Arduino IDE (https://www.arduino.cc/en/software)

      • ESP32 Arduino board support, if using ESP32 based board (see https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html)

      • Arduino Client for MQTT(https://github.com/knolleary/pubsubclient)
        You can follow the setup instructions or directly download and include the PubSubClient.zip library within the Arduino IDE (Sketch -> Include Library -> Add .ZIP library)

      • Adafruit DHT sensor library (https://github.com/adafruit/DHT-sensor-library). Note the library dependencies section!
        You can follow the setup instructions or directly download and include the DHT_sensor_library.zip and Adafruit_Unified_Sensor.zip libraries within the Arduino IDE (Sketch -> Include Library -> Add .ZIP library)

      • GUI-O design tool (https://www.gui-o.com/design-tool)

      • GUI-O application (https://play.google.com/store/apps/details?id=com.guio.guioapp)

      • For additional information about the GUI-O application, download the developer manual from https://www.gui-o.com/

      Components needed:

      • ESP32-WROOM-32 (or any other Arduino supported WiFi capable board; see https://github.com/knolleary/pubsubclient#compatible-hardware for compatible hardware)
      • 10k resistor
      • DHT11 sensor

      The entire tutorial is split into various steps. All necessary information is given in each step.

      0. DESIGN THE GUI (optional)

      The best way to create a GUI layout is to use GUI-O live designer tool.

      Note that the Arduino source code already includes the necessary commands, so this step is not needed, unless you want to make some visual adjustments. If you make adjustments, please include the generated ASCII code in the Arduino source code (see section 3. MODIFY AND UPLOAD THE SOURCE CODE).

      First, you need to establish a TCP/IP connection between the designer tool and GUI-O application:

      1. Determine the local IP address of your PC's network interface (WiFi or Ethernet)
      • Under Windows, open the command prompt, enter ipconfig and press Enter
      • Under Linux, open the terminal, enter ifconfig and press Enter
      1. Open GUI-O application and open settings menu. Select "Connections -> Ethernet" and create a new device with IP address (determined from 1.) and any port between 49152 - 65535

      2. Open GUI-O designer and select "TCP/IP connection" tab. Set the IP address and port. Both values must match the device settings created within the GUI-O application. Click "Start server" button.

      3. Within the GUI-O application, tap the created device and wait for successful connection.

      4. In the GUI-O designer, select "File -> Load designer file" and load the HumidityTemperatureReader.gdf design file. Make the desired adjustments, if necessary. Copy / replace the GUI-O commands into the Arduino source code (see section 3. MODIFY AND UPLOAD THE SOURCE CODE).

      1. CONNECT THE COMPONENTS

      Connecting the components is straightforward.

      schematic.png

      2. CREATE A UNIQUE MQTT CHANNEL

      Open GUI-O application and navigate to settings menu. Select "Connections -> IoT" and add a new device. After adding the device, note the In and Out token (you can share this tokens e.g., to your e-mail by pressing the "share" button).

      Finally, press "Connect" menu entry to establish the connection with the MQTT server.

      3. MODIFY AND UPLOAD THE SOURCE CODE

      The source code has inline comments, describing the important parts of the code. You can copy the source code from the snippet below, or download it here.

      The only thing that needs to be done is to set the ssid and password of your router and the unique In and Out channels that were generated by the GUI-O application (see section 2. CREATE A UNIQUE MQTT CHANNEL).

      After setting these values, upload the code to your board (make sure that the correct board and upload port are selected). Reset the board after upload.

      /*
       * GUI-O Humidity and temperature reader MQTT example (using ESP32-WROOM-32)
       *
       * Copyright (C) 2022, kl3m3n
       * last updated on 12.11.2022
       *
       * SPDX-License-Identifier: BSD-3-Clause
       */
      
      #include <WiFi.h>
      #include <PubSubClient.h>
      #include <DHT.h>
      
      static const char *ssid = "<ssid>"; // router name
      static const char *pass = "<pass>"; // router password
      
      static const char *mqttServer = "mqtt.gui-o.com";   // host name
      static const char *mqttUser = "gui-o-mqtt-generic"; // user name
      static const char *mqttPass = "lqXeZpv5VJyv0XBT";   // password
      
      // IMPORTANT NOTE: if optional user name was specified when adding a new IoT device,
      // the user name should also be included when setting the topics (e.g., "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/<user_name>")
      static const char *Out = "<Out>"; // GUI-O app publish topic
      static const char *In = "<In>";  // GUI-O app subscribe topic
      
      // mqtt client
      WiFiClient wiFiClient;
      PubSubClient mqttClient(wiFiClient);
      
      // forward declare functions for mqtt messages handling
      void mqttCallback(char* topic, byte* message, unsigned int length);
      void parseGuioMsg(const String &msg);
      
      // using DHT11 sensor
      char buf[100];
      const int dhtPin = 25;
      DHT dht(dhtPin, DHT11);
      
      unsigned long startTimestampMsec, currentTimestampMsec;
      const unsigned long readIntervalMsec = 2000; // milliseconds
      
      void setup() {
        // debug output
        Serial.begin(115200);
      
        // dht setup
        dht.begin();
        
        // connect WiFi (keep trying...)
        Serial.print("Connecting to ");
        Serial.println(ssid);
        
        WiFi.begin(ssid, pass);
        while(WiFi.status() != WL_CONNECTED) { 
          Serial.print(".");
          delay(500); 
        }
        
        Serial.println("WiFi connected!"); 
        
        // setup mqtt
        mqttClient.setServer(mqttServer, 1883);
        mqttClient.setCallback(mqttCallback);
      
        startTimestampMsec = millis();
      }
      
      void loop() {
        while(!mqttClient.connected()) {
          Serial.println("MQTT connecting...");
      
          // mqtt client id is the mac address (AABBCCDDEEFF)
          char mqttClientId[15];    
          uint8_t mac[6];
          WiFi.macAddress(mac);
      
          snprintf(mqttClientId, sizeof(mqttClientId), "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
      
          if(mqttClient.connect(mqttClientId, mqttUser, mqttPass)) {
            Serial.println("MQTT connected!");
            mqttClient.subscribe(&Out[0]);
          }
          else {
            Serial.print("MQTT connection failed (");
            Serial.print(mqttClient.state());
            Serial.println(")! Retrying...");      
            delay(2500);
          }
        }
        mqttClient.loop();
      
        currentTimestampMsec = millis();
      
        if(currentTimestampMsec - startTimestampMsec > readIntervalMsec) {
          // read humidity and temperature (in °C)
          float hum = dht.readHumidity();
          float temp = dht.readTemperature();
      
          if(!isnan(hum) && !isnan(temp)) {
            // labels
            snprintf(buf, sizeof(buf), "@hum TXT:\"%.0f %%\"\r\n", hum);
            mqttClient.publish(&In[0], &buf[0]);
            //
            snprintf(buf, sizeof(buf), "@temp TXT:\"%.1f °C\"\r\n", temp);
            mqttClient.publish(&In[0], &buf[0]);
            
            // dial indicators
            snprintf(buf, sizeof(buf), "@humInd VAL:%.0f %%\r\n", hum);
            mqttClient.publish(&In[0], &buf[0]);
            //
            snprintf(buf, sizeof(buf), "@tempInd VAL:%.0f °C\r\n", temp);
            mqttClient.publish(&In[0], &buf[0]);
      
            Serial.print("H = ");
            Serial.print(hum);
            Serial.println(" %");
      
            Serial.print("T = ");
            Serial.print(temp);
            Serial.println(" °C");
          }
          
          startTimestampMsec = millis();
        }
      }
      
      // mqtt callback function
      void mqttCallback(char* topic, byte* message, unsigned int length) {
        // build message string
        String msg;
        for(int i = 0; i < length; i++) {
          msg += (char) message[i];
        }
        // parse message string
        parseGuioMsg(msg);
      }
      
      void parseGuioMsg(const String &msg) {
        if(msg.startsWith("@init")) {
          Serial.println("GUI-O app is requesting INITIALIZATION!");
      
          // clear screen and set background
          mqttClient.publish(&In[0], "@cls\r\n");
          mqttClient.publish(&In[0], "@guis BGC:#FFFFFF\r\n");
          delay(100);
      
          // initialize GUI
          mqttClient.publish(&In[0], "|DRB UID:display X:50 Y:10 W:50 FGC:#FFFFFF DAL:\"Both,Temperature,Humidity\"\r\n");
          mqttClient.publish(&In[0], "|CB UID:tempInd X:50 Y:35 SFGC:#FF281E IP:\"\" HVAL:40 TXTC:#000000 XTC:4 YTC:0 RCA:0 CE:0 SHT:1\r\n");
          mqttClient.publish(&In[0], "|LB UID:temp X:50 Y:35 FGC:#000000 FSZ:5 FFA:\"font6\" TXT:\"\"\r\n");
          mqttClient.publish(&In[0], "|CB UID:humInd X:50 Y:65 IP:\"\" TXTC:#000000 XTC:4 YTC:0 RCA:0 CE:0 SHT:1\r\n");
          mqttClient.publish(&In[0], "|LB UID:hum X:50 Y:65 FGC:#000000 FSZ:5 FFA:\"font6\" TXT:\"\"\r\n");
          mqttClient.publish(&In[0], "|LB UID:details X:50 Y:90 FSZ:2 TXT:\"GUI-O humidity and temperature<br>reader demonstration by kl3m3n\"\r\n");
        }
        else if(msg.startsWith("@display")) {
          // could do this better, but does the job fine (don't remove the trailing spaces...)
          if(msg.indexOf("Temperature ") >= 0) {
            // show temperature only
            mqttClient.publish(&In[0], "@tempInd VIS:1\r\n");
            mqttClient.publish(&In[0], "@temp VIS:1\r\n");
            //
            mqttClient.publish(&In[0], "@humInd VIS:0\r\n");
            mqttClient.publish(&In[0], "@hum VIS:0\r\n");
          }
          else if(msg.indexOf("Humidity ") >= 0) {
            // show humidity only
            mqttClient.publish(&In[0], "@tempInd VIS:0\r\n");
            mqttClient.publish(&In[0], "@temp VIS:0\r\n");
            //
            mqttClient.publish(&In[0], "@humInd VIS:1\r\n");
            mqttClient.publish(&In[0], "@hum VIS:1\r\n");
          }
          else {
            // show all
            mqttClient.publish(&In[0], "@tempInd VIS:1\r\n");
            mqttClient.publish(&In[0], "@temp VIS:1\r\n");
            //
            mqttClient.publish(&In[0], "@humInd VIS:1\r\n");
            mqttClient.publish(&In[0], "@hum VIS:1\r\n");
          }
        }    
      }
      

      4. ESTABLISH CONNECTION

      Make sure that the GUI-O application is connected to the MQTT server.
      Also make sure that the ESP32 board (or other Arduino supported board) is connected to the MQTT server (you can check this by observing the serial debug messages using the Arduino serial monitor).

      Press the Initialize button (see image below) from the GUI-O application home screen.

      initialize_button.jpg

      5. THE RESULT

      Images below shows the result (screen capture) on my Android device after pressing the "Initialize" button. The humidity and temperature indicators are updated every 2 seconds. The visibility of indicators can be controlled via the drop-down box widget.

      screen0.jpg


      screen1.jpg


      screen2.jpg


      If you have any questions or run into any problems, please let me know!

      Best regards,
      kl3m3n

      1 Reply Last reply Reply Quote 0
      • First post
        Last post