物联网开发笔记(56)- 使用Micropython开发ESP32开发板之手机蓝牙控制舵机

一、目的

        这一节我们学习如何使用我们的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))添加到下图的位置

 

  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔都飘雪

您的1毛奖励是我创作的源源动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值