Настройки собраны в 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>
63 lines
1.4 KiB
C++
63 lines
1.4 KiB
C++
#include "link.h"
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include "config.h"
|
|
|
|
static const size_t BUF_SIZE = 64;
|
|
static char buf[BUF_SIZE];
|
|
static size_t len = 0;
|
|
|
|
void linkBegin() {
|
|
Serial.begin(SERIAL_BAUD);
|
|
len = 0;
|
|
}
|
|
|
|
static bool parseLine(char *line, CpuStats &out) {
|
|
bool haveTemp = false;
|
|
bool haveLoad = false;
|
|
CpuStats parsed = {0.0f, 0};
|
|
|
|
char *save = nullptr;
|
|
for (char *tok = strtok_r(line, ";", &save); tok; tok = strtok_r(nullptr, ";", &save)) {
|
|
char *eq = strchr(tok, '=');
|
|
if (!eq) continue;
|
|
*eq = '\0';
|
|
const char *key = tok;
|
|
const char *val = eq + 1;
|
|
|
|
if (strcmp(key, "T") == 0) {
|
|
parsed.tempC = atof(val);
|
|
haveTemp = true;
|
|
} else if (strcmp(key, "L") == 0) {
|
|
parsed.loadPct = atoi(val);
|
|
haveLoad = true;
|
|
}
|
|
// прочие ключи игнорируются намеренно: протокол расширяемый
|
|
}
|
|
|
|
if (!haveTemp || !haveLoad) return false;
|
|
out = parsed;
|
|
return true;
|
|
}
|
|
|
|
bool linkPoll(CpuStats &out) {
|
|
bool got = false;
|
|
while (Serial.available()) {
|
|
const char c = (char)Serial.read();
|
|
if (c == '\r') continue;
|
|
if (c == '\n') {
|
|
buf[len] = '\0';
|
|
if (len > 0 && parseLine(buf, out)) got = true;
|
|
len = 0;
|
|
continue;
|
|
}
|
|
if (len < BUF_SIZE - 1) {
|
|
buf[len++] = c;
|
|
} else {
|
|
len = 0; // строка длиннее буфера — мусор, начинаем заново
|
|
}
|
|
}
|
|
return got;
|
|
}
|