0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何设置用于旋转编码器的简单Arduino菜单

454398 来源:网络整理 作者:网络整理 2020-01-29 17:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

步骤1:准备工作

如何设置用于旋转编码器的简单Arduino菜单

如果还没有,请参阅我的其他Instructable旋转编码器阅读,以了解如何设置硬件和Arduino IDE软件。

硬件

图片中显示了需要使用中心按钮的其他硬件连接。我使用Fritzing绘制了图表,但它没有代表最可能的引脚布局的旋转编码器组件,因此只需将该图表与注释结合使用,然后查看旋转编码器的照片,即可了解更多内容。可能正在寻找旋转编码器引脚布局方面的信息。

旋转编码器一侧(与具有三个引脚的一侧相对)的两个引脚之一需要接地,而另一端则要连接到Arduino的数字引脚。我已将D4用于示例草图。如果您选择其他引脚,请不要忘记更改草图中的 buttonPin 的值。

接下来是步骤2中的代码。

步骤2:代码

这是代码。通过查看结构和评论,我希望您会发现很容易适应您的特定需求!

/*******Interrupt-based Rotary Encoder Menu Sketch*******

* by Simon Merrett, based on insight from Oleg Mazurov, Nick Gammon, rt and Steve Spence, and code from Nick Gammon

* 3,638 bytes with debugging on UNO, 1,604 bytes without debugging

*/

// Rotary encoder declarations

static int pinA = 2; // Our first hardware interrupt pin is digital pin 2

static int pinB = 3; // Our second hardware interrupt pin is digital pin 3

volatile byte aFlag = 0; // let‘s us know when we’re expecting a rising edge on pinA to signal that the encoder has arrived at a detent

volatile byte bFlag = 0; // let‘s us know when we’re expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)

volatile byte encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255

volatile byte oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)

volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent

// Button reading, including debounce without delay function declarations

const byte buttonPin = 4; // this is the Arduino pin we are connecting the push button to

byte oldButtonState = HIGH; // assume switch open because of pull-up resistor

const unsigned long debounceTime = 10; // milliseconds

unsigned long buttonPressTime; // when the switch last changed state

boolean buttonPressed = 0; // a flag variable

// Menu and submenu/setting declarations

byte Mode = 0; // This is which menu mode we are in at any given time (top level or one of the submenus)

const byte modeMax = 3; // This is the number of submenus/settings you want

byte setting1 = 0; // a variable which holds the value we set

byte setting2 = 0; // a variable which holds the value we set

byte setting3 = 0; // a variable which holds the value we set

/* Note: you may wish to change settingN etc to int, float or boolean to suit your application.

Remember to change “void setAdmin(byte name,*BYTE* setting)” to match and probably add some

“modeMax”-type overflow code in the “if(Mode == N && buttonPressed)” section*/

void setup() {

//Rotary encoder section of setup

pinMode(pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)

pinMode(pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)

attachInterrupt(0,PinA,RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the “PinA” Interrupt Service Routine (below)

attachInterrupt(1,PinB,RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the “PinB” Interrupt Service Routine (below)

// button section of setup

pinMode (buttonPin, INPUT_PULLUP); // setup the button pin

// DEBUGGING section of setup

Serial.begin(9600); // DEBUGGING: opens serial port, sets data rate to 9600 bps

}

void loop() {

rotaryMenu();

// carry out other loop code here

}

void rotaryMenu() { //This handles the bulk of the menu functions without needing to install/include/compile a menu library

//DEBUGGING: Rotary encoder update display if turned

if(oldEncPos != encoderPos) { // DEBUGGING

Serial.println(encoderPos);// DEBUGGING. Sometimes the serial monitor may show a value just outside modeMax due to this function. The menu shouldn‘t be affected.

oldEncPos = encoderPos;// DEBUGGING

}// DEBUGGING

// Button reading with non-delay() debounce - thank you Nick Gammon!

byte buttonState = digitalRead (buttonPin);

if (buttonState != oldButtonState){

if (millis () - buttonPressTime 》= debounceTime){ // debounce

buttonPressTime = millis (); // when we closed the switch

oldButtonState = buttonState; // remember for next time

if (buttonState == LOW){

Serial.println (“Button closed”); // DEBUGGING: print that button has been closed

buttonPressed = 1;

}

else {

Serial.println (“Button opened”); // DEBUGGING: print that button has been opened

buttonPressed = 0;

}

} // end if debounce time up

} // end of state change

//Main menu section

if (Mode == 0) {

if (encoderPos 》 (modeMax+10)) encoderPos = modeMax; // check we haven’t gone out of bounds below 0 and correct if we have

else if (encoderPos 》 modeMax) encoderPos = 0; // check we haven‘t gone out of bounds above modeMax and correct if we have

if (buttonPressed){

Mode = encoderPos; // set the Mode to the current value of input if button has been pressed

Serial.print(“Mode selected: ”); //DEBUGGING: print which mode has been selected

Serial.println(Mode); //DEBUGGING: print which mode has been selected

buttonPressed = 0; // reset the button status so one press results in one action

if (Mode == 1) {

Serial.println(“Mode 1”); //DEBUGGING: print which mode has been selected

encoderPos = setting1; // start adjusting Vout from last set point

}

if (Mode == 2) {

Serial.println(“Mode 2”); //DEBUGGING: print which mode has been selected

encoderPos = setting2; // start adjusting Imax from last set point

}

if (Mode == 3) {

Serial.println(“Mode 3”); //DEBUGGING: print which mode has been selected

encoderPos = setting3; // start adjusting Vmin from last set point

}

}

}

if (Mode == 1 && buttonPressed) {

setting1 = encoderPos; // record whatever value your encoder has been turned to, to setting 3

setAdmin(1,setting1);

//code to do other things with setting1 here, perhaps update display

}

if (Mode == 2 && buttonPressed) {

setting2 = encoderPos; // record whatever value your encoder has been turned to, to setting 2

setAdmin(2,setting2);

//code to do other things with setting2 here, perhaps update display

}

if (Mode == 3 && buttonPressed){

setting3 = encoderPos; // record whatever value your encoder has been turned to, to setting 3

setAdmin(3,setting3);

//code to do other things with setting3 here, perhaps update display

}

}

// Carry out common activities each time a setting is changed

void setAdmin(byte name, byte setting){

Serial.print(“Setting ”); //DEBUGGING

Serial.print(name); //DEBUGGING

Serial.print(“ = ”); //DEBUGGING

Serial.println(setting);//DEBUGGING

encoderPos = 0; // reorientate the menu index - optional as we have overflow check code elsewhere

buttonPressed = 0; // reset the button status so one press results in one action

Mode = 0; // go back to top level of menu, now that we’ve set values

Serial.println(“Main Menu”); //DEBUGGING

}

//Rotary encoder interrupt service routine for one encoder pin

void PinA(){

cli(); //stop interrupts happening before we read pin values

reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB‘s values

if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin’s rising edge

encoderPos --; //decrement the encoder‘s position count

bFlag = 0; //reset flags for the next turn

aFlag = 0; //reset flags for the next turn

}

else if (reading == B00000100) bFlag = 1; //signal that we’re expecting pinB to signal the transition to detent from free rotation

sei(); //restart interrupts

}

//Rotary encoder interrupt service routine for the other encoder pin

void PinB(){

cli(); //stop interrupts happening before we read pin values

reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB‘s values

if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin’s rising edge

encoderPos ++; //increment the encoder‘s position count

bFlag = 0; //reset flags for the next turn

aFlag = 0; //reset flags for the next turn

}

else if (reading == B00001000) aFlag = 1; //signal that we’re expecting pinA to signal the transition to detent from free rotation

sei(); //restart interrupts

}

// end of sketch!

在任何对菜单执行操作都不重要的行的每个注释的开头,我都使用了“ DEBUGGING”。如果您对菜单功能满意,则可能需要注释掉或删除这些行以缩小编译的草图尺寸。

请注意,菜单导航的关键部分是在用户滚动浏览选项和设置时反馈给用户。因此,如果您选择不包括DEBUGGING行,则可能应该使用另一个可视指示器(例如LCD文本显示器,LED),编码器输入正在导航菜单并更改设置。

如果我注释掉DEBUGGING行(注意,菜单导航仍需要一些视觉反馈),Arduino Uno的编译后代码约为1,650字节,希望在ATMEGA328P上留出足够的空间以容纳草图中更令人兴奋的部分!

转到步骤3,了解菜单系统的工作原理

步骤3:操作和结论

操作

如果上传此草图后在Arduino中打开串行监视器,并开始转动编码器轴,则应该看到顶层菜单在子菜单/选项数中旋转您拥有(使用 modeMax 变量进行限制)。如果按中间的按钮,您会看到已选择要滚动到的模式/子菜单,现在可以自由选择要滚动浏览该子菜单中的0-255值。现在,如果您按下中央按钮,则将其设置为 setting1 或 setting2 或 setting3 等。Arduino自动并立即返回

上电后,Arduino会记住您将每个设置设置为什么,并且如果您返回子菜单以获取设置,则您已经设置了一个值到此为止,它将从您选择的最后一个值开始进行编码器调整!

结论

我着手编写一些基于草图的代码,旋转编码器导航Arduino的基本菜单。我还尝试使其具有可读性,以便与某些替代方案不同,有人可以看到菜单结构,并知道他们需要进行哪些更改才能根据自己的需要定制菜单。

此代码是基本的和通用的,专门用于演示功能,同时易于适应您自己的应用程序。它使用串行监视器作为基本的调试工具,如果您想查看代码的工作原理,也不需要单独显示。希望您发现它有用,并受到启发进行编辑,修改和改进!

责任编辑:wv

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编码器
    +关注

    关注

    45

    文章

    4023

    浏览量

    143739
  • Arduino
    +关注

    关注

    191

    文章

    6535

    浏览量

    197664
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    HDXN-C变电站互感负荷模拟向量检查装置单机联机输出方法

    设置】首先需要进行系统设置旋转操作面板上“旋转编码器”到【系统设置】功能选项,按下“
    的头像 发表于 05-20 11:19 40次阅读
    HDXN-C变电站互感<b class='flag-5'>器</b>负荷模拟向量检查装置单机联机输出方法

    绝对式旋转编码器常用什么类型磁铁?

    绝对式旋转编码器是一种能够在任意时刻直接输出唯一角度位置值的传感,即使断电重启也无需回零,所以被广泛用于工业控制,机器人,这种编码器是需要
    的头像 发表于 03-26 13:44 326次阅读
    绝对式<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>常用什么类型磁铁?

    磁铁在编码器中的作用与应用

    编码器中,磁铁的作用不可小觑,常用的磁性材料主要是钕铁硼和铁氧体,今天这篇文章主要介绍下磁铁用于哪些编码器类型,以及其具体作用。磁铁在编码器中的作用(功能)是什么?在
    的头像 发表于 03-19 14:42 571次阅读
    磁铁在<b class='flag-5'>编码器</b>中的作用与应用

    增量型旋转编码器:工业自动化的“精密之眼”

    在钢铁厂的高炉旁,滚烫的钢水在传送带上疾驰;在港口的起重机下,集装箱被精准吊装;在纺织车间里,纱线以每分钟数万转的速度飞旋……这些场景背后,都藏着一双“精密之眼”——贝弗德增量型旋转编码器。它以微米
    的头像 发表于 12-31 08:43 419次阅读
    增量型<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>:工业自动化的“精密之眼”

    探索AEDR - 9930E:三通道反射式增量旋转编码器的技术剖析

    探索AEDR - 9930E:三通道反射式增量旋转编码器的技术剖析 在当今的电子设备设计领域,编码器的性能和适用性对于系统的整体表现起着至关重要的作用。今天,我们将深入探讨博通(Broadcom
    的头像 发表于 12-30 15:40 420次阅读

    旋转编码器增量:工业自动化领域的“精密之眼”

    在工业自动化飞速发展的今天,每一个细微的精度提升都可能带来生产效率的巨大飞跃。而旋转编码器增量,作为工业自动化领域的核心元件,正以其独特的优势,成为众多行业不可或缺的“精密之眼”。 旋转编码器
    的头像 发表于 12-08 08:41 561次阅读
    <b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>增量:工业自动化领域的“精密之眼”

    Vishay RAIK060 旋转绝对感应套件编码器技术解析

    Vishay RAIK060旋转绝对电感套件编码器专门用于电机驱动、机器人位置和具有精确定位的工业运动控制。这些编码器通过LED状态颜色轻松组装,对外部磁场、电场和温度不敏感。RAIK
    的头像 发表于 11-11 11:31 1371次阅读
    Vishay RAIK060 <b class='flag-5'>旋转</b>绝对感应套件<b class='flag-5'>编码器</b>技术解析

    增量式编码器工作原理是什么?

    增量式编码器工作原理是什么?增量式编码器是一种通过输出脉冲信号来反映旋转位置变化的传感,广泛应用于电机测速、位置控制等领域。其工作原理可从
    的头像 发表于 09-29 11:00 2787次阅读
    增量式<b class='flag-5'>编码器</b>工作原理是什么?

    国产编码器在人形机器人领域的进展

    电子发烧友网综合报道 编码器是测量旋转角度、位移及速度的传感,作为伺服系统的核心部件,在人形机器人领域,其数据反馈对实现机器人运动的精密控制与定位至关重要。   编码器种类丰富,按技
    的头像 发表于 09-24 09:41 1816次阅读

    多圈增量式编码器:工业自动化中的“旋转记忆大师”

    在工业自动化设备高速运转的场景中,一台风电齿轮箱的传动轴持续旋转了128圈,传统单圈编码器早已因数据溢出而“失忆”,而多圈增量式编码器却能精准记录每一圈的位移变化,为控制系统提供连续、可靠的位置反馈
    的头像 发表于 09-18 17:14 1169次阅读

    圣邦微电子推出高度集成旋转编码器芯片VCE2755

    圣邦微电子推出 VCE2755,一款基于各向异性磁阻(AMR)技术的高度集成旋转编码器芯片。该器件可应用于各种典型的需要角度位置反馈和速度检测的应用场景。
    的头像 发表于 08-21 11:51 1825次阅读
    圣邦微电子推出高度集成<b class='flag-5'>旋转</b>磁<b class='flag-5'>编码器</b>芯片VCE2755

    新品|Unit Step16,16 定位BCD旋转编码器控制单元

    UnitStep16是一款基于STM32G031G8U6微控制的16定位旋转编码器控制单元。其核心功能在于实时采集旋转编码器的BCD
    的头像 发表于 08-01 17:35 1616次阅读
    新品|Unit Step16,16 定位BCD<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>控制单元

    增量型旋转编码器:工业智能化的“精密罗盘”

    在工业自动化浪潮席卷全球的今天,每一个精密动作的背后都离不开传感的精准反馈。作为工业控制领域的“隐形冠军”,增量型旋转编码器凭借其高性价比、高可靠性和灵活适配性,正成为智能制造、机器人、新能源汽车
    的头像 发表于 07-30 08:33 866次阅读
    增量型<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>:工业智能化的“精密罗盘”

    增量型编码器与绝对值型编码器怎么选择?

    在选择增量型编码器与绝对值型编码器时,需要考虑多个因素,包括应用需求、成本、精度、可靠性以及环境适应性等。以下是对两种编码器的详细比较及选择建议: 一、增量型编码器 1. 优点:  
    的头像 发表于 07-10 10:34 1977次阅读

    Bourns 扩展增量式编码器产品线,旋转寿命功能再升级

    组件领导制造供货商,宣布扩展其 PEC11J 增量式编码器产品系列,新增功能可提升装置的旋转寿命。设计人员现在可选择每 360° 旋转 24 脉冲的产品,并可选配无定位点选项。旋转脉冲
    发表于 06-10 14:56 1763次阅读
    Bourns 扩展增量式<b class='flag-5'>编码器</b>产品线,<b class='flag-5'>旋转</b>寿命功能再升级