//// для потенциометра //////////////
#define FILTER_STEP 25
#define FILTER_COEF 0.05
int val_PTC;
float val_f_PTC = 0.0;
unsigned long filter_timer;
/////////////////////////////////////
bool flag = false; // для кнопки
uint32_t btnTimer = 0;
const uint8_t knop=2;
const uint8_t knopV=34;
const uint8_t knopN=35;
const uint8_t potenc=39;
const uint8_t pin_ENA = 25; // Вывод Arduino подключённый к входу драйвера ENA+.
const uint8_t pin_DIR = 32; // Вывод Arduino подключённый к входу драйвера DIR+.
const uint8_t pin_PUL = 33; // Вывод Arduino подключённый к входу драйвера PUL+.
// Вывод GND Arduino соединён с входами драйвера ENA-, DIR-, PUL-.
bool flag_stop = false; //флаг на прерывание
uint32_t spd = 100;
///////////////////////////////// класс на таймер //////////////////////////////////////
class Timer {
public:
Timer(uint32_t nprd = 0) {
setPeriod(nprd);
}
void setPeriod(uint32_t nprd) {
prd = nprd;
}
bool ready() {
return (prd && micros() - tmr >= prd) ? (tmr = micros(), 1) : 0;
}
private:
uint32_t tmr = 0, prd = 0;
};
/////////////////////////////////////////////////////////////////////////////////////
Timer tmr1;
/////////////////////////////////////////////////////////////////////////////////////
void knopka () {
// читаем инвертированное значение для удобства
bool btnState = !digitalRead(knop);
if (btnState && !flag && millis() - btnTimer > 80) {
flag = true;
btnTimer = millis();
Serial.println("stop");
}
if (!btnState && flag && millis() - btnTimer > 80) {
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 как выход.
pinMode(knopV, INPUT_PULLUP);
pinMode(knopN, INPUT_PULLUP);
Serial.begin(9600);
Serial.setTimeout(50);
attachInterrupt(2, 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,100);
}
knopka ();
vpr ();
PTC();
// motor (3200, 100);
}
//////////////////////////////////////////////////////////////////////////////////
IRAM_ATTR void motor_stop () {
flag_stop = true;
}
/////////////////////////////////////////////////////////////////////////////////
void motor(int32_t step, uint32_t speed) { // указываем число шагов и скорость
int32_t count = 0;
uint32_t t = 1000000/2/speed; // расчет длительности импульсов. Меньше 40 мкс все равно около 45
bool p = 0;
int8_t dir= 0;
if (step >0) dir = 0; // если что, поменять знаки наоборот
if (step <0) dir = 1;
if (step != 0) {
// Готовимся к движению вала: //
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 .
digitalWrite( pin_DIR, dir ); // Выбираем направление вращения.
delayMicroseconds(5); // Выполняем задержку t2 .
// Поворачиваем вал на 2 оборота: //
tmr1.setPeriod(t); //установить период таймера для переключения с 1 на 0 на пине step
for (;;) {
if (step == 0) break;
if (tmr1.ready()){p = !p; digitalWrite( pin_PUL, p ); count++;}
if (count == abs(step*2) or flag_stop == true) {step = 0; flag_stop = false; break;} //выход из цикла при достижении заданного количества шагов
}
// Останавливаем вал без удержания: //
digitalWrite( pin_ENA, 1 ); // Запрещаем работу двигателя, отключаем токи в обмотках.
delayMicroseconds(5);
}
}
/////////////////////////////////////////////////////////////
void vpr (){
uint32_t t = 1000000/2/spd;
bool p = 0;
if (digitalRead(knopV) == 0) {
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 .
digitalWrite( pin_DIR, 0 ); delayMicroseconds(5);
tmr1.setPeriod(t); //установить период таймера для переключения с 1 на 0 на пине step
for (;;) {
if (tmr1.ready()){p = !p; digitalWrite( pin_PUL, p );}
if (digitalRead(knopV) == 1 ) {
digitalWrite( pin_ENA, 1 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 .
break;} //выход из цикла при достижении заданного количества шагов
}
}
if (digitalRead(knopN) == 0) {
digitalWrite( pin_ENA, 0 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 .
digitalWrite( pin_DIR, 1 ); delayMicroseconds(5);
tmr1.setPeriod(t); //установить период таймера для переключения с 1 на 0 на пине step
for (;;) {
if (tmr1.ready()){p = !p; digitalWrite( pin_PUL, p );
}
if (digitalRead(knopN) == 1 ) {
digitalWrite( pin_ENA, 1 ); // Разрешаем работу двигателя.
delayMicroseconds(5); // Выполняем задержку t1 .
break;} //выход из цикла при достижении заданного количества шагов
}
}
}
/////////////////////////////////////////////////////////////////////////
void PTC (){
if (millis() - filter_timer > FILTER_STEP) {
filter_timer = millis(); // просто таймер
// читаем значение (не обязательно с аналога, это может быть ЛЮБОЙ датчик)
val_PTC = analogRead(39);
// основной алгоритм фильтрации. Внимательно прокрутите его в голове, чтобы понять, как он работает
// val_f_PTC = val_PTC * FILTER_COEF + val_f_PTC * (1 - FILTER_COEF);
spd = map(val_PTC, 0, 4095, 100, 10000);
// для примера выведем в порт
Serial.println(spd);
}
}