Reputation: 1326
This is my first time trying to establish a connection between a Raspberry Pi Zero and an ESP32 over bluetooth and I can't get it work. The goal is to just exchange simple text (not more, not less)
I have two different platforms (the ESP32 and the Raspberry Pi Zero) and I want them to communicate over Bluetooth using RFCOMM
.
On my Raspberry Pi, an RFCOMM Server (a slightly adapted version of this code from here, which apparently has been taken from this site) is running.
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
On my ESP32 a very simple example application is running. This example has been taken from 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);
}
I'm attempting to connect my ESP32 via bluetoothctl
.
[bluetooth]# pair 24:62:AB:**:**:**
This seems to work at first, but I receive a Connected: no after some seconds (last line).
[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
Anyhow, I see my paired device:
[bluetooth]# paired-devices
Device 24:62:AB:**:**:** ESP32test
--- BUT my server on the RPi Zero does not detect the new device:
sudo python3 BluetoothServer.py
Waiting for connection on RFCOMM channel 1
I was expecting that the server recognises my device but that's not the case. I guess my ESP32 application is not recognized as a client? How to a make the server be aware of my ESP32 device, so I can communicate over bleutooth?
If I'm connection to the RPi using a Bluetooth Terminal for Android like Serial Bluetooth Terminal my server seems to be working correctly. I can send and receive commands over Bluetooth. This software is also available as Open Source but I'm not that familiar with Java and have a hard time understanding what going on here. This seems to work as well if I'm connecting to my ESP32... ...but not between my to devices.
Upvotes: 0
Views: 7786
Reputation: 1
From the pairing example notice the message received:
Pairing successful
[CHG] Device 24:62:AB:**:**:** ServicesResolved: no
To use the device as a serial port, a device to consume the bluetooth serial port service needs to be defined on the raspberry pi, which rfcomm can be used to handle this.
I had the same issue and followed the instructions at:https://c2plabs.com/blog/2020/09/30/how-to-enable-bluetooth-serial-port-spp-in-headless-raspberry-pi-zero-w/
Below is an example which worked perfectly for me.
1) Identify the bluetooth device with hcitool scan. The following is an example of a pi4 which has an esp32-wroover-e nearby with the name RETROCOMP.
pi@pi4:~ $ hcitool scan
Scanning ...
A8:03:2A:EC:14:82 RETROCOMP
2) Get more details by executing hcitool again with the info option and parm the address of the bluetooth device from step 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) The UUID for serial the port profile or btspp is 0x1101. Search the nearby devices for this profile with the Service discovery protocol (SDP). Using the device from above:
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) We now have the information needed to define a service offered by this bluetooth device, in this case a serial port service. Using the above example, create a file rfcomm.conf in the /etc/bluetooth/ directory which rfcomm will parse while connecting remote device.
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) Finally, to create the serial port device on the pi so it may be used with putty, minicom, etc.
sudo rfcomm bind 0 A8:03:2A:EC:14:82
The device will now show under /dev
pi@pi4:~ $ ls -la /dev/rfcomm0 crw-rw---- 1 root dialout 216, 0 Mar 23 01:00 /dev/rfcomm0
With putty, minicom, etc... use device /dev/rfcomm0 .
The device will go away on reboot, however to bring it back only the command to bind is needed next time, i.e. repeat step 5 or automate it's re-creation on boot. There are multiple ways to automate the devices re-creation, such as @reboot crontab entry, an entry for /etc/init.d, adding the command to /etc/rc.local, etc...
Good luck!
Upvotes: 0
Reputation: 7974
You seem to have setup both the ESP and the RPi to be servers. The Serial Bluetooth App is a client and that is why it is able to connect.
My suggestion is to have the ESP as the server and have the RPi as the client.
Currently you appear to have the RPi Python code using PyBlueZ. PyBlueZ is not under active development.
You can achieve the same thing on Linux with the standard Python sockets library as detailed in the following blog: http://blog.kevindoran.co/bluetooth-programming-with-python-3/
There is also functionality within the Bluedot library that might be helpful. In addition to the documentation there is also some examples.
Upvotes: 1