|
我在wokwi上面做uno仿真,想实现通过按钮调节舵机转动速度的挡位控制
但是似乎因为按键防抖(或是别的原因)导致中断多次触发,即无法实现“按一下,挡位+1”的功能
*下面代码中在中断函数onButtonClick里面加了前后延时可以基本实现功能
但是实际上还是存在跳变,中断函数多次触发的情况,请问这种问题是否有解决办法?
源码:
/*
项目说明:类比雨刮器,设置了三个挡位;
分别对应不同的舵机转动速度;
按下按钮切换挡位;
LCD显示当前挡位信息;
*/
#include <Servo.h> //舵机控制库文件
#include <LiquidCrystal_I2C.h> //LCD1602 i2c控制库文件
LiquidCrystal_I2C lcd(0x27,16,2); //初始化LCD1602,0x27是LCD设备默认地址
Servo myservo; //创建舵机控制对象
uint32_t delay_time[] = {10,20,40}; //舵机控制延迟函数数值,越大越慢
uint16_t crl_data = 0; //控制delay_time[]选择的数值
void setup()
{
myservo.attach(9); //设置D9口为舵机PWM信号输出口
lcd.init(); //lcd初始化
lcd.backlight();//lcd开启背光
lcd.setCursor(0,0); //lcd设置显示光标至第1列第1行
lcd.print("speed level:"); //lcd显示"speed level:"
attachInterrupt(0, onButtonClick, FALLING); //开启外部中断,下降沿触发外部中断信号,执行onButtonClick函数
}
void loop()
{
servoContrl();
}
void onButtonClick() //按键中断触发函数
{
delay(100); //设置按键防抖延迟,下同
crl_data = (crl_data + 1) % 3; //控制crl_data在0 1 2之间切换
delay(100);
}
void servoContrl() //舵机控制函数
{
for (int pos = 0; pos <= 180; pos += 1) { //舵机顺时针转动循环
myservo.write(pos); //设置舵机转动角度
displayLevel(); //更新lcd显示挡位
delay(delay_time[crl_data]); //舵机转动延时
}
for (int pos = 180; pos >= 0; pos -= 1) { //舵机逆时针转动循环
myservo.write(pos);
displayLevel();
delay(delay_time[crl_data]);
};
}
void displayLevel() //lcd显示挡位函数
{
int data = crl_data % 3;
switch(data)
{
case 0:
lcd.setCursor(7,1); //lcd设置显示光标至第8列第2行
lcd.print(data+1);
break;
case 1:
lcd.setCursor(7,1);
lcd.print(data+1);
break;
case 2:
lcd.setCursor(7,1);
lcd.print(data+1);
break;
}
}
|
|