//https://deepbluembedded.com/esp32-timers-timer-interrupt-tutorial-arduino-ide/
//https://docs.espressif.com/projects/arduino-esp32/en/latest/api/timer.html
#define pin_PUL 33
#define pin_DIR 32
#define pin_ENA 25
#define knopS 2
#define knop_sliv 27
#define knop_nabor 26
#define potenc 39
#define konc1 35
#define konc2 34
//// для потенциометра //////////////
#define FILTER_STEP 25
#define FILTER_COEF 0.05
int val_PTC;
float val_f_PTC = 0.0;
unsigned long filter_timer;
/////////////////////////////////////
bool flag_knop = false; // для кнопки стоп
bool flag_konc1 = false; // для кнопки стоп
bool flag_konc2 = false; // для кнопки стоп
uint32_t btnTimer_konc1 = 0;
uint32_t btnTimer_konc2 = 0;
uint32_t btnTimer_knop = 0;
uint32_t spd = 1000; // скорость шаг/с
unsigned long local_timer;
//////////////////////////// ТАЙМЕР ISR ///////////////////////////////////
volatile bool p = 0; //состояние STEP
bool flag_go = false; //флаг на движение мотора
bool flag_targ_go = false; // флаг, поднимается при задании целевого движения
volatile int32_t t_step = 0; //целевые шаги
volatile int32_t local_step = 0; //текущее положение шагов относительно 0 положения
int32_t dir = 1; // направление 1 или -1
hw_timer_t *Timer0_Cfg = NULL; //ссылка на таймер
void IRAM_ATTR Timer0_ISR() {
if (flag_go == true) { digitalWrite( pin_PUL, 1 ); digitalWrite( pin_PUL, 0 );
local_step = local_step + dir; }
if (flag_targ_go == true and t_step > 0) {
digitalWrite( pin_PUL, 1 ); digitalWrite( pin_PUL, 0 );
t_step = t_step - 1; local_step = local_step + dir; }
}
////////////////////////////////////////////////////////////////////////////
/////////////////////////////// КНОПКА СТОП ///////////////////////////////
void knopka_stop () {
// читаем инвертированное значение для удобства
bool btnState = !digitalRead(knopS);
if (btnState && !flag_knop && millis() - btnTimer_knop > 80) {
flag_knop = true;
btnTimer_knop = millis();
Serial.println("stop");
flag_go = false;
flag_targ_go = false;
}
if (!btnState && flag_knop && millis() - btnTimer_knop > 80) {
flag_knop = false;
btnTimer_knop = millis();
// Serial.println("release");
}
}
/////////////////////////////// ПОТЕНЦИОМЕТР ////////////////////////////////
void PTC (){
if (millis() - filter_timer > FILTER_STEP) {
filter_timer = millis(); // просто таймер
// читаем значение
val_PTC = analogRead(potenc);
// val_f_PTC = val_PTC * FILTER_COEF + val_f_PTC * (1 - FILTER_COEF);
uint32_t _spd = map(val_PTC, 0, 4095, 1, 100);
uint32_t spd_new = _spd*_spd;
if (spd_new != spd) {spd = spd_new; timerAlarm(Timer0_Cfg, 1000000/spd, true, 0); }
// для примера выведем в порт
//Serial.println(spd);
}
}
///////////////////////////////////////////////////////////////////////////////
//////////////////////////// движение по кнопке ////////////////////////////////////////
void motor_knop () {
if (digitalRead(knop_sliv) == 0 and digitalRead(konc1) == 1 ) {
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
digitalWrite( pin_DIR, 0 );
dir = 1;
flag_go = true; }
if (digitalRead(knop_nabor) == 0 and digitalRead(konc2) == 1 ) {
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
digitalWrite( pin_DIR, 1 );
dir = -1;
flag_go = true; }
if (digitalRead(knop_sliv) == 1 and digitalRead(knop_nabor) == 1) {
flag_go = false;
}
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// motor //////////////////////////////////////
void motor (int32_t step) {
bool direct = 0;
if (step >0) {direct = 0; dir = 1;} // если что, поменять знаки наоборот
if (step <0) {direct = 1; dir = -1;}
if (step != 0) {
t_step = abs(step);
digitalWrite( pin_ENA, 0 );
digitalWrite( pin_DIR, direct );
if (dir == 1 and analogRead (konc2)>0) {flag_targ_go = true; }
if (dir == -1 and analogRead (konc1)>0) {flag_targ_go = true; }
//Serial.println(t_step);
}
}
////////////////////////////////////////////////////////////////////////////
///////////////////////////// СТОПЫ /////////////////////////////////////
void konc1_stop () {
// читаем инвертированное значение для удобства
bool btnState = !digitalRead(konc1);
//bool btnState = 0;
//if ( analogRead(konc1)== 0) {btnState = 1;}
if (btnState && !flag_konc1 && millis() - btnTimer_konc1 > 80) {
flag_konc1 = true;
btnTimer_konc1 = millis();
Serial.println("stop1");
flag_go = false;
flag_targ_go = false;
}
if (!btnState && flag_konc1 && millis() - btnTimer_konc1 > 80) {
flag_konc1 = false;
btnTimer_konc1 = millis();
// Serial.println("release1");
}
}
void konc2_stop () {
// читаем инвертированное значение для удобства
//bool btnState = 0;
//if ( analogRead(konc2)== 0) {btnState = 1;}
bool btnState = !digitalRead(konc2);
if (btnState && !flag_konc2 && millis() - btnTimer_konc2 > 80) {
flag_konc2 = true;
btnTimer_konc2 = millis();
Serial.println("stop2");
flag_go = false;
flag_targ_go = false;
}
if (!btnState && flag_konc2 && millis() - btnTimer_konc2 > 80) {
flag_konc2 = false;
btnTimer_konc2 = millis();
// Serial.println("release2");
}
}
/////////////////////////// SETUP /////////////////////////////////////////
void setup() {
Serial.begin(115200); Serial.setTimeout(50);
pinMode(knopS, INPUT_PULLUP);
pinMode( pin_ENA, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode( pin_DIR, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode( pin_PUL, OUTPUT ); // Конфигурируем вывод Arduino как выход.
pinMode(knop_sliv, INPUT);
pinMode(knop_nabor, INPUT);
pinMode(konc1, INPUT);
pinMode(konc2, INPUT);
// УСТАОВКА частоты таймера прерывания
Timer0_Cfg = timerBegin(1000000); // частота, Гц
timerAttachInterrupt(Timer0_Cfg, &Timer0_ISR);
timerAlarm(Timer0_Cfg, 1000, true, 0); //период в мкс
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////// ЛУУУПП /////////////////////////////////////
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);
}
// konc_stop ();
if (t_step == 0) {flag_targ_go = false;}
if (flag_targ_go == false and flag_go == false ) {digitalWrite( pin_ENA, 1 );}
motor_knop ();
PTC ();
loc_step ();
knopka_stop();
konc1_stop ();
konc2_stop ();
}
//////////////// вывод шагов относительно 0 //////////////////////////////
void loc_step () {
if (millis() - local_timer > 1000) {
local_timer = millis(); // просто таймер
//Serial.println(digitalRead(konc2));
Serial.println(local_step);
// Serial.println(t_step);
}
}
///////////////////////////////////////////////////////////////////////////////