Я спрашивал - в какой строчке написано “запрещаю прерывания”. Предположил, что прерывания не запрещаются, и предложил вариант решения для этого случая.
Использовал библиотеку #include “GyverPlanner2.h”. Взял базовый пример и добавил в него кусок кода с общением по модбас, поставил на миллис раз в 250 миллисекунд и чудо, ничего не произошло так же step сигнал прерывается и соответственно шаговики дёргаются.
// пример с записанным в памяти маршрутом
// смотри график, а лучше запусти stepperPlot
int path[][2] = {
{100, 250},
{160, 30},
{230, 250},
{60, 100},
{270, 100},
};
// количество точек (пусть компилятор сам считает)
// как вес всего массива / (2+2) байта
int nodeAmount = sizeof(path) / 4;
#include "GyverPlanner2.h"
Stepper< STEPPER2WIRE > stepper1(2, 3);
Stepper< STEPPER2WIRE > stepper2(4, 5);
GPlanner2< STEPPER2WIRE, 2 > planner;
void setup() {
Serial.begin(115200);
// добавляем шаговики на оси
planner.addStepper(0, stepper1); // ось 0
planner.addStepper(1, stepper2); // ось 1
// устанавливаем ускорение и скорость
planner.setAcceleration(500);
planner.setMaxSpeed(500);
// начальная точка системы должна совпадать с первой точкой маршрута
planner.setCurrent(path[0]);
planner.start();
}
int count = 0; // счётчик точек маршрута
void loop() {
// здесь происходит движение моторов, вызывать как можно чаще
planner.tick();
// если в буфере планировщика есть место
if (planner.available()) {
// добавляем точку маршрута и является ли она точкой остановки (0 - нет)
planner.addTarget(path[count], 0);
if (++count >= sizeof(path) / 4) count = 0; // закольцевать
}
// асинхронно вывожу в порт графики
static uint32_t tmr;
if (millis() - tmr >= 20) {
tmr = millis();
Serial.print(stepper1.pos);
Serial.print(',');
Serial.println(stepper2.pos);
}
}
// тож самое, но тик по таймеру
// пример с записанным в памяти маршрутом окружности
// работу можно посмотреть в плоттере, а лучше в приложенном stepperPlot для Processing
uint32_t T1 = 0, T = 0, T2 = 0;
const int pointAm = 30; // количество точек в круге
int radius = 500; // радиус круга
int32_t path[pointAm + 1 + 1][2]; // буфер круга
// +1 на стартовую точку +1 на замыкание круга
#include "GyverPlanner2.h"
#include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus.
ModbusClient modbus(Serial2);
Stepper<STEPPER2WIRE> stepper1(4, 5);
Stepper<STEPPER2WIRE> stepper2(7, 6);
GPlanner2<STEPPER2WIRE, 2> planner;
void setup() {
Serial.begin(115200);
Serial2.begin(9600); // Инициируем работу с шиной UATR-RS485 указав её скорость.
modbus.begin();
// добавляем шаговики на оси
planner.addStepper(0, stepper1); // ось 0
planner.addStepper(1, stepper2); // ось 1
// устанавливаем ускорение и скорость
planner.setAcceleration(5000);
planner.setMaxSpeed(5000);
// начальная точка системы должна совпадать с первой точкой маршрута
planner.setCurrent(path[0]);
// заполняем буфер
for (int i = 0; i <= pointAm; i++) {
path[i + 1][0] = radius + radius * cos(TWO_PI * i / pointAm);
path[i + 1][1] = radius + radius * sin(TWO_PI * i / pointAm);
}
// 0 - координата 0,0
// 1 - первая координата круга
// итд
// заводим всё
planner.start();
initTimer();
}
// прерывание таймера
ISR(TIMER1_COMPA_vect) {
// здесь происходит движение моторов
// если мотор должен двигаться (true) - ставим новый период таймеру
if (planner.tickManual()) setPeriod(planner.getPeriod());
else stopTimer();
// если нет - останавливаем таймер
}
int count = 0; // счётчик точек маршрута
void loop() {
if(millis() - T > 50){
Serial.print("HoldingRegister[0]=10000 "); //
if( modbus.holdingRegisterWrite(3, 1, stepper1.pos) ){ Serial.println("Ok" ); } // Функция возвращает результат записи: true при успехе, false при неудаче.
else { Serial.println("Err"); } // Тип (код) последней ошибки можно получить функцией modbus.lastError().
T = millis();
}
// вручную проверяем буфер. Если начался новый отрезок движения
if (planner.checkBuffer()) {
startTimer(); // запускаем таймер
setPeriod(planner.getPeriod()); // устанавливаем новый период
}
// если в буфере планировщика есть место
if (planner.available()) {
// добавляем точку маршрута и является ли она точкой остановки (0 - нет)
planner.addTarget(path[count], 0);
if (++count >= sizeof(path) / 8) count = 0; // закольцевать
}
// асинхронно вывожу в порт графики
static uint32_t tmr;
if (millis() - tmr >= 20) {
tmr = millis();
Serial.print(stepper1.pos);
Serial.print(',');
Serial.println(stepper2.pos);
}
}