#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Wire.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <TM1637Display.h>
#include <Adafruit_AHTX0.h>
// ===== WiFi Config =====
const char* ssid = "XXXXXXXXXX";
const char* password = "ZZZZZZZZZZ";
// ===== Pin Config =====
#if defined(ESP32)
#define CLK 18 // TM1637
#define DIO 19 // TM1637
#define SDA_PIN 21 // AHT30
#define SCL_PIN 22 // AHT30
#else
#define CLK D5 // TM1637
#define DIO D6 // TM1637
#define SDA_PIN D2 // AHT30
#define SCL_PIN D1 // AHT30
#endif
TM1637Display display(CLK, DIO);
Adafruit_AHTX0 aht;
// ===== NTP Config =====
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7 * 3600);
// ===== Variables =====
bool showColon = true;
unsigned long lastSensorRead = 0;
unsigned long lastModeSwitch = 0;
float temperature = NAN, humidity = NAN;
int displayMode = 0; // 0 = เวลา, 1 = อุณหภูมิ, 2 = ความชื้น
// ===== ฟังก์ชัน encodeDigit =====
uint8_t encodeDigit(uint8_t digit) {
const uint8_t digitCode[10] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};
if (digit > 9) return 0;
return digitCode[digit];
}
// ===== Segment map สำหรับ °C และ H =====
const uint8_t MY_SEG_DEGREE = 0b01100011; // °
const uint8_t MY_SEG_C = 0b00111001; // C
const uint8_t MY_SEG_H = 0b01110110; // H
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
display.setBrightness(7);
display.showNumberDecEx(0, 0b01000000, true);
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(300);
Serial.print(".");
}
Serial.println("\nWiFi connected!");
timeClient.begin();
if (!aht.begin()) {
Serial.println("Failed to find AHT sensor!");
} else {
Serial.println("AHT initialized");
}
}
void loop() {
timeClient.update();
// อ่าน AHT ทุก 5 วินาที
if (millis() - lastSensorRead > 5000) {
lastSensorRead = millis();
sensors_event_t humidityEvent, tempEvent;
if (aht.getEvent(&humidityEvent, &tempEvent)) {
temperature = tempEvent.temperature;
humidity = humidityEvent.relative_humidity;
Serial.printf("Temp: %.1f C | Hum: %.1f %%\n", temperature, humidity);
} else {
Serial.println("AHT read failed");
}
}
// สลับโหมดทุก 5 วินาที
if (millis() - lastModeSwitch > 5000) {
lastModeSwitch = millis();
displayMode++;
if (displayMode > 2) displayMode = 0;
}
if (displayMode == 0) {
// ===== เวลา =====
int hours = timeClient.getHours();
int minutes = timeClient.getMinutes();
int displayTime = hours * 100 + minutes;
showColon = !showColon;
uint8_t colonMask = showColon ? 0b01000000 : 0;
display.showNumberDecEx(displayTime, colonMask, true);
} else if (displayMode == 1) {
// ===== อุณหภูมิ xx.x°C =====
if (!isnan(temperature)) {
int temp10 = (int)round(temperature * 10);
uint8_t segs[4];
segs[0] = encodeDigit((temp10 / 100) % 10); // หลักสิบ
segs[1] = encodeDigit((temp10 / 10) % 10); // หลักหน่วย
segs[1] |= 0x80; // จุดทศนิยม
segs[2] = encodeDigit(temp10 % 10); // หลักทศนิยม
segs[3] = MY_SEG_C; // C (แสดง °C)
display.setSegments(segs);
} else {
display.showNumberDecEx(8888, 0, true);
}
} else if (displayMode == 2) {
// ===== ความชื้น xx.xH =====
if (!isnan(humidity)) {
int hum10 = (int)round(humidity * 10);
uint8_t segs[4];
segs[0] = encodeDigit((hum10 / 100) % 10);
segs[1] = encodeDigit((hum10 / 10) % 10);
segs[1] |= 0x80; // จุดทศนิยม
segs[2] = encodeDigit(hum10 % 10);
segs[3] = MY_SEG_H; // H
display.setSegments(segs);
} else {
display.showNumberDecEx(8888, 0, true);
}
}
delay(200);
}