Ubuntu 系统使用 ESP32 作为蓝牙 adapter (适配器)

14 篇文章 0 订阅
6 篇文章 2 订阅

Ubuntu 系统使用 ESP32 作为蓝牙 adapter (适配器)


蓝牙可以通过 HCI 将 HOST 部分与 Controller 部分进行连接。

这篇文章说明了如何使用 ESP32-IDF 中包含的蓝牙示例应用程序 controller_hci_uart 通过主机控制器接口(Host Controller Interface)与 ESP32 蓝牙 controller 进行连接和通信。使用任何操作系统(Mac,Linux或Windows)的电脑都可以来编译此工程。

在此示例中使用的 Host 是 BlueZ 蓝牙协议栈。由于 BlueZ 是用于基于 Linux 内核的操作系统系列的蓝牙协议栈,因此本示例需要在一台运行 Linux OS 且安装了 BlueZ 的计算机与 ESP32 开发板进行通讯。

主机控制器接口(Host Controller Interface)可以使用 UART 连接 BlueZESP32 蓝牙的 controller


使用 uart 串口作为 hci 接口


方法一:外部串口链接 uart 对应管脚

串口ESP32
TxGPIO 18 (Rx)
RxGPIO 05 (Tx)
CTSGPIO 19 (RTS)
RTSGPIO 22 (CTS)
  • 如果不使用硬件流控,RTSCTS 引脚设置可以写 -1

使用下面代码设置串口引脚

uart_set_pin(HCI_UART_PORT, HCI_UART_TXD, HCI_UART_RXD, HCI_UART_RTS, HCI_UART_CTS)

默认的波特率为 921600


方法二:使用自带的 USB 转 uart 接口作为 hci 接口

使用其他引脚作为串口链接到电脑需要额外链接一个串口设备,增加了成本还比较麻烦,所以我还考虑了使用 ESP 默认使用的 USB 串口,作为蓝牙链接串口的方案。

但是由于 UART0 是默认配置的串口,用作系统信息的打印,所以默认没有打开作为 HCI 串口的选项,这里我们可以通过修改 esp_bt_controller_config 来设置 hci 使用串口 0

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    /* set hci use uart number*/
    bt_cfg.hci_uart_no = HCI_UART_PORT;

同样由于 UART0 是系统信息打印的串口,引脚(TX->GPIO1,RX->GPIO3)已经默认配置好了,不需要再次设置引脚。但是 ESP32 DevKitCUSBUART 没有接 RTSCTS,所以需要使用 uart_set_hw_flow_ctrl 关闭硬件流控。

如果使用 uart_set_sw_flow_ctrl 开启软件流控,需要修改 XONXOFF的值,有些数据会被软件流控截断,不建议使用。


使用 Ubuntu 系统连接 ESP32 蓝牙适配器

将串口链接到电脑上,会出现对应串口的设备。如: /dev/ttyUSB1

  • 将串行设备 (serial devices) 连接到 BlueZ 蓝牙协议栈
sudo btattach -B /dev/ttyUSB1 -S 921600

可以添加 -N 关闭 BlueZ 的硬件流控
sudo btattach -N -B /dev/ttyUSB1 -S 921600

成功执行后会显示配置信息和连接设备的编号(index)

Attaching Primary controller to /dev/ttyUSB0
Switched line discipline from 0 to 15
Device index 1 attached

注意:这个窗口不要关闭!
到这里,系统就已经连接了 ESP32 的 adapter ,可以在系统设置中找到蓝牙选项卡,并且使用系统中的蓝牙功能了。

~~~


测试命令

我们还可以使用以下命令行工具进行调试。

  • 使用 BlueZ 管理工具 btmgmt

btmgmt: - A command-line interface of BlueZ for management Usage:

根据 btattach 连接上设备的 index,使用下面命令连接设备。

sudo btmgmt --index 1
power on 打开电源
find 搜索设备
stop-find 停止搜索
power off 关闭电源

示例:

$ sudo btmgmt --index 1

[hci1]# power on
hci1 Set Powered complete, settings: powered bondable ssp br/edr le secure-conn 
[hci1]# find
Discovery started
hci1 type 7 discovering on
hci1 dev_found: 6F:E6:68:BD:41:05 type LE Random rssi -94 flags 0x0000 
AD flags 0x1a 
eir_len 18
hci1 dev_found: 0C:E9:99:CE:F5:7D type LE Random rssi -69 flags 0x0004 
AD flags 0x00 
eir_len 31
[hci1]# stop-find
Discovery stopped
hci1 type 7 discovering off
[hci1]# power off
hci1 Set Powered complete, settings: bondable ssp br/edr le secure-conn 
hci1 class of device changed: 0x000000
[hci1]# 


代码


#include <stdio.h>
#include <string.h>
#include "nvs_flash.h"
#include "esp_bt.h"
#include "soc/uhci_periph.h"
#include "driver/uart.h"
#include "driver/periph_ctrl.h"
#include "esp_log.h"

static const char *tag = "CONTROLLER_UART_HCI";


#define HCI_UART_PORT (0)

#define BUF_SIZE (1024*4)

#if HCI_UART_PORT == 0

#define HCI_UART_TXD  (1)
#define HCI_UART_RXD  (3)
#define HCI_UART_RTS  (-1)
#define HCI_UART_CTS  (-1)

#elif HCI_UART_PORT == 1 

#define HCI_UART_TXD  (5)
#define HCI_UART_RXD  (18)
#define HCI_UART_RTS  (19)
#define HCI_UART_CTS  (23)

#endif 


void reconfig_hci_uart()
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    int intr_alloc_flags = 0;

    ESP_ERROR_CHECK(uart_driver_delete(HCI_UART_PORT));
    ESP_ERROR_CHECK(uart_driver_install(HCI_UART_PORT, BUF_SIZE, 0, 0, NULL, intr_alloc_flags));
    ESP_ERROR_CHECK(uart_param_config(HCI_UART_PORT, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(HCI_UART_PORT, HCI_UART_TXD, HCI_UART_RXD, HCI_UART_RTS, HCI_UART_CTS));

    #if ((HCI_UART_RTS == -1) || (HCI_UART_CTS == -1))
    ESP_ERROR_CHECK(uart_set_hw_flow_ctrl(HCI_UART_PORT, UART_HW_FLOWCTRL_DISABLE, UART_FIFO_LEN - 8));
    #endif
    
}


void app_main(void)
{ 
    esp_err_t ret;

    /* Initialize NVS — it is used to store PHY calibration data */
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

// HCI_UART_PORT == 0 had been enabled
#if HCI_UART_PORT == 1
    periph_module_enable(PERIPH_UART1_MODULE);
#elif HCI_UART_PORT == 2
    periph_module_enable(PERIPH_UART2_MODULE);
#endif
    periph_module_enable(PERIPH_UHCI0_MODULE);

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    /* Set the uart number used by hci*/
    bt_cfg.hci_uart_no = HCI_UART_PORT;
  
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret != ESP_OK) {
        ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret));
        return;
    }
    reconfig_hci_uart();

    ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
    if (ret != ESP_OK) {
        ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret));
        return;
    }

}


  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
上一期免费开源项目中,我最新发布了:最简单DIY的51蓝牙遥控小车设计方案,地址是:https://www.cirmall.com/circuit/20328当时测试用的是手机蓝牙调试助手来遥控智能小车的,那么这次开源免费项目中,我要用ESP32来实现串口蓝牙的功能来完全替代手机蓝牙调试助手来无线控制蓝牙智能小车。 优酷视频演示地址: 友情提示:蓝牙控制的设备是智能小车,想下载的买家可以到上面的网址免费下载,配套使用的。本次设计采用Arduino开发环境编写ESP32 C++程序,不会搭建开发环境的买家可以到:https://www.cirmall.com/circuit/19141自行按照说明搭建,这次为了改变口味,我用的是ESP32DEVKITV1开发板,价格更低十几块在某宝就能买到,这次下载程序可以直接使用手机数据线跟ESP32连接,在arduino里面直接点击下载就可以把程序下载进去了。 彩图如下: 科普一下:串口蓝牙就是模块设定为master模式,自动连上蓝牙设备-智能小车(client模式),不需要使用AT指令(我这个方案的优势),连上蓝牙设备之后将串口的数据通过蓝牙方式转发出去(注意我用的不是串口蓝牙模块),最后达到遥控蓝牙智能小车的效果,我现在用arduino自带的串口调试助手来测试。 下面是全家福照片: 下面是本次项目的主角: 源码代码截图: 注意了:我用的蓝牙设备-智能小车上安装的是串口蓝牙模块的型号是HC-05,所以我的串口蓝牙遥控器编写的程序里面写死了适配蓝牙的名字和密码,买家根据自己的情况来修改了。 下面是串口调试截图: 按照图上的配置信息配置,烧录源码,重启,输入FFF,点击“发送”按钮,小车就前进,串口调试窗口就看到小车回复了FFF,输入BBB就是倒退,左转是LLL,右转是RRR。 稍微说一下程序原理:电脑串口传输字符串给ESP32ESP32将字符串通过蓝牙天线发送给智能小车,智能小车的串口蓝牙接收到信号之后触发串口中断,在中断服务程序执行控制小车行动的逻辑,然后再返回一个相同的字符串给ESP32ESP32接收到字符串之后打印到电脑串口显示端上显示出来。 下一期我将会用ESP32DEVKITV1开发板做一个脱离电脑的串口蓝牙遥控器,通过摇杆AD转换成蓝牙控制信号来控制智能小车,敬请期待。
Ubuntu是一种开源操作系统,可以在桌面和服务器上运行。Ubuntu 22桌面版本提供了许多功能和驱动程序,以支持各种硬件设备,包括蓝牙适配器。 在Ubuntu 22桌面上,蓝牙适配器的驱动程序是btusb。btusb是一个内核模块,它允许操作系统蓝牙适配器进行通信。一旦安装了Ubuntu 22桌面版,btusb驱动程序将已经包含在操作系统中,并自动加载。 要确保btusb驱动程序正常工作,首先需要确保蓝牙适配器已正确连接到计算机。可以通过检查系统设置中的蓝牙选项来验证它是否被识别和激活。 如果蓝牙适配器没有被检测到或无法正常工作,可能需要执行以下步骤来解决问题: 1. 更新系统使用终端命令或软件更新工具,确保系统是最新的。有时,新的更新可以修复与蓝牙适配器相关的问题。 2. 重新插拔蓝牙适配器:如果适配器连接到USB端口,请尝试重新插拔它,以确保接触良好。 3. 检查蓝牙服务:确保蓝牙服务已启用并正在运行。可以通过终端命令"sudo service bluetooth status"来检查蓝牙服务的状态。 4. 重新安装驱动程序:如果蓝牙适配器仍然无法工作,可能需要重新安装btusb驱动程序。可以通过终端命令或软件包管理器将其重新安装。 综上所述,Ubuntu 22桌面版支持蓝牙适配器,并使用btusb驱动程序来实现与适配器的通信。如果遇到问题,可以尝试更新系统、重新插拔适配器、检查蓝牙服务或重新安装驱动程序来解决。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值