Files
Arduino/CPU_temp/docs/2026-09-14-cpu-temp-design.md
oskarvitaliiandClaude Opus 5 59848698ff 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>
2026-09-14 21:42:24 +07:00

172 lines
9.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CPU Temp — настольный индикатор температуры процессора
Дата: 2026-09-14
Статус: дизайн согласован, реализация не начата
## Задача
Показывать температуру CPU домашнего ПК на отдельной плате ESP32-C3 с
OLED-экраном 72×40, стоящей на столе. Кроме текущего значения — история за
последнюю минуту, чтобы было видно, греется машина под нагрузкой или нет.
## Оборудование
| Параметр | Значение |
|---|---|
| Плата | ESP32-C3 (QFN32), ревизия v0.4, встроенный OLED 0.42″ |
| Флеш | 4 МБ (XMC), кристалл 40 МГц |
| Подключение | нативный USB Espressif, `VID_303A&PID_1001`, на текущем ПК — COM4 |
| FQBN | `esp32:esp32:esp32c3` (ядро esp32 3.3.8) |
| ПК | Windows 10 Pro, Intel Core i5-11400H |
## Архитектура
```
LibreHardwareMonitorLib.dll ──> PowerShell-агент ──COM4 (USB CDC)──> ESP32-C3 ──I2C──> OLED 72×40
(драйвер, MSR) раз в секунду текстовая строка U8g2
```
Плата ничего не измеряет сама и не хранит настроек: принимает строки и рисует.
Вся работа с железом ПК — на стороне агента.
### Почему так
- **Данные с ПК, а не встроенный датчик ESP32.** Встроенный сенсор меряет
собственный кристалл платы — величина малоинформативная.
- **Температуру CPU читает LibreHardwareMonitor, а не наш код.** Прямое чтение
требует MSR-регистров через подписанный драйвер ядра и отдельных формул под
каждое поколение CPU. LHM даёт готовую `LibreHardwareMonitorLib.dll`.
- **Транспорт — COM-порт, не Wi-Fi.** Плата и так питается по USB от этого же
ПК: провод уже есть. Нет настройки сети, паролей, IP и mDNS.
- **Агент на PowerShell, не на C#.** Загрузка .NET-сборки доступна из
PowerShell напрямую; компилятор и IDE не нужны.
## Протокол
Одна строка в секунду, `\n` в конце:
```
T=67.0;L=34
```
| Ключ | Смысл | Формат |
|---|---|---|
| `T` | CPU Package, °C | дробное |
| `L` | общая загрузка CPU, % | целое |
Формат «ключ=значение» выбран ради расширяемости: добавление `G=` (GPU) или
`M=` (RAM) не ломает старую прошивку — неизвестные ключи прошивка молча
игнорирует. Скорость 115200.
**Отсутствие данных.** Если валидная строка не приходила дольше 5 секунд,
прошивка показывает `NO DATA` и перестаёт дописывать историю (чтобы пауза не
рисовалась как провал температуры).
## Экран
Разрешение 72×40, монохром, драйвер SSD1306 с ненулевым смещением по обеим осям.
Используется `U8G2_SSD1306_72X40_ER_F_HW_I2C` из U8g2 2.36.19 (уже установлена).
```
┌────────────────────────┐
│ 67° 34% │ крупные цифры (~24 px) + мелкая загрузка
│ │
│ ▁▂▃▃▄▆█▆▅▄▃▂▂▁▁▂▃▄▅▆ │ спарклайн: 72 точки = 72 секунды
└────────────────────────┘
```
**Шкала графика фиксированная: 30–90 °C.** Автомасштаб отвергнут: в простое
шум ±1 °C рисовался бы горами и создавал ложную тревогу. Значения вне диапазона
обрезаются по краю.
История — кольцевой буфер на 72 значения (по пикселю на точку, одно значение в
секунду).
## Состав проекта
```
CPU_temp/
CPU_temp.ino setup/loop, тайм-аут «нет данных»
link.h / link.cpp чтение строки из Serial, разбор в структуру CpuStats
ui.h / ui.cpp отрисовка U8g2, кольцевой буфер истории
docs/ этот документ
agent/
cpu_temp_agent.ps1 агент для ПК
README.md установка и автозапуск
```
Границы модулей: `link` ничего не знает об экране и отдаёт только структуру с
данными и признаком свежести; `ui` не знает, откуда данные взялись, и принимает
ту же структуру. Оба тестируются и меняются независимо.
## Агент
Файл `agent/cpu_temp_agent.ps1`:
1. загружает `LibreHardwareMonitorLib.dll` из `D:\Soft\LibreHardwareMonitor`;
2. включает мониторинг CPU, ищет сенсоры `Temperature/CPU Package` и
`Load/CPU Total`;
3. находит COM-порт по `VID_303A&PID_1001` (не по фиксированному номеру: номер
меняется при перетыкании в другой разъём);
4. раз в секунду пишет строку протокола;
5. при исчезновении порта (перезагрузка платы, перезаливка прошивки) —
переподключается в цикле, не падая.
**Требует прав администратора**: без них драйвер LHM не загружается и
температура приходит пустой.
**Автозапуск** — задание в Планировщике заданий: триггер «при входе в систему»,
галка «Выполнить с наивысшими правами», окно скрыто.
## Установка LibreHardwareMonitor
Каталог `D:\Soft\LibreHardwareMonitor` — вне репозитория Arduino. Само
приложение не запускается, нужны только `LibreHardwareMonitorLib.dll` и её
драйвер.
## Порядок работ и риски
1. **Определить пины I2C дисплея эмпирически.** Шелкография подписывает
`GPIO8/GPIO9` (дефолтные Wire-пины ESP32-C3), но встроенный OLED у плат этого
семейства обычно на `GPIO5/GPIO6`. Первый шаг — залить I2C-сканер и найти
адрес экрана перебором обеих пар. Пины не угадывать.
2. Прошивка: вывод фиксированной заглушки на экран — убедиться в геометрии и
смещении 72×40.
3. Приём и разбор строк, `NO DATA` по тайм-ауту.
4. График.
5. Агент, затем автозапуск.
Прочие риски:
- **COM4 — тот же порт, через который прошивается плата.** Перед каждой
заливкой агента надо останавливать, иначе `PermissionError`. То же ограничение
уже описано в `CLAUDE.md` для монитора порта Arduino IDE.
- **`USB CDC On Boot` должен быть включён** в настройках платы, иначе `Serial`
уйдёт в аппаратный UART, а не в USB.
## Решения, принятые явно
- Git: проект пока **не** добавляется в белый список `.gitignore`. Заливаем,
когда появятся первые рабочие результаты, чтобы не засорять публичную историю.
- Автозапуск агента: через Планировщик заданий (вариант B), а не ручной ярлык.
- Каталог LHM: `D:\Soft\LibreHardwareMonitor`.
## Вне рамок (YAGNI)
- GPU, RAM, частоты, вентиляторы — протокол расширяем, но сейчас не делаем.
- Переключение экранов кнопкой BOOT.
- Wi-Fi, веб-панель, сохранение настроек в LittleFS — прошивке нечего хранить.
## Подтверждённые пины (Задача 1, 2026-09-14)
Сканер `tools/i2c_scan` перебрал пары (5,6), (6,5), (8,9), (9,8). Устройство
отвечает только на одной:
```
SDA=5 SCL=6: device 0x3C
```
Итого: **SDA = GPIO5, SCL = GPIO6, адрес 0x3C**. Подпись `GPIO8/GPIO9` на
шелкографии относится к дефолтным Wire-пинам ESP32-C3, а не к разводке
встроенного экрана.