Добрый день, друзья! Решил собрать себе станок для протяжки PET пластика в пруток для печати, и написать программу я взялся сам своими силами. Схема простая, к Arduino nano подключаются: MOSFET для нагревателя, NTC термистор, драйвер A4988, OLED экран и энкодер. Так вот у меня проблема, шаговый двигатель не работает нормально при обработке энкодера, шаговик еле крутится. Независимо от того как энкодер обрабатывается в loop-е или в прерываниях. Если убираю обработку энкодера, то шаговик работает нормально. Использовал библиотеки от уважаемого Alex Gyver-а. Куда копать и как обрабатывать и энкодер и ШД?
Мой скетч без работы PID:
#include <GyverStepper.h>
#include <GyverOLED.h>
#include <EncButton.h>
#include <GyverNTC.h>
#include <GyverPID.h>
#include <GyverTimers.h>
#define MOS_PIN 10
#define THERM_PIN A7
GStepper<STEPPER2WIRE> stepper(6400, 5, 6); //400*16=6400 шагов, пин step, пин dir (шагов на градус берется из документации на двигатель)
EncButton<EB_TICK, 2, 3, 4> encoder; // энкодер с кнопкой
GyverOLED<SSD1306_128x32, OLED_NO_BUFFER> oled; //oled подключается на пины sck - A5, sda - A4
GyverNTC NTC (THERM_PIN, 100000, 3950, 25, 4693); //термистор (аналоговый пин, сопротивление термистора, коэффицент(обычно 3950), базовая температура термистора, сопротивление парного резистора)
GyverPID pid(15.2, 0.82, 0);
int period = 500;
unsigned long timing;
int count = 1;
bool flag1;
void setup() {
//Serial.begin(9600);
stepper.setRunMode(KEEP_SPEED); // режим поддержания скорости
stepper.setSpeedDeg(1); // в градусах/сек, не ставить 0, иначе не запускается прога
stepper.setMaxSpeedDeg(600); //нужно для работы getMinPeriod
encoder.setEncType(EB_HALFSTEP);
Timer2.setPeriod(stepper.getMinPeriod() / 2);
Timer2.enableISR();
pid.setpoint = 243;
pid.setDt(period);
pinMode(MOS_PIN, OUTPUT);
oled.init();
oled.clear();
oled.setCursor(5, 1); // курсор в (пиксель X, строка Y)
oled.setScale(2);
oled.print("PeT_Pull_2");
delay(2000);
oled.clear();
oled.setScale(1);
// прерывание обеих фаз энкодера на функцию isr
attachInterrupt(0, isr, CHANGE);
attachInterrupt(1, isr, CHANGE);
}
void loop() {
encoder.tick();
if (encoder.right()) {
count = count - 50;
if (count < 1) count = 1;
flag1 = 1;
}
if (encoder.left()) {
count = count + 50;
if (count == 51) count = 50;
if (count > 600) count = 600; // Скорость от 0 до 600 градусов/сек при повороте движка
flag1 = 1;
}
if (encoder.click()) {
stepper.setSpeedDeg(count); //скорость записывается в драйвер по нажатию на энкодер.
oled.setCursor(5, 2);
oled.print("Set!");
flag1 = 1;
}
if (millis() - timing > 1000) { // 1 сек
timing = millis();
if (flag1 == 1) {
oled.clear();
oled.home();
oled.print("Stp_spd=");
oled.print(count);
oled.setCursor(5, 2);
oled.print("temp=");
oled.print(pid.setpoint);
oled.print("/");
oled.print(NTC.getTempAverage());
flag1 = 0;
}
}
}
ISR(TIMER2_A) {
stepper.tick(); // мотор асинхронно крутится в прерывании
}
void isr() {
encoder.tickISR(); // тикер в прерывании
// Не вызывает подключенные коллбэки внутри прерывания!!!
}