用Arduino玩转掌控板(ESP32):蓝牙翻页笔(PPT 控制器)-程序员宅基地

技术标签: qt  arduino  物联网  蓝牙  单片机  

众所周知,掌控板在创客教育中用的非常广泛,它是一块基于 ESP32 的学习开发板。大家对掌控板编程,用的比较多的都是图形化编程的方式,比如 mPython、Mind+ 等。但是,既然掌控板是基于 ESP32 芯片的,所以我们也可以用 Arduino 软件对其编程。所以,有时间的话,我准备给大家分享一系列用 Arduino 代码对掌控板(ESP32)编程的教程:用 Arduino 玩转掌控板(ESP32)系列

本系列历史文章目录:

在前面几期中,有读者反馈,因为网络原因,在 Arduino 软件中配置 ESP32 和 ESP8266 开发环境,经常会失败。所以这次我给大家带来了已经配置好开发环境的 Arduino 绿色版软件,解压即用,可直达文末获取下载地址。

本期给大家带来的案例是:蓝牙翻页笔

先来看一下演示视频吧:

# 前言

关于翻页笔,其实我在之前就已经给大家分享过用好搭徽章板和 micro:bit 来实现翻页笔的案例,大家可以跳转下面的连接去查看:

萌宠体感翻页笔DIY教程

这次要设计的翻页笔,功能与之前做的类似,不同点在于:

  • 主控板采用了ESP32掌控板,而且只要一块板子就够了,不需要两块板子配合;

  • 程序采用了 Arduino 代码方式,当然在文末我也会提供图形化代码供参考;

  • 连接方式变成了 BLE 无线蓝牙,可以兼容 Mac、WIndows、iOS、Android 等。

下面开始进入正题。

# ESP32 蓝牙键盘库

编写蓝牙翻页笔程序之前,我们先来了解一下 ESP32-BLE-Keyboard 这个 Arduino 库。我们编写翻页笔程序主要是借助这个库来完成。这个库的功能,主要是将 ESP32 模拟成蓝牙键盘,然后向电脑发送按键命令,比如说我们翻页笔中会用到的:F5 按键(控制 PPT 开始播放)、ESC 按键(控制 PPT 退出播放)、还有上、下翻页按键 Page Up 和 Page Down(或者箭头 ← 和 →)。

使用这个库之前,首先我们要将这个库导入 Arduino 软件中,具体导入方法,这里不展开了,网上随便搜一下就有。

我们打开这个库的头文件 BleKeyboard.h,可以对这个库有一个大概的了解。这个库里面主要有以下几个功能模块:

## BleKeyboard 对象

BleKeyboard 用来声明蓝牙键盘对象,用在程序开头,用来初始化设定蓝牙键盘的名称 deviceName 、键盘生产厂商 deviceManufacturer、键盘电量 batteryLevel。当然你也可以不用设置,这个时候,程序就会用默认值来对键盘进行设置。

BleKeyboard(std::string deviceName = "ESP32 BLE Keyboard", std::string deviceManufacturer = "Espressif", uint8_t batteryLevel = 100);

## begin()  和 end() 函数

这两个函数的定义如下:

void begin(void);
void end(void);

主要是用来启动与结束键盘的。

## press() 函数

在头文件定义中,press() 函数有两个:

size_t press(uint8_t k);
size_t press(const MediaKeyReport k);

这两个 press() 函数,可以用来控制按下键盘上的所有按键,比如 0-9,A-Z,以及一些特殊的功能键等。

注意,这边我写的是按下键盘上的按键,表示并没有松开,这样的好处是,可以控制键盘发送一些组合键。

区别在于前一个是用来控制普通按键的,后一个是用来控制媒体键(MediaKey)的。什么是媒体键呢?比如说控制音乐播放的上一首、下一首、暂停、控制音量的加减等,这些都是媒体键。

实际上我们在使用时不用去区分,程序会根据我们输入的按键,自动去调用相应的函数。

比如我们要按下键盘上的 A 键,只要调用 press(‘a’) 就可以了;如果我们要按下键盘上的 Ctrl 按键,只要调用 press(KEY_LEFT_CTRL) 就可以了。普通按键,类似 A-Z 或者 0-9,我们只要正常输入就可以了,但是 Ctrl 这类特殊按键在程序中的对应名称是什么呢?在这个库的头文件 BleKeyboard.h中都有定义,读者可以自行去查看,这里由于篇幅原因不再赘述。

## release() 函数

release() 正好与 press() 函数相反,是用来控制松开键盘上的按键的,在定义中也有两个:

size_t release(uint8_t k);
size_t release(const MediaKeyReport k);

这两个函数的区别不再赘述,press() 函数和 release() 一般组合起来使用,可以用在需用使用组合键的场合,比如需要使用 Ctrl + C 按键时,可以先按下两个按键,再松开这两个按键。

## releaseAll() 函数

从名字就可以看出,是 release() 函数的加强版,可以一次性松开所有按键。比如我们同时按下 Ctrl + Alt + Delete 按键,可以通过 releaseAll() 函数,一次性松开 3 个按键。

## write() 函数

write() 函数可以简单理解为 press() 函数和 release() 函数的相加,也就是先按下按键,再松开按键,这个过程自动完成,适合用在发送单独按键的场合。

size_t write(uint8_t c);
size_t write(const MediaKeyReport c);
size_t write(const uint8_t *buffer, size_t size);

## isConnected() 函数

这个函数用来判断 ESP32 模拟的蓝牙键盘,是否与电脑已经配对连接。

## print() 函数

除了以上这些函数之外,还有一个 print() 函数,这个函数是继承自 Arduino 自带的库 Print 类的。

这个函数有什么用呢?试想一下,如果我们要一次性发送好几个按键,比如电脑上输入“Hello World!”这句话的时候,难道要调用好几次 write() 函数来把这句话发送完成么?其实不是的,只要通过 print("Hello World!") 这一句话就够了。

OK,有了这些讲解,模拟键盘控制电脑就很简单了,我们来看一下蓝牙翻页笔的程序怎么写吧。

# 翻页笔程序

## 完整程序

这里先把完整程序放上来:

## 引入头文件

我们现在程序开头引入了几个头文件,控制 OLED 显示屏的 U8g2lib 和 Wire 库,模拟键盘的 BleKeyboard 库:

#include <U8g2lib.h>
#include <Wire.h>
#include <BleKeyboard.h>

然后定义了一个键盘对象 bleKeyboard。这里设置键盘的名称为 mPython,键盘厂商为 Espressif,键盘电量为 95%。实际上这些设置都是随意的,主要是键盘名称,只要方便记忆就好了。

BleKeyboard bleKeyboard("mPython", "Espressif", 95);

接着定义了一个 OLED 屏对象 u8g2,OLED 屏幕的功能主要是提示我们控制 PPT 时按了哪个按键。这里需要根据你使用的 OLED 屏幕类型和连接方式来定义,先不展开讲,后面有时间再专门讲一讲屏幕显示的问题。掌控版自带的 OLED 屏是通过 I2C 连接,只要通过下面的语句定义即可。

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

## setup() 初始化

然后在 setup() 初始化中,初始化串口 Serial 方便后面可以打印调试信息;初始化 OLED 屏并进行相应的设置;初始化蓝牙键盘。

void setup() {
  Serial.begin(115200);


  // OLED 初始化
  u8g2.begin();
  u8g2.enableUTF8Print();
  u8g2.setFont(u8g2_font_wqy16_t_gb2312b);// 设置字体:宋体16号字
  u8g2.setFontPosTop();// 设置字体的定位点为左上角
  u8g2.clearDisplay();


  // 蓝牙键盘初始化
  Serial.println("Starting BLE Keyboard!");
  bleKeyboard.begin();
}

## loop() 主程序

在 loop() 循环中,通过 bleKeyboard.isConnected() 来判断我们的键盘有没有与电脑连接上了,如果没有连接,写在这里面的程序是不会执行的,只有在电脑上我们与这个蓝牙键盘配对连接之后,里面的程序才会执行。

void loop() {
  if (bleKeyboard.isConnected()) {
      // codes here...
  }
}

下面的程序,用来读取掌控版上的按键 A 和 B,以及触摸按键 P、Y、T、H、O、N 的值,通过读取他们的值,去判断按键有没有被按下触发。

// button A and B
int buttonA = !digitalRead(0);
int buttonB = !digitalRead(2);


// touchpad P Y T H O N
int touchpadP = touchRead(27);
int touchpadY = touchRead(14);
int touchpadT = touchRead(12);
int touchpadH = touchRead(13);
int touchpadO = touchRead(15);
int touchpadN = touchRead(4);

掌控板上的按键 A 和 B 是数字信号,而且默认情况下高电平信号,按下按键,通过 digitalRead() 函数会读取到低电平。所以前面加了个非(!),方便后面判断。

掌控板或 ESP32 自带了几个触摸按键,所以系统也自带了检测触摸按键的函数 touchRead() ,触摸按键读取的值是一个模拟量。

至于这几个按键的引脚编号为什么是这些呢?也就是 digitalRead() 和 touchRead() 函数里面的数字,为什么是这些呢?我们来看一下掌控板的引脚定义图。

掌控板引脚定义

先来看一下上图中的“引脚定义正面”这张图,我们看到触摸引脚 P 对饮的编号是 P23。再来看一下芯片引脚定义,P23 对应的芯片引脚是 IO27。在 Arduino 程序中,我们实际上编写的是芯片引脚,所以读取触摸引脚 P 的值时,我们在 touchRead() 函数中的数字是 27。其他几个触摸引脚对应的芯片引脚 IO 口,读者可以自己对应查一下。

读者也可以查询掌控板的官方文档,获取掌控板引脚定义:
https://mpython.readthedocs.io/zh/master/board/hardware.html
如果使用的是其他 ESP32 开发板的话,也可以查询相应的官方产品资料,获取对应的引脚编号。

然后通过判断按键 A 和 B 的值,控制 PPT 开始播放与结束播放。控制 PPT 播放,我们只要按 F5 键即可以,所以调用的程序是 bleKeyboard.write(KEY_F5);结束 PPT 播放,只要按 ESC 键即可以,所以调用的程序是bleKeyboard.write(KEY_ESC)。注意,由于是程序控制键盘,所以加了 delay(500) 程序,以防止按键按得太快。

// Start PPT
if (buttonA) {
  Serial.println("Button A pressed!");
  Serial.println("Sending key: F5 (start PPT");
  display("开始播放");


  bleKeyboard.write(KEY_F5);


  delay(500);
}


// Quit PPT
if (buttonB) {
  Serial.println("Button B pressed!");
  Serial.println("Sending key: ESC (quit PPT)");
  display("结束播放");


  bleKeyboard.write(KEY_ESC);


  delay(500);
}

里面的 display() 函数后面再讲,是用来控制掌控板的 OLED 显示屏上显示相应的提示语的,比如“开始播放”、“结束播放”等。

同样道理,我们可以通过检测触摸按键 P 和 N 的值,来控制 PPT 播放上一页和下一页,这里分别用 bleKeyboard.write(KEY_LEFT_ARROW)bleKeyboard.write(KEY_RIGHT_ARROW) 来控制。

// Previous page
if (touchpadP < 20 && touchpadP > 0) {
  Serial.println("Touchpad P touched!");
  Serial.println("Sending key: <-- (previous page)");
  display("上一页");


  bleKeyboard.write(KEY_LEFT_ARROW);


  delay(500);
}


// Next page
if (touchpadN < 20 && touchpadN > 0) {
  Serial.println("Touchpad N touched!");
  Serial.println("Sending key: --> (next page)");
  display("下一页");


  bleKeyboard.write(KEY_RIGHT_ARROW);


  delay(500);
}

至此,主程序也讲解完成了,逻辑是不是很简单,只要通过判断掌控板上哪个按键被按下了,模拟键盘触发相应的按键行为就好了。

## display() 函数

在程序中,我们还定义了另外一个函数 display(String tipsOnScreen),它的功能是根据掌控板上的按键,用来控制 OLED 显示相应的内容的,直接看代码就行。

void display(String tipsOnScreen) 
{
  u8g2.firstPage();
  do 
  {
   u8g2.clearDisplay();
   u8g2.setCursor(32, 24);
   u8g2.print(tipsOnScreen);
  } while (u8g2.nextPage());
}

至此,程序讲解完成,上传到掌控板即可。

# 连接蓝牙

上面我们通过编写程序已经将掌控板模拟成了蓝牙键盘,接下来只要与电脑进行配对,就可以愉快的使用啦。

这里我以 Windows 10 系统为例,其他系统类似。首先打开电脑的设置,找到添加蓝牙设备页面,点击最上面的“+”号,准备添加蓝牙设备。

打开蓝牙设置

选择“蓝牙”,开始搜寻电脑附近的蓝牙设备。

添加蓝牙设备

这个时候就会出现一个名称为“mPython”的蓝牙设备,“mPython”是我们在程序中给掌控板起的名字,这个边上有一个键盘的图标,说明掌控板已经被电脑识别为蓝牙键盘了,选择它与电脑进行配对连接即可。

选择蓝牙设备

连接成功后,我们就可以在蓝牙设置页面看到刚刚添加的蓝牙键盘“mPython”了,再看一看它的电量,95%,跟程序里设置的一模一样!

添加成功

这个时候,你就可以在电脑中打开一个 PPT,试试看你的翻页笔好不好使了~

# 彩蛋

看到这里的朋友,为了感谢你,所以特意留了一个彩蛋。

相信好多朋友看到代码就头大,所以我给大家做了一个蓝牙键盘的图形库,大家只要打开 Mind+ 软件 v1.6.2 及以上的版本,在用户库中加入我的蓝牙键盘库,就可以开始蓝牙键盘编程之旅啦。

蓝牙键盘库直达网址:

https://gitee.com/ironpanda/ext-BLEKeyboard

这上面有这个蓝牙键盘库的使用教程和简单案例。

将上述网址添加到 Mind+ 软件用户库中,如下图所示:

导入蓝牙键盘库

导入完成后,就可以在“用户库”分类中看到蓝牙键盘库相应的编程模块了。

蓝牙键盘库

本文对应的蓝牙键盘 Mind+ 图形程序如下:

蓝牙翻页笔Mind+程序

是不是很简单?你会了么?学会了的话,就点个“在看”吧~

# 代码下载

欢迎关注公众号:铁熊玩创客,不定期更新创客制作、技术教程、创客教育等相关内容。

  • 回复“蓝牙翻页笔”获取完整代码,包含 Arduino C 语言代码和 Mind+ 图形代码;

  • 回复“Arduino”获取绿色版 Arduino 软件下载地址,已为您配置好掌控板 ESP32 和 ESP8266 开发环境


*欢迎转发朋友圈。如需转载,请注明出处和原作者。

往期精彩内容

创客项目缺少高颜值电路图?看这里就对了

小白也能学会的激光切割创意盒子设计方法

还在羡慕大疆 S1?教你自制麦轮战车

萌宠Pando机器人,不但能卖萌,还能跳太空步

学生获奖作品:戒烟帽

学生获奖作品:体感转向安全帽

掌控+Mixly+Blynk,让你的麦轮战甲嗨炸全场

搞定掌控板Siri语音控制,只要半小时

我知道你在看

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ironpandaaa/article/details/118081139

智能推荐

SVM简单非线性分类,画出分类面与支持向量(MATLAB)-程序员宅基地

文章浏览阅读7.1k次,点赞11次,收藏73次。创造两类二维非线性可分点,使用SVM进行分类,同时画出支持向量和分类面,其实在二维的情况下就是个分界线,这个分类面并不是高维的,因为SVM的映射是个黑箱,画不出高维映射后的分类面。代码中调用了台湾大学林智仁教授的libsvm包,因为怕与MATLAB自带的SVM函数名重了,所以改成了libsvmtrain和libsvmpredict。libsvm 3.22版本的包可以到这里去下载解压后...

Yii2.0 游客访问限制_yii 未登录限制-程序员宅基地

文章浏览阅读1.7k次。最近在用Yii2.0做项目,其中需要实现一个功能:没有登录不能访问部分页面,即游客身份访问限制。查了半天资料,终于找到答案。解决方法如下: 在access里,access即访问的意思,其中有个配置项 ‘only’=>['login','about'] 这是什么意思呢,意思是仅仅在login、about两个action内起作用,即当action 是login、about_yii 未登录限制

EfficientNet迁移学习(一) —— 主程序(train.py)_python 预训练efficientnet迁移学习-程序员宅基地

文章浏览阅读801次。项目背景EfficientNet系列博客与ResNet迁移学习的目标一致,均是进行二分类的迁移学习,唯一差别在于网络结构的不同。其它相关的内容,参考下面链接:ResNet迁移学习(一)—— 主程序结构,部分内容如下图所示:代码框架下面我们主要介绍train.py的程序框架和功能模块接口。程序框架是构建工程的首要步骤,而功能模块是完善框架的内容。这样在构建工程的时候,思路会比较清晰,不至于无从下手。..._python 预训练efficientnet迁移学习

excel部分网格线不见了_EXCEL-绘制箱形图-程序员宅基地

文章浏览阅读473次。特征统计可能是数据科学中最常用的统计学概念。它是你在研究数据集时经常使用的统计技术,包括偏差、方差、平均值、中位数、百分数等等。中间的直线表示数据的中位数。中位数用在平均值上,因为它对异常值更具有鲁棒性。第一个四分位数本质上是第二十五百分位数,即数据中的25%要低于该值。第三个四分位数是第七十五百分位数,即数据中的75%要低于该值。而最大值和最小值表示该数据范围的上下两端。箱形图很好地说明了基本统..._箱形图不显示中线怎么回事

SDE安装 esri_sde service failed during initialization._esri_sde service failde during initialization-程序员宅基地

文章浏览阅读2.5k次。原因:该错误出现在ArcSDE不正确或不完整的安装或配置。解决方法:确保输入正确的SDE用户密码,如果密码不正确,会在sde.errlog文件出现一个“-93”错误。确保完全的删除当前的SDE服务,建立一个新的SDE服务。1:利用SDE命令“sdeservice –o delet_esri_sde service failde during initialization

AI与RAG的融合:信息检索与生成的重大创新-程序员宅基地

文章浏览阅读938次,点赞16次,收藏9次。通过实时检索最新的、准确的信息,RAG系统能够提供更可靠和权威的回答,增强了用户对AI系统的信任。这种融合不仅提升了现有技术的性能,还开辟了新的研究方向和应用场景,预示着一个更智能、高效和个性化的信息时代的到来。最新的深度学习技术,如基于Transformer架构的模型,已经取得了显著进展,使得RAG系统能够利用上下文信息快速检索到最相关的信息,为用户提供精准的信息服务。RAG技术促进了定制化解决方案的发展,通过针对特定行业或领域的数据进行训练和优化,RAG系统能够提供更专业化的服务。

随便推点

AdpterView和Adapter接口以及实现的子类_adapterview常用接口-程序员宅基地

文章浏览阅读827次。四种为AdapterView填充Adapter的方法实现Adapter或者他子接口用Adapter接口的实现子类SimapleAdapter在xml文件中指定entries属性让当前Activity继承ListActivity使用SimpleAdapter创建ListViewpackage com.phone.hty.myapplication;import android.os.Bundl_adapterview常用接口

VC随笔文档视图结构_单文档应用程序的框架窗口是唯一的主框架窗口,它的窗口类是cmain-程序员宅基地

文章浏览阅读692次。VC随笔文档视图结构使用断点调试观察MFC应用程序框架的创建过程:由于一个对象被创建时会自动调用构造函数,而一个窗口被创建时会调用OnCreate函数,因此在下列地方设置断点:1、应用程序类、文档类、框架窗口类、视图类的构造函数开始处(函数开始大括号所在行)2、CMy2DCADApp::InitInstance函数开始处、添加文档模板处、结尾处(函数结束大括号所在行)3、CMa_单文档应用程序的框架窗口是唯一的主框架窗口,它的窗口类是cmain

threejs 管子_threejs 3d 智能园区-程序员宅基地

文章浏览阅读930次。一、页面效果二、技术选择中间的建筑相关的显示和效果都是threejs实现的左右两侧用的是echarts三、代码结构1. 画布用js自己创建一个放置画布的divcontainer = document.createElement(‘div‘)document.body.appendChild(container)2. 场景的创建之后的比如几何体 摄像机 光源都是放在场景里面scene = newTH..._threejs 直角管道

计算机毕设基于springboot+MySQL的公选课在线选课系统vue-程序员宅基地

文章浏览阅读9次。spring boot+MySQL公选课在线选课系统》该项目含有源码、文档等资料、配套开发软件、软件安装教程、项目发布教程等。开发工具:IDEA(2020版)/MyEclipse(10)/Eclipse、Visual Studio Code。系统功能完整,适合作为毕业设计、课程设计、数据库大作业 参考 以及学习商用皆可。操作系统:Windows 10、Windows 7、Windows 8。前端技术:JavaScript、VUE.js(2.X)、css3。数据库:MySQL 5.7.26(版本号)

NumPy入门讲座(1):基本概念_numpy数据相关概念-程序员宅基地

文章浏览阅读1.2w次,点赞20次,收藏37次。NumPy 是 Python 科学计算的基础软件包,提供多了维数组对象,多种派生对象(掩码数组、矩阵等)以及用于快速操作数组的函数及 API,它包括数学、逻辑、数组形状变换、排序、选择、I/O 、离散傅立叶变换、基本线性代数、基本统计运算、随机模拟等等。_numpy数据相关概念

VS创建C/C++项目_vs怎么创建c++项目-程序员宅基地

文章浏览阅读449次。示例工具 VS20171.打开VS 新建项目文件-新建-项目 或者点击如下新建项目也可以2.选择新建项目类型如果是VS13 选择win32控制台应用程序 如果是VS17选择桌面向导其中项目名和解决方案名字都可以修改项目名 单个项目(一个项..._vs怎么创建c++项目