一、目的
这一节我们学习如何使用我们的ESP32开发板来实现通过蓝牙控制接在ESP32开发板上的舵机。
二、环境
ESP32 + MG90S舵机 + Thonny IDE + 几根杜邦线 + 手机
舵机的链接方法见第54节:物联网开发笔记(54)- 使用Micropython开发ESP32开发板之控制MG90S舵机_魔都飘雪的博客-CSDN博客
三、手机APP
这里用到的手机APP是BluefruitConnect,使用苹果手机的同学打架早Apple Store中直接搜索安装即可。安卓暂时我没找到这个APP,哪位同学有的可以评论区留言哈。。。
BluefruitConnect APP的图标是这个样子:
安卓的同学我们使用:BLE调试助手:
几款常用的ble调试app(nRF Connect、BLE调试助手、LightBlue) - 知乎
四、代码
from machine import Pin
from machine import Timer # 导入定时器
from time import sleep_ms
from machine import PWM # 导入PWM
import time
import bluetooth # 导入蓝牙
BLE_MSG = "" # 定义一个变量来接收蓝牙发送来的数据
# 创建一个蓝牙类
class ESP32_BLE():
def __init__(self, name): # 蓝牙类的初始化
self.led = Pin(2, Pin.OUT) # 创建LED对象
self.timer1 = Timer(0) # 使用0号定时器,ESP32共有4个定时器0,1,2,3
self.name = name # 传入蓝牙名字
self.ble = bluetooth.BLE() # 创建蓝牙对象
self.ble.active(True) # 打开蓝牙
self.ble.config(gap_name=name) # 设置蓝牙的名字
self.disconnected() # 断开蓝牙连接
self.ble.irq(self.ble_irq) # 蓝牙中断
self.register() # 蓝牙注册
self.advertiser()
def connected(self):
self.led.value(1)
self.timer1.deinit()
def disconnected(self):
self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.value(not self.led.value()))
def ble_irq(self, event, data):
global BLE_MSG
if event == 1: #_IRQ_CENTRAL_CONNECT 手机链接了此设备
self.connected()
elif event == 2: #_IRQ_CENTRAL_DISCONNECT 手机断开此设备
self.advertiser()
self.disconnected()
elif event == 3: #_IRQ_GATTS_WRITE 手机发送了数据
buffer = self.ble.gatts_read(self.rx)
BLE_MSG = buffer.decode('UTF-8').strip()
def register(self):
service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
services = (
(
bluetooth.UUID(service_uuid),
(
(bluetooth.UUID(sender_uuid), bluetooth.FLAG_NOTIFY),
(bluetooth.UUID(reader_uuid), bluetooth.FLAG_WRITE),
)
),
)
((self.tx, self.rx,), ) = self.ble.gatts_register_services(services)
def send(self, data):
self.ble.gatts_notify(0, self.tx, data + '\n')
def advertiser(self):
name = bytes(self.name, 'UTF-8')
adv_data = bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name
self.ble.gap_advertise(100, adv_data)
print(adv_data)
print("\r\n")
# 创建BOOT按键中断执行函数
def buttons_irq(pin):
led.value(not led.value()) # 翻转LED灯的状态
print('LED is ON.' if led.value() else 'LED is OFF') # 打印LED的状态
ble.send('LED is ON.' if led.value() else 'LED is OFF') # 发送LED的状态给手机
if __name__ == "__main__":
ble = ESP32_BLE("ESP32BLE") # 定义蓝牙的名字为ESP32BLE
# 检测boot按键
but = Pin(0, Pin.IN) # 创建BOOT按键对象,GPIO脚为0
# 创建BOOT按键的中断,中断出发模式设置为下降沿触发,触发对象为buttons_irq
but.irq(trigger=Pin.IRQ_FALLING, handler=buttons_irq)
# 控制蓝色led
led = Pin(2, Pin.OUT) # 创建LED对象
# 控制舵机
p15 = PWM(Pin(15)) # 创建舵机对象
p15.freq(50) # PWM的频率为59HZ
duty_num = 1638 # 定义一个变量,设置舵机的角度为0度
p15.duty_u16(1638)
# 0度 p15.duty_u16(1638)
# 45度 p15.duty_u16(3276)
# 90度 p15.duty_u16(4915)
# 135度 p15.duty_u16(6553)
# 180度 p15.duty_u16(8192)
# 下面ESP32按照蓝牙接收到的数据进行判断,执行响应的动作
while True:
if BLE_MSG == 'read_LED':
print(BLE_MSG) # 打印接收到的信息
BLE_MSG = ""
print('LED is ON.' if led.value() else 'LED is OFF')
ble.send('LED is ON.' if led.value() else 'LED is OFF')
elif BLE_MSG:
print("接收到的信息:>>%s<<" % BLE_MSG) # 打印接收到的信息
if BLE_MSG == "!B11:": # 按下app上数字1
duty_num += 100
if duty_num > 8192:
duty_num = 8192
print(duty_num)
p15.duty_u16(duty_num)
elif BLE_MSG == "!B219": # 按下app上数字2
duty_num -= 100
if duty_num < 1638:
duty_num = 1638
print(duty_num)
p15.duty_u16(duty_num)
elif BLE_MSG == "!B318": # 按下app上数字3
duty_num += 300
if duty_num > 8192:
duty_num = 8192
print(duty_num)
p15.duty_u16(duty_num)
elif BLE_MSG == "!B417": # 按下app上数字4
duty_num -= 300
if duty_num < 1638:
duty_num = 1638
print(duty_num)
p15.duty_u16(duty_num)
elif BLE_MSG == "!B516": # 按下app上up键
p15.duty_u16(4915) # 90度
duty_num = 4915
elif BLE_MSG == "!B615": # 按下app上down键
p15.duty_u16(3276) # 45度
duty_num = 3276
elif BLE_MSG == "!B714": # 按下app上left键
p15.duty_u16(8192) # 180度
duty_num = 8192
elif BLE_MSG == "!B813": # 按下app上right键
p15.duty_u16(1638) # 0度
duty_num = 1638
BLE_MSG = ""
sleep_ms(100)
'''
此处,讲解一下手机蓝牙发送的按键的指令,针对苹果手机APP:
按钮1,2,3,4,上,下,左,右分别对应指令的第三位“!Bxxx”
z指令!Bxxx,前两位是固定格式,第三位是按钮的ID,按钮1到4的ID就是1到4. 按钮上下左右对应的ID是5到8.
比如:按钮5对应的指令就是!B5xx。指令的第四为指的是按钮是按下还是释放,按下是1,释放是0.
'''
五、苹果手机APP操作
大家下载完成后,按照图片中操作即可,注意先运行程序哈:
分别按1,2,3,4,上,下,左,右,BOOT键后Thonny IDE打印如下:
六、安卓手机APP操作
操作可参考如下图片,注意先运行程序哈:
BLE调试助手界面:
六、蓝牙突破20字节限制
无意中发现APP发送命令超过20个字节,比如36个字节,ESP32开发板只能接受20个字节。然后查阅了资料,在Micropython官方网站中,找到了答案。原因是我们的ESP32开发板固件默认是只接受20字节的数据。
bluetooth — low-level Bluetooth — MicroPython latest documentation
然后我们根据官方文档的介绍,在代码调用register之后调用gatts_writer方法就行了:
将self.ble.gatts_write(self.rx, bytes(100))
添加到下图的位置
文章来源:https://www.toymoban.com/news/detail-483535.html
文章来源地址https://www.toymoban.com/news/detail-483535.html
到了这里,关于物联网开发笔记(56)- 使用Micropython开发ESP32开发板之手机蓝牙控制舵机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!