Помогите пожалуйста с логикой сверлильного станка для печатных плат на STM32f103c8t6

Здравствуйте уважаемые.
Я новичок и уже запутался в логике которую сам и задумал.
Цель сделать для себя инструмент для сверления печатных плат.
Понимаю что ЧПУ станок будет лучшим выбором. Но в ближайшем времени нет возможности. Инструмент нужен в следствии необходимости (после аварии правая рабочая рука плохо работает)
Аналогичные проекты меня не устроили по разным причинам.
А на выходе может и другим пригодится.
Пока нужно ваше мнение и советы по логике.

Логика ниже:

На данный момент я реализовал почти все.

  1. Работу с шаговым двигателем
  2. PWM яркостью подсветки
  3. PWM DC (скорость)
    Кроме меню. И пока не смог проверить проверку записи во внешнюю EEPROM (пока ее нет)
    Может кто подскажет более простую и главное правильную логику. Подскажет как реализовать логику правильно.

Логика проекта — пошагово:

Ниже — Описано поведение при старте, калибровках, всех режимах (ручном и Peck/PCB), меню, управлении вводом и безопасностью.

  1. Обозначения
    • Координатная система: Z = 0 — нижний концевик (Z-min).
    • posLimitTop — максимально допустимое Z (верхняя граница хода), вычисляется как posMax - 12.0 мм (после калибровки концевиков).
    • surface_mm — позиция поверхности материала (мм) в той же системе координат (то есть положение поверхности относительно Z=0).
    • posDrillPCBStart = surface_mm + 2.0 мм (всегда 2 мм выше поверхности). Это обязательное правило.
    • Все концевики NC → GND (в коде читаем LOW как «сработал»). Touch Plate тоже активный LOW.
    • Шаги/мм: stepsPerMM = MOTOR_STEPS * microsteps / SCREW_LEAD. Примеры: MOTOR_STEPS=200, SCREW_LEAD=4 мм/об, microsteps=16 → stepsPerMM = 200*16/4 = 800 шага/мм.
    • Скорости: пользователь вводит в мм/мин → переводим в шаги/сек для stepper: stepsPerSec = (mmPerMin / 60) * stepsPerMM.
  2. Поведение при старте (power-on / reset)
  3. Инициализация:
    • инициализировать I²C (Wire), дисплей (PCF8574), энкодер (прерывания A и кнопка), все входы/выходы (концевики, кнопки), PWM-таймеры (PA8, PA9).
    • конфигурировать STEP/DIR/EN/MS1/MS2 как выходы.
  4. Попытка загрузить конфиг из EEPROM (24LC256) и проверить CRC:
    • если конфиг валиден → применить: microsteps (установить MS1/MS2), вычислить stepsPerMM, настроить PWM и LED;
    • если нет → загрузить значения по умолчанию и записать в EEPROM.
  5. Немедленно выполнить калибровку концевиков (обязательная):
    • опускание вниз до Z-min → установить позицию 0;
    • подъём до Z-max → записать posMax;
    • posLimitTop = max(0, posMax - 12.0);
    • установить calibratedZ = true и сохранить.
    (Если по какой-то причине концевики не срабатывают — уйти в STATE_EMERGENCY и вывести ошибку.)
  6. Если calibratedPlate == false, на главный экран выводится приглашение выполнить калибровку Touch Plate (предложение, не обязательное — но без обеих калибровок работа сверления блокируется по безопасности).5. Показать главный экран — режим Idle.
  7. Главные состояния
    • STATE_IDLE — ожидание ввода; отображение статуса.
    • STATE_IN_MENU — пользователь изменяет параметры; движение заблокировано.
    • STATE_CALIBRATING_Z — автоматическая калибровка по концевикам.
    • STATE_PROBING_PLATE — калибровка по Touch Plate.
    • STATE_MANUAL_DRILL — ручное сверление (Drill button удерживается).
    • STATE_PECK_DRILL — автоматический Peck Drill (Drill PCB).
    • STATE_EMERGENCY — аварийный стоп (концевик/ошибка/прерывание).
    Переключение между состояниями только по командам/условиям, при входе/выходе — всегда сохранять/восстанавливать PWM и стоп шаговика.
  8. Калибровка по концевикам (Z)
  9. Переход в STATE_CALIBRATING_Z.
  10. Медленно опуститься вниз (small feed) до срабатывания Z-min (LOW).
  11. Установить текущую позицию шагов в 0 (stepper.setCurrentPosition(0)).
  12. Подняться вверх до срабатывания Z-max. Записать posMax = stepsToMM(currentSteps).
  13. posLimitTop = max(0, posMax - 12.0).
  14. Пометить calibratedZ = true, записать в EEPROM.
  15. Выход в STATE_IDLE.
    Защита: при любом движении проверять концевики; при неожиданном срабатывании — emergencyStop.
  16. Калибровка Touch Plate (высота инструмента)
    (Пункт меню / процедура)
  17. Требование: calibratedZ == true. Если нет — предложить сначала калибровать Z.
  18. Пользователь кладёт Touch Plate на заготовку и подтверждает (кнопка энкодера).
  19. Подъехать в безопасную позицию сверху
  20. Медленное опускание (низкая скорость) до срабатывания TOUCH (LOW).
  21. Когда Touch Plate сработал — фиксируем measured_mm = stepsToMM(currentSteps).
  22. surface_mm = measured_mm - plateThickness (plateThickness задаётся в меню).
    • Ограничить: surface_mm = clamp(surface_mm, 0, posLimitTop).7. Автоматически: posDrillPCBStart = surface_mm + 2.0 (2 мм выше поверхности). Обязательно сохранить в EEPROM.
  23. calibratedPlate = true. Вывести результат на LCD. Выход в STATE_IDLE. Примечание: Touch Plate должен быть изолирован и иметь контакт с инструментом
    (инструмент → GND).
  24. Пункт 3.3 «Проверка поверхности»
    • Опция в меню. Поведение:
  25. Проверка флагов calibratedZ и calibratedPlate. Если нет — ошибка.
  26. По подтверждению: подъехать к surface_mm (медленно).
  27. Остановиться и показать Z = surface_mm на LCD.
  28. При нажатии — подъехать к posDrillPCBStart (surface + 2 mm) и показать позицию.
  29. Возврат к posDrillStart после проверки.
    • Это функциональное тестирование, чтобы визуально убедиться в корректности калибровки.
  30. Ручное сверление (Drill)
    • Кнопка Drill — активна при удержании (нормально HIGH, замкнута на GND при нажатии).
    • Алгоритм:
  31. Проверить флаги калибровок; если отсутствуют — предупредить и не начинать.
  32. Включить шпиндель PWM на speedPWMDrill %.
  33. Пока кнопка удерживается:
    • двигать вниз с шагом/итерацией (например, по 0.1–0.2 мм) со скоростью speedDrillDrill (мм/мин), каждая итерация — проверка границ:
    • не опускаться ниже (surface_mm - maxManualDepth) (защита по глубине);
    • не заходить ниже 0 (Z >= 0);
    • контролировать Z-min (если сработал — emergencyStop).
  34. По отпусканию кнопки: выключить шпиндель и возврат в posDrillStart по speedMoveDrill.
    • Дополнительно: при удержании кнопки оператор вручную ограничивает глубину → system respects maxManualDepth.
  35. Peck Drill — Drill PCB (автомат)
    • Цель: сверлить до drill_PCBDepth в ступенях peckDepth, возвращаясь после каждого захода в posDrillPCBStart.• Алгоритм:
  36. Проверить калибровки.
  37. Перейти в posDrillPCBStart (движение с speedMovePeck).
  38. currentDepth = 0
  39. Пока currentDepth < drill_PCBDepth:
    • dive = min(peckDepth, drill_PCBDepth - currentDepth).
    • target_mm = surface_mm - (currentDepth + dive) — пояснение: уменьшаем Z (вниз) на глубину.
    • target_mm = clamp(target_mm, 0.0, posLimitTop) — защита.
    • Включить шпиндель на speedPWMDrillPCB.
    • Перемещение вниз к target_mm со скоростью speedDrillPeck.
    • Остановить шпиндель.
    • Подняться обратно в posDrillPCBStart со скоростью speedMovePeck.
    • currentDepth += dive.
  40. По завершении отключить шпиндель, вернуться в posDrillPCBStart и STATE_IDLE.
    • Защиты во время каждого движения:
  41. Контроль Z-min/Z-max.
  42. Контроль posLimitTop и нижней границы (0).
  43. Смена инструмента (Tool Change)
    • Кнопка ToolChange:
  44. При нажатии → подняться вверх до Z-max (верхний концевик), установить позицию posLimitTop (или просто убедиться в нахождении у верхнего лимита).
  45. Остановиться; затем опуститься на 3 оборота ШВП (3 * SCREW_LEAD = 12 мм) вниз и стоп.
  46. Это позиция для смены инструмента; шпиндель выключён.
  47. Возврат operator-initiated (по кнопке или автоматически в posDrillStart).
    • Защита: мониторить концевики; если Z-min сработал во время подъёма — emergencyStop.
  48. Меню и параметры (структура + поведение)
    • Структура меню (главная ветка):1. Режимы сверления:
    • Pos Drill Start (редактируемый)
    • Pos Drill PCB (авто; показывается)
    • Peck Depth
    • PCB Total Depth
    • Speed Move Drill
    • Speed Drill Drill
    • Speed Move Peck
    • Speed Drill Peck
    • PWM Spindle Drill (%)
    • PWM Spindle PCB (%)
  49. Настройки оборудования:
    • Microsteps (1 / 2 / 4 / 8 / 16) — изменение устанавливает MS1/MS2 и пересчитывает stepsPerMM
    • Plate thickness
    • LED Brightness
  50. Калибровка:
    • Calibrate Z
    • Calibrate Touch Plate
    • Check Surface (пункт 3.3)
  51. Сохранить конфиг
  52. Exit
    • Поведение редактора:
  53. Энкодер вращает значение (delta → ±N * step).
  54. Кнопка энкодера подтверждает (короткое) или входит/выходит (долгое).
  55. При изменении microsteps — установить пины MS1/MS2 (учесть LL-тоггл поведение), пересчитать stepsPerMM, пересчитать ограничения.
  56. При изменении surface_mm вручную — автоматически скорректировать posDrillPCBStart = surface_mm + 2.0; сохранить по запросу.
  57. EEPROM — хранение конфигурации
    • В EEPROM (24LC256) сохраняем структуру Config, включающую все параметры, флаги калибровок и posLimitTop/posMax.
    • Перед записью вычисляем CRC16-CCITT и записываем в конец блока. При загрузке — проверяем CRC.
    • Формат: бинарный блок sizeof(Config) (фиксированная длина).
    • Запись: блоками по 64 байта (page write) с ожиданием tWR (≈5–10 ms).• При изменении критичных параметров (microsteps, plateThickness, surface_mm, speeds) — сохранять по явному запросу (Save) и/или при выходе из меню, а иногда
    автоматически (encoder short press = quick save).
  58. Управление микрошагами TMC2209 (MS1/MS2)
    • Управление аппаратными пинами MS1/MS2; учесть особенность драйвера:
    • LL → 1/1 ↔ 1/16 (повторный LL переключает между 1/1 и 1/16).
    • HL → 1/2 ↔ 1/32
    • LH → 1/4 ↔ 1/64
    • HH → 1/8 ↔ 1/128
    • При старте прошивки: прочитать cfg.microsteps из EEPROM и установить MS1/MS2 (выполнить нужную последовательность, возможно двойной LL).
    • В меню «Microsteps» — менять значение (1/2/4/8/16) и применять сразу:
    • установить пины MS1/MS2 корректно,
    • вызвать computeStepsPerMM() и пересчитать скорости/параметры зависимости.
    • Защита: запретить редкие значения, обязать значение из списка {1,2,4,8,16}.
  59. Управление PWM (шпиндель и LED)
    • Использовать аппаратный таймер (TIM1 CH1 → PA8 и CH2 → PA9) настроенный на ~60 kHz (или 30kHz для шпинделя по желанию).
    • PWM задаётся в % (0–100). В меню для шпинделя — два параметра: speedPWMDrill и speedPWMDrillPCB.
    • Для LED (DF6113 DIM) соблюдаем ограничение 10–100% (DF6113 не корректно реагирует на очень малые скважности).
    • Изменение значения в меню — немедленное применение (applyImmediately=true при редактировании).
    • При аварии/останове — PWM = 0.
  60. Работа с энкодером и кнопками (ввод)
    • Энкодер A — прерывание CHANGE; в ISR читаем B и корректно
    приращиваем/уменьшаем encoderPos (очень коротко, минимум работы); не вызывать LCD/Stepper из ISR.
    • Энкодер кнопка — прерывание FALLING (установить флаг encoderBtnPressed = true), но реальные действия (дебаунс/определение долгого/короткого нажатия) выполнять в основном цикле.
    • Остальные кнопки (Drill, DrillPCB, UP, DOWN, ToolChange) — использовать Bounce2 или поллинг+дебаунс в loop(); можно использовать fell()/rose() для событий.
    • Правило ISR: никаких длительных операций (delay, I2C, stepper.run) — только атомарные флаги/счётчики.
  61. Проверки безопасности и аварии
    • В любой функции движения (moveToPositionMM / moveRelativeMM / stepper.run loop) — постоянно проверять:
    • if (digitalRead(Z_MIN) == LOW && movingDown) emergencyStop(“Z-min”)
    • if (digitalRead(Z_MAX) == LOW && movingUp) emergencyStop(“Z-max”)
    • Ограниечение по posLimitTop и по нижней границе 0.
    • EmergencyStop:
    • Остановить stepper, установить PWM шпинделя = 0, пометить состояние STATE_EMERGENCY, вывести сообщение на LCD, ждать ручного
    вмешательства (сброс флага/перезапуск).
    • В логе/Serial можно вывести причину для отладки.
    • Защита параметров: при установке глубин/скоростей — clamp значений к разумным пределам.
  62. Преобразования и формулы
    • stepsPerMM = MOTOR_STEPS * microsteps / SCREW_LEAD
    • stepsTarget = round(mm * stepsPerMM)
    • mmCurrent = stepsCurrent / stepsPerMM
    • stepsPerSec = (mmPerMin / 60.0) * stepsPerMM
    • AccelStepper принимает setMaxSpeed() в шагах/сек и setAcceleration() в шагах/сек².
  63. Сохранение макросов / G-code (если потребуется)
    • Текущая логика генерирует G-подобные последовательности динамически (peck routine) на MCU, хранит только параметры (позиции, глубины, скорости).
    • Если нужен функционал «сохранить N макросов с разными параметрами» —
    выделить область EEPROM для массива записей {peckDepth, drillDepth, speedMove, speedDrill, posStart} и индекс/имена; при выборе — загружать и выполнять. (Примечание: это расширение — делается по запросу.)
  64. Протоколы логирования и отладки
    • Серийный порт (Serial 115200) — логирование старт/ошибок/событий (калибровка, emergency, EEPROM load/save).
    • LCD показывает краткую информацию; для подробного лога — использовать Serial.18. Взаимодействие задач
    • ISR: только флаги/счётчики; все тяжёлые действия в loop() или задачах.
    • Движения — последовательны: одна операция движения (moveToPositionMM / performPeckDrillRoutine) блокирует другие пользовательские команды (используем состояние) — кнопки должны задавать запросы, а не выполнять движение прямо.
    • При экстренной ситуации — флаги прерывают цикл движения и вызывают emergencyStop.
  65. Поведение при некорректных параметрах
    • При вводе параметра, который физически выводит инструмент за пределы (например, posDrillStart > posLimitTop), GUI должен не позволить сохранить или автоматически ограничить его.
    • Перед стартом Peck/Drill — вычисляется контрольный маршрут; если любой target выходит за 0..posLimitTop — блокируется с сообщением.
  66. контрольный список логики
  67. Старt: init HW → load EEPROM (CRC) → set microsteps → compute stepsPerMM → mandatory calibrate Z → ask/perform plate probe.
  68. Все движения проверяют Z-min/Z-max и posLimitTop/0.
  69. Touch Plate калибровка автоматически корректирует posDrillPCBStart = surface + 2 mm.
  70. Manual Drill: шпиндель ON при удержании, движение вниз шагами, не глубже maxManualDepth, возврат в posDrillStart.
  71. Peck Drill: автоматический цикл dive/raise до общей глубины, с PWM control и подъемом между заходами.
  72. Menu: редактирование всех параметров, microsteps устанавливаются через MS1/MS2 с учетом особенностей LL комбинации.
  73. EEPROM: хранение конфигурации + CRC16, запись pagewise, чтение при старте.
  74. Энкодер — прерывания; кнопки — debounced polling; ISR максимально «лёгкие».
  75. EmergencyStop — немедленный стоп шаговика и PWM, вывод ошибки, блокировка операций до ручного сброса.

Вы всерьез рассчитываете что этот талмуд кто-то тут будет читать? И анализировать?

Выглядит разумно в общем. Концевики аварийные лучше заводить аппаратно на отключение без процессора.

4 лайка

Неплохо было -бы, если бы вы кратко, в нескольких предложениях, описали задуманый функционал станка.
Т.е. , простыми словами - что должен уметь станок?

1 лайк

Мне интересно было почитать :grinning_cat:. Я станок делал себе такой, интересно было заниматься.

Ps

Вот так бы тз клиенты писали подробно и понятно, а то каждое слово только под страшными пытками:grinning_cat::grinning_cat:

попытка сделать станок с ручным управлением в мире управляющих программ непонятна, вопрос, какова цель, кроме занять себя?

План на 75 пунктов (с 0 по 74) с подпунктами, количество которых может достигать 11 на один пункт, - это круто!
Но мне кажется, двух уровней иерархии (пункты и подпункты) явно недостаточно.
Рекомендуется, чтобы пункт любого уровня содержал от 2 до 7 пунктов следующего уровня.
Могу порекомендовать разбить пункты на 4-5 уровней иерархии и добавить один факультативный уровень иерархии для подпунктов.

Ну и - да, присоединяюсь к пожеланию в сообщении №5.

1 лайк

А если плата будет допустим 200х200 - как её сверлить ? Она же упрётся в вертикальную часть станка и дырки в центре платы будут недосягаемы шпинделем.

Или станок ставится целиком поверх платы ?
(сверление сквозь станину). Тогда как контролировать попадание сверла ?

если сверлить платы, то я бы смотрел в сторону станочка CNC-3018,сверлит он идеально, осталось доделать две оси

1 лайк

Ок. По фото пропорции не угадал.
Вещь, конечно, монументальная. Столько нужно сил и времени.
Может лучше взять 3018 за 10 тыр. на Озоне ? Как бы перспективнее.

сверлит он идеально, точность тоже идеальная

Это они до металлизации не добрались.
Ну Вам виднее, каждый должен сам пройти этот путь.

Уважаемые:
Подскажите как удалить эту тему?
Не хочу форум засорять.

Только админа просить

v258: Спасибо.

в кои-то веки нормально составленное ТЗ появилось и нате

Не вижу причины, которая бы мешала приступить к написанию программы.
Я бы начал с малого - кнопки UP/DOWN и концевики.
Далее добавлять функционал по-блочно. Логика по ходу дела прояснится.
Как по мне - так проще, чем накатать сразу простыню, потом концов не найдёшь при отладке.
Да, бывает, приходится делать откат назад, и чуть не с нуля переписывать. Но всё равно, это легче, т.к. отдельные наработки уже есть ИМХО.

1 лайк

Всё так. Можно писать “сверху-вниз” типа:

ВыходВноль();
ЖдемТоСё();

Для компиляции сразу пишем пустые функции-затычки

void ВыходВноль()
{
};

и потом по одной пишем и отлаживаем.

2 лайка

Что-то очень сложное задумано. Если это не станок с чпу, то проще будет сделать педальку и панель с настройками скорости и глубины опускания. Подвел плату к точке сверления, нажал педальку, станок сделал вжик и можно переходить к следующему отверстию. Скорость вращения шпинделя если надо вынести на ручку регулировки, хотя диаметр отверстий такой что можно сверлить и на 12000 и на 24000 об/мин (стандартные шпиндели с ER8-20).
Да, концевики лишнее - движение вниз по расстоянию, движение вверх до отбойника, ШД просто пропустит шаги когда упрется в него. Отбойник (верхнее состояние) можно сделать подстраиваемым для установки сверл нужной длины.