Arduino提高篇15—摇杆操作OLED多级菜单

摇杆操作OLED多级菜单

随着越来越多的人机交互需求,带有屏幕的嵌入式设备需要展示的信息也越来越多,多种菜单随着按键输入进行各种深入、各种切换操作。如何方便的管理不同菜单之间的切换操作呢?本篇通过实验来介绍多级菜单的实现思路。

1. 多级菜单介绍

在各种屏幕操作中,多级菜单其实是一种思路或者说是一种固定的编程框架。简单来说就是当按键触发时,根据按键定义从数组中取出当前按键需要跳转的界面索引,然后根据索引去执行响应的界面函数。

2. 具体实现

1. 首先,我们要定义一个结构体,结构体成员变量一般包括界面索引号、界面函数指针和与实际按键对应的变量,用来存储按键表示的索引号。其中,索引号与界面函数指针是对应的。

typedef struct
{
  unsigned char index;
  unsigned char up;
  unsigned char down;
  unsigned char left;
  unsigned char right;
  void (*operation)(void);
} KEY_TABLE;

本实验中定义了四个按键,故定义了up、down、left、right四个按键变量。

2. 使用定义的结构体类型来定义一个结构体数组,有多少个界面,数组的元素个数就是多少。

KEY_TABLE table[9] =
{
  {0, 0, 0, 0, 0, (*menu11)},
  {1, 0, 0, 0, 0, (*menu12)},
  {2, 0, 0, 0, 0, (*menu21)},
  {3, 0, 0, 0, 0, (*menu22)},
  {4, 0, 0, 0, 0, (*menu23)},
  {5, 0, 0, 0, 0, (*menu31)},
  {6, 0, 0, 0, 0, (*menu32)},
  {7, 0, 0, 0, 0, (*menu33)},
  {8, 0, 0, 0, 0, (*menu34)},
};

本实验中定义了9个界面,所以如上数组元素有9个,其中界面索引号从0到8,分别对应其界面函数指针。本实验中一级菜单有2个,二级菜单有3个,三级菜单有4个。

3. 确定各按键按下需要跳转的界面索引。这一步骤确定了各界面之间的切换关系,非常重要。在此之前可以通过草图来整理菜单之间切换关系,如下所示为本实验9个界面之间的关联图。

多级菜单结构

举几个例子:

在index为0,即menu11界面下,确定{0, 0, 0, 0, 0, (*menu11)}中四个按键变量的值:

  • 当按下up键时,显示menu11界面,即index为0的界面,那么此时up=0;
  • 当按下down键时,显示menu12界面,即index为1的界面,那么此时down=1;
  • 当按下left键时,显示menu11界面,即index为0的界面,那么此时down=0;
  • 当按下right键时,显示menu21界面,即index为2的界面,那么此时down=2;

故得到{0, 0, 1, 0, 2, (*menu11)}

在index为5,即menu31界面下,确定{5, 0, 0, 0, 0, (*menu31)}中四个按键变量的值:

  • 当按下up键时,显示menu31界面,即index为5的界面,那么此时up=5;
  • 当按下down键时,显示menu32界面,即index为6的界面,那么此时down=6;
  • 当按下left键时,显示menu21界面,即index为2的界面,那么此时down=2;
  • 当按下right键时,显示menu31界面,即index为5的界面,那么此时down=5;

故得到{5, 5, 6, 2, 5, (*menu31)}

各个界面之间的跳转关系根据实际的需求进行确立,如下为本实验中完整的结构体数组变量赋值情况。

KEY_TABLE table[9] =
{
  {0, 0, 1, 0, 2, (*menu11)},
  {1, 0, 1, 1, 4, (*menu12)},
  {2, 2, 3, 0, 5, (*menu21)},
  {3, 2, 3, 0, 7, (*menu22)},
  {4, 4, 4, 1, 4, (*menu23)},
  {5, 5, 6, 2, 5, (*menu31)},
  {6, 5, 6, 2, 6, (*menu32)},
  {7, 7, 8, 3, 7, (*menu33)},
  {8, 7, 8, 3, 8, (*menu34)},
};

4. 根据实际按键返回值对应的功能,获取按键对应的界面索引号,然后根据索引号找到并执行对应的界面函数。

switch (keyValue)//获取按键对应序号
    {
      case 1: funIndex = table[funIndex].right; break;
      case 2: funIndex = table[funIndex].left; break;
      case 3: funIndex = table[funIndex].down; break;
      case 4: funIndex = table[funIndex].up; break;
    }
current = table[funIndex].operation;//根据需要获取对应需要执行的函数
(*current)();//执行获取到的函数

3. 实验材料

  • Uno R3开发板
  • 配套USB数据线
  • 面包板及配套连接线
  • 双轴按键摇杆模块
  • OLED显示屏

4. 实验步骤

1. 根据原理图搭建电路图。

OLED屏的VCC、GND分别连接开发板的3.3V、GND,OLED屏的SDA和SCL分别连接开发板的A4和A5。双轴按键摇杆模块的VCC、GND分别连接开发板的5V、GND,模块的X轴输出、Y轴输出分别连接开发板的模拟引脚A0、A1。

实验原理图如下图所示:

实验原理图

实物连接图如下图所示:

实物连接图

2. 新建sketch,拷贝代码替换自动生成的代码并进行保存。

由于代码较长,完整代码可在文末获取。

3. 连接开发板,设置好对应端口号和开发板类型,进行程序下载。

程序下载

5. 实验现象

多界面切换效果:

实验现象


关注公众号「TonyCode」,后台回复“提高”,获取文中代码。
Arduino学习交流群:868283450
更多内容,欢迎关注我的公众号。 微信扫一扫下方二维码即可关注:
扫码加入微信公众号:TonyCode

  • 23
    点赞
  • 175
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
以下是手势识别的Arduino代码,使用了OLED显示屏: ``` #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <SparkFun_APDS9960.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET 4 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); SparkFun_APDS9960 apds; void setup() { Serial.begin(9600); if (!apds.init()) { Serial.println("Failed to initialize APDS-9960 sensor."); } apds.enableGestureSensor(true); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.display(); } void loop() { if (apds.isGestureAvailable()) { switch (apds.readGesture()) { case DIR_UP: display.clearDisplay(); display.setCursor(0, 0); display.println("UP"); display.display(); break; case DIR_DOWN: display.clearDisplay(); display.setCursor(0, 0); display.println("DOWN"); display.display(); break; case DIR_LEFT: display.clearDisplay(); display.setCursor(0, 0); display.println("LEFT"); display.display(); break; case DIR_RIGHT: display.clearDisplay(); display.setCursor(0, 0); display.println("RIGHT"); display.display(); break; case DIR_NEAR: display.clearDisplay(); display.setCursor(0, 0); display.println("NEAR"); display.display(); break; case DIR_FAR: display.clearDisplay(); display.setCursor(0, 0); display.println("FAR"); display.display(); break; default: break; } } } ``` 这个代码使用了SparkFun的APDS9960手势传感器来检测手势,并使用Adafruit的SSD1306 OLED显示屏来显示检测到的手势。在setup()函数中,初始化了传感器和显示屏。在loop()函数中,检测手势并根据手势在显示屏上显示相应的方向。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值