Загрузка данных


# Промышленный ЧПУ-Контроллер на ESP32 для 4-метрового Фрезера

Технический паспорт архитектуры, алгоритмов компенсации, карты периферии, сетевого протокола и логических режимов кастомной системы ЧПУ. Проект разработан в среде **VS Code + PlatformIO** под микроконтроллер **ESP32 (38-pin, CH9102)** на базе стабильного ядра Arduino Core v2.x.x (частота процессора зафиксирована на 240 МГц).

---

## 1. Архитектура и Распределение Задач (FreeRTOS)
Вычислительные ресурсы двухъядерного процессора ESP32 жестко распределены для изоляции критически важных по времени процессов генерации импульсов:

* **Ядро 0 (Core 0) — Фоновое / Диспетчеризация (Низкий приоритет):**
  * Управление Wi-Fi точкой доступа `CNC_4METERS_ROUTER` и TCP-сервером (порт 8888).
  * Прием, строковая распаковка и динамическое наполнение буфера G-кода в RAM.
  * Инкапсулированная обработка смещений рабочих систем координат (WCS $G54$), геометрического выравнивания заготовки и пошагового выполнения ($Single\ Block$).
  * Проверка команд настройки конфигурации (`GET_CONFIG` / `SET_CONFIG`).
  * Фоновый низкочастотный опрос периферийных модулей (ESP32-CAM и цифрового индикатора часового типа).
* **Ядро 1 (Core 1) — Real-Time Интерполятор (Высший приоритет):**
  * Обработчик прерывания аппаратного таймера (Timer 0), работающий на жесткой частоте **100 кГц** (интервал вызова — 10 мкс, делитель 80).
  * Синхронная генерация импульсов `STEP/DIR` для 3 осей методом DDA (Digital Differential Analyzer) на числах с плавающей точкой.
  * Мгновенный аппаратный мониторинг физических контуров безопасности (E-Stop, Alarm сервошагов, Концевики).

---

## 2. Геометрия, Кинематика и Особенности Механики
Конструкция станка адаптирована под жесткую обработку протяженных деталей (до 4 метров) и спроектирована на базе пространственной сварной фермы. Кинематика осей имеет смешанный тип:

### Особенности осей и принятые решения:
* **Ось X (Длина 4000 мм — Ведущая ось):**
  * **Механика:** Перемещение осуществляется посредством привода **зубчатая рейка — шестерня**. Это обеспечивает высокую скорость холостого хода ($G0$) на большой длине и исключает провис, свойственный длинным винтам ШВП. Шагов на мм: `100.0`.
  * **Нагрузка:** По оси X перемещается тяжелая чугунная каретка, несущая на себе всю электронику, шкаф автоматики и механизмы осей Y и Z. Для компенсации инерции этой массы заложены плавные линейные векторные ускорения (`cfg.maxAcceleration = 150.0 мм/сек²`).
* **Оси Y (500 мм) и Z (200 мм):**
  * **Механика:** Направляющие выполнены по типу **«ласточкин хвост»**, а в качестве приводных элементов используются **трапецеидальные винты**. Шагов на мм: `400.0`.
  * **Выборка люфта (Anti-Backlash):** Для минимизации осевого люфта винтов применяется механический поджим пружинами. При этом ласточкин хвост обладает большой площадью контакта и высоким трением покоя. Чтобы моторы не срывались в защиту (Alarm) при старте, в конфигурации задана повышенная стартовая скорость вектора (`cfg.minVectorSpeed = 2.0 мм/сек`), что позволяет приводам мгновенно развивать необходимый крутящий момент.
* **Топология подвижного шкафа (Кареточное размещение):**
  * Вся управляющая электроника (драйверы сервошагов, контроллер ESP32, индуктивные датчики и блоки питания) смонтирована в едином экранированном шкафу автоматики, жестко закрепленном на подвижной чугунной каретке.
  * **Преимущество:** Сигнальные провода `STEP/DIR`, линии связи с ESP32-CAM (UART2) и кабели датчиков имеют минимальную длину (<1 метра) и неподвижны относительно шкафа, что сводит к нулю наведение электромагнитных помех (ЭМП) от шпинделя на логические цепи. Единственный подвижный элемент в 4-метровом кабель-треке — сетевой кабель питания шкафа класса *High-Flex*.

---

## 3. Спецификация Конечного Автомата (Machine States)
Глобальное состояние станка контролируется модулем `state_manager`. Переключение в режимы движения, калибровки и автоматического выполнения жестко заблокировано до прохождения процедуры хоуминга, если в конфигурации не активирован сервисный флаг принудительной наладки.

* `STATE_INIT` — Начальная инициализация портов ввода-вывода при подаче питания. Моторы принудительно обесточены.
* `STATE_ALARM` — Аварийное состояние. Включается аппаратно из прерывания при размыкании любой NC-петли защиты. Мгновенно выставляет `MOTORS_ENABLE = HIGH` (снятие удержания), отключает реле шпинделя и СОЖ, очищает текущий вектор планировщика. Выход возможен только по команде `RESET_ALARM`.
* `STATE_IDLE` — Режим ожидания. Моторы находятся в режиме удержания (`MOTORS_ENABLE = LOW`). 
  * *Нюанс:* Если флаг `isHomed == false`, станок переходит в статус `IDLE (LOCKED)`. Блокируются любые перемещения. Разрешены только команды загрузки программ, карт и хоуминг.
* `STATE_HOMING` — Режим автоматического поиска механических баз. Выполняется строго последовательно по общей NC-цепи: Z (вверх) -> Y (в ноль) -> X (в ноль). Алгоритм для каждой оси: быстрое касание -> отскок (Pull-off) на 1200 шагов -> медленный точный доезд. По окончании выставляется флаг `isHomed = true`, снимая блокировку станка.
* `STATE_JOGGING` — Режим ручного позиционирования каретки кнопками из Python-приложения. Разрешен до хоуминга, если `cfg.allowJogBeforeHoming == true` (Soft-лимиты при этом временно отключаются для возможности съезда с физических концевиков).
* `STATE_CALIBRATION` — Автоматический прогон по X со скоростью 400 мм/мин для формирования карты лазерных отклонений или комплексного сканирования геометрии.
* `STATE_MAP_TRANSFER` — Изолированный режим импорта/экспорта CSV-таблиц компенсации между ОЗУ контроллера и ПК.
* `STATE_RUNNING` — Автоматическое векторное выполнение бинарной программы ЧПУ из RAM станка.
* `STATE_HOLD` — Пауза выполнения программы. Запускает контролируемое плавное торможение вектора до нуля по рампе ускорения, сохраняя текущие координаты в памяти.

---

## 4. Алгоритмы Управления и Компенсации

### 4.1 Умное торможение и Soft Limits
На этапе подготовки кадра координаты проверяются по зонам Soft Limits (`cfg.minX / cfg.maxX` и т.д.). При превышении цель принудительно обрезается до границы зоны, планировщик автоматически рассчитывает декремент скорости `vSeg.decelTicks`, и тяжелая каретка плавно останавливается на границе лимита на базе ускорения `cfg.maxAcceleration` без удара.

### 4.2 Энергонезависимый буфер бинарных команд
Для исключения задержек сетевой передачи управляющая программа целиком загружается в ОЗУ станка (динамическая куча, буфер на **10 000 команд**). Каждая команда сжата до **15 байт**:
```cpp
struct __attribute__((packed)) BinaryCommand {
    uint8_t  cmdType;  // 0=G0, 1=G1, 3=M3, 5=M5, 8=M8, 9=M9
    uint16_t lineNum;  // Физический номер строки исходного .nc файла на ПК
    float    x; float y; float z; float f;
};
```
Диспетчер `gcode_program.cpp` непрерывно пишет номер текущей выполняемой строки в ячейку EEPROM (`cfg.lastExecutedLine`). При аварийном отключении электричества индекс последней строки сохраняется, а при перезапуске и хоуминге станок готов продолжить фрезеровку точно с прерванного кадра.

### 4.3 Программный разворот заготовки (Наклон оси X)
Компенсирует непараллельность укладки 4-метровой детали. Оператор фиксирует координаты краев заготовки (Точки А и В). Модуль вычисляет приращение координат на 1 мм хода:
$$\text{slopeY} = \frac{B_y - A_y}{B_x - A_x}, \quad \text{slopeZ} = \frac{B_z - A_z}{B_x - A_x}$$
При выполнении G-кода к координатам автоматически подмешивается смещение: $\Delta Y = \Delta X \cdot \text{slopeY}$. Флаг активности `isAlignmentActive`, значения `slopeY/Z` и координаты точек намертво сохраняются в энергонезависимую память Preferences чипа ESP32.

### 4.4 Оптическая лазерная компенсация фермы
Смещение лазерного пятна на матрице ESP32-CAM преобразуется в массив поправок `curvatureMap` (шаг сетки 20 мм, 201 точка на 4 метрах). Поправка рассчитывается методом линейной интерполяции между узлами сетки и накладывается планировщиком *строго на основе абсолютной машинной координаты X*, независимо от текущего рабочего нуля детали.

---

## 5. Сетевой Протокол Обмена по TCP (Синтаксис Команд)

Все текстовые команды, передаваемые через Wi-Fi сокет (порт 8888), должны завершаться символом перевода строки `\n`. Контроллер отвечает символом `ok\n` в момент успешного парсинга/буферизации команды.

### 5.1 Исходящая телеметрия от станка в ПК (Каждую секунду):
* `<Status:ИМЯ_СТАТУСА|Pos:X=0.00,Y=0.00,Z=0.00|Line=0>` — текущий режим, рабочие координаты детали (WCS мм) и номер обрабатываемой строки.
* `SINGLE_BLOCK_WAIT` — оповещение ПК о том, что станок выполнил один кадр и замер в ожидании подтверждения.

### 5.2 Входящие сервисные и аварийные команды от ПК:
* `ESTOP` — мгновенный переход в `STATE_ALARM`, аппаратное отключение силовой периферии.
* `RESET_ALARM` — сброс режима аварии, перевод станка в `IDLE (LOCKED)`, принудительный сброс флага хоуминга `isHomed = false`.
* `HOME` или `$H` — запуск полного цикла хоуминга.
* `SET_ZERO:ALL` (или `SET_ZERO:X`, `SET_ZERO:Y`, `SET_ZERO:Z`) — обнуление рабочей системы координат (WCS G54). Смещения автоматически пишутся в EEPROM.
* `GET_LAST_ABORTED_LINE` — запрос к станку выдать номер строки, на которой произошло аварийное отключение питания в прошлую сессию (Ответ станка: `LAST_LINE:Номер`).

### 5.3 Команды настройки конфигурации (Инкапсулировано в config.cpp):
* `GET_CONFIG` — запрос текущих параметров. Станок возвращает строку:
  `CONFIG_DATA:stepsX=100.0;stepsY=400.0;stepsZ=400.0;accel=150.0;rapFeed=2000.0;maxX=4000.0;maxY=500.0;maxZ=0.0`
* `SET_CONFIG:КЛЮЧ=ЗНАЧЕНИЕ` — изменение параметра в ОЗУ и автозапись в флэш-память. Примеры: `SET_CONFIG:accel=180.0`, `SET_CONFIG:stepsX=100.5`.

### 5.4 Команды управления геометрией и покадровым режимом:
* `SET_ALIGN_A` / `SET_ALIGN_B` — фиксация текущих координат как опорных точек А и В заготовки.
* `ACTIVATE_ALIGN` — расчет коэффициентов наклона, запись матрицы в EEPROM и активация разворота СК.
* `DEACTIVATE_ALIGN` — отключение разворота СК, запись флага false в EEPROM.
* `SINGLE_BLOCK_ON / SINGLE_BLOCK_OFF` — переключение режима выполнения программы по одному кадру.NEXT_BLOCK — команда (пинок) на выполнение следующего кадра в режиме Single Block.

### 5.5 Команды измерительных сканеров
* `START_CALIBRATION` — запуск автоматического прогона по оси X для формирования лазерной карты провиса `curvatureMap`.
* `EXPORT_MAP` — выгрузка текущей лазерной карты из ОЗУ станка в ПК в формате CSV-строк.
* `MAP_LOAD_START` -> серия строк `MAP_LOAD:IDX=номер;Y=знач;Z=знач` -> `MAP_LOAD_END` — быстрая пакетная заливка ранее сохраненной лазерной карты с ПК в RAM контроллера.
* `SCAN_GEOMETRY:START;END;STEP;SPEED` — запуск комплексного сканирования фермы часовым индикатором и лазером одновременно. Пример: `SCAN_GEOMETRY:100;3900;50;500`. Станок выдает в сокет поток CSV-данных: `X_POS;DIAL_INDICATOR;LASER_Y;LASER_Z`.

### 5.6 Предзагрузка и выполнение управляющей программы G-кода
* `GCODE_UPLOAD_START` — очистка бинарного буфера в ОЗУ станка, подготовка к приему стрима.
* `B:TYPE;LINE_NUM;X;Y;Z;F` — пакет упаковки одного кадра. Пример: `B:1;452;150.00;25.30;-5.00;800.0`. Поступает напрямую в функцию `handleBinaryCommandPacket`, минуя проверки текущих режимов станка.
* `GCODE_UPLOAD_END` — закрытие сессии загрузки. Станок сообщает количество успешно принятых кадров.
* `START_PROGRAM` — запуск автоматического выполнения всей загруженной программы с кадра №0.
* `START_FROM_LINE:НОМЕР` — перемотка бинарной программы в ОЗУ до указанного номера строки и старт выполнения (используется для восстановления работы после сбоя питания).
* `JOG:КОМАНДА` — мгновенное ручное перемещение каретки стрелками. Пример: `JOG:G0 X-10 F1200`.

---

## 6. Карта Подключения Периферии (Pinout) и Защита от Помех

Для обеспечения надежности 4-метровых линий в условиях работы мощного инвертора шпинделя реализована полная гальваническая изоляция. Силовая/датчиковая земля `GND_24V` и логическая земля `GND_3.3V` полностью изолированы друг от друга. Связь идет исключительно внутри оптронов.

| Назначение узла | Пин ESP32 | Направление | Электрические требования и Защита от помех |
| :--- | :---: | :---: | :--- |
| **Ось X: Сигнал STEP** | **GPIO 25** | Выход | К драйверу (Рейка X). Логика 5В через буфер 74HCT245 |
| **Ось X: Сигнал DIR** | **GPIO 26** | Выход | К драйверу X. Логика 5В через буфер 74HCT245 |
| **Ось Y: Сигнал STEP** | **GPIO 27** | Выход | К драйверу Y (Винт). Провод <1м внутри кареточного шкафа |
| **Ось Y: Сигнал DIR** | **GPIO 14** | Выход | К драйверу Y. Провод <1м внутри кареточного шкафа |
| **Ось Z: Сигнал STEP** | **GPIO 32** | Выход | К драйверу Z (Винт). Провод <1м внутри кареточного шкафа |
| **Ось Z: Сигнал DIR** | **GPIO 33** | Выход | К драйверу Z. Провод <1м внутри кареточного шкафа |
| **Общий MOTORS_ENABLE** | **GPIO 13** | Выход | HIGH = Обесточить моторы (Авария) / LOW = Удержание |
| **Единый контур E-STOP** | **GPIO 34** | **Вход (Only)** | Цепь NC кнопок-грибков. Оптрон PC817 (24В) + RC-фильтр 0.1мкФ |
| **Контур ALARM драйверов**| **GPIO 35** | **Вход (Only)** | Последовательное ИЛИ ошибок сервошагов. Оптрон PC817 (24В) |
| **Петля КОНЦЕВИКОВ (X,Y,Z)**| **GPIO 39** | **Вход (Only)** | Последовательная цепь всех NC датчиков осей. Оптрон PC817 + RC |
| **Модуль Лазера RX2** | **GPIO 16** | Вход | К TX платы ESP32-CAM. Защищен резистором 330 Ом и TVS 3.3В |
| **Модуль Лазера TX2** | **GPIO 17** | Выход | К RX платы ESP32-CAM. Защищен резистором 330 Ом и TVS 3.3В |
| **Цифровой индикатор CLK**| **GPIO 18** | Вход | Съемный модуль. Защищен TVS-супрессором 3.3В и резистором 330 Ом |
| **Цифровой индикатор DATA**| **GPIO 19** | Вход | Съемный модуль. Защищен TVS-супрессором 3.3В и резистором 330 Ом |
| **Обороты шпинделя (ШИМ)** | **GPIO 23** | Выход | На RC-фильтр ШИМ -> 0-10В для инвертора VFD |
| **Реле 1: Шпиндель** | **GPIO 21** | Выход | Включение силового пускателя питания шпинделя |
| **Реле 2: Охлаждение (СОЖ)**| **GPIO 22** | Выход | Включение реле помпы охлаждения фрезы |
| **Резерв связи с ПК (USB)** | **GPIO 3** | Вход | Аппаратный порт RX0 через чип CH9102 |
| **Резерв связи с ПК (USB)** | **GPIO 1** | Выход | Аппаратный порт TX0 через чип CH9102 |

*Примечание:* Пины универсального ввода-вывода `GPIO 4, 2, 5, 15` свободны и зарезервированы для будущей модернизации (датчик высоты заготовки Z-Probe, клапан обдува зоны резания воздухом или сигнальный трехцветный светофор состояния станка). Все экраны кабелей заземляются на шину PE строго с одной стороны — внутри шкафа автоматики.