使用bounce2库来检测开关,实现无阻塞流程,并升级 adduino 鼠标滚轮编码器 程序

在arduino中常用的机械开关信号在开关瞬间其实电平都不稳定,

 

 

硬件上可以接个电容

 

 

软件上可以用简易的delay函数来避免信号抖动造成的不稳定,不过delay函数属于简单暴力的阻塞流程,延时期间别的啥都干不了。如果自己写的话可以用mile计时函数来实现延时。也可以用github大神的现成库。实现原理是一样的

在arduino   ide里搜bounce2,安装这个库   GitHub - thomasfredericks/Bounce2: Debouncing library for Arduino and Wiring

基本用法

#include <Bounce2.h>
Bounce b = Bounce(); //实例Bounce对象
SETUP{
    b.attach ( <PIN> , <PIN MODE> );//设置针脚,可以设置为内部上拉
    b.interval( <INTERVAL IN MS> );//设置防抖动时间  单位毫秒
}
LOOP{
    b.update();//没有使用中断,所以要手动更新状态
    if ( b.changed() ) { 
      // 读状态
      int deboucedValue = b.read();
      // to  do
}

还可以用fell()和rose()检测信号上升沿下降沿,用duration ()和previousDuration ()来获得输入脚的现状态持续时间与上一次状态持续时间

 

程序进化来啦   对前天检测鼠标滚轮并用七段显示器显示的更新,上一个程序如果防抖时间太长就会屏幕闪的厉害。这次使用bounce2库来更新

#include <MsTimer2.h>//加入计时器用来测量速度
#include "SevSeg.h"//引入七段显示器库
#include <Bounce2.h>//引入去抖动库
SevSeg sevseg;//构建七段显示器对象
#define DEBOUNCE_TIME 10 //延时用来过滤不正常的信号,
// 定义引脚2.3
int APhase = 2;
int BPhase = 3;

long count = 0;//计数

Bounce bounceA = Bounce();//实例bounceA对象,因为有两根输入,所以需要建立俩对象
Bounce bounceB = Bounce();//实例bounceB对象
long preverCount = 0;//上一次的计数
long cerrentCount = 0;//当前计数


void getSpeed(){   
  preverCount = cerrentCount;
  cerrentCount = count;
  Serial.println( "speed is " + String (cerrentCount - preverCount) ) ;

   
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  bounceA.attach( APhase, INPUT_PULLUP);
  bounceB.attach( BPhase, INPUT_PULLUP);
  bounceA.interval(DEBOUNCE_TIME); 
  bounceB.interval(DEBOUNCE_TIME);
  pinMode(LED_BUILTIN,OUTPUT);
  MsTimer2::set(1000, getSpeed);//改变计时时间可以调整速度的刷新率
  //开始计时
  MsTimer2::start();






  byte numDigits = 4;//四位七段式显示器
  byte digitPins[] = {4, 5, 6, 7};//每位数字的针脚
  byte segmentPins[] = {8, 9, 10, 11, 12, 13, A0, A1};//依顺序的针脚
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options,共阳极
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected
  
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(100);
  
}

void loop() {
  //更新输入状态
  bounceA.update();
  bounceB.update();


  
  
  if ( bounceA.fell() ) {    //从1变成0 开始判断是正转还是反转
    
    
    
    
      //用B相信号判断正反转
      if (bounceB.read() == 0) {
      count++;
      Serial.println(count);
      
      }
      if (bounceB.read() == 1) {
      count--;
      Serial.println(count);
      
      }
    
    
    
  }
    if ( bounceA.rose() ) {    //从0变成1开始判断是正转还是反转
    
    
    
    
      //用B相信号判断正反转
      if (bounceB.read() == 1) {
      count++;
      Serial.println(count);
      
      }
      if (bounceB.read() == 0) {
      count--;
      Serial.println(count);
      
      }
    
    
    
  }
  sevseg.setNumber(count, 0);
  sevseg.refreshDisplay();//不刷新的话不亮灯
  
  
}

这里怎么设置防抖动时间,屏幕都不会闪烁。

posted @ 2021-05-28 16:45  kyo413  阅读(1191)  评论(0编辑  收藏  举报