bool flag = false;
uint32_t btnTimer = 0;
const int knop=2;
const uint8_t pin_ENA = 6; // Вывод Arduino подключённый к входу драйвера ENA+.
const uint8_t pin_DIR = 4; // Вывод Arduino подключённый к входу драйвера DIR+.
const uint8_t pin_PUL = 5; // Вывод Arduino подключённый к входу драйвера PUL+.
// Вывод GND Arduino соединён с входами драйвера ENA-, DIR-, PUL-.
volatile uint32_t step=0; // Переменная хранит количество микрошагов, которые требуется совершить.
uint32_t shag_stop; // для переполнения числа шагов
void knopka () {
// читаем инвертированное значение для удобства
bool btnState = !digitalRead(knop);
if (btnState && !flag && millis() - btnTimer > 100) {
flag = true;
btnTimer = millis();
Serial.println("stop");
}
if (!btnState && flag && millis() - btnTimer > 100) {
flag = false;
btnTimer = millis();
// Serial.println("release");
}
}
void setup() {
pinMode(knop, INPUT_PULLUP);
pinMode( pin_ENA, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode( pin_DIR, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode( pin_PUL, OUTPUT ); // Конфигурируем вывод Arduino как выход.
// funcSetTimer2( 1000 ); // Запускаем 2 таймер указав частоту следования микрошагов от 1 до 200'000 Гц.
Serial.begin(9600);
Serial.setTimeout(50);
attachInterrupt(0, motor_stop, FALLING);
}
void loop() {
if (Serial.available()>0) {
char data[100];
int amount = Serial.readBytesUntil(';',data,100);
data[amount]=NULL;
int32_t val = atol(data);
Serial.println(val);
motor (val,1000,0);
}
knopka ();
}
//
// ОБРАБОТКА ПРЕРЫВАНИЙ 2 ТАЙМЕРА: //
ISR(TIMER2_COMPA_vect){ // Функция вызывается по совпадению регистров TCNT2 и OCR2A.
if( step ){ // Если требуется выполнять микрошаги, то ...
bool p = digitalRead(pin_PUL); // Определяем текущее состояние на выводе PUL.
digitalWrite(pin_PUL, !p); // Меняем состояние на выводе PUL.
if( p ){ step--; } // Уменьшаем количество требуемых микрошагов.
} //
} //
//
// ФУНКЦИЯ НАСТРОЙКИ 2 ТАЙМЕРА: //
void funcSetTimer2(uint32_t f){ // Параметр: «f» - частота тактирования ШД от 1 до 200'000 Гц.
if(f>200000){f=200000;}
// Определяем значение предделителя:
uint16_t i; uint8_t j; f*=2;
if(f>(F_CPU/255/ 1)){i= 1; j=1;}else
if(f>(F_CPU/255/ 8)){i= 8; j=2;}else
if(f>(F_CPU/255/ 32)){i= 32; j=3;}else
if(f>(F_CPU/255/ 64)){i= 64; j=4;}else
if(f>(F_CPU/255/128)){i= 128; j=5;}else
if(f>(F_CPU/255/256)){i= 256; j=6;}else
{i=1024; j=7;}
// Устанавливаем регистры 2 таймера:
TCCR2A = 0<<COM2A1 | 0<<COM2A0 | 0<<COM2B1 | 0<<COM2B0 | 1<<WGM21 | 0<<WGM20;
TCCR2B = 0<<FOC2A | 0<<FOC2B | 0<<WGM22 | j;
OCR2A = (uint8_t)(F_CPU/(i*f))-1;
TIMSK2 = 0<<OCIE2B | 1<<OCIE2A | 0<<TOIE2;
SREG = 1<<7;
}
/*
void motor (uint32_t step, int16_t speed, int8_t dir) {
//задаем шаги, скорость в с-1, направление плюс/минус 1, ускорение, по умолчанию 500
stepper.setSpeed(speed); // скорость движения к цели
stepper.setTarget(dir * step, RELATIVE); // устанвливаем целевое количество шагов
//stepper.setAcceleration(acs);
}
*/
void motor_stop () {
step = shag_stop;
}
void motor (uint32_t shag, uint32_t speed, bool dir) {
shag_stop = shag;
funcSetTimer2(speed); // Запускаем 2 таймер указав частоту следования микрошагов от 1 до 200'000 Гц.
// Готовимся к движению вала: //
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 (см. график STEP/DIR).
digitalWrite( pin_DIR, dir ); // Выбираем направление вращения.
delayMicroseconds(5); // Выполняем задержку t2 (см. график STEP/DIR).
// Поворачиваем вал на 2 оборота: //
step= shag; // Указываем количество микрошагов, которые требуется совершить.
while(step){;} // Ждём обнуления переменной.
// Останавливаем вал без удержания: //
digitalWrite( pin_ENA, 1 ); // Запрещаем работу двигателя, отключаем токи в обмотках.
delayMicroseconds(5);
} //