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

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

    关注

    41

    文章

    3360

    浏览量

    131481
  • Arduino
    +关注

    关注

    184

    文章

    6427

    浏览量

    184826
收藏 人收藏

    评论

    相关推荐

    差分编码器信号如何接plc

    差分编码器信号通常用于测量旋转运动或线性位置,接收差分编码器信号的PLC(可编程逻辑控制器)需要进行相应的信号处理才能正确读取并理解编码器
    的头像 发表于 02-26 14:43 761次阅读

    如何将增量旋转编码器Arduino连接

    在本教程中,您将学习如何将增量旋转编码器Arduino连接,以读取旋钮的运动。这对于在机器人和其他应用程序中创建用户界面或读取机械位置非常有用。
    的头像 发表于 02-11 10:00 387次阅读
    如何将增量<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>与<b class='flag-5'>Arduino</b>连接

    旋转编码器的工作原理,旋转编码器的作用功能及应用

    旋转编码器用于测量轴或轴旋转的组件。它们通常用于音频设备、DIY 游戏控制器中的音量旋钮,或用作不同
    的头像 发表于 02-11 09:53 1186次阅读
    <b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>的工作原理,<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>的作用功能及应用

    编码器与PLC的接线方法

    编码器分为旋转编码器和线性编码器两种。旋转编码器用于检测旋转
    发表于 12-22 09:20 458次阅读
    <b class='flag-5'>编码器</b>与PLC的接线方法

    旋转编码器能直接换吗_旋转编码器更换注意事项

    旋转编码器更换步骤第一步,卸开电机后盖,编码器的后盖。第二步,松开编码器安装螺丝。第三步,旋转电机转子轴,使
    的头像 发表于 11-12 08:07 841次阅读
    <b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>能直接换吗_<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>更换注意事项

    iC-Haus在旋转、直线编码器及磁栅尺有何应用?

    旋转、直线编码器及磁栅尺中得到广泛应用的两款产品:“磁性传感器”及“插补细分器”。
    的头像 发表于 10-12 18:17 575次阅读

    全志R128应用开发案例—中断方式驱动旋转编码器

    旋转编码器是一种位置传感器,可将旋钮的角位置(旋转)转换为用于确定旋钮旋转方向的输出信号。
    发表于 10-12 16:56 363次阅读
    全志R128应用开发案例—中断方式驱动<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>

    旋转编码器如何工作?如何与Arduino-HowToMechanicronics一起使用?

    包含详细说明+代码在本教程中,我们将学习旋转编码器的怎样工作的,以及如何使它与Arduino配合使用。旋转编码器是一种位置传感
    发表于 09-26 07:52

    编码器是什么?编码器有哪些分类?

    一种将角位移或者角速度转换成一连串电数字脉冲的旋转式传感器,我们可以通过编码器测量到位移或者速度信息。编码器通常由一个旋转部分和一个固定部分组成,
    的头像 发表于 08-21 11:50 5803次阅读
    <b class='flag-5'>编码器</b>是什么?<b class='flag-5'>编码器</b>有哪些分类?

    增量式编码器和绝对值编码器有哪些区别?

    增量式编码器和绝对值编码器有哪些区别?增量式编码器通过对变化量进行计数来测量位置变化,而绝对值编码器可提供实际位置值。因此,增量式编码器对于
    的头像 发表于 07-05 13:34 2582次阅读
    增量式<b class='flag-5'>编码器</b>和绝对值<b class='flag-5'>编码器</b>有哪些区别?

    伺服电机编码器

    伺服电机编码器 伺服电机编码器是安装在伺服电机上用来测量磁极位置和伺服电机转角及转速的一种传感器,从物理介质的不同来分,伺服电机编码器可以分为光电编码器和磁电
    发表于 06-26 14:01 986次阅读

    什么是旋转编码器 旋转编码器的工作原理

    旋转编码器是一种常见的传感器,它能够通过检测旋转轴的转动实现实时位置监测与控制。它具有高精度、长寿命、可重复性高、体积小等特点,因此在机器人控制、自动化生产、医疗设备、轮廓检测等方面被广泛应用。
    发表于 06-09 10:16 1735次阅读
    什么是<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b> <b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>的工作原理

    旋转编码器是什么?浅读旋转编码器工作原理与特点及应用

    旋转编码器是什么?浅读旋转编码器工作原理与特点及应用:旋转编码器是一种常见的传感器,它能够通过检
    的头像 发表于 05-29 09:21 2246次阅读
    <b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>是什么?浅读<b class='flag-5'>旋转</b><b class='flag-5'>编码器</b>工作原理与特点及应用

    编码器种类及型号

    编码器种类及型号:最常见的编码器类型是旋转编码器和线性编码器旋转
    的头像 发表于 05-18 11:15 3778次阅读
    <b class='flag-5'>编码器</b>种类及型号

    NodeMCU是否可以使用旋转编码器进行这种菜单滚动?

    我是 NodeMCU 硬件的新手,我想知道是否可以使用旋转编码器进行这种菜单滚动v=3OGU- fXRD1E I没有找到任何示例,只有没有交互的纯显示。
    发表于 05-04 06:00