TL;DR
在EFR32MG24上,使用CircuitPython 的BLE库方法,模拟无线蓝牙键盘和鼠标的项目
项目介绍
本期为大家带来芯科EFR32MG24开发套件和CircuitPython组合实现一个蓝牙键盘的项目。
这个项目也是Funpack,第三季第一期个任务Funpack活动是硬核学堂联合得捷发起活动,第三季第一期板卡来自芯科XG24-EK2703A板卡。
参考连接:https://www.eetree.cn/page/digikey-funpack/phase19
自我介绍
关于自我介绍部分,我是一个MicroPython和CircuitPython的爱好者,喜欢学习和了解不同的开发板,对于此次活动。我选择的是任务二,
B站:disk0,欢迎直通道和的朋友一起学习进步
本次任务,我选择的是任务二,具体内容是对蓝牙功能进行开发,实现一个蓝牙鼠标复合设备,利用开发板的两个按键然后实现。模拟板牙鼠标和蓝牙键盘的功能。
WHY?
首先,讨论一下为什么选择了蓝牙任务。
因为在以往的无论是学习还是工作当中。较多的接触是Wi-Fi无线连接,对于蓝牙连接是第一次尝试。可以说是一个新的领域,
然后第二个为什么选择这个开发板。
熟悉我的朋友都知道,之前我会集中于乐鑫开发板。主要原因是:
- 这一次是芯科带来新的厂商,可以了解不同的品牌,
- 此外,这个开发板的芯片是ARM Cortex-M3架构。和之前接触的乐鑫相比也是不同的。
- 最后一点。他被这个CircuitPython官方支持,也为我入手这个项目带来一些便利,
硬件部分
简单介绍一下这块开花板。具体的参数我就不就一一和大家介绍了。开发板会有两个制定按钮然后,两个led灯然后也使用了Type C作为外部供电和调试接口。
此外,这上面也有对于我来说是比较新的接口,比如在右上角qwric这个接口也是我第一次接触。
软件&逻辑
关于这个任务的硬逻辑是相对简单,在代码编写完成后,启动开发板开启蓝牙。然后在电脑端寻找并连接蓝牙。配对完之后。使用板载的两个按键模拟我们日常中的蓝牙鼠标和键盘。
关于设计思路。
第一步和第二步都是对硬件插板进行出手化设置。我使用的开发环境是windows11需要在官网下载。对应了驱动接另一个大windows这个驱动第二步。在安装完驱动之后,官方也提供一个免安装的烧录软件。这个值得点赞!
对于我们嵌入式开发者/爱好者来说,点灯程序相当于开发板的Hello World,然后我就会以这为基础来构建蓝牙键盘的主要功能。主要依赖于adafruit_ble和adafruit_hid两个仓库,在点灯的代码上加入蓝牙连接和鼠标键盘的动作。
软件清单:
第一个就是接link的驱动。第二个提供的commander收录工具,第三个比较特殊的。是CircuitPython的特定固件,我使用的是9.0.0-beta.1 版本(重点),最后一个是我们的老朋友 Thonny IDE。
实施步骤
- 烧录
烧录CircuitPython相对简单。打开烧录软件,在右上角选择你的开发板。然后我们可以首先在Device Info这个栏目下,查看一下我们的硬件信息确保正确识别。
在第三个Flsh模块下,首先擦除已有的部件信息。然后第二步选择正确的固件文件。第三步,点击flash就可以刷入了这个项目。
相对于之前接触的开发板来说,烧入速度还是蛮快的,
代码:
根据代码讲解一下主要功能的实现,第一步就是点灯模块。
import board
import digitalio
import time
def init_gpio(pin,mode):
dio = digitalio.DigitalInOut(pin)
if mode == "input":
dio.switch_to_input(pull=digitalio.Pull.UP)
elif mode == "output":
dio.switch_to_output()
return dio
# 初始化 按钮和LED
btn0 = init_gpio(board.BTN0,"input")
btn1 = init_gpio(board.BNT1,"input")
led0 = init_gpio(board.LED0,"output")
led1 = init_gpio(board.LED1,"output")
while True:
if not btn0.value:
led0.value = not led0.value
if not btn1.value: # 按下BTN1
led1.value = not led1.value
# 简单去抖动
time.sleep(0.3)
头部引用了board/ digitalio还有time。然后在第6行到第14行。我定义了一个GPIO的初始化函数,方便初始化按钮和LED。最后在大循环当中。把两组按钮和LED相互绑定。最后在循环中获取按钮状态来改变对应的LED。细心的朋友会发现17行和18行关于BTN0和BNT1名字有所不同,这个也就是官方的一个"彩蛋",他正确写法就是这样。
无线蓝牙键鼠
import time
import board
from digitalio import DigitalInOut, Direction, Pull
from adafruit_ble import BLERadio
from adafruit_ble.advertising import Advertisement
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.standard.hid import HIDService
from adafruit_ble.services.standard.device_info import DeviceInfoService
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from adafruit_hid.mouse import Mouse
def init_gpio(pin,mode):
dio = DigitalInOut(pin)
if mode == "input":
dio.switch_to_input(pull=Pull.UP)
elif mode == "output":
dio.switch_to_output()
return dio
btn0 = init_gpio(board.BTN0,"input")
btn1 = init_gpio(board.BNT1,"input")
led0 = init_gpio(board.LED0,"output")
led1 = init_gpio(board.LED1,"output")
# BLE
hid = HIDService()
advertisement = ProvideServicesAdvertisement(hid)
advertisement.appearance = 961
scan_response = Advertisement()
scan_response.complete_name = "EFR32MG24 CircuitPython HID"
ble = BLERadio()
if not ble.connected:
print("蓝牙开启【广播模式】")
ble.start_advertising(advertisement, scan_response)
else:
print("蓝牙已连接!")
print(ble.connections)
# KEYBOARD
k = Keyboard(hid.devices)
kl = KeyboardLayoutUS(k)
# MOUSE
mouse = Mouse(hid.devices)
print("等待连接...")
while not ble.connected:
pass
print("蓝牙已连接!")
while True:
while ble.connected:
if not btn0.value and btn1.value: # 按下BTN0
led0.value = not led0.value #切换LED状态
mouse.move(wheel=-1)
print('滚轮向下')
time.sleep(0.2)
if not btn1.value and btn0.value: # 按下BTN1
led1.value = not led1.value
mouse.move(wheel=1)
print('滚轮向上')
time.sleep(0.2)
if not btn1.value and not btn0.value:
print('双键同时按下')
time.sleep(2) # 延时 2 秒
if not btn1.value and not btn0.value:
print('已按足2秒')
for i in "EETREE.CN":
kl.write(i)
time.sleep(0.3)
time.sleep(0.3)
第二步。我们这里面主要引入的是adafruit_ble和adafruit_hid,其中adafruit_hid模块,我们会使用keyboard的和mouse。接下来,从33行起开始,初始化BLE/kboard还有鼠标,在76行到79行我们会一直等待电脑连接。在大循环部分,主要逻辑和判断条件和我们的点灯程序是一致的。
因为我们会有一个双键同时按下的判断条件。所以我们在前面的基础上会判定:只有其中一个按键按下另外一个按键没有被按下(状态没有改变)的时候,我们才会对应鼠标的滚动;当两个按键同时按下而且持续时间(我用一个他们sleep来判定),然后继续进入下一个判定,使用键盘模拟输出特定字符。
实际展示环节:
参考视频部分。
总结:
对于我个人感受来说优点有四点,
第一个,相较于我之前接触较多的乐鑫卡板来说,它会有更完备的BLE支持在实现项目中。我学习的新的知识。
第二点,体积相对小巧。接口丰富,让我印象比较深刻的是开发板做工良好,烧入速度也非常优秀,
第三是,CircuitPython的支持。当然,开发板也支持其他开发语言。
第四点,较为易用的驱动和烧录工具(免安装,速度快)。节省了我很多的开发时间。
当然事情不会总是很完美。在这块开发板上CircuitPython支持目前还有待提升。此外,只提供蓝牙一种无线连接方式,如果能加上Wi-Fi。会让个开发板的如虎添翼,第三点可能因人而异,性价比方面还算不上特别的优秀(相比友商来说)
再次感谢电子森林和得捷电子,以及微信群里的各位小伙伴。谢谢和大家一起积极帮助和相互学习。
以上