ZBLOG

attachInterrupt(digitalPinToInterrupt(ENCODER_EL1), encoderISR1, CHANGE); attachInterrupt(digitalPinToInterrupt(ENCODER_EL2), encoderISR2, CHANGE); attachInterrupt(digitalPinToInterrupt(ENCODER_ER1), encoderISR3, CHANGE); attachInterru...

您提供的代码片段是Arduino中使用外部中断来处理编码器输入的典型用法。通过attachInterrupt()函数,您可以将特定引脚上的变化(如电平变换)与一个ISR(中断服务例程)关联起来,从而在每次编码器脉冲到来时更新计数。

完整示例

以下是一个完整的示例,其中包含了如何设置这些中断、编码器ISR以及如何计算RPM:

// 编码器引脚定义
#define ENCODER_EL1 2 // 左侧电机编码器引脚1
#define ENCODER_EL2 3 // 左侧电机编码器引脚2
#define ENCODER_ER1 4 // 右侧电机编码器引脚1
#define ENCODER_ER2 5 // 右侧电机编码器引脚2

// 全局变量用于存储编码器计数
volatile int encoderCount1 = 0;
volatile int encoderCount2 = 0;
volatile int encoderCount3 = 0;
volatile int encoderCount4 = 0;

unsigned long lastTime3 = 0;
unsigned long lastTime4 = 0;

const int PULSES_PER_REVOLUTION = 20; // 根据实际情况设置这个值

float speed3 = 0;
float speed4 = 0;

// 初始化设置
void setup() {
    Serial.begin(9600);

    // 设置编码器引脚为输入,并启用内部上拉电阻(如果需要)
    pinMode(ENCODER_EL1, INPUT_PULLUP);
    pinMode(ENCODER_EL2, INPUT_PULLUP);
    pinMode(ENCODER_ER1, INPUT_PULLUP);
    pinMode(ENCODER_ER2, INPUT_PULLUP);

    // 附加中断处理程序
    attachInterrupt(digitalPinToInterrupt(ENCODER_EL1), encoderISR1, CHANGE);  
    attachInterrupt(digitalPinToInterrupt(ENCODER_EL2), encoderISR2, CHANGE);  
    attachInterrupt(digitalPinToInterrupt(ENCODER_ER1), encoderISR3, CHANGE);  
    attachInterrupt(digitalPinToInterrupt(ENCODER_ER2), encoderISR4, CHANGE);  
}

// 循环执行的代码
void loop() {
    Encoder_Read();
}

// 中断服务程序 (ISR)
void encoderISR1() {
    encoderCount1++;
}

void encoderISR2() {
    encoderCount2++;
}

void encoderISR3() {
    encoderCount3++;
}

void encoderISR4() {
    encoderCount4++;
}

// 编码器读取速度并打印 RPM
void Encoder_Read() {
    if (millis() - lastTime3 >= 500) {  
        float rpm3 = (encoderCount3 * 60.0) / (6 * PULSES_PER_REVOLUTION);  
        speed3 = rpm3;  
        encoderCount3 = 0;  
        lastTime3 = millis();  

        Serial.print("Motor R1 Speed: ");  
        Serial.print(rpm3);  
        Serial.println(" RPM");  
    }  
  
    if (millis() - lastTime4 >= 500) {  
        float rpm4 = (encoderCount4 * 60.0) / (6 * PULSES_PER_REVOLUTION);  
        speed4 = rpm4;  
        encoderCount4 = 0;  
        lastTime4 = millis();  

        Serial.print("Motor R2 Speed: ");  
        Serial.print(rpm4);  
        Serial.println(" RPM");   
    }
}

注意事项:

  • 中断安全:在 ISR 中尽量避免使用延时和复杂逻辑,因为这会阻塞其他任务。
  • 噪声问题:有时可能会遇到抖动或噪声导致错误计数,可以考虑使用更高级别的去抖动技术,例如滤波。
  • 有效性测试:确保您的硬件连接正确,所有编写的代码能够正常响应真实信号。

这个示例展示了如何利用Arduino中的中断功能,以高效地捕捉和处理来自旋转编码器的输入信号。如果您有其他问题或需求,请随时告诉我!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=19270

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?