c++ - 如何读取带有 ESP32 中断和全局标志的旋转编码器
问题描述
使用中断时,任何类型的 digitalRead 都应该过时,或者我认为。让我解释一下我对此的理解以显示我的问题:
比如说,正交增量旋转编码器 (RE) 在两个信号引脚上都被拉高,因此处于空闲状态。如果我在两个引脚的下降沿配置中断服务例程 (ISR) 并让引脚 B 的 ISR 仅将标志“flag_B”设置为 false(表示引脚的逻辑状态)和引脚的 ISR A 在 A 的 ISR 期间根据 flag_B 的状态设置或重置标志“flag_顺时针”,那么我应该为每个转弯步骤获得正确的方向,对吗?我唯一的任务是在 ISR 之后再次将引脚 B 的状态设置为高电平,并且我的代码应该为下一次中断做好准备。但这不起作用,当您感觉到一点“颠簸”时,在转动步骤的前半部分显示错误方向或逆时针显示的许多随机情况 在转动旋钮的同时,在下半部分顺时针方向转动,当轴完成一步时,基本上只转动一步就做了两个相反的动作。我的逻辑有问题吗?所有信号都在硬件中去抖动,并且在示波器上看起来像预期的那样。
ISR:
//re-CLK signal
void IRAM_ATTR reCLK_ISR(void){
if(myFlags->pinBstate){
//this means the first interrupt of a turning step comes from the clock, not data
myFlags->direction = CCW;
}
else{
//this means the interrupt of a turning step occured from data first
myFlags->direction = CW;
}
}
//re-DATA signal
void IRAM_ATTR reDATA_ISR(void){
myFlags->pinDATAstate = false;
}
进一步处理:
//some function
//scroll = CW / CCW
if((myFlags->direction) != STOP){
if(myFlags->direction == CW){
//DEBUG
digitalWrite(PIN_LED_DEBUG, LOW);
}
}
if(myFlags->direction == CCW){
//DEBUG
digitalWrite(PIN_LED_DEBUG, HIGH);
}
myFlags->pinDATAstate = true;
myFlags->direction = STOP; //direction has 3 states: CW, CCW and STOP
}
最后两条语句应该将所有受影响的标志恢复到编码器被触摸之前的状态,这意味着为下一回合做好准备。LED 只是替代应根据转向方向执行的不同计算。
解决方案
即使该引脚被分配为中断,您仍然可以使用它digitalRead()
来确定方向。例如:
const uint8_t pinA = 25;
const uint8_t pinB = 26;
volatile int counter;
void IRAM_ATTR isr(){
if(digitalRead(pinA) == digitalRead(pinB)) {
//Clockwise
counter++;
} else {
//Counter Clockwise
counter--;
}
}
您甚至不需要另一个 ISR 来确定方向。我用这种方法来确定速度和方向;
推荐阅读
- c - C 代码在 RHEL7 中构建并在 RHEL6 中部署,gdb 无法正常工作
- bash - macOS - 根据部分文件名创建文件夹(第 2 部分)
- c# - 如何在 pycharm 中调用 SOAP Web 服务?
- javascript - 更新行但未编辑下拉列时,DHTMLX dataProcessor 不选择下拉列表的选项值(它选择标签)
- java - Swagger UI 不显示所有标题值
- javascript - Google 广告 dfp js 代码未呈现所有广告位
- java - 如何通过从第一类调用第二类的方法来调用第三类的方法
- c# - 获取 ListView 内开关的选中状态
- r - 如何更换
特定列的值? - postgresql - 当名称实际上是大写时,如何使用确保表名是小写的查询?