Разработать программу на ардуино

7 500 руб. за проект
25 октября 2024, 21:46 • 17 откликов • 143 просмотра
Требуется написать программу на ардуино.
Программа должна управлять одновременно четырьмя шаговыми двигателями (NEMA 23) подключенными к ардуино через драйверы DM556P.
В программе должна быть возможность установить ускорение (шаги/с/с) и количество шагов на 1 оборот (установленное на драйвере).
Программа должна принимать на вход через сериал-порт строку содержащую набор данных для управления двигателями (номер двигателя, количество шагов (угол поворота), направление, скорость вращения (шаг/мин).
Программа должна обновлять сериал-порт постоянно и сразу по получении команды начинать ее исполнение.
Прикладываю пример написанной мной программы. Пример приведен для минимизации уточняющих вопросов и для лучшего понимания ТЗ а не как руководство.
Python (отправляет управляющую строку с определенным интервалом)
import serial
import time

# Массив углов для поворота и соответствующие направления (0 - CW, 1 - CCW)
angles_and_directions = [(360, 0), (90, 1)]
ser = serial.Serial('COM3', 9600)
step_count = 0

frequency = 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 <Arduino.h>

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);
}