# Методический стандарт xSTEM: как документировать компонент

Этот файл — эталон для авторов новых датчиков и модулей. Он описывает
структуру документации одного компонента `firmware/<Категория>/<Компонент>/`,
которая затем без переписывания подключается в `content/docs/` шорткодами
`firmware-doc` и `firmware-code`. Источник правды — код и markdown внутри
`firmware/`; сайт документации ничего не копирует, только показывает.

Эталон, на котором стандарт был выведен и проверен: `Sensors/Navigation/MPU6050`.
При разработке нового компонента держите его открытым рядом как образец тона
и глубины.

## 1. Зачем нужен именно такой набор файлов

Курс построен вокруг **живых данных из реального датчика**, а не абстрактных
примеров. Урок работает только если ученик может: (1) собрать схему,
(2) увидеть числа в терминале, (3) связать число с формулой, которую проходят
по программе, (4) увидеть то же самое как график в реальном времени. Отсюда
пять ролей документации — они закрывают эти четыре шага плюс презентационный
слой для защиты проекта/урока перед классом или комиссией:

| Файл | Роль | Отвечает на вопрос |
|---|---|---|
| `README.md` | Инженерный обзор | Что это, из чего состоит код, как прошить и что видно в порту |
| `THEORY.md` | Физико-математическая база | Как из сырых чисел получается измеряемая величина |
| `WIRING.md` | Схема подключения | Как физически собрать стенд |
| `Lesson.md` | Методическое пособие | Как провести урок(и), что за эксперимент, какой разбор |
| `PREZ.md` | Презентация (слайды в markdown) | Как за 5 слайдов защитить проект |
| `tools/*.py` | Живая визуализация | Как показать процесс, а не столбик цифр |

Ни один файл не дублирует другой: README — это "что и как запустить",
THEORY — "почему получаются такие числа", Lesson — "что с этим делать в классе".
Если тянет повторить кусок текста между файлами — значит, он не на своём месте.

## 2. Разбор эталона по разделам

### README.md — инженерный обзор компонента
Обязательные разделы, в этом порядке:
1. **Заголовок + 1 абзац** — что за датчик, какая архитектура прошивки
   (например "FreeRTOS, dual-core, 200 Гц").
2. **Основные возможности** — буллеты с **жирным** ключевым словом в начале
   каждого (сканируется взглядом за 10 секунд).
3. **Содержание** — якорные ссылки внутри README + относительные ссылки на
   WIRING.md/THEORY.md/Lesson.md/PREZ.md (см. §4 про относительные ссылки).
4. **Описание** — физика датчика в 3–5 предложениях, без формул (это в THEORY).
5. **Программная архитектура** — таблица или список "файл → что в нём".
6. **Работа через CLI** — команды PlatformIO, пример строки вывода в Serial.
7. **Визуализация** — таблица `скрипт → что показывает → какой урок иллюстрирует`,
   плюс команда запуска. Это прямой мост README → tools/ → Lesson.md.
8. **Параметры телеметрии** — для каждого поля вывода: тип/диапазон,
   физический смысл, **"где встречается за пределами лаборатории"** — обязательный
   подпункт, который переводит абстрактное число в бытовой/индустриальный контекст
   (фитнес-трекер, автопилот дрона, защита жёсткого диска и т.д.).

### THEORY.md — физика и математика
Стандарт глубины: полный вывод от физического принципа датчика (MEMS,
пьезоэффект, TOF и т.п.) до формулы, которая реально сидит в коде драйвера.
Каждая формула в LaTeX (`$$...$$`), с расшифровкой символов. Обязательно:
- секция про **источник погрешности** конкретно этого класса датчиков
  (дрейф гироскопа, температурный уход, шум АЦП, многолучевость — что уместно);
- секция про **пределы применимости модели** (Gimbal Lock для Эйлеровых
  углов — хороший образец: не только "как работает", но и "где ломается,
  и что делают вместо этого в индустрии");
- последний раздел — **как теория легла в конкретную реализацию** ("Особенности
  реализации в экосистеме Sensor Hub"), чтобы не остаться чистой абстракцией.

### WIRING.md — схема подключения
Три обязательных блока:
1. ASCII-схема (`┌─┐` box-drawing) — работает без картинок, не ломается в git diff.
2. Таблица пин → пин с колонкой "Описание".
3. **Рекомендации** — 2–4 практических пункта про типичные ошибки монтажа
   (подтяжка шины, длина проводов, вибрации, экранирование — что применимо
   к физике конкретного интерфейса).

### Lesson.md — методическое пособие
Это ядро курса и самый труднокопируемый по качеству файл. Структура:
1. **Шапка**: состав стенда, одна фраза про то, что пособие связывает
   показания датчика со школьной программой.
2. **"Кто чем пользуется"** — три роли (инженер / учитель / методист) с
   одной строкой на каждую. Явно разводит "кто откалибровал стенд" и
   "кто ведёт урок".
3. **Модули**, каждый = один раздел школьной программы (например у MPU6050:
   Механика и динамика / Геометрия и тригонометрия / Вычислительная
   математика и статистика). Модуль объединяет 1–3 урока.
4. **Урок** — фиксированный формат, не отступать:
   - `* Тема:` — формулировка из программы.
   - `* Параметры датчика:` — какие поля из README реально смотрим.
   - **Ход работы** — конкретное физическое действие ("роняем с 1.5 м на поролон"),
     не абстракция.
   - **На графике** — ASCII-график ожидаемой кривой (спасает урок, если
     класс собрался без проектора).
   - **Разбор** — от наблюдения к формуле, с явным выводом (не просто "вот формула").
   - **Визуализация** — какой скрипт из `tools/` показывает то же самое живьём,
     команда запуска.
   - Если применимо: **Практическое задание** — самостоятельная работа
     ученика (сбор статистики, построение гистограммы и т.п.).
5. **Приложение** (опционально) — альтернативная прошивка/режим для быстрого
   переключения между уроками без перепрошивки, если у датчика есть смысл
   так делать.
6. **Заключение** — 2–3 предложения про роль ученика как исследователя,
   не пассивного слушателя. Держит рамку "почему это не просто лабораторная".

Урок никогда не должен требовать оборудования за пределами: сам датчик,
ESP32, то, что есть в любом кабинете физики (нитка, линейка, транспортир,
поролон). Если нужен нестандартный реквизит — это красный флаг, что урок
не пройдёт методическую приёмку.

### PREZ.md — презентация
5 слайдов ровно по одному экрану внимания:
1. Что и зачем (платформа, сенсор, цель).
2. Ключевая техническая/физическая проблема и как она решена.
3. Программные "фишки" реализации.
4. Расширенная телеметрия / что именно измеряем.
5. Где это применяется за пределами учебного стенда.
Каждый слайд — заголовок + 3–4 буллета с **жирным** ключевым термином.
Презентация не пересказывает README целиком — это выжимка для защиты.

### tools/*.py — живая визуализация
Один скрипт = один урок или один физический эффект, не универсальный
комбайн. Обязательно: читает тот же текстовый протокол Serial, что печатает
прошивка (никаких отдельных "демо-режимов" прошивки только для Python);
`requirements.txt` рядом; вызов из терминала одной командой с портом
как аргументом. Задача скрипта — заменить "голые числа" Serial Plotter
наглядной картинкой конкретно под то, что разбирается в Lesson.md
(3D-куб для ориентации, лента для ударных нагрузок, график дрейфа для
накопления погрешности — визуализация выбирается под физику явления,
не по умолчанию "просто нарисовать графики всех полей").

## 3. Обязательный / опциональный набор

- **Обязательно для любого нового датчика**: `README.md`, `WIRING.md`, `platformio.ini`.
- **Обязательно, если у датчика есть измеряемая физическая величина** (не просто
  дискретный сигнал вкл/выкл): `THEORY.md`.
- **Обязательно, если компонент используется в уроке**: `Lesson.md`.
- **Опционально**: `PREZ.md` (нужен для публичной защиты/демонстрации),
  `tools/*.py` (нужен, если наглядность через график/3D существенно
  улучшает понимание — не нужен для простых цифровых компонентов вроде
  одиночного светодиода или активного зуммера, где сам физический эффект
  уже нагляден).

Компонент без `THEORY.md`/`Lesson.md`/`PREZ.md`/`tools/` — это не брак,
а более ранняя стадия готовности. В `content/docs/` он подключается с той
вкладкой, которая фактически есть; отсутствующие вкладки не создаются
и не заглушаются "заглушкой в разработке" (см. §5 про интеграцию).

## 4. Технические правила, обязательные для совместимости с шорткодами

- Заголовки в исходном `.md` начинаются с `# Title` (уровень 1). Шорткод
  `firmware-doc` с `offset="1"` сдвигает все заголовки на один уровень вниз,
  чтобы не было двух `<h1>` на странице — офсет ставится всегда при
  подключении на `_index.md` с несколькими вкладками.
- Внутренние ссылки вида `[Теория](THEORY.md)` **не переписываются**
  шорткодом — они резолвятся против URL страницы документации, а не против
  дерева `firmware/`. Такие ссылки допустимы в README как оглавление "для
  чтения прямо в репозитории", но их 404 на сайте — ожидаемое поведение,
  не баг. Не полагайтесь на них как на единственную навигацию — основная
  навигация сайта это вкладки.
- Пути к файлам в шорткодах передаются без ведущего `/` и без `..`
  (проверяется самим шорткодом), относительно `firmware/`, например:
  `Sensors/Navigation/MPU6050/README.md`.
- Блоки кода из `src/*.cpp`/`include/*.h` встраиваются отдельным шорткодом
  `firmware-code` (не `firmware-doc`) — он даёт подсветку синтаксиса, номера
  строк и кнопку копирования. Использовать в README/Lesson, если нужно
  показать один фрагмент кода среди текста. **`firmware-code` не принимает
  `offset`** (у него нет заголовков для сдвига) — параметр молча
  игнорируется, если его всё же указать, поэтому не копируйте его по
  аналогии с `firmware-doc`.
- Если нужно показать **все файлы кода целиком** (например, у компонента ещё
  нет README/THEORY и код — единственная содержательная документация, как у
  NEO-6-8) — заводится одна вкладка `Код` верхнего уровня, а внутри неё —
  вложенный `{{< tabs >}}` с отдельной вкладкой на каждый файл (Hextra
  поддерживает вложенные табы, ID групп не конфликтуют):
  ```markdown
  {{< tab >}}
  {{< tabs items="GpsNeo.h,GpsNeo.cpp,main.cpp" >}}

  {{< tab >}}
  {{< firmware-code file="Sensors/Navigation/NEO-6-8/include/GpsNeo.h" >}}
  {{< /tab >}}

  {{< tab >}}
  {{< firmware-code file="Sensors/Navigation/NEO-6-8/src/GpsNeo.cpp" >}}
  {{< /tab >}}

  {{< tab >}}
  {{< firmware-code file="Sensors/Navigation/NEO-6-8/src/main.cpp" >}}
  {{< /tab >}}

  {{< /tabs >}}
  {{< /tab >}}
  ```
  Не заводите отдельную вкладку верхнего уровня на каждый файл — это не
  масштабируется (компонент может обрасти файлами) и путает вкладку
  README/Теория/Схема/Урок с навигацией по файловому дереву кода; вложенный
  `{{< tabs >}}` держит эту навигацию на своём уровне.
- **`items="…"` в `{{< tabs >}}` и число блоков `{{< tab >}}` должны совпадать
  один в один**, в одном порядке. Это не проверяется сборкой — Hugo не упадёт
  на рассинхроне, вкладка просто отрендерится без имени или не откроется.
  При добавлении вкладки (например, "Код" под `firmware-code`) — не забудьте
  дописать её название в `items` тем же шагом.

## 5. Как подключать в `content/docs/` (шаблон `_index.md`)

```markdown
---
title: "<Полное имя> — <короткая техническая характеристика>"
linkTitle: "<Короткое имя для меню>"
weight: <10, 20, 30… по порядку внутри категории>
---

<1 абзац: тип датчика/модуля, ключевая фишка прошивки (RTOS/фильтр/протокол),
чем визуализация примечательна>. Исходный код и `platformio.ini` — в
[`firmware/<Категория>/<Компонент>`](/src/<Категория>/<Компонент>/).

{{< tabs items="README,Теория,Схема,Урок,Презентация" >}}

{{< tab >}}
{{< firmware-doc file="<Категория>/<Компонент>/README.md" offset="1" >}}
{{< /tab >}}

{{< tab >}}
{{< firmware-doc file="<Категория>/<Компонент>/THEORY.md" offset="1" >}}
{{< /tab >}}

{{< tab >}}
{{< firmware-doc file="<Категория>/<Компонент>/WIRING.md" offset="1" >}}
{{< /tab >}}

{{< tab >}}
{{< firmware-doc file="<Категория>/<Компонент>/Lesson.md" offset="1" >}}
{{< /tab >}}

{{< tab >}}
{{< firmware-doc file="<Категория>/<Компонент>/PREZ.md" offset="1" >}}
{{< /tab >}}

{{< /tabs >}}
```

Правило: `items="…"` в `{{< tabs >}}` и число `{{< tab >}}` блоков должны
включать **только те файлы, что реально существуют** у компонента, в том же
порядке README → Теория → Схема → Урок → Презентация → (опционально) Код.
Не создавайте вкладку под несуществующий файл (шорткод упадёт со сборочной
ошибкой `could not read`, что и является желаемым поведением — сборка обязана
падать на битой ссылке, а не молча показывать пустую вкладку). Добавляя
вкладку с `firmware-code` (листинг конкретного файла кода) поверх основного
набора — не забудьте дописать её имя в `items` (см. §4): это единственная
рассинхронизация, которую сборка не ловит сама.

## 6. Промпты-генераторы

Ниже — рабочие промпты для LLM-ассистента (Claude Code и подобных), которые
пишут новый компонент документации по этому стандарту. Каждый промпт
рассчитан на то, что модель имеет доступ к репозиторию и может прочитать
исходники драйвера/прошивки, а также сам эталон MPU6050 для калибровки тона.

### 6.1 Промпт: новый компонент с нуля (полный комплект)

```
Ты — методист и embedded-инженер, пишешь документацию нового компонента
для курса xSTEM по стандарту firmware/METHODOLOGY.md.

Компонент: <Название>, категория: firmware/<Категория>/<Компонент>/
Датчик/модуль: <краткое тех. описание, интерфейс (I2C/SPI/аналог/UART),
что физически измеряет или делает>.
Прошивка уже существует в src/ — прочитай её перед началом (main.cpp,
драйвер), не выдумывай API и формат телеметрии, которых нет в коде.

Изучи firmware/Sensors/Navigation/MPU6050/{README,THEORY,WIRING,Lesson,PREZ}.md
как эталон глубины и тона. Не копируй формулировки — только структуру
и уровень детализации.

Напиши по стандарту из firmware/METHODOLOGY.md §2:
1. README.md — обзор, возможности, архитектура, CLI, [визуализация — только
   если есть или планируется tools/*.py], таблица параметров телеметрии
   с обязательным подпунктом "где встречается за пределами лаборатории"
   для каждого параметра.
2. THEORY.md — физический принцип датчика, формулы преобразования сырых
   данных, источники погрешности именно этого класса датчика, пределы
   применимости модели, как теория связана с конкретной реализацией в коде.
3. WIRING.md — ASCII-схема, таблица пин→пин, раздел "Рекомендации" под
   конкретный интерфейс (I2C/SPI/аналог — типичные грабли разные).
4. Lesson.md — ТОЛЬКО если компонент используется в уроке (уточни, если
   не уверен, не выдумывай сам факт, что урок нужен). Явная привязка к
   разделам школьной программы, формат "Тема / Параметры датчика / Ход
   работы / На графике (ASCII) / Разбор / Визуализация" на каждый урок.
   Ход работы — конкретное физическое действие, без абстракций.
5. PREZ.md — 5 слайдов, структура "Слайд N: Заголовок" + 3–4 буллета
   с жирным термином.

Не пиши tools/*.py и не предлагай визуализацию, если она не была явно
запрошена — Python-визуализация нужна не каждому компоненту (см. §3).

Ограничения:
- Никаких формул/цифр, которых нет в физике датчика или в его даташите —
  если не уверен в константе (масштаб, диапазон, частота), спроси, а не
  придумывай правдоподобное число.
- Не дублируй один и тот же текст между README и THEORY — они разные роли.
- Заголовок каждого файла начинается с одного `# Title`.
- Пиши на русском, тот же регистр формальности, что в эталоне (профессионально,
  без разговорных сокращений, с эмодзи только в заголовках верхнего уровня —
  как в MPU6050).

В конце сверь свой результат с чек-листом §3 METHODOLOGY.md — какие файлы
обязательны для этого типа компонента — и явно скажи, каких файлов не
хватает и почему (например "PREZ.md не нужен, компонент не участвует в
защите проекта").
```

### 6.2 Промпт: интеграция готового компонента в `content/docs/`

```
Ты интегрируешь уже существующий компонент firmware/<Категория>/<Компонент>/
в content/docs/ по стандарту firmware/METHODOLOGY.md §5.

1. Прочитай firmware/<Категория>/<Компонент>/ и составь список файлов,
   которые там реально есть из набора {README.md, THEORY.md, WIRING.md,
   Lesson.md, PREZ.md}. Не предполагай — проверь через листинг каталога.
2. Создай content/docs/<Раздел>/<Компонент>/_index.md по шаблону из
   METHODOLOGY.md §5: frontmatter (title, linkTitle, weight — следующий
   свободный номер в разделе, шаг 10), 1 абзац описания компонента,
   ссылка на исходники /src/<Категория>/<Компонент>/, блок {{< tabs >}}
   только с вкладками под фактически существующие файлы, в порядке
   README → Теория → Схема → Урок → Презентация.
3. Каждый {{< firmware-doc file="..." offset="1" >}} должен указывать
   на реальный относительный путь от firmware/ — проверь его точным
   совпадением с листингом из шага 1 (регистр символов важен).
4. Не переписывай и не дополняй содержимое файлов в firmware/ — только
   подключаешь их. Если каких-то файлов не хватает для полного стандарта —
   не выдумывай контент, просто не создавай для них вкладку.
5. После создания собери `hugo` (или проверь через шорткод), что путь
   резолвится и страница строится без ошибок try/readFile.
```

### 6.3 Промпт: методическая проверка существующего Lesson.md

```
Ты — профессор педагогических наук, методолог курса xSTEM. Проверь
firmware/<Категория>/<Компонент>/Lesson.md на соответствие стандарту
firmware/METHODOLOGY.md §2 (раздел Lesson.md).

Проверь по каждому уроку внутри файла:
- Есть явная привязка "Тема" к разделу школьной программы (не абстрактная
  формулировка "изучаем датчик", а конкретная тема физики/математики/
  информатики).
- "Ход работы" — это воспроизводимое физическое действие с обычным
  школьным реквизитом (не требует нестандартного оборудования).
- "Разбор" доходит до формулы и объясняет, откуда она берётся, а не
  просто предъявляет результат.
- Есть связь с tools/*.py, если такие скрипты существуют у компонента.
- Прогрессия по модулям логична (от простого наблюдения к более
  абстрактной математике), без учебных дыр.

Не переписывай файл сам — верни список конкретных несоответствий с
указанием урока/раздела и предложение правки в 1-2 строки на каждое
несоответствие. Если всё соответствует стандарту — явно скажи это,
не выдумывай замечания искусственно.
```

## 7. Известные отклонения от стандарта (на 2026-07-13)

Ниже — компоненты, чьи каталоги в `firmware/` уже подключены в
`content/docs/`, но не дотягивают до полного эталона MPU6050. Это не ошибка
интеграции — вкладки на сайте отражают то, что фактически есть в файлах.
Список нужен методисту как план дозаполнения.

| Компонент | Категория | Чего не хватает |
|---|---|---|
| `NEO-6-8` | Sensors/Navigation | Другой формат: `GUIDE.md`/`ROADMAP.md` вместо `THEORY.md`/`Lesson.md`/`PREZ.md`. Оба имени уже поддержаны шорткодом `firmware-tabs`, так что на сайт компонент выводится корректно; открытым остаётся методический вопрос — оставить формат самоучителя или привести к эталону |
| `AHT20_BMP280` | Sensors/Meteo | Нет `Lesson.md`, нет `tools/` |
| `GY-271` | Sensors/Navigation | Нет `PREZ.md` |
| `APDS9960` | Sensors/Optic | Нет `PREZ.md` |
| `nRF24L01` | Sensors/Radio | Нет `PREZ.md` |
| `AS734x` | Sensors/Optic | Нет `PREZ.md`, нет `tools/` (есть отдельный `monitor.py` вне стандарта `tools/`) |

Компоненты `firmware/Components/*` (ActiveBuzzer, LED_adress, LED_middle,
LED_simple, PassiveBuzzer, ST7735) сознательно не приведены к этому
стандарту — это не измерительные датчики, а исполнительные/индикаторные
модули, для них полный набор {THEORY, Lesson, PREZ, tools} не всегда
осмыслен (см. §3, критерий "есть ли измеряемая физическая величина").
Они интегрированы в `content/docs/Components/` с тем набором вкладок,
что у них фактически есть.
