diff --git a/README.md b/README.md
index 071e1fa..557fd63 100644
--- a/README.md
+++ b/README.md
@@ -2,32 +2,30 @@
Уличный тренажёр с электронным управлением нагрузкой. Мотор-колесо Xiaomi M365 Pro работает как управляемый тормоз/генератор через барабан кабестана. Нагрузка регулируется током VESC-контроллера (FOC).
-## Архитектура
-
-3 узла на CAN Bus (250 Кбит/с):
-
-| Узел | Компонент | Роль |
-|------|-----------|------|
-| ID:20 | Waveshare ESP32-S3 LCD 3.5" | Мастер, UI, управление |
-| ID:10 | Flipsky 75100 Pro V2 | VESC, FOC current control |
-| ID:30 | STM32F103 Blue Pill | Каретка: IMU + тензодатчик |
-
## Структура проекта
```
smart-trainer/
-├── README.md # Этот файл
-├── SPEC.md # Полная инженерная спецификация
-├── CHANGELOG.md # История проектных решений v1→v4
-├── docs/
-│ └── wiring.html # Схема подключения (интерактивная)
-├── firmware/ # (будущее) прошивки ESP32, STM32
-└── cad/ # (будущее) чертежи барабана, каретки, рамы
+├── README.md
+├── docker-compose.yml # Docsify docs server
+├── docs/ # Документация (Docsify)
+│ ├── index.html # Docsify loader
+│ ├── README.md # Главная страница
+│ ├── spec.md # Инженерная спецификация
+│ ├── changelog.md # История решений v1→v4
+│ └── wiring.html # Схема подключения (интерактивная)
+├── firmware/ # (будущее) прошивки ESP32, STM32
+└── cad/ # (будущее) чертежи
```
-## Схема подключения
+## Документация
-Интерактивная схема: [`docs/wiring.html`](docs/wiring.html)
+Docs server (Docsify + nginx):
+
+```bash
+docker compose up -d
+# http://192.168.50.212:8090/
+```
## Как работать со схемой (wiring.html)
@@ -59,8 +57,3 @@ smart-trainer/
- `mod-safety-summary` — сводка безопасности
- `mod-bom-electronics` — BOM электроника
- `mod-bom-power-mech` — BOM силовая + механика
-
-## Документация
-
-- [Спецификация](SPEC.md) — все инженерные решения и расчёты
-- [История изменений](CHANGELOG.md) — эволюция проекта v1→v4
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..b97c84e
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,16 @@
+services:
+ docs:
+ image: nginx:alpine
+ container_name: smart-trainer-docs
+ restart: unless-stopped
+ mem_limit: 64m
+ ports:
+ - "8090:80"
+ volumes:
+ - ./docs:/usr/share/nginx/html:ro
+ - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
+ healthcheck:
+ test: ["CMD", "wget", "-q", "--spider", "http://localhost:80/"]
+ interval: 30s
+ timeout: 5s
+ retries: 3
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..6d66635
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,19 @@
+# Умный тренажёр жима лёжа
+
+Уличный тренажёр с электронным управлением нагрузкой. Мотор-колесо Xiaomi M365 Pro работает как управляемый тормоз/генератор через барабан кабестана.
+
+## Архитектура
+
+3 узла на CAN Bus (250 Кбит/с):
+
+| Узел | Компонент | Роль |
+|------|-----------|------|
+| ID:20 | Waveshare ESP32-S3 LCD 3.5" | Мастер, UI, управление |
+| ID:10 | Flipsky 75100 Pro V2 | VESC, FOC current control |
+| ID:30 | STM32F103 Blue Pill | Каретка: IMU + тензодатчик |
+
+## Навигация
+
+- [Спецификация](spec.md) — полная инженерная спецификация
+- [История изменений](changelog.md) — эволюция проекта v1→v4
+- [Схема подключения](wiring.html ':ignore') — интерактивная схема (HTML)
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
new file mode 100644
index 0000000..1249c34
--- /dev/null
+++ b/docs/_sidebar.md
@@ -0,0 +1,4 @@
+- [Главная](/)
+- [Спецификация](spec.md)
+- [История изменений](changelog.md)
+- [Схема подключения](wiring.html ':ignore')
diff --git a/docs/changelog.md b/docs/changelog.md
new file mode 100644
index 0000000..e750435
--- /dev/null
+++ b/docs/changelog.md
@@ -0,0 +1,55 @@
+# CHANGELOG — История проектных решений
+
+## v1 → v2: Расчёт мотора и барабана
+- Выбран барабан D30мм (оптимум по расчёту: 100кг при 30А рабочих)
+- Рассчитаны константы мотора M365 Pro (Kt, Ke, R, KV)
+- Кабестан 3 витка, μ=0.25 — коэффициент удержания 14.1
+- Контроллер: MKS VESC Mini 6.7 Pro (первоначальный выбор)
+- Батарея 48В 500Вт·ч (автономная работа)
+
+## v2 → v3: Waveshare ESP32-S3 Touch LCD 3.5"
+- **Замена:** ESP32 + OLED + RTC + TF → Waveshare ESP32-S3 Touch LCD 3.5" (~$20)
+- Плата включает: 3.5" IPS тачскрин, QMI8658 IMU, PCF85063 RTC, AXP2101 PMU, TF слот
+- ESP32-S3 имеет TWAI (аппаратный CAN) — нужен только трансивер SN65HVD230
+- Бортовой IMU (QMI8658) для диагностики; внешний MPU6050 на каретке для ускорения штанги
+- BOM электроники снизился с ~$350 до ~$270
+
+## v3 → v4: CAN Bus архитектура
+- **Проблема I2C:** шлейф ~1м к каретке рядом с фазными проводами — ненадёжно для I2C
+- **Решение:** CAN шина, 3 узла, все датчики читаются локально
+- **CAN узел #3 (каретка):** STM32F103C8T6 Blue Pill (~$2)
+ - Выбран вместо ESP32-C3 (overkill) и ATtiny (нет встроенного CAN)
+ - STM32F103 — самый распространённый STM32, CAN 2.0B встроен, $1.5-2, тонна примеров
+ - Читает MPU6050 (I2C) + HX711+тензодатчик (GPIO) локально
+- **Тензодатчик перемещён на каретку** (inline: каретка ↔ трос)
+ - Раньше был внизу у ролика — длинный провод HX711 к ESP32
+ - Теперь рядом с Blue Pill — провод 3 см, никаких проблем
+ - Бонус: мерим силу прямо в точке приложения к штанге
+- **Контроллер:** Flipsky 75100 Pro V2 вместо MKS VESC Mini 6.7
+ - 100А длительно (запас ×2 при пиках 40-50А)
+ - 84В макс (48В батарея — в зоне комфорта)
+ - BT встроен (VESC Tool без провода)
+ - Фазный EMI фильтр на плате
+ - Стоимость: ~$90 (vs ~$35 MKS)
+
+## v4 дополнения: Питание и безопасность
+- **Питание от сети 220В** — вводной щит (автомат + УЗО + БП 48В)
+- **Батарея уменьшена:** 500Вт·ч → 100-250Вт·ч (только буфер рекуперации + UPS)
+ - Заряд до 90% — оставляем буфер для приёма энергии рекуперации
+- **Тормозной резистор:** 100-200Вт, 1-5Ом — сброс излишков при полной батарее
+ - Flipsky 75100 поддерживает brake resistor нативно
+ - Без резистора: батарея 100% → рекуперация → overvoltage → VESC fault → штанга падает
+- **Реле:** 3× НЗ 40А (не 80А — реально через обмотки 20-30А при торможении)
+ - Или трёхфазный контактор НЗ на DIN-рейку в щите
+- **Концевики:** остаются на GPIO ESP32 с RC-фильтром (1К+100нФ)
+ - Бинарный сигнал, помехозащита RC-фильтром достаточна, CAN overkill
+
+## Открытые вопросы / TODO
+- [ ] Софт ESP32: CAN-драйвер, управляющие алгоритмы, UI на тачскрине
+- [ ] Софт STM32: чтение IMU+HX711, упаковка в CAN фрейм
+- [ ] Настройка VESC: FOC, лимиты тока/температуры, brake resistor
+- [ ] Чертежи: барабан, каретка, кронштейны, щит
+- [ ] Приложение смартфон (BLE): профили, статистика
+- [ ] Тестирование безопасности: watchdog, реле, концевики
+- [ ] Выбор конкретного контактора НЗ / реле для щита
+- [ ] Подбор БП 48В от сети (мощность, форм-фактор)
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..ca5d442
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+ Smart Trainer — Docs
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/spec.md b/docs/spec.md
new file mode 100644
index 0000000..690f25b
--- /dev/null
+++ b/docs/spec.md
@@ -0,0 +1,159 @@
+# Умный тренажёр для жима лёжа — Спецификация проекта
+
+## Концепция
+Уличный тренажёр с электронным управлением нагрузкой. Мотор-колесо Xiaomi M365 Pro работает как управляемый тормоз/генератор через барабан кабестана. Нагрузка регулируется током VESC-контроллера (FOC). Питание от сети 220В + батарея-буфер для рекуперации и UPS.
+
+## Мотор M365 Pro — паспортные данные
+- Kt = 0.511 Н·м/А (моментная постоянная)
+- Ke = 0.511 В/(рад/с) (противо-ЭДС)
+- R = 0.392 Ом (сопротивление обмоток)
+- KV = 16.67 об/(мин·В)
+- 15 пар полюсов, Hall-сенсоры встроены (U/V/W + 5V + GND)
+- NTC 10K термистор встроен
+- Outrunner — ротор снаружи
+
+## Барабан кабестана
+- Диаметр: D = 30мм (оптимальный выбор по расчёту)
+- Материал: нержавеющая сталь 12Х18Н10Т
+- 3 канавки под трос D4мм, шаг 6мм, глубина 2мм (полукруглый профиль R2)
+- Крепление: фланец к ободу ротора (outrunner)
+- Кабестан: 3 витка, μ=0.25 (сталь-полимер), коэффициент удержания e^(0.25×6π) = 14.1
+- Свободный конец троса → пружина-натяжитель 1-2 кг
+
+## Нагрузки на барабане D30мм
+| Ток (А) | Сила (кг) | Режим |
+|---------|-----------|-------|
+| 20 | 65 | лёгкий |
+| 30 | 100 | рабочий (подход 30с) |
+| 40 | 135 | пик (3-5с) |
+| 50 | 170 | абсолютный максимум |
+
+## Электроника — CAN Bus архитектура (3 узла)
+
+### CAN узел #1: Flipsky 75100 Pro V2 (ID: 10)
+- VESC 6.0, 100А длительно, 84В макс
+- FOC current control
+- BT встроен (VESC Tool настройка по Bluetooth)
+- Фазный EMI фильтр на плате
+- CAN 2.0B встроен
+- Стоимость: ~$90
+- Расположение: низ рамы, в электрощите
+- Отдаёт: ERPM, I_mot, T_mot, V_bat (100 Гц)
+- Принимает: set_current(I_ref) от ESP32
+
+### CAN узел #2: Waveshare ESP32-S3 Touch LCD 3.5" (ID: 20) — МАСТЕР
+- ESP32-S3R8, двухъядерный LX7 240МГц
+- 3.5" IPS тачскрин 320×480, ёмкостный (ST7796 + FT6336)
+- QMI8658 6-осевой IMU на плате (бортовой, для диагностики вибраций)
+- PCF85063 RTC часы реального времени
+- AXP2101 управление питанием + зарядка Li-ion
+- TF-карта слот (логирование тренировок)
+- WiFi 802.11 b/g/n + BLE 5
+- TWAI (CAN) контроллер встроен в ESP32-S3
+- Стоимость: ~$20
+- Расположение: верхняя перекладина рамы, тачскрин к спортсмену
+- Подключение к CAN через внешний трансивер SN65HVD230 ($1)
+- Дополнительная периферия (локально на ESP32):
+ - Концевики ×2 (GPIO, НЗ, pull-up 10K, RC-фильтр 1К+100нФ)
+ - RC522 NFC (SPI, идентификация пользователей)
+ - BLE → смартфон (настройки, статистика)
+
+### CAN узел #3: STM32F103C8T6 Blue Pill (ID: 30) — КАРЕТКА
+- Cortex-M3, 72МГц, CAN 2.0B встроен
+- Стоимость: ~$2
+- Расположение: на каретке штанги (движется)
+- Подключение к CAN через SN65HVD230 ($1)
+- Локальные датчики:
+ - MPU6050 (I2C): 6-осевой IMU, 200 Гц, ускорение + гироскоп
+ - HX711 + тензодатчик S-тип 200кг (GPIO): реальная сила на тросе, 80 Гц
+- Тензодатчик inline: между кареткой и точкой крепления троса
+- Кабель к основной шине: 4 провода (CAN_H, CAN_L, 5V, GND), гибкий шлейф вдоль направляющей
+- Отдаёт: accel[3], gyro[3], force_N (200 Гц)
+
+### CAN шина
+- Стандарт: CAN 2.0B, 250 Кбит/с
+- Топология: линейная, витая пара
+- Терминаторы: 120Ω на обоих концах (ESP32 сверху, VESC снизу)
+- Blue Pill — отвод к каретке (без терминатора, посередине шины)
+- Загрузка шины: ~30%, запас для расширения
+- Протокол: VESC CAN (стандартные команды set_current, get_values, status msgs)
+
+## Питание
+- Сеть 220В → вводной щит (автомат + УЗО) → БП 48В
+- Батарея 48В 100-250Вт·ч (буфер рекуперации + UPS)
+ - Заряд до 90% (50.4В на 13S), оставляя буфер для рекуперации
+- DC-DC 48В → 5В для логики, LDO 3.3В на каждом узле
+- Тормозной резистор: 100-200Вт, 1-5Ом, через MOSFET
+ - Сброс излишков рекуперации при полной батарее
+ - Flipsky 75100 поддерживает brake resistor нативно (настройка порога в VESC Tool)
+ - Расположение: в щите или на раме (нужна вентиляция)
+
+## Безопасность — аппаратная цепь
+- ESP32 GPIO → Watchdog (555/TPL5010, 50мс) → реле НЗ → замыкание обмоток мотора
+- Реле: 3× автомобильных НЗ 40А, катушки параллельно ИЛИ трёхфазный контактор НЗ на DIN-рейку в щите
+- Логика: ESP32 генерирует импульсы ~100Гц → watchdog сбрасывается. Сбой/зависание → watchdog timeout 50мс → реле отпускает → НЗ контакты замыкают три фазы → электромагнитное торможение
+- Тормозная сила при замкнутых обмотках: F = Kt² × v / (R × r²). При 0.5 м/с → ~150 кг
+- Опционально: резистор 0.1-0.3Ω / 100Вт в цепи замыкания для смягчения торможения
+- Софтовый лимит позиции по ERPM (дополнительно к аппаратному)
+- VESC: max input voltage лимит (ослабление рекуперации при высоком напряжении)
+
+## Концевики
+- Нижний: homing (нулевая точка отсчёта позиции)
+- Верхний: аварийный стоп
+- НЗ контакты, pull-up 10K к 3.3В
+- RC-фильтр: 1К + 100нФ на входе GPIO ESP32 (τ = 0.1мс, подавление наводок)
+- Debounce программный: 10-20мс
+- Подключены напрямую к GPIO ESP32 (бинарный сигнал, помехозащита RC-фильтром достаточна)
+
+## Механика
+- Рама: профиль 80×80×4мм, сталь 09Г2С, сварная
+- Высота стоек ~1200мм, ширина между стойками ~340мм, глубина ~700мм
+- Анкеры 4×M12 в бетон
+- Направляющие: 2 вала D25мм, сталь 40Х хромированная, длина 900мм
+- Линейные подшипники LM25UU ×4 на каретке
+- Ход каретки: 650мм
+- Каретка: масса 8кг (с грифом), крепление троса снизу через тензодатчик
+- Компенсация веса каретки: противовес 8кг на тросе через ролик наверху (груз в стойке: стальной цилиндр D60×300мм)
+- Трос: D4мм, сталь в полимерной оболочке, разрывная нагрузка 8000Н
+- Путь троса: каретка → тензодатчик (inline) → вниз → ролик D60мм (подшипник 6201-2RS, поворот 90°) → горизонтально к барабану мотора → 3 витка → пружина-натяжитель
+- Мотор: закреплён за ось внизу рамы, антивандальный кожух сталь 2мм
+- Вводной щит 220В: на раме или рядом (DIN-рейка: автомат, УЗО, БП 48В, контактор НЗ, тормозной резистор)
+- Электроника: IP54 бокс (VESC, DC-DC, Watchdog) внизу рамы / в щите
+- Батарея: IP67 бокс
+- Габариты: Ш×Г×В ≈ 800×700×1250мм
+
+## Режимы нагрузки
+1. **Постоянная**: фиксированный ток, опц. виртуальная инерция (F = m_virtual × a)
+2. **Эксцентрический**: разная нагрузка вверх/вниз (направление по ERPM)
+3. **Аккомодационное**: F(x) = F_min + (F_max - F_min) × x / L
+4. **Интервальный**: чередование нагрузок по повторениям
+5. **Изокинетический**: постоянная скорость, VESC speed control
+6. **Страховщик**: v_up < 0.05 м/с > 0.5с → снизить 30%; v_down > 0.7 м/с > 0.3с → аварийное торможение
+
+## BOM (оценка)
+| Компонент | Стоимость |
+|-----------|-----------|
+| Waveshare ESP32-S3 LCD 3.5" | ~$20 |
+| Flipsky 75100 Pro V2 | ~$90 |
+| Blue Pill STM32F103 | ~$2 |
+| SN65HVD230 ×2 | ~$2 |
+| MPU6050 + HX711 + тензодатчик S-тип 200кг | ~$10 |
+| 3× реле НЗ 40А / контактор НЗ | ~$15 |
+| Watchdog 555 + обвязка | ~$2 |
+| RC522 NFC | ~$3 |
+| Концевики ×2 | ~$2 |
+| DC-DC 48→5V | ~$5 |
+| Тормозной резистор 100Вт + MOSFET | ~$5 |
+| Батарея 48V 100-250Вт·ч | ~$100-150 |
+| БП 48В от сети | ~$25 |
+| Мотор M365 Pro (б/у) | ~$60 |
+| Рама + направляющие + механика | ~$120 |
+| Щит 220В (автомат + УЗО) | ~$20 |
+| **ИТОГО** | **~$480-530** |
+
+## Файлы проекта
+- `SPEC.md` — этот файл
+- `CHANGELOG.md` — история решений
+- `wiring.html` — схема подключения (модульная, CSS grid)
+- (будущее) `firmware/` — прошивки ESP32, STM32
+- (будущее) `cad/` — чертежи барабана, каретки, рамы
diff --git a/nginx.conf b/nginx.conf
new file mode 100644
index 0000000..d3ce0fa
--- /dev/null
+++ b/nginx.conf
@@ -0,0 +1,20 @@
+server {
+ listen 80;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ types {
+ text/html html;
+ text/markdown md;
+ text/css css;
+ application/javascript js;
+ application/json json;
+ image/png png;
+ image/jpeg jpg jpeg;
+ image/svg+xml svg;
+ }
+
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+}