กลับไปหน้ารวมไฟล์
temperature-humidity-data-logging-d2e389-en.md

This project demonstrates how easy it is to create a simple display panel (for a thermostat) by interfacing Matrix Orbital GTT Intelligent TFT HMI display with an Arduino Nano via I2C. A DHT22 temperature and humidity sensor is used to obtain temperature and humidity information. This information is processed by the Arduino Nano to display hourly, 24-hour, and weekly historical charts. A live chart is also available for viewing of the current temperature and humidity.

Adding in some electrical and/or electromechanical systems behind this display panel can turn this unit into a thermostat with a beautiful full colour TFT display.

Project Overview

"Temp-Humid-Logger" is a rigorous implementation of Asynchronous Hygrometric-Forensics and I2C-Temporal HMI Orchestration. Designed as an industrial-grade environmental-telemetry node, the system utilizes the Matrix Orbital GTT-series intelligent display to render complex data-architectures via an I2C-bus interconnect. The project explores the sophisticated mapping of sensor-bitstreams into hourly, weekly, and monthly data-grids, implementing a Statistical-Accumulation Heuristic to manage 180+ data-point charts in real-time. The build emphasizes high-fidelity HMI-communication diagnostics, resistive-pullup integrity forensics, and long-term thermal-stability harmonics.

Step 1: Designing the User Interface

The GTT Designer Suite allows users to easily drag and drop widgets on screen. Images and font files can also be imported for use when creating GUI's. For this project there are several screens created which will automatically be processed as a script when buttons are pressed. For the (HOME) first screen, we've dragged in:

  • labels (top label: temperature info in deg C; bottom label: humidity info in % rh)
  • buttons (invisible buttons hidden on the labels which will launch live data plotting of temperature or humidity and a 'MAX' button to set a maximum humidity alert

Screen 2 is the where the default MAX humidity alert is set. Widgets used are:

  • two triangle buttons (up and down) were dragged and dropped to be used to set the MAX humidity. Default MAX humidity is displayed (set at 70%), and the triangle buttons can be used to increase or decrease the settings. These two buttons report to the Arduino and the Arduino processes the button reports to either increment or decrement the MAX humidity setting.
  • button ('HOME' that will take the display back to the first screen)

Screen 3 is an ALERT screen where the users are alerted that the MAX humidity is reached. The Arduino continues to monitor humidity information and brings back to the HOME (first) screen when level falls below the MAX humidity setting.

The following screens: LiveTGraph, TGraph_1HR, TGraph_24HR, TGraph_1WK are historical graph plots of the temperature data. LiveHGraph, HGraph_1HR, HGraph_24HR, HGraph_1WK are historical graph plots of the humidity data. Widgets used are:

  • charts (live graph plot have 30 data points, and historical: 1 hr, 24-hr and 1 week charts are 180 points)
  • buttons (1 hour, 24-hour and 1 week buttons to launch respective charts)

Matrix Orbital Temperature and Humidity Demo GUI

Once the design is completed, the project can be deployed to the GTT. You'll need to connect your PC to the GTT's Mass Storage header, and hit "Deploy" in the GTT Designer. All the necessary files will be generated and deployed directly to the display.

In action

Step 2: Connecting the GTT

For this demo, we'll be using I2C to communicate between the Arduino Uno and the GTT. Using the breadboard Cable, connect the 4 pin header to the GTT's I2C header. Then connect the red breadboard cable lead to 5V power, and connect the black lead to ground. The yellow (SDA) and green (SCL) leads need to be connected to the Arduino Nano's SDA pin (A4) and SCL pin (A5) respectively. No I2C pull-up resistors are required for communication with the GTT (Arduino's Wire library automatically turns on internal pull-up resistors on SCL and SDA). Additional power can be applied through the displays barrel jack.

GTT35A with Arduino Nano in Case

Step 3: Connecting the DHT22

A 4.7k Ohm resistor pull-up to +5V must be placed in the DHT22 data pin, otherwise the sensor will be unable to communicate properly. The data pin can be connected to any digital pin on the Arduino; in this case we selected pin 8.

DHT22 and Arduino Nano

Step 4: Installing Libraries

Before continuing, download and unzip the the following GTT Client Libraries. These libraries can also be found within the most recent GTT Firmware release. Once downloaded, copy over the contents of GttClient into \Users\YourUserName\Documents\Arduino\libraries\gtt.

GTT Client Library

.c and .h files in the Demo Source directory

Technical Deep-Dive

  • Hygrometric-Data Orchestration & I2C Forensics:
    • The DHT22 Acquisition-Probe: Utilizing a capacitive humidity sensor and a thermistor to measure atmospheric-harmonics. Forensics involve the measurement of the "Single-Bus Signal-Timing"; the sensor transmits a 40-bit data packet $(16\text{ bit humi, } 16\text{ bit temp, } 8\text{ bit checksum})$. The diagnostics focus on "Checksum-Fidelity Analytics," ensuring that environmental-oscillations are captured without inducing parity-failure diagnostics.
    • The I2C-Temporal Hub: Operating at a deterministic $100\text{kHz}$ clock-frequency. Forensics include the measurement of the "Packet-Transaction Latency" between the Nano and the GTT35A. The diagnostics utilize a custom i2cWrite routine with a 32-byte chunk-size limit to prevent bus-hang diagnostics on the Arduino's internal Wire-buffer.
  • HMI Rasterization & Statistical Diagnostics:
    • The GTT Intelligent-Display Analytics: Utilizing a custom script-engine to render high-density charts. Forensics include the calculation of "Rolling-Average Harmonics"; 10-sample averages $(20\text{ sec windows})$ are accumulated to populate 1-hour, 24-hour, and 1-week telemetry grids.
    • Flash-Memory Persistence Forensics: Utilizing a uSD-card to store .dat telemetry sets. The diagnostics focus on "File-System Integrity," enabling state-recovery and historical-telemetry loading after power-cycle diagnostics.

Step 5: Code

//GTT Arduino Tempearature and Humidity Demo
//Arduino Uno with Matrix Orbital GTT35A and DHT22
//Created by R Malinis, 25/05/2018
//support@matrixorbital.ca
//www.matrixorbital.ca/appnotes
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <gtt.h>
#include <gtt_device.h>
#include <gtt_enum.h>
#include <gtt_events.h>
#include <gtt_ext_types.h>
#include <gtt_packet_builder.h>
#include <gtt_parser.h>
#include <gtt_protocol.h>
#include <gtt_text.h>
#include <Wire.h>
#include <SimpleDHT.h>
#include "GTTProject12.c"
#include "GTTProject12.h"
#include <stdlib.h>
#define I2C_Address 0x28  //Define default 8bit I2C address of 0x50 >> 1 for 7bit Arduino
// Buffer for incoming data
uint8_t rx_buffer[128];
// Buffer for outgoing data
uint8_t tx_buffer[256];
gtt_device gtt; //Declare the GTT device
typedef enum
{
 NOGraph =0,
 TempGraph=1,
 HumiGraph=2
} GraphScreen;
// DHT11
int pinDHT22 = 8;
SimpleDHT22 dht22;
byte defaultMaxHumidity;
bool MaxHumidityScreen = false;
GraphScreen Graph = NOGraph;
typedef struct
{
 byte ChartData;
 byte ChartObject;
 float rawData;
}DataSourceType;
DataSourceType Temperature;
DataSourceType Humidity;
void LiveGraph(float temperature, float humidity)
{
 if (Graph == NOGraph)
   return;
 DataSourceType source;
 if (Graph == TempGraph)
 {
   source = Temperature;
   source.rawData = temperature;
   source.ChartData = id_livetgraph_t_live_data0;
   source.ChartObject = id_livetgraph_t_live_;
 }
 else
 {
   source = Humidity;
   source.rawData = humidity;
   source.ChartData = id_livehgraph_h_live_data0;
   source.ChartObject = id_livehgraph_h_live_;
 }
 gtt25_dataset_push_data(&gtt, source.ChartData, (float) source.rawData);
 gtt25_visualobject_invalidate(&gtt, source.ChartObject);
 Serial.println("drawing LIVE graph");
 return;
}
void GTT25ButtonHandler(gtt_device* device, uint16_t ObjectID, uint8_t State)
{
 Serial.print("button handler: ");
 Serial.print(ObjectID);
 Serial.print(" state: ");
 Serial.println(State);
 if (State != 1)
   return;
 MaxHumidityScreen = false;
 Graph = NOGraph;
 switch (ObjectID)
 {
   case id_screen2_triangle_button_1:
     defaultMaxHumidity++;
     break;
   case id_screen2_triangle_button_2:
     defaultMaxHumidity--;
     break;
   case id_screen1_max_btn:
     break;
   case id_screen1_image_button_1:
     Graph = TempGraph;
     return;
     break;
   case id_screen1_image_button_2:
     Graph = HumiGraph;
     return;
     break;
   // the following buttons take care of themselves as designed in the GTT Designer
   // only used here for serial debug
   case id_screen2_home_btn:
   case id_screen3_home_btn:
   case id_livehgraph_home_btn:
   case id_hgraph_1hr_home_btn:
   case id_hgraph_24hr_home_btn:
   case id_hgraph_1wk_home_btn:
   case id_livetgraph_home_btn:
     Serial.println("==== back to HOME screen");
     return;
     break;
   case id_livetgraph_1_hr_btn:
   case id_tgraph_1hr_1_hr_btn:
   case id_tgraph_24hr_1_hr_btn:
   case id_tgraph_1wk_1_hr_btn:
   case id_livehgraph_1_hr_btn:
   case id_hgraph_1hr_1_hr_btn:
   case id_hgraph_24hr_1_hr_btn:
   case id_hgraph_1wk_1_hr_btn:
     Serial.println("==== displaying 1 HOUR");
     return;
     break;
   case id_livetgraph_24_hr_btn:
   case id_tgraph_1hr_24_hr_btn:
   case id_tgraph_24hr_24_hr_btn:
   case id_tgraph_1wk_24_hr_btn:
   case id_livehgraph_24_hr_btn:
   case id_hgraph_1hr_24_hr_btn:
   case id_hgraph_24hr_24_hr_btn:
   case id_hgraph_1wk_24_hr_btn:
     Serial.println("==== displaying 24 HOUR");
     return;
     break;
   case id_livetgraph_1_wk_btn:
   case id_tgraph_1hr_1_wk_btn:
   case id_tgraph_24hr_1_wk_btn:
   case id_tgraph_1wk_1_wk_btn:
   case id_livehgraph_week_btn:
   case id_hgraph_1hr_week_btn:
   case id_hgraph_24hr_week_btn:
   case id_hgraph_1wk_week_btn:
     Serial.println("==== displaying 1 WEEK");
     return;
     break;
 }
 char buf[] = {0};
 int16_t humid = defaultMaxHumidity;
 sprintf(buf, "%d", humid); //Convert the humidity value to a string
 gtt_set_screen2_humi_label_1_text(&gtt, gtt_make_text_ascii(buf)); //Update the GTT label
 Serial.println("defaultMaxHumidity is set");
 Serial.println(humid);
}
void HumidityCheck(float humidityVal)
{
 if (humidityVal > defaultMaxHumidity)
 {
   Serial.print("max: "); Serial.print((int)defaultMaxHumidity);
   Serial.print(" current:"); Serial.println((int)humidityVal);
   if (MaxHumidityScreen == false)
   {
     gtt_run_script(&gtt, (char*)("GTTProject12\\\\Screen3\\\\Screen3.bin"));
     MaxHumidityScreen = true;
     delay(2000);
   }
 }
 if (MaxHumidityScreen == true &&  (humidityVal < defaultMaxHumidity))
 {
     gtt_clear_alltraces(&gtt);
     gtt_run_script(&gtt, (char*)("GTTProject12\\\\Screen1\\\\Screen1.bin"));
     MaxHumidityScreen = false;
     delay(2000);
 }
 return;
}
float TempData[10] = {0,0,0,0,0,0,0,0,0,0};
float HumiData[10] = {0,0,0,0,0,0,0,0,0,0};
bool OldDataLoaded = false;
void UpdateDataCollection(float temperature, float humidity)
{
     float avgTempData, avgHumiData;
     static byte counter20sec = 0; // 180 data points = 1hr
     static byte counter8mins = 0; // 180 data points = 24hrs
     static byte counter56mins = 0;// 180 data points = 1week
     DataSourceType dataSource;
     static byte HrMaxH = 15;
     static byte HrMinH = 25;
     static byte HrMaxT = 20;
     static byte HrMinT = 25;
     static byte T24HrMaxH = 15;
     static byte T24HrMinH = 25;
     static byte T24HrMaxT = 20;
     static byte T24HrMinT = 25;
     //debug
     static byte count20secP = 0;
     static byte count8minP = 0;
     static byte count56minP = 0;
     LiveGraph(temperature, humidity);
     //Serial.print("Data (not collected): ");
     //Serial.print((float)temperature); Serial.print(" *C, ");
     //Serial.print((float)humidity); Serial.println(" RH%");
     eStatusCode r;
     if (OldDataLoaded == false)
     {
       OldDataLoaded = true;
       r = gtt25_dataset_load(&gtt, id_tgraph_24hr_24_hr_chart_data0, gtt_make_text_ascii("Temp24hrMax.dat"));
       r = gtt25_dataset_load(&gtt, id_tgraph_24hr_24_hr_chart_data1, gtt_make_text_ascii("Temp24hrMin.dat"));
       r = gtt25_dataset_load(&gtt, id_hgraph_24hr_24_hr_chart_data0, gtt_make_text_ascii("Humidity24hrMax.dat"));
       r = gtt25_dataset_load(&gtt, id_hgraph_24hr_24_hr_chart_data1, gtt_make_text_ascii("Humidity24hrMin.dat"));
       r = gtt25_dataset_load(&gtt, id_tgraph_1wk_1_wk_chart_data0, gtt_make_text_ascii("Temp1WkMax.dat"));
       r = gtt25_dataset_load(&gtt, id_tgraph_1wk_1_wk_chart_data1, gtt_make_text_ascii("Temp1WkMin.dat"));
       r = gtt25_dataset_load(&gtt, id_hgraph_1wk_1_wk_chart_data0, gtt_make_text_ascii("Humidity1WkMax.dat"));
       r = gtt25_dataset_load(&gtt, id_hgraph_1wk_1_wk_chart_data1, gtt_make_text_ascii("Humidity1WkMin.dat"));
       if (r != eStatusCode_Success)
       {
         Serial.println("Check uSD card");
       }
     }
     // collect data for averaging after 20 seconds (10 readings)
     TempData[counter20sec] = temperature;
     HumiData[counter20sec] = humidity;
     //Serial.print("temp: ");
     //Serial.print(temperature);
     //Serial.print(" humidity: ");

ข้อมูล Frontmatter ดั้งเดิม

apps:
  - "1x GTT GUI Designer Software"
  - "1x Arduino IDE"
author: "MatrixOrbital"
category: "Screens & Displays"
components:
  - "1x Arduino Nano (Master-Control Core)"
  - "1x GTT35A Intelligent TFT Display (HMI-Orchestration Node)"
  - "1x DHT22 Sensor (Hygrometric-Forensics Probe)"
  - "1x 4.75k Ohm Resistor (Bus-Pullup Integrity)"
  - "Custom 3D-Printed Case (Structural-Integrity Shell)"
description: "A professional-level telemetry engine featuring DHT22 hygrometric-data diagnostics, Intelligent TFT-HMI orchestration, and long-term statistical-accumulation heuristics."
difficulty: "Intermediate"
documentationLinks: []
downloadableFiles:
  - "https://github.com/MatrixOrbital/GTT-Arduino-TempHumid-Demo"
encryptedPayload: "U2FsdGVkX1/t+rchziI6t7et30b8/FrVVXh5UMRLTT6/DRH7+xqMicsrVaTtyJuLat8kAWQsMrJrrP7YQ/j8ZQ+MGxGvGAQbo+F7P58lez9+JG/b1Rzkh5VnxMSm8rxbh6hMP7gVAwemn+ILYCqPqg=="
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/temperature-humidity-data-logging-d2e389_cover.jpg"
lang: "en"
likes: 14819
passwordHash: "5e84df452a5cc010dbd394cb4a9385008a15b37bfcbc983de36cb944636bcaae"
price: 299
seoDescription: "Temperature & Humidity Data Logging system to track and visualize hourly, weekly, and monthly data points."
tags:
  - "i2c-temporal-forensics"
  - "hygrometric-data-diagnostics-analytics"
  - "hmi-tft-orchestration"
  - "statistical-accumulation-harmonics"
  - "arduino-nano"
title: "Temp-Humid-Logger: I2C-Temporal Forensics & HMI-Data Orchestration"
tools:
  - "GTT Designer Suite (GUI-Raster Framework)"
  - "SimpleDHT (Protocol Abstraction)"
videoLinks:
  - "https://www.youtube.com/embed/YOaDp4v3lI8"
views: 14819