Raspberry Pi和ESP32通过蓝牙进行通信

如何解决Raspberry Pi和ESP32通过蓝牙进行通信

这是我第一次尝试通过蓝牙 Raspberry Pi Zero ESP32 之间建立连接,但我无法这行得通。目标是只交换简单文本(不多也不少)

我的设置

我有两个不同的平台(ESP32和Raspberry Pi Zero),我希望它们使用RFCOMM通过蓝牙进行通信。

Raspberry Pi

在我的Raspberry Pi上,正在运行一个RFCOMM服务器(此代码从here改编而成,显然是从this site提取的)。

import os
import glob
import time
import RPi.GPIO as GPIO
from bluetooth import *

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)

port = server_sock.getsockname()[1]

uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"

advertise_service( server_sock,"AquaPiServer",service_id = uuid,service_classes = [ uuid,SERIAL_PORT_CLASS ],profiles = [ SERIAL_PORT_PROFILE ],#                  protocols = [ OBEX_UUID ] 
                    )
while True:          
    print("Waiting for connection on RFCOMM channel %d" % port)

    client_sock,client_info = server_sock.accept()
    print("Accepted connection from ",client_info)

    try:
        data = client_sock.recv(1024)
        if len(data) == 0: break
        print("received [%s]" % data)
        data = 'Hello!' 
        client_sock.send(data)
        print("sending [%s]" % data)

    except IOError:
        pass

    except KeyboardInterrupt:
        print("disconnected")
        client_sock.close()
        server_sock.close()
        print("all done")
        break

ESP32

在我的ESP32上,一个非常简单的示例应用程序正在运行。此示例摘自here

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32test"); //Bluetooth device name
  Serial.println("The device started,now you can pair it with bluetooth!");
}

void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    Serial.write(SerialBT.read());
  }
  delay(20);
}

连接

我正在尝试通过bluetoothctl连接我的ESP32。

[bluetooth]# pair 24:62:AB:**:**:**

这似乎起初很有效,但是几秒钟后(最后一行),我收到一个 Connected:no

[bluetooth]# pair 24:62:AB:**:**:**
Attempting to pair with 24:62:AB:**:**:**
[CHG] Device 24:62:AB:**:**:** Connected: yes
Request confirmation
[agent] Confirm passkey 101977 (yes/no): yes
[CHG] Device 24:62:AB:**:**:** UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 24:62:AB:**:**:** UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 24:62:AB:**:**:** UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 24:62:AB:**:**:** ServicesResolved: yes
[CHG] Device 24:62:AB:**:**:** Paired: yes
Pairing successful
[CHG] Device 24:62:AB:**:**:** ServicesResolved: no
[CHG] Device 24:62:AB:**:**:** Connected: no

无论如何,我会看到配对的设备:

[bluetooth]# paired-devices
Device 24:62:AB:**:**:** ESP32test

问题和到目前为止的经验

---但是我在RPi Zero上的服务器未检测到新设备:

sudo python3 BluetoothServer.py 
Waiting for connection on RFCOMM channel 1

我期望服务器能够识别我的设备,但事实并非如此。我猜我的ESP32应用程序不被视为客户端吗?如何使服务器知道我的ESP32设备,以便我可以通过蓝牙进行通信?

什么有效?

如果我使用Serial Bluetooth Terminal之类的Android蓝牙终端连接到RPi,则我的服务器似乎正常工作。我可以通过蓝牙发送和接收命令。该软件也可以以Open Source的形式获得,但是我对Java不那么熟悉,很难理解这里发生的事情。 如果我连接到ESP32,这似乎也能正常工作... ...但在我与设备之间却没有。

我尝试了什么

解决方法

您似乎已经将ESP和RPi都设置为服务器。串行蓝牙应用程序是一个客户端,这就是它能够连接的原因。

我的建议是将ESP作为服务器,将RPi作为客户端。

当前,您似乎已经使用PyBlueZ获得了RPi Python代码。 PyBlueZ是not under active development

您可以使用标准Python套接字库在Linux上实现相同的目的,如以下博客所述:http://blog.kevindoran.co/bluetooth-programming-with-python-3/

Bluedot库中还有一些功能可能会有所帮助。除了文档外,还有一些examples

,

从配对示例通知收到的消息:

Pairing successful
[CHG] Device 24:62:AB:**:**:** ServicesResolved: no

要将设备作为串口使用,需要在树莓派上定义一个消费蓝牙串口服务的设备,可以使用rfcomm来处理。

我遇到了同样的问题并按照以下说明操作:https://c2plabs.com/blog/2020/09/30/how-to-enable-bluetooth-serial-port-spp-in-headless-raspberry-pi-zero-w/

下面是一个非常适合我的例子。

1) 使用 hcitool 扫描识别蓝牙设备。以下是 pi4 的示例,它附近有一个名为 RETROCOMP 的 esp32-wroover-e。

pi@pi4:~ $ hcitool scan 
Scanning ...
    A8:03:2A:EC:14:82   RETROCOMP

2) 使用 info 选项再次执行 hcitool 以获取更多详细信息,并从步骤 1 中设置蓝牙设备的地址。

pi@pi4:~ $ sudo hcitool info A8:03:2A:EC:14:82
Requesting information ...
    BD Address:  A8:03:2A:EC:14:82
    Device Name: RETROCOMP
    LMP Version: 4.2 (0x8) LMP Subversion: 0x30e
    Manufacturer: RivieraWaves S.A.S (96)
    Features page 0: 0xbf 0xee 0xcd 0xfe 0xdb 0xff 0x7b 0x87
        <3-slot packets> <5-slot packets> <encryption> <slot offset> 
        <timing accuracy> <role switch> <sniff mode> <RSSI> 
        <channel quality> <SCO link> <HV3 packets> <u-law log> 
        <A-law log> <CVSD> <power control> <transparent SCO> 
        <broadcast encrypt> <EDR ACL 2 Mbps> <EDR ACL 3 Mbps> 
        <enhanced iscan> <interlaced iscan> <interlaced pscan> 
        <inquiry with RSSI> <extended SCO> <EV4 packets> <EV5 packets> 
        <AFH cap. slave> <AFH class. slave> <LE support> 
        <3-slot EDR ACL> <5-slot EDR ACL> <sniff subrating> 
        <pause encryption> <AFH cap. master> <AFH class. master> 
        <EDR eSCO 2 Mbps> <EDR eSCO 3 Mbps> <3-slot EDR eSCO> 
        <extended inquiry> <LE and BR/EDR> <simple pairing> 
        <encapsulated PDU> <err. data report> <non-flush flag> <LSTO> 
        <inquiry TX power> <EPC> <extended features> 
    Features page 1: 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00
    Features page 2: 0x5f 0x03 0x00 0x00 0x00 0x00 0x00 0x00

3) 串行端口配置文件或 btspp 的 UUID 为 0x1101。使用服务发现协议 (SDP) 在附近的设备中搜索此配置文件。从上方使用设备:

pi@pi4:~ $ sdptool search  --bdaddr A8:03:2A:EC:14:82 0x1101
Class 0x1101
Searching for 0x1101 on A8:03:2A:EC:14:82 ...
Service Name: ESP32SPP
Service RecHandle: 0x10000
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0102

4) 我们现在拥有定义此蓝牙设备提供的服务所需的信息,在本例中为串行端口服务。使用上面的示例,在 /etc/bluetooth/ 目录中创建一个文件 rfcomm.conf,rfcomm 将在连接远程设备时解析该文件。

rfcomm0 {
        #  Bind the device at startup
       bind no;

         # Remote device Bluetooth address

       device A8:03:2A:EC:14:82;
       # RFCOMM channel this info we can get from sdptool browse

       channel 1;

       # Description of the connection

       comment \u201cBluetooth Serial port\u201d;
}

5) 最后,在 pi 上创建串口设备,以便它可以与 putty、minicom 等一起使用。

sudo rfcomm bind 0 A8:03:2A:EC:14:82
  1. 设备现在将显示在 /dev

    pi@pi4:~ $ ls -la /dev/rfcomm0 crw-rw---- 1 根拨出 216,0 Mar 23 01:00 /dev/rfcomm0

  2. 使用 putty、minicom 等...使用设备 /dev/rfcomm0 。

设备将在重新启动时消失,但是下次只需要绑定命令即可将其恢复,即重复步骤 5 或在启动时自动重新创建。有多种方法可以自动重新创建设备,例如@reboot crontab 条目、/etc/init.d 的条目、将命令添加到/etc/rc.local 等...

祝你好运!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-