feat(cpu_temp): индикатор температуры CPU на ESP32-C3 с OLED
Плата принимает по USB-CDC строки "T=67.0;L=34" от агента на ПК и рисует крупную цифру, загрузку и график за последнюю минуту на экране 72x40. Пины дисплея (SDA=5, SCL=6) определены сканером, а не по шелкографии: подписи GPIO8/GPIO9 на плате - это дефолтные Wire-пины чипа. Агент читает сенсоры через LibreHardwareMonitorLib. С версии 0.9.5 она требует отдельно установленный драйвер PawnIO: без него загрузка CPU читается, а температуры пусты даже под администратором. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ed4dad0a52
commit
59848698ff
12 files changed
+1473
No files matched your search
@@ -0,0 +1,60 @@
|
||||
#include "link.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
static const size_t BUF_SIZE = 64;
|
||||
static char buf[BUF_SIZE];
|
||||
static size_t len = 0;
|
||||
|
||||
void linkBegin() {
|
||||
Serial.begin(115200);
|
||||
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;
|
||||
}
|
||||
Reference in new issue
Block a user