feat(ui): тревога по перегреву и config.h со всеми настройками
Настройки собраны в config.h: пины, ориентация, пороги тревоги, шкала графика, тайминги и скорость Serial. Раньше они были раскиданы по модулям, и подстройка требовала лазить по коду. Тревога включается на ALARM_ON_C и отпускает только на ALARM_OFF_C (85 и 82 градуса). Один порог заставлял бы её дёргаться каждую секунду, пока температура топчется на границе. В тревоге экран мигает негативом (инверсия буфера, а не команда контроллера - не зависит от микросхемы дисплея), светодиод GPIO8 мигает с ним в общей фазе. Без данных светодиод горит ровно, в норме погашен. Зажигается низким уровнем: проверено опытом, заодно в простое пин стоит высоким, что безопасно для GPIO8 как пина начальной загрузки. Переменная alarm переименована в alarmActive: имя alarm занято функцией из unistd.h, которая попадает в сборку ESP32. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
db86597433
commit
bd0a87ea49
6 files changed
+131
-21
No files matched your search
+14
-12
@@ -3,24 +3,15 @@
|
||||
#include <U8g2lib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Подтверждено сканером из tools/i2c_scan: экран отвечает только на этой паре.
|
||||
static const uint8_t PIN_SDA = 5;
|
||||
static const uint8_t PIN_SCL = 6;
|
||||
|
||||
// Ориентация экрана: U8G2_R0 — как разведено на плате, U8G2_R2 — поворот на 180 градусов.
|
||||
static const u8g2_cb_t *const DISPLAY_ROTATION = U8G2_R2;
|
||||
#include "config.h"
|
||||
|
||||
// Порядок параметров: (rotation, reset, clock, data) — SCL идёт раньше SDA.
|
||||
static U8G2_SSD1306_72X40_ER_F_HW_I2C display(DISPLAY_ROTATION, U8X8_PIN_NONE, PIN_SCL, PIN_SDA);
|
||||
|
||||
static const uint8_t GRAPH_W = 72; // по пикселю на отсчёт: 72 точки = 72 секунды
|
||||
static const uint8_t GRAPH_W = 72; // по пикселю на отсчёт: 72 точки = 72 секунды
|
||||
static const uint8_t GRAPH_TOP = 28;
|
||||
static const uint8_t GRAPH_H = 12;
|
||||
|
||||
// Шкала фиксированная: при автомасштабе шум +-1 градус в простое рисовался бы горами.
|
||||
static const float SCALE_MIN = 30.0f;
|
||||
static const float SCALE_MAX = 90.0f;
|
||||
|
||||
static uint8_t history[GRAPH_W]; // 0 = нет данных, иначе высота столбика 1..GRAPH_H
|
||||
|
||||
void uiBegin() {
|
||||
@@ -51,13 +42,22 @@ static void drawGraph() {
|
||||
}
|
||||
}
|
||||
|
||||
void uiRender(bool fresh, float tempC, int loadPct) {
|
||||
// Негатив всего кадра. Через буфер, а не командой контроллера: так поведение
|
||||
// не зависит от конкретной микросхемы дисплея.
|
||||
static void invertBuffer() {
|
||||
uint8_t *b = display.getBufferPtr();
|
||||
const size_t n = (size_t)display.getBufferTileWidth() * display.getBufferTileHeight() * 8;
|
||||
for (size_t i = 0; i < n; i++) b[i] = (uint8_t)~b[i];
|
||||
}
|
||||
|
||||
void uiRender(bool fresh, float tempC, int loadPct, bool invert) {
|
||||
display.clearBuffer();
|
||||
|
||||
if (!fresh) {
|
||||
display.setFont(u8g2_font_6x10_tf);
|
||||
display.drawStr(0, 14, "NO");
|
||||
display.drawStr(0, 26, "DATA");
|
||||
if (invert) invertBuffer();
|
||||
display.sendBuffer();
|
||||
return;
|
||||
}
|
||||
@@ -81,5 +81,7 @@ void uiRender(bool fresh, float tempC, int loadPct) {
|
||||
|
||||
drawGraph();
|
||||
|
||||
if (invert) invertBuffer();
|
||||
|
||||
display.sendBuffer();
|
||||
}
|
||||
Reference in new issue
Block a user