Требуется написать программу на ардуино.Программа должна управлять одновременно четырьмя шаговыми двигателями (NEMA 23) подключенными к ардуино через драйверы DM556P. В программе должна быть возможность установить ускорение (шаги/с/с) и количество шагов на 1 оборот (установленное на драйвере). Программа должна принимать на вход через сериал-порт строку содержащую набор данных для управления двигателями (номер двигателя, количество шагов (угол поворота), направление, скорость вращения (шаг/мин).Программа должна обновлять сериал-порт постоянно и сразу по получении команды начинать ее исполнение.Прикладываю пример написанной мной программы. Пример приведен для минимизации уточняющих вопросов и для лучшего понимания ТЗ а не как руководство.Python (отправляет управляющую строку с определенным интервалом)import serialimport time# Массив углов для поворота и соответствующие направления (0 - CW, 1 - CCW)angles_and_directions = [(360, 0), (90, 1)]ser = serial.Serial('COM3', 9600)step_count = 0frequency = 4000 # Частота в (Гц)micro_step = 800 # Число микрошагов установленное на драйвереdelay_time = 2 # Задержка между циклами# Добавляем задержку перед первой отправкойtime.sleep(1)for angle, direction in angles_and_directions: step_count = int(angle * (micro_step / 360) * 10) #10 передаточное число редуктора cycle_duration = step_count / frequency # Формируем строку для отправки на Arduino params = f"{frequency} {step_count} {direction}" ser.write((params + "\n").encode()) ser.flush() # Убедимся, что данные отправлены # Ждем, пока Arduino завершит выполнение текущего цикла, плюс заданная задержка time.sleep(cycle_duration + delay_time)Код на ардуино.#include
const uint8_t pin_ENA = 5; // Пин включенияconst uint8_t pin_DIR = 6; // Пин направленияconst uint8_t pin_PUL = 7; // Пин импульсовvolatile uint32_t maxFrequency = 4000; // Максимальная частотаvolatile uint32_t stepCount = 8000; // Общее количество шаговvolatile bool shouldRun = false; // Флаг запускаvoid setup() { pinMode(pin_ENA, OUTPUT); pinMode(pin_DIR, OUTPUT); pinMode(pin_PUL, OUTPUT); Serial.begin(9600); while (!Serial);}void loop() { if (Serial.available() >= 3) { maxFrequency = Serial.parseInt(); // Считываем максимальную частоту stepCount = Serial.parseInt(); // Считываем количество шагов int direction = Serial.parseInt(); // Считываем направление shouldRun = true; // Устанавливаем направление в зависимости от значения digitalWrite(pin_DIR, direction == 0 ? LOW : HIGH); } if (shouldRun) { digitalWrite(pin_ENA, LOW); delayMicroseconds(5); int accelerationSteps = stepCount / 10; // Количество шагов для разгона int decelerationSteps = stepCount / 10; // Количество шагов для торможения int constantSpeedSteps = stepCount - accelerationSteps - decelerationSteps; // Остальные шаги в постоянной скорости // Разгон for (int i = 0; i < accelerationSteps; i++) { uint32_t frequency = map(i, 0, accelerationSteps, 0, maxFrequency); // Плавное увеличение частоты uint32_t t = 1000000 / (frequency * 2); // Расчет задержки pulseMotor(t); } // Постоянная скорость for (int i = 0; i < constantSpeedSteps; i++) { uint32_t t = 1000000 / (maxFrequency * 2); // Задержка на максимальной частоте pulseMotor(t); } // Торможение for (int i = 0; i < decelerationSteps; i++) { uint32_t frequency = map(decelerationSteps - i, 0, decelerationSteps, 0, maxFrequency); // Плавное уменьшение частоты uint32_t t = 1000000 / (frequency * 2); // Расчет задержки pulseMotor(t); } shouldRun = false; }}void pulseMotor(uint32_t delayTime) { digitalWrite(pin_PUL, HIGH); delayMicroseconds(delayTime); digitalWrite(pin_PUL, LOW); delayMicroseconds(delayTime);}