Update: animation, backup WiFi, docs
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
22
README.md
22
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Описание
|
## Описание
|
||||||
|
|
||||||
ESP32 часы с OLED дисплеем 1.3" (SH1106), синхронизация времени по NTP, отображение температуры из MQTT.
|
ESP32 часы с OLED дисплеем 1.3" (SH1106), синхронизация времени по NTP, отображение температуры из MQTT. При включении показывает анимационную заставку UA1ZBE.
|
||||||
|
|
||||||
## Аппаратная часть
|
## Аппаратная часть
|
||||||
|
|
||||||
@@ -21,12 +21,17 @@ GPIO21 → SDA
|
|||||||
GPIO22 → SCL
|
GPIO22 → SCL
|
||||||
```
|
```
|
||||||
|
|
||||||
## Настройка WiFi
|
## WiFi настройки
|
||||||
|
|
||||||
В файле `src/main.cpp`:
|
В файле `src/main.cpp`:
|
||||||
```cpp
|
```cpp
|
||||||
|
// Основная сеть
|
||||||
const char* ssid = "Keenetic-3222";
|
const char* ssid = "Keenetic-3222";
|
||||||
const char* password = "28021980";
|
const char* password = "28021980";
|
||||||
|
|
||||||
|
// Резервная сеть (подключается если основная недоступна)
|
||||||
|
const char* ssid2 = "TP-Link_45EC";
|
||||||
|
const char* password2 = "16314733";
|
||||||
```
|
```
|
||||||
|
|
||||||
## MQTT настройки
|
## MQTT настройки
|
||||||
@@ -34,8 +39,8 @@ const char* password = "28021980";
|
|||||||
```cpp
|
```cpp
|
||||||
const char* mqtt_server = "ua1zbe.ru";
|
const char* mqtt_server = "ua1zbe.ru";
|
||||||
const int mqtt_port = 1883;
|
const int mqtt_port = 1883;
|
||||||
const char* mqtt_topic_pz = "/Meteo/dsw1";
|
const char* mqtt_topic_pz = "/Meteo/dsw1"; // Температура П-Зори
|
||||||
const char* mqtt_topic_kand = "max_kand/temp";
|
const char* mqtt_topic_kand = "max_kand/temp"; // Температура Кандалакша
|
||||||
```
|
```
|
||||||
|
|
||||||
## Режимы отображения
|
## Режимы отображения
|
||||||
@@ -47,11 +52,20 @@ const char* mqtt_topic_kand = "max_kand/temp";
|
|||||||
| 30-45 | Температура Кандалакша |
|
| 30-45 | Температура Кандалакша |
|
||||||
| 45-60 | Часы + дата |
|
| 45-60 | Часы + дата |
|
||||||
|
|
||||||
|
## Последовательность запуска
|
||||||
|
|
||||||
|
1. Анимационная заставка UA1ZBE (рамка с надписью, 2 цикла)
|
||||||
|
2. "Connecting..." - подключение к WiFi
|
||||||
|
3. "NTP sync..." - синхронизация времени
|
||||||
|
4. "WiFi + MQTT OK" - всё готово
|
||||||
|
5. Режим отображения часов и температур
|
||||||
|
|
||||||
## Структура проекта
|
## Структура проекта
|
||||||
|
|
||||||
```
|
```
|
||||||
esp32_oled_clock/
|
esp32_oled_clock/
|
||||||
├── platformio.ini # конфигурация PlatformIO
|
├── platformio.ini # конфигурация PlatformIO
|
||||||
|
├── README.md # документация
|
||||||
└── src/
|
└── src/
|
||||||
└── main.cpp # основной код
|
└── main.cpp # основной код
|
||||||
```
|
```
|
||||||
|
|||||||
49
src/main.cpp
49
src/main.cpp
@@ -64,9 +64,40 @@ void setup() {
|
|||||||
Wire.begin(21, 22);
|
Wire.begin(21, 22);
|
||||||
u8g2.begin();
|
u8g2.begin();
|
||||||
u8g2.setFont(u8g2_font_ncenB14_tr);
|
u8g2.setFont(u8g2_font_ncenB14_tr);
|
||||||
|
int16_t txtW = u8g2.getStrWidth("UA1ZBE");
|
||||||
|
int16_t framePad = 8;
|
||||||
|
int16_t txtX = (128 - txtW) / 2;
|
||||||
|
int16_t txtY = 28;
|
||||||
|
int16_t frmX = txtX - framePad;
|
||||||
|
int16_t frmY = txtY - 16;
|
||||||
|
int16_t frmW = txtW + framePad * 2;
|
||||||
|
int16_t frmH = 22;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
for (int offset = 5; offset >= 0; offset--) {
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
u8g2.drawFrame(frmX - offset, frmY - offset, frmW + offset * 2, frmH + offset * 2);
|
||||||
|
u8g2.drawStr(txtX, txtY, "UA1ZBE");
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
delay(60);
|
||||||
|
}
|
||||||
|
for (int offset = 0; offset <= 5; offset++) {
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
u8g2.drawFrame(frmX - offset, frmY - offset, frmW + offset * 2, frmH + offset * 2);
|
||||||
|
u8g2.drawStr(txtX, txtY, "UA1ZBE");
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
delay(60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(20, 40, "Connecting...");
|
u8g2.drawFrame(frmX - 2, frmY - 2, frmW + 4, frmH + 4);
|
||||||
|
u8g2.drawStr(txtX, txtY, "UA1ZBE");
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
delay(1500);
|
||||||
|
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
u8g2.drawStr(5, 40, "Connecting...");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
|
|
||||||
Serial.println("Connecting to WiFi...");
|
Serial.println("Connecting to WiFi...");
|
||||||
@@ -82,7 +113,7 @@ void setup() {
|
|||||||
if (WiFi.status() != WL_CONNECTED) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
Serial.println("\nTrying backup WiFi...");
|
Serial.println("\nTrying backup WiFi...");
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "Backup WiFi...");
|
u8g2.drawStr(5, 40, "Backup WiFi...");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
|
|
||||||
WiFi.begin(ssid2, password2);
|
WiFi.begin(ssid2, password2);
|
||||||
@@ -99,7 +130,7 @@ void setup() {
|
|||||||
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
||||||
Serial.println("Waiting for NTP sync...");
|
Serial.println("Waiting for NTP sync...");
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "NTP sync...");
|
u8g2.drawStr(5, 40, "NTP sync...");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
|
|
||||||
int syncAttempts = 0;
|
int syncAttempts = 0;
|
||||||
@@ -117,19 +148,19 @@ void setup() {
|
|||||||
client.setCallback(callback);
|
client.setCallback(callback);
|
||||||
reconnect();
|
reconnect();
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "WiFi + MQTT OK");
|
u8g2.drawStr(5, 40, "WiFi + MQTT OK");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
delay(1500);
|
delay(1500);
|
||||||
} else {
|
} else {
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "NTP failed!");
|
u8g2.drawStr(5, 40, "NTP failed!");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
delay(2000);
|
delay(2000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.println("\nWiFi failed! Status: " + String(WiFi.status()));
|
Serial.println("\nWiFi failed! Status: " + String(WiFi.status()));
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "No WiFi!");
|
u8g2.drawStr(5, 40, "No WiFi!");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
delay(2000);
|
delay(2000);
|
||||||
}
|
}
|
||||||
@@ -138,7 +169,7 @@ void setup() {
|
|||||||
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
||||||
Serial.println("Waiting for NTP sync...");
|
Serial.println("Waiting for NTP sync...");
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "NTP sync...");
|
u8g2.drawStr(5, 40, "NTP sync...");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
|
|
||||||
int syncAttempts = 0;
|
int syncAttempts = 0;
|
||||||
@@ -156,12 +187,12 @@ void setup() {
|
|||||||
client.setCallback(callback);
|
client.setCallback(callback);
|
||||||
reconnect();
|
reconnect();
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "WiFi + MQTT OK");
|
u8g2.drawStr(5, 40, "WiFi + MQTT OK");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
delay(1500);
|
delay(1500);
|
||||||
} else {
|
} else {
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.drawStr(10, 40, "NTP failed!");
|
u8g2.drawStr(5, 40, "NTP failed!");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
delay(2000);
|
delay(2000);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user