docs: переписать README как пошаговую инструкцию по повторению
Прежний README описывал устройство проекта, но по нему нельзя было собрать всё с нуля. Теперь это инструкция: что установить, какие пункты меню выставить, как определить пины дисплея, как поставить агента и автозапуск, как проверить без агента. Отдельно вынесены грабли, на которые мы наступили: USB CDC On Boot по умолчанию выключен, LibreHardwareMonitor требует PawnIO, разделитель дробной части должен быть точкой, .ps1 нужен UTF-8 с BOM, порт надо освобождать перед заливкой. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bd0a87ea49
commit
03db58473c
1 file changed
+307
-70
+307
-70
@@ -1,107 +1,344 @@
|
|||||||
# CPU Temp — индикатор температуры процессора на ESP32-C3
|
# CPU Temp — индикатор температуры процессора на ESP32-C3
|
||||||
|
|
||||||
Плата ESP32-C3 со встроенным OLED 0.42″ (72×40) стоит на столе и показывает
|
Небольшая плата ESP32-C3 со встроенным OLED-экраном 0.42″ стоит на столе и
|
||||||
температуру процессора компьютера: крупная цифра, загрузка CPU рядом и график
|
показывает температуру процессора компьютера: крупная цифра, загрузка CPU рядом
|
||||||
за последнюю минуту.
|
и график за последнюю минуту. При перегреве экран мигает негативом.
|
||||||
|
|
||||||
```
|
```
|
||||||
LibreHardwareMonitorLib.dll ──> PowerShell-агент ──COM (USB CDC)──> ESP32-C3 ──I2C──> OLED 72×40
|
LibreHardwareMonitorLib.dll ──> PowerShell-агент ──COM (USB CDC)──> ESP32-C3 ──I2C──> OLED 72×40
|
||||||
(через драйвер PawnIO) раз в секунду "T=67.0;L=34" U8g2
|
(через драйвер PawnIO) раз в секунду "T=67.0;L=34" U8g2
|
||||||
```
|
```
|
||||||
|
|
||||||
Плата ничего не измеряет сама: она принимает готовые строки и рисует их. Всё
|
**Плата ничего не измеряет сама.** Она принимает готовые строки по USB и рисует
|
||||||
чтение железа происходит на ПК.
|
их. Всё чтение датчиков происходит на компьютере — иначе никак: температура CPU
|
||||||
|
доступна только через драйвер уровня ядра.
|
||||||
|
|
||||||
## Состав
|
Подключение — по USB-кабелю, которым плата и так питается. Wi-Fi не
|
||||||
|
используется: настраивать нечего, задержки нет.
|
||||||
|
|
||||||
| Путь | Что это |
|
---
|
||||||
|
|
||||||
|
## Что понадобится
|
||||||
|
|
||||||
|
| | Что | Примечание |
|
||||||
|
|---|---|---|
|
||||||
|
| Железо | Плата ESP32-C3 со встроенным OLED 0.42″ (72×40) | «фиолетовая» плата с разъёмом Type-C |
|
||||||
|
| | Кабель USB Type-C | он же питание, он же канал данных |
|
||||||
|
| ПО на ПК | Windows | агент написан под Windows PowerShell 5.1 |
|
||||||
|
| | Arduino IDE 2.x | сборка и заливка прошивки |
|
||||||
|
| | LibreHardwareMonitor | чтение датчиков |
|
||||||
|
| | PawnIO | драйвер, без него температуры не будет |
|
||||||
|
|
||||||
|
Всё программное обеспечение бесплатное.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Часть 1. Прошивка платы
|
||||||
|
|
||||||
|
### 1.1 Arduino IDE
|
||||||
|
|
||||||
|
Скачать с <https://www.arduino.cc/en/software> и установить. Проект собран на
|
||||||
|
версии 2.3.10.
|
||||||
|
|
||||||
|
### 1.2 Ядро ESP32
|
||||||
|
|
||||||
|
**Инструменты → Плата → Менеджер плат**, найти **esp32** (Espressif Systems),
|
||||||
|
установить. Проект собран на версии 3.3.8.
|
||||||
|
|
||||||
|
Добавлять URL в настройках IDE не нужно: пакет есть в штатном индексе Arduino.
|
||||||
|
|
||||||
|
### 1.3 Библиотека U8g2
|
||||||
|
|
||||||
|
**Инструменты → Управлять библиотеками**, найти **U8g2** (автор oliver),
|
||||||
|
установить. Проект собран на версии 2.36.19.
|
||||||
|
|
||||||
|
Библиотека поддерживает экран 72×40 готовым драйвером. Это важнее, чем кажется:
|
||||||
|
у такого экрана ненулевое смещение по обеим осям, и вручную его подбирать
|
||||||
|
пришлось бы вслепую.
|
||||||
|
|
||||||
|
### 1.4 Настройки платы
|
||||||
|
|
||||||
|
Подключить плату кабелем. В меню **Инструменты** выставить:
|
||||||
|
|
||||||
|
| Пункт меню | Значение |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `config.h` | **все настройки**: пины, пороги тревоги, шкала графика, тайминги |
|
| Плата | **ESP32C3 Dev Module** |
|
||||||
| `CPU_temp.ino` | основной скетч: свежесть данных, гистерезис тревоги, светодиод |
|
| **USB CDC On Boot** | **Enabled** ← обязательно |
|
||||||
| `link.h` / `link.cpp` | неблокирующее чтение строки из Serial и её разбор |
|
| Flash Size | **4MB (32Mb)** |
|
||||||
| `ui.h` / `ui.cpp` | отрисовка через U8g2 и кольцевой буфер истории |
|
| Partition Scheme | Default 4MB with spiffs |
|
||||||
| `tools/i2c_scan/` | одноразовый скетч: поиск пинов встроенного дисплея |
|
| Upload Speed | 921600 |
|
||||||
| `agent/` | агент для ПК, см. [agent/README.md](agent/README.md) |
|
| Порт | тот, что появился после подключения платы |
|
||||||
| `docs/` | спецификация и план реализации |
|
|
||||||
|
|
||||||
## Железо
|
Два пункта критичны:
|
||||||
|
|
||||||
| Параметр | Значение |
|
- **USB CDC On Boot = Enabled.** По умолчанию стоит `Disabled`, и тогда `Serial`
|
||||||
|---|---|
|
уходит в аппаратный UART вместо USB. Прошивка соберётся и зальётся, но данные
|
||||||
| Плата | ESP32-C3 (QFN32), ревизия v0.4, встроенный OLED 0.42″ |
|
до платы доходить не будут, а на экране навсегда останется `NO DATA`.
|
||||||
| Флеш | 4 МБ |
|
- **Flash Size должен совпадать с физическим объёмом флеша.** У этой платы 4 МБ.
|
||||||
| Дисплей | SSD1306 72×40, I2C, адрес `0x3C`, **SDA = GPIO5, SCL = GPIO6** |
|
Посмотреть фактический объём можно через **Инструменты → Get Board Info** или
|
||||||
| Подключение к ПК | нативный USB, `VID_303A&PID_1001` |
|
в выводе утилиты прошивки. При несовпадении разделы уезжают за границу
|
||||||
|
микросхемы.
|
||||||
|
|
||||||
Пины дисплея определены сканером `tools/i2c_scan`, а не по шелкографии: подписи
|
Если номер COM-порта неочевиден: **Диспетчер устройств → Порты (COM и LPT)**,
|
||||||
`GPIO8/GPIO9` на плате относятся к дефолтным Wire-пинам чипа, а не к разводке
|
плата видна как устройство с идентификатором `VID_303A&PID_1001` (Espressif).
|
||||||
экрана.
|
|
||||||
|
|
||||||
## Сборка и заливка
|
### 1.5 Определить пины дисплея
|
||||||
|
|
||||||
|
На **этой** плате экран подключён к `SDA = GPIO5`, `SCL = GPIO6`, адрес `0x3C` —
|
||||||
|
уже прописано в `config.h`, шаг можно пропустить.
|
||||||
|
|
||||||
|
Если плата похожая, но другая, не доверяйте надписям на текстолите: подписи
|
||||||
|
`GPIO8/GPIO9` рядом с пометкой I2C относятся к стандартным пинам чипа, а не к
|
||||||
|
разводке встроенного экрана. Залейте `tools/i2c_scan/i2c_scan.ino` и откройте
|
||||||
|
монитор порта на скорости 115200. Сканер перебирает пары пинов и печатает
|
||||||
|
найденное:
|
||||||
|
|
||||||
|
```
|
||||||
|
--- I2C scan ---
|
||||||
|
SDA=5 SCL=6: device 0x3C
|
||||||
|
SDA=6 SCL=5: nothing
|
||||||
|
SDA=8 SCL=9: nothing
|
||||||
|
SDA=9 SCL=8: nothing
|
||||||
|
```
|
||||||
|
|
||||||
|
Найденную пару вписать в `config.h` (`PIN_SDA`, `PIN_SCL`).
|
||||||
|
|
||||||
|
### 1.6 Залить прошивку
|
||||||
|
|
||||||
|
Открыть `CPU_temp.ino` в Arduino IDE и нажать **Загрузить**.
|
||||||
|
|
||||||
|
Сразу после заливки на экране появится `NO DATA` — так и должно быть: агента на
|
||||||
|
компьютере ещё нет.
|
||||||
|
|
||||||
|
То же самое из командной строки:
|
||||||
|
|
||||||
```
|
```
|
||||||
arduino-cli compile -b esp32:esp32:esp32c3:CDCOnBoot=cdc,FlashSize=4M,PartitionScheme=default .
|
arduino-cli compile -b esp32:esp32:esp32c3:CDCOnBoot=cdc,FlashSize=4M,PartitionScheme=default .
|
||||||
arduino-cli upload -p COM4 -b esp32:esp32:esp32c3:CDCOnBoot=cdc,FlashSize=4M,PartitionScheme=default .
|
arduino-cli upload -p COM4 -b esp32:esp32:esp32c3:CDCOnBoot=cdc,FlashSize=4M,PartitionScheme=default .
|
||||||
```
|
```
|
||||||
|
|
||||||
`CDCOnBoot=cdc` обязателен: по умолчанию в ядре стоит `Disabled`, и тогда
|
Вместо `COM4` подставить свой порт.
|
||||||
`Serial` уходит в аппаратный UART вместо USB, а данные до платы не доходят.
|
|
||||||
|
|
||||||
**Перед заливкой остановить агента** — он держит тот же COM-порт:
|
---
|
||||||
|
|
||||||
|
## Часть 2. Агент на компьютере
|
||||||
|
|
||||||
|
Агент — скрипт `agent/cpu_temp_agent.ps1`. Он читает датчики и раз в секунду
|
||||||
|
шлёт плате строку.
|
||||||
|
|
||||||
|
### 2.1 LibreHardwareMonitor
|
||||||
|
|
||||||
|
Скачать со страницы релизов
|
||||||
|
<https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/releases> архив
|
||||||
|
**`LibreHardwareMonitor.zip`** и распаковать в `D:\Soft\LibreHardwareMonitor`.
|
||||||
|
|
||||||
|
- Путь можно выбрать другой, но тогда поправьте переменную `$LhmPath` в начале
|
||||||
|
скрипта.
|
||||||
|
- **Не берите `LibreHardwareMonitor.NET.10.zip`** — это сборка под .NET 10, а
|
||||||
|
Windows PowerShell 5.1 работает на .NET Framework и такую сборку не загрузит.
|
||||||
|
- Запускать саму программу не нужно. Используются только библиотека
|
||||||
|
`LibreHardwareMonitorLib.dll` и лежащий рядом `HidSharp.dll`.
|
||||||
|
|
||||||
|
### 2.2 Драйвер PawnIO
|
||||||
|
|
||||||
|
Скачать со страницы <https://github.com/namazso/PawnIO.Setup/releases> файл
|
||||||
|
`PawnIO_setup.exe` и запустить **без аргументов**, двойным щелчком, затем пройти
|
||||||
|
мастер. Потребуются права администратора.
|
||||||
|
|
||||||
|
Установщик не принимает ключей командной строки: на `/S` или `/quiet` он
|
||||||
|
отвечает кодом 87 и молча ничего не делает.
|
||||||
|
|
||||||
|
**Зачем это нужно.** Начиная с версии 0.9.5 LibreHardwareMonitor читает регистры
|
||||||
|
процессора через PawnIO, а не через прежний WinRing0, и в архив с программой
|
||||||
|
драйвер не входит. Без него **загрузка CPU читается, а все температуры пустые** —
|
||||||
|
даже из консоли администратора. Симптом сбивает с толку: выглядит как нехватка
|
||||||
|
прав, хотя права ни при чём.
|
||||||
|
|
||||||
|
### 2.3 Проверить вручную
|
||||||
|
|
||||||
|
Открыть PowerShell **от имени администратора** (правый щелчок по значку →
|
||||||
|
«Запуск от имени администратора») и выполнить:
|
||||||
|
|
||||||
|
```
|
||||||
|
powershell -ExecutionPolicy Bypass -File "D:\Soft\Arduino\CPU_temp\agent\cpu_temp_agent.ps1" -Echo
|
||||||
|
```
|
||||||
|
|
||||||
|
Ожидается поток строк раз в секунду:
|
||||||
|
|
||||||
|
```
|
||||||
|
connected: COM4
|
||||||
|
T=47.0;L=24
|
||||||
|
T=48.0;L=14
|
||||||
|
```
|
||||||
|
|
||||||
|
Одновременно на экране платы появится температура. Остановить — Ctrl+C.
|
||||||
|
|
||||||
|
Права администратора нужны всегда: без них драйвер не открывается. Агент
|
||||||
|
проверяет это при старте и называет причину, а не молчит.
|
||||||
|
|
||||||
|
### 2.4 Автозапуск при входе в систему
|
||||||
|
|
||||||
|
В консоли администратора:
|
||||||
|
|
||||||
|
```
|
||||||
|
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File "D:\Soft\Arduino\CPU_temp\agent\cpu_temp_agent.ps1"'
|
||||||
|
$trigger = New-ScheduledTaskTrigger -AtLogOn -User "$env:USERDOMAIN\$env:USERNAME"
|
||||||
|
$set = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero)
|
||||||
|
Register-ScheduledTask -TaskName 'CPU Temp Agent' -Action $action -Trigger $trigger -Settings $set -RunLevel Highest -Force
|
||||||
|
```
|
||||||
|
|
||||||
|
- `-RunLevel Highest` обязателен — это и есть «выполнить с наивысшими правами».
|
||||||
|
- Нулевой `ExecutionTimeLimit` нужен, иначе Планировщик убьёт агента через трое
|
||||||
|
суток.
|
||||||
|
|
||||||
|
Проверить, не перезагружаясь:
|
||||||
|
|
||||||
|
```
|
||||||
|
Start-ScheduledTask -TaskName 'CPU Temp Agent'
|
||||||
|
(Get-ScheduledTask -TaskName 'CPU Temp Agent').State
|
||||||
|
```
|
||||||
|
|
||||||
|
Ожидается `Running`.
|
||||||
|
|
||||||
|
Удалить задание:
|
||||||
|
|
||||||
|
```
|
||||||
|
Unregister-ScheduledTask -TaskName 'CPU Temp Agent' -Confirm:$false
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Повторная заливка прошивки
|
||||||
|
|
||||||
|
Плата прошивается через тот же COM-порт, по которому идут данные. Пока агент
|
||||||
|
держит порт, заливка падает с `PermissionError`. Порядок такой:
|
||||||
|
|
||||||
```
|
```
|
||||||
Stop-ScheduledTask -TaskName 'CPU Temp Agent'
|
Stop-ScheduledTask -TaskName 'CPU Temp Agent'
|
||||||
|
# ... залить прошивку ...
|
||||||
|
Start-ScheduledTask -TaskName 'CPU Temp Agent'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Протокол
|
Порт может держать и монитор порта Arduino IDE — его тоже надо закрыть.
|
||||||
|
|
||||||
Одна строка в секунду, `\n` в конце:
|
---
|
||||||
|
|
||||||
|
## Настройка
|
||||||
|
|
||||||
|
Всё, что имеет смысл менять, собрано в `config.h`:
|
||||||
|
|
||||||
|
| Константа | По умолчанию | Смысл |
|
||||||
|
|---|---|---|
|
||||||
|
| `PIN_SDA`, `PIN_SCL` | 5, 6 | пины экрана |
|
||||||
|
| `DISPLAY_ROTATION` | `U8G2_R2` | ориентация; `U8G2_R0` — повернуть обратно |
|
||||||
|
| `ALARM_ON_C` | 85.0 | температура включения тревоги |
|
||||||
|
| `ALARM_OFF_C` | 82.0 | температура отпускания тревоги |
|
||||||
|
| `ALARM_BLINK_MS` | 500 | полупериод мигания |
|
||||||
|
| `PIN_LED` | 8 | светодиод |
|
||||||
|
| `LED_ACTIVE_LEVEL` | `LOW` | уровень, при котором светодиод горит |
|
||||||
|
| `SCALE_MIN`, `SCALE_MAX` | 30.0, 90.0 | шкала графика, °C |
|
||||||
|
| `SERIAL_BAUD` | 115200 | скорость обмена; менять вместе с агентом |
|
||||||
|
| `STALE_MS` | 5000 | молчание, после которого показывается `NO DATA` |
|
||||||
|
| `SAMPLE_MS` | 1000 | шаг истории графика |
|
||||||
|
| `DRAW_MS` | 200 | период перерисовки экрана |
|
||||||
|
|
||||||
|
### Почему порогов тревоги два, а не один
|
||||||
|
|
||||||
|
С одним порогом тревога дёргалась бы включениями и выключениями каждую секунду,
|
||||||
|
пока температура топчется на границе. Поэтому включение и отпускание разведены:
|
||||||
|
загорается на 85, гаснет только при спуске до 82.
|
||||||
|
|
||||||
|
### Почему шкала графика фиксированная
|
||||||
|
|
||||||
|
Автомасштаб отвергнут сознательно: в простое колебания ±1 °C рисовались бы во
|
||||||
|
всю высоту экрана и выглядели тревожно, хотя ничего не происходит.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что показывает экран
|
||||||
|
|
||||||
|
| Состояние | Экран | Светодиод GPIO8 |
|
||||||
|
|---|---|---|
|
||||||
|
| Норма | температура, загрузка, график | погашен |
|
||||||
|
| Перегрев | то же, мигает негативом | мигает синхронно с экраном |
|
||||||
|
| Нет данных дольше 5 с | `NO DATA` | горит ровно |
|
||||||
|
|
||||||
|
В режиме `NO DATA` история графика не пополняется — иначе обрыв связи выглядел бы
|
||||||
|
как резкое падение температуры.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Протокол обмена
|
||||||
|
|
||||||
|
Агент шлёт плате по одной строке в секунду, в конце — перевод строки:
|
||||||
|
|
||||||
```
|
```
|
||||||
T=67.0;L=34
|
T=67.0;L=34
|
||||||
```
|
```
|
||||||
|
|
||||||
`T` — температура CPU Package в °C, `L` — общая загрузка CPU в процентах.
|
| Ключ | Смысл |
|
||||||
Неизвестные ключи прошивка игнорирует, поэтому протокол можно расширять
|
|
||||||
(например, `G=` для GPU), не трогая старую прошивку.
|
|
||||||
|
|
||||||
Если валидная строка не приходила дольше 5 секунд, на экране появляется
|
|
||||||
`NO DATA`, и история перестаёт пополняться — чтобы пауза связи не выглядела
|
|
||||||
как падение температуры.
|
|
||||||
|
|
||||||
## Экран
|
|
||||||
|
|
||||||
Шкала графика фиксированная, 30–90 °C. Автомасштаб сознательно не используется:
|
|
||||||
при нём шум ±1 °C в простое рисовался бы горами и создавал ложную тревогу.
|
|
||||||
|
|
||||||
Ориентация задаётся константой `DISPLAY_ROTATION` в `config.h`: `U8G2_R0` —
|
|
||||||
как разведено на плате, `U8G2_R2` — поворот на 180°.
|
|
||||||
|
|
||||||
## Тревога по перегреву
|
|
||||||
|
|
||||||
Порогов два, `ALARM_ON_C` и `ALARM_OFF_C` (по умолчанию 85 и 82 °C). Тревога
|
|
||||||
включается на верхнем и отпускает только на нижнем — с одним порогом она
|
|
||||||
дёргалась бы каждую секунду, пока температура топчется на границе.
|
|
||||||
|
|
||||||
В тревоге экран мигает негативом, а светодиод на GPIO8 мигает с ним в такт
|
|
||||||
(общая фаза, период `ALARM_BLINK_MS`).
|
|
||||||
|
|
||||||
Светодиод по состояниям:
|
|
||||||
|
|
||||||
| Состояние | Светодиод |
|
|
||||||
|---|---|
|
|---|---|
|
||||||
| Норма | погашен |
|
| `T` | температура CPU Package, °C |
|
||||||
| Тревога | мигает синхронно с экраном |
|
| `L` | общая загрузка CPU, % |
|
||||||
| `NO DATA` | горит ровно |
|
|
||||||
|
|
||||||
Светодиод зажигается **низким** уровнем (`LED_ACTIVE_LEVEL = LOW`, определено
|
Неизвестные ключи прошивка молча игнорирует, поэтому протокол расширяем: можно
|
||||||
опытом). Попутно это удобно: в обычном режиме пин удерживается высоким, а GPIO8
|
добавить, например, `G=` для видеокарты, не трогая уже прошитые платы.
|
||||||
— пин начальной загрузки, которому высокий уровень и нужен.
|
|
||||||
|
|
||||||
Проверять тревогу можно, не трогая пороги: остановить агента и подать значения
|
**Разделитель дробной части — только точка.** Агент форматирует числа через
|
||||||
вручную.
|
`InvariantCulture`: в русской локали иначе вышло бы `T=67,0`, и разбор на плате
|
||||||
|
прочитал бы `67`, молча потеряв дробную часть.
|
||||||
|
|
||||||
## Требования к ПК
|
Плату можно проверить без агента, отправив строки вручную. Порт при этом должен
|
||||||
|
быть свободен, то есть агента надо остановить:
|
||||||
|
|
||||||
Windows, LibreHardwareMonitor и драйвер PawnIO — порядок установки и разбор
|
```
|
||||||
подводных камней в [agent/README.md](agent/README.md).
|
$sp = New-Object System.IO.Ports.SerialPort 'COM4',115200,'None',8,'One'
|
||||||
|
$sp.DtrEnable = $true; $sp.RtsEnable = $false
|
||||||
|
$sp.Open()
|
||||||
|
40..90 | ForEach-Object { $sp.WriteLine("T=$_.0;L=50"); Start-Sleep -Milliseconds 400 }
|
||||||
|
$sp.Close()
|
||||||
|
```
|
||||||
|
|
||||||
|
Так же удобно проверять тревогу, не меняя пороги в `config.h`: подать значение
|
||||||
|
выше 85, затем 83 (тревога должна сохраниться) и 81 (должна отпустить).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Если не работает
|
||||||
|
|
||||||
|
| Симптом | Причина | Что делать |
|
||||||
|
|---|---|---|
|
||||||
|
| На экране всегда `NO DATA`, хотя агент шлёт строки | `USB CDC On Boot` выключен, `Serial` ушёл в аппаратный UART | включить в меню платы и перезалить |
|
||||||
|
| Экран не светится вовсе | неверные пины I2C | залить `tools/i2c_scan`, найти пару, вписать в `config.h` |
|
||||||
|
| Агент пишет, что температура недоступна | не установлен PawnIO | установить драйвер, см. 2.2 |
|
||||||
|
| Агент отказывается запускаться из-за прав | консоль не от администратора | открыть «от имени администратора» |
|
||||||
|
| Заливка падает с `PermissionError` | порт держит агент или монитор порта IDE | `Stop-ScheduledTask`, закрыть монитор |
|
||||||
|
| Температура без дробной части | число пришло с запятой вместо точки | агент должен форматировать через `InvariantCulture` |
|
||||||
|
| Скрипт `.ps1` падает с ошибками про скобки | файл сохранён в UTF-8 **без BOM** | пересохранить в UTF-8 **с BOM**: PowerShell 5.1 иначе читает файл как ANSI и портит кириллицу |
|
||||||
|
| После перетыкания в другой разъём данные не идут | сменился номер порта | ничего не делать: агент ищет плату по `VID_303A&PID_1001` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как устроено
|
||||||
|
|
||||||
|
| Путь | Что это |
|
||||||
|
|---|---|
|
||||||
|
| `config.h` | все настройки |
|
||||||
|
| `CPU_temp.ino` | свежесть данных, гистерезис тревоги, светодиод |
|
||||||
|
| `link.h` / `link.cpp` | неблокирующее чтение строки из Serial и её разбор |
|
||||||
|
| `ui.h` / `ui.cpp` | отрисовка через U8g2, кольцевой буфер истории, негатив |
|
||||||
|
| `tools/i2c_scan/` | одноразовый скетч поиска пинов дисплея |
|
||||||
|
| `agent/cpu_temp_agent.ps1` | агент для ПК |
|
||||||
|
| `agent/README.md` | подробности по агенту |
|
||||||
|
| `docs/` | спецификация и план реализации |
|
||||||
|
|
||||||
|
Разделение простое: `link` ничего не знает об экране, `ui` не знает, откуда
|
||||||
|
взялись данные, а логика состояний живёт в скетче.
|
||||||
|
|
||||||
|
## Расход ресурсов
|
||||||
|
|
||||||
|
Агент занимает около 70 МБ оперативной памяти и со временем не растёт. Почти всё
|
||||||
|
это — обвязка Windows PowerShell и .NET Framework; сам цикл держит в памяти
|
||||||
|
несколько чисел.
|
||||||
|
|
||||||
|
Прошивка занимает 26% флеша платы и 4% её оперативной памяти.
|
||||||
Reference in new issue
Block a user