Releases: VibeEngineering-LLC/atomspectra-waterfall-esp32
Release list
firmware v1.1.2 — полевой режим (Outdoor AP) + captive-landing + CRC32 stream-export
Полевой режим (Outdoor AP) + captive-landing + контроль целостности stream-export.
Накопительный релиз v1.0.11 → v1.1.2 (промежуточные v1.1.0/v1.1.1 отдельными релизами не публиковались).
🌲 Полевой режим (Outdoor AP) — главное в этом релизе
Плата теперь умеет работать в поле без роутера и интернета — сама поднимает точку доступа Wi-Fi, к которой подключается телефон и получает полный интерфейс прибора. Всё, что нужно в поле: плата, телефон и (по желанию) повербанк для питания.
Как это работает:
- Плата поднимает точку доступа
AtomSpectra-Outdoor(парольatomspectra, WPA2-PSK), адрес192.168.4.1. - Телефон подключается к сети → операционная система делает обычную «проверку связи» → показывает привычное уведомление «Вход в сеть» (как в кафе или аэропорту) → всплывает лёгкая страница входа с крупным адресом прибора (
192.168.4.1иatomspectra.local), которая сама открывает интерфейс прибора за ~1 секунду. Там же кнопка «Открыть прибор →». - Страница входа нарочно лёгкая (без внешних шрифтов и скриптов) — гарантированно рисуется в упрощённом «captive-браузере» телефона, где тяжёлый основной интерфейс иногда не догружается. Если авто-переход не сработал (iOS умеет ограничивать) — адрес виден на экране, введите
192.168.4.1в браузере вручную. - В интерфейсе доступно всё: живой спектр, водопад, экспорт (N42/XML/SPE/CSV), управление прибором (
-sta/-sto/-rst), калибровка, сохранение спектров. - Данные водопада всё это время копятся на flash платы (LittleFS) и забираются дома в режиме Indoor приёмником.
- Всё офлайн: ни SNTP, ни выгрузки наружу, ни облака.
Три способа войти в Outdoor:
- Переключатель Indoor ↔ Outdoor в шапке стартовой страницы — «липкий» режим, сохраняется между перезагрузками, пока не переключите обратно.
- Автоматически (fallback) — если домашняя сеть недоступна ≥ 90 с, плата одноразово поднимает полевой AP; следующая перезагрузка снова пробует домашнюю сеть.
- С новой (ненастроенной) платы — кнопка «Полевой режим (Outdoor)» в setup-портале.
Время в поле. Интернета нет → SNTP не работает. Время берётся с браузера телефона автоматически при открытии любой страницы (и раз в час); ручная коррекция — поле datetime-local в разделе «Система». При активном SNTP (дома) ручная/браузерная установка игнорируется. Экспорт со дня, когда время ещё не пришло (часы = 1970), помечается «TIME NOT SYNCHRONIZED» и не портит нормальные записи.
Безопасность. Пароль AP по умолчанию atomspectra — публичный, документированный; через открытый AP управляется прибор (включая -rst, стирающий спектр), поэтому для людных мест смените пароль в разделе «Система» (применяется после ребута). При дефолтном пароле Web UI показывает предупреждение.
Bluetooth. Не используется и не собирается (CONFIG_BT_ENABLED=n) — BLE-радио не инициализируется ни в одном режиме, RAM и питание не тратит.
Прочее в релизе
- CRC32 на stream-export (v1.1.1):
GET /api/waterfall/export.aswf(выгрузка из кольца ОЗУ) теперь пишет per-row CRC32 — единый формат v5 с flash-сегментами. Контроль целостности.aswfдоступен и на потоковых выгрузках, не только на сегментах flash.
Прошивка
Web-флешер тянет firmware.factory.bin автоматически (offset 0x0). Ручная прошивка — см. INSTALL.md (bootloader / partition-table / app по offset'ам из flasher_args.json).
SHA256: firmware.factory.bin a7d39da9998293cff53f8804439b25e05a9702626d052e6ace1cbc8b841ebd4c
firmware-v1.0.11
AtomSpectra Waterfall Gateway — firmware-v1.0.11
Накопительный релиз поверх firmware-v1.0.6: температура детектора в формате водопада, адаптивный Web UI на всю ширину, рабочий тумблер шкалы времени на «Мониторинге» + пакет фиксов прошивки.
Cumulative release over firmware-v1.0.6: detector temperature in the waterfall format, full-width responsive Web UI, working monitoring time-scale toggle + a firmware fix batch.
Что нового / What's new
- #FW-41 — температура детектора (
t1) в формате водопада.aswf, бамп формата v4 → v5 (version:5,row_stride:16406, полеtemperature@16402, float32 °C). Читатели v4 совместимы. - #UI-42 — все 6 страниц Web UI растягиваются на всю ширину окна (снята
max-widthу.wrap, сеткиauto-fit). - #FW-49 — поле «префикс имени файла» перенесено со страницы «Система» на каждую вкладку экспорта.
- #UI-43 — тумблер шкалы X (с/м/ч) на «Мониторинге» снова даёт эффект (density-based
xTickStep). - #FW-42/#FW-43/#FW-44/#FW-46 — настраиваемый префикс во всех экспортах; починен hotplug-reinit USB-спектрометра; диагностика в консоль на свежей плате без WiFi;
sdkconfigUSB-FIFO bias→IN + hostnameatomspectra-gw. - #FW-48 — откат экспериментального «kick» линий DTR/RTS (эффекта не давал).
Полный перечень исправлений — KNOWN_ISSUES.md / KNOWN_ISSUES.en.md.
Прошивка / Flashing
Единый образ firmware.factory.bin пишется по смещению 0x0 (bootloader + partition-table + app), ESP32-S3, 16 MB, DIO @ 80 MHz. Именно этот файл тянет и проверяет фирменный флешер.
esptool.py --chip esp32s3 write_flash 0x0 firmware.factory.bin
Раздельные образы (atomspectra_gw.bin@0x10000, bootloader.bin@0x0, partition-table.bin@0x8000) и flasher_args.json приложены для ручной/OTA-прошивки.
SHA-256
firmware.factory.bin BC17693F077180E165F8300DA7C67317531022BE360EEE4DD67626101FBBF2D9
atomspectra_gw.bin 8A6C8BC8DCF56F0146229E0AF16FF49D0EF9D692B34F12A1AF609E65B975E6F9
bootloader.bin DFD7D06511E102E8A73AF7BC96185E38D612C6935D2C1F0B4547D12D62D0C223
partition-table.bin 3D6618F869E029B89931EEDAA807F28E696AEB86AACB08AE8A418CA6C846FA7F
flasher_args.json 3DA640B3168BCB3C42C335DDE454B3352287C315C55A55E27C7C0B560B6E38ED
Commit: c4c81ce.
firmware v1.0.6 — board-side мониторинг + быстрые тумблеры линий + фикс склейки водопада
firmware v1.0.6 — board-side мониторинг, быстрые тумблеры линий, фикс склейки водопада
Изменения с v1.0.5 (#BRIDGE-3):
- #MON-1 — мониторинг на стороне платы. Раньше CPS-мониторинг собирался только в браузере — при закрытой/фоновой вкладке в данных появлялись дыры, плюс дублирование с записью водопада. Сбор перенесён на плату (
main/monitor.c), интервалы ровные независимо от состояния вкладки (снимает и #FW-40 — скачки Δt 10→58 с из-за throttling браузерного таймера в фоне). - #FW-39 — фикс склейки водопада. Ошибка
row_strideв заголовке экспорта (16406→16402) искажала выравнивание строк в собранном.aswf. Исправлено вweb_waterfall.c. - #UI-39 — перекрестие основного экрана водопада. Под курсором теперь № строки и время «от сейчас» (
#N · −Mm Ss, для активной строки —LIVE), в дополнение к ch / кэВ / count. - #UI-40 / #UI-41 — быстрый тумблер линий нуклидов. Кнопка вкл/выкл выбранных линий на странице водопада и на странице спектра. Меняется только видимость — сам выбор нуклидов не трогается. Состояние общее для обеих страниц (
aswf-nuc-vis), переживает F5.
Прошивка: единый firmware.factory.bin @ 0x0 (bootloader + partition-table + app). Flasher тянет его из этого релиза (pull-from-release). Ручная заливка сырых сегментов — ассеты bootloader.bin / partition-table.bin / atomspectra_gw.bin + flasher_args.json.
⚠ Экспериментальная любительская прошивка, поставляется «как есть», без гарантий. Не для метрологических, медицинских или защитных применений.
SHA256: firmware.factory.bin 8CD26FE90EC3428BD33E349F91BBCF97E18B932B5D0BB571A8563272D1C69C30
firmware v1.0.5 — #BRIDGE-3 fix: bridge -inf/-cal race
#BRIDGE-3 — гонка ответов -inf/-cal в bridge mode
Симптомы (репорт оператора): при подключении в bridge mode и запросах -inf/-cal вразнобой серийный номер становился FFFFFFFF, температура падала в 0, поля перемешивались.
Корень: ответ -cal (40 hex-строк без ключей) заходил в ветку разбора -inf → memset(device_info) обнулял температуру/версию, а безусловное serial = lbuf[39] при сдвиге строк под TCP-конкатенацией попадало на пустой слот FFFFFFFF.
Фикс: content-based дискриминатор is_inf = (strstr(text,"VERSION ") != NULL).
-cal→ только калибровка + guarded-serial (device_info/s_info_raw не трогаются).-inf→ прежняя логика.- serial принимается только при ровно 8 hex И не all-F.
Проверка: прошито COM16, верифицировано по HTTP — t1/version/serial стабильны на 6 перемешанных -inf/-cal запросах (до фикса -cal обнулял t1 27.5→0). Финальное подтверждение bridge-mode (TCP-фрагментация) — на стороне оператора/Андрея.
SHA256: firmware.factory.bin 53975D9747A9C23A1B1354CCC825EDDE3B43BB813E902B10ADEE00A20220CB60
firmware v1.0.4 — целостность v4 + RX-декаплинг + временная ось Мониторинга
ESP32-S3 gateway для AtomSpectra (гамма-водопад). Flasher тянет этот release автоматически.
Изменения
- #BRIDGE-1/#BRIDGE-2 RX-декаплинг USB Host: internal RX ring (data_cb → ring → usb_rxw) — устранены потери кадров под TCP-нагрузкой; счётчик
rx_ring_dropsв status JSON - #DATA-1a per-row CRC32 в строке ASWF v4 — целостность каждой строки проверяема на PC
- #DATA-1b глобальный seq сегмента (NVS-персист) — детект потерянных сегментов
- #DATA-1c reconciliation-счётчик прибор-total vs записано (справочная метрика)
- #UI-36 спектр: лог Y авто-диапазон, лёгкая заливка + линия (как в AtomSpectra)
- #UI-37 кнопка «Проверить обновление»: по размеру текста, прижата вправо
- #UI-38 Мониторинг: временная ось X (сек/мин/час + реальное время), выбор часового пояса в «Системе»
- scripts: офлайн-проверки формата v4 (
v4_verify.pyи др.), сборщик под v4-контроль целостности
Прошивка (esptool, ESP32-S3, 16MB)
Flasher-приложение шьёт единым файлом firmware.factory.bin (offset 0x0).
Раздельные сегменты (для ручной прошивки idf.py):
0x0bootloader.bin0x8000partition-table.bin0x10000atomspectra_gw.bin
SHA256: firmware.factory.bin c8ad258d4b9dcd54eaf58dc91158065da9f1e5d11e0d6c43fedfc831ac33b767
WiFi — через captive portal (fallback AP), сохраняется в NVS. Прошивка публичная, без приватных данных.
firmware v1.0.2 — вкладка Мониторинг + фиксы UI
ESP32-S3 gateway для AtomSpectra (гамма-водопад). Flasher тянет этот release автоматически.
Изменения
- #FW-29 вкладка Мониторинг: запись CPS с усреднением по интервалу + экспорт CSV
- #FW-30 фикс: Мониторинг не писал отсчёты (CPS был пуст)
- #FW-31 график мониторинга: сырая линия + наложение SMA
- #FW-35 спектр в режиме CPS: нижняя граница Y = 0
- #FW-36 убрана сигма (± σ) из графика мониторинга
- #FW-37 «Сохранённые» после F5: JSON error / список пропадал — фикс
- #FW-38 Мониторинг: F5 сбрасывал старт — клиентский якорь
- #DOC-9 README RU+EN: новые скрины (Спектр / Водопад / Мониторинг / Сохранённые)
Прошивка (esptool, ESP32-S3, 16MB)
Flasher-приложение шьёт единым файлом firmware.factory.bin (offset 0x0).
Раздельные сегменты (для ручной прошивки idf.py):
0x0bootloader.bin0x8000partition-table.bin0x10000atomspectra_gw.bin
SHA256: firmware.factory.bin f1082b3c0b4889abc4b8f817511acd96ea65ce37935b81d3ddeef243e8b31864
WiFi — через captive portal (fallback AP), сохраняется в NVS. Прошивка публичная, без приватных данных.
firmware v1.0.1 — #FW-23 n42 StartDateTime 1970 fix
#FW-23 fix — n42-экспорт водопада больше не застревает на 1970 году.
Проблема (репорт Andrey)
При boot-автозапуске водопада usb_host_cdc_init() стартует раньше init_sntp(),
поэтому spectrogram_start() фиксировал started_at = time(NULL) пока RTC ещё
near-epoch. Результат: <StartDateTime>1970-01-01T…Z</StartDateTime> в каждой строке
n42-экспорта сегмента.
Фикс
SNTP time-sync callback (esp_sntp_set_time_sync_notification_cb) →
spectrogram_time_synced(): если запись активна и started_at < WF_SANE_EPOCH
(1700000000), пересчитывает started_at от монотонного аптайм-якоря
(esp_timer, #FW-21) и персистит через write_state(true) — переживает ребут.
Идемпотентно; когда часы уже валидны, коррекция не нужна.
Commit: 79eff24.
Flash (ESP32-S3, per flash_args)
- 0x0 bootloader.bin
- 0x8000 partition-table.bin
- 0x10000 atomspectra_gw.bin
Целостность (flasher verify)
SHA256: firmware.factory.bin 14cf6bb4d1569c530677be0e19dfef14cd4b6d6ef6498de4ee4ef075f8e81df5
firmware v1.0.0 — #WF-2 fix: httpd max_uri_handlers 45→60
First firmware release for flasher pull-from-release architecture.
#WF-2 fix
Root: httpd max_uri_handlers=45 overflowed (30 base + 21 waterfall handlers registered, 5 dropped incl. /ws/waterfall). Symptom: browser WS закрыт, переподключение… every 2-3s.
UART: 5× httpd_uri: httpd_register_uri_handler: no slots left. Fix: 45→60 in main/web_server.c.
Commit: 6c81c37. Details: INC-16 in references/incidents.md.
Flash (ESP32-S3, per flash_args)
- 0x0 bootloader.bin
- 0x8000 partition-table.bin
- 0x10000 atomspectra_gw.bin
wf_recorder v0.1.0 — Windows exe pull-стрим-сборщика (#REC-12 / #PKG-1)
Что это
Standalone Windows exe десктоп-приложения для непрерывной записи спектрограмм (waterfall) с платы AtomSpectra по HTTP (pull-стрим), со швом сегментов на лету в единый .aswf файл. Собран PyInstaller-ом из scripts/wf_recorder_app.py + scripts/wf_pull_client.py.
Быстрый старт
- Скачайте
wf_recorder.exe(ниже, ~12 МБ). - Положите куда угодно (
Downloads, рабочий стол — не важно). - Двойной клик → GUI откроется.
- Задайте адрес платы (по умолчанию
http://atomspectra.local), путь файла (по умолчаниюreceived/spectrogram.aswfрядом с exe), интервал опроса (60 с). - ▶ Старт — приложение начнёт забирать финализированные сегменты с платы и приписывать их строки в единый растущий
.aswf.
Python не нужен. tkinter, requests, wf_pull_client — всё внутри exe.
Как это работает (кратко)
Каждый --interval секунд приложение:
- Читает
/api/status→ температура прибора → в<file>.temps.csv. - Читает
/api/waterfall/segments→ список финализированных сегментов на плате. - Для каждого нового сегмента (по
<file>.state.json):GET /api/waterfall/segment?name=…, приписывает только строки в конец растущего.aswf(заголовок сегмента отбрасывается, первый заголовок остаётся как шапка склеенного файла),fsync. - Только после успешного
fsync—POST /api/waterfall/segment/deleteна плате.
Сеть/файл/плата отвалились посреди — сегмент останется на плате, попадёт в следующий проход. Дубликаты режутся state.json по паре (name, size).
Прогон 11 ч (соак-тест 2026-07-04)
- 11.00 ч непрерывной записи, 60 сегментов склеены на лету в единый 10.32 МБ
.aswf. - 0 потерь, 0 швов, 0 ребутов, склеенный файл байт-в-байт совпадает с ожидаемым размером (
60 × 184350 − 59 × 4104 = 10 818 864). - Пик Cs-137 662 кэВ стабилен по всей высоте 3D-водопада и 2D-карты.
- Полный отчёт:
docs/rec12_report.md· HTML-версия
Что нужно на стороне платы
Прошивка main (после WF-1 фикса) или новее, с pull-эндпоинтами водопада:
GET /api/waterfall/segmentsGET /api/waterfall/segment?name=…POST /api/waterfall/segment/delete?name=…GET /api/status
Все прошивки в этом репо, начиная с main post-WF-1, эти эндпоинты имеют.
Известные ограничения
- Только Windows x64. Для Linux/macOS собирайте сами из исходников (
python -m PyInstaller --onefile --windowed --name wf_recorder --hidden-import wf_pull_client --paths . wf_recorder_app.py). - Pull-путь не пинит сегмент от keep-last кольца (см.
KNOWN_ISSUES.md). При интервале опроса 60 с и типовой скорости записи запас многократный — на 11-часовом соак-тесте кольцо ни разу не приблизилось к границе (seg_dropped=0). Обходной путь: держать--intervalзаметно короче времени съедания кольцом непрочитанного сегмента при текущей скорости записи.
Пересборка из исходников
cd scripts
python -m PyInstaller --onefile --windowed --name wf_recorder --hidden-import wf_pull_client --paths . wf_recorder_app.py
Требует PyInstaller и Python 3.10+. Выход: scripts/dist/wf_recorder.exe.