使用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();//不刷新的话不亮灯 }
这里怎么设置防抖动时间,屏幕都不会闪烁。