按键触发uno外部中断防抖问题-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 638|回复: 7

[未解决] 按键触发uno外部中断防抖问题

[复制链接]
发表于 2022-5-12 00:25 | 显示全部楼层 |阅读模式
我在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;
  }
}

发表于 2022-5-12 07:28 | 显示全部楼层
程序初始加 int k=0;
void loop()
{
  servoContrl();
  k=0;
}

void onButtonClick()
{
  if(k==0){
  crl_data = (crl_data + 1) % 3;
  k=1;
}
}
发表于 2022-5-12 07:28 | 显示全部楼层
本帖最后由 shouzama 于 2022-5-12 07:30 编辑

使用下降檢測觸發,那表示你按鍵按下是 LOW,
先問一下你的按鍵有沒有自己做 PULL-UP 電路?
按鍵的可靠度(接點阻值穩不穩)?

再不行把 delay 100→200 試試
发表于 2022-5-12 11:23 | 显示全部楼层
按键并个100nf的电容试试,再不行换个好一点的按键
 楼主| 发表于 2022-5-12 15:08 | 显示全部楼层
lwq1947 发表于 2022-5-12 07:28
程序初始加 int k=0;
void loop()
{

好逻辑
 楼主| 发表于 2022-5-12 22:45 | 显示全部楼层
shouzama 发表于 2022-5-12 07:28
使用下降檢測觸發,那表示你按鍵按下是 LOW,
先問一下你的按鍵有沒有自己做 PULL-UP 電路?
按鍵的可靠度(接 ...

因为是仿真,所以没做上拉电路,主要是我是按照空悬默认为高去做的
 楼主| 发表于 2022-5-12 22:46 | 显示全部楼层
myself1820 发表于 2022-5-12 11:23
按键并个100nf的电容试试,再不行换个好一点的按键

这个想法有想过,但是仿真没有电容
发表于 2022-5-13 13:17 | 显示全部楼层
在中断里  delay(100);也是厉害
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 04:50 , Processed in 0.073233 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表