Я хотел бы построить и запрограммировать регулятор скорости из угловой шлифовальной машины с Arduino. Поэтому я купил модуль регулятора скорости двигателя (на нем есть потенциометр, который я заменю аналоговым выходом моего arduino) и инфракрасный модуль предотвращения препятствий (его также можно использовать для измерения оборотов в минуту).
Arduino должен измерять скорость вращения вала с помощью датчика (поэтому я использую функцию прерывания в коде).
Это значение оборотов затем передается в рассчитанный мной контроллер (контроллер работает с таймером 1). функция, чтобы сохранить постоянное время цикла) и аналоговый выход используется для передачи рассчитанного значения в контроллер скорости двигателя. Также на дисплее I2 C отображается фактическая скорость угловой шлифовальной машины.
Теперь мой вопрос: способен ли Arduino одновременно выполнять функции прерывания и таймера1, или будут ли они мешать друг другу?
(значения контроллера были проверены с использованием Winfact's Boris)
Мой код:
#include <LiquidCrystal_I2C.h>
#include <TimerOne.h>
//Regler: Siehe Haager S.147
//RPM Counter: Siehe https://forum.arduino.cc/index.php?topic=634139.0
const int X_input=1;
const int U_output=3;
int X=0;
int U=0, W=0;
const float kr=0.1;
const float Tn=0.12;
const float Tv=0.3;
const float T1=1.0e6;
const float T=0.01;
double w_k, u_k, e_k, e_k1, e_k2, u_k1, u_k2, x_k, d1, d2, c0, c1, c2;
float value = 0;
float rev = 0;
int rpm;
int oldtime = 0;
int time;
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup() {
//RPM Counter:
attachInterrupt(digitalPinToInterrupt (2), RPM_Count, RISING); //interrupt pin
//Regler:
Timer1.initialize(T*1.0e6);
Timer1.attachInterrupt(regler);
d1=(T+2*T1)/(T+T1);
d2=-T1/(T+T1);
c0=kr*(1+T/Tn+Tv/(T+T1));
c1=kr*((T*T+T*Tn-2*Tv*Tn)/(T*Tn+T1*Tn)-T/Tn-2);
c2=kr*(Tv+T1)/(T+T1);
e_k1=0.0, e_k2=0.0, u_k1=0.0, u_k2=0.0;
//Display:
lcd.begin();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("------Drehzahl------");
}
void regler(){
detachInterrupt(digitalPinToInterrupt(2));
time = millis() - oldtime;
rpm = (rev / time) * 60000;
oldtime = millis();
rev = 0;
attachInterrupt(digitalPinToInterrupt (2), RPM_Count, RISING);
w_k=rpm;
X=analogRead(X_input);
x_k=X*1000.0/1024-500;
e_k2=e_k1;
e_k1=e_k;
e_k=w_k-x_k;
u_k2=u_k1;
u_k1=u_k;
u_k=d1*u_k1 + d2*u_k2 + c0*e_k + c1*e_k1 + c2*e_k2;
U=256.0/320.0*u_k + 128;
if(U>255) U=255;
if(U<0) U=0;
analogWrite(U_output, U);
}
void RPM_Count() {
rev++;
}
void loop() {
lcd.setCursor(0,1);
lcd.print(rpm);
lcd.print(" U/min");
}