I have an ESP32 on which I am running the Arduino example Bluetooth sniffer code (in C via Arduino IDE). I presume this is the "client". The ESP32 is BLE.
I want to run python code on my Pi0W (Stretch) to turn it into a simple Bluetooth server (I hope that I have the terminology correct).
I'm just tinkering to see if the ESP32 can see the Pi0W and if I can make my own GATT message structures.
Can anyone point me at some suitable python code that will do what I want (or give me a starting push) please?
Cheers.
I already run code (based on someone else's hard work) on a Pi0W that talks to my WiiFit board (which I just about understand) and wonder if I can modify that in some way?
Re: How can I make a Pi0W into a bluetooth server using python?
the ble model isnt the traditional client server arrangement.
http://www.raspberry-pi-geek.com/Archiv ... (offset)/1
Is a pretty good walk through and intro to the subject, and get you on the way to creating a ble device that advertises its presence and type ..
edit personally i would use the esp to create the low power ble device to advertise and offer data and use the pi to host a system to query record and perhaps analyse the data for presentation..
http://www.raspberry-pi-geek.com/Archiv ... (offset)/1
Is a pretty good walk through and intro to the subject, and get you on the way to creating a ble device that advertises its presence and type ..
edit personally i would use the esp to create the low power ble device to advertise and offer data and use the pi to host a system to query record and perhaps analyse the data for presentation..
Re: How can I make a Pi0W into a bluetooth server using python?
Many thanks. I will take a look in the morning when I'm more awake...
Re: How can I make a Pi0W into a bluetooth server using python?
Here's some Python code I adapted from the BlueZ sample code that implements a GATT server: https://github.com/Douglas6/cputemp
Re: How can I make a Pi0W into a bluetooth server using python?
Hi Douglas6
Thanks for the link. I've downloaded and will be playing shortly. I like a well documented GitHub repository. Many thanks.
Thanks for the link. I've downloaded and will be playing shortly. I like a well documented GitHub repository. Many thanks.
Re: How can I make a Pi0W into a bluetooth server using python?
Hi Douglas6
It does exactly what I want. Thanks. It works as advertised on the app you suggested for the Android phone and I see it as a device on my ESP32.
Now I've got to work out why I can't see the services on my ESP32, but that's my problem now...
Regards Mark
It does exactly what I want. Thanks. It works as advertised on the app you suggested for the Android phone and I see it as a device on my ESP32.
Now I've got to work out why I can't see the services on my ESP32, but that's my problem now...
Regards Mark
Re: How can I make a Pi0W into a bluetooth server using python?
HI Douglas6
I have got it working now and will post the 'C' code that works on an ESP32 when I have tidied it up so that other people may make use of it.
Thanks for the advice about connecting. That is the conclusion that I had arrived at.
I can't profess to fully understand what is going on in the Python code on the Pi as 'C' is my speciality, but I'm going to try to modify it to include some of the 'standard' GATT messages. I will try with 180A (2A24, 2A26 etc) first to put in some manufacturer info.
Also, one thing puzzles me. My Pi 'device' does not report a name via Bluetooth. It's network name is 'oddjob' which I would have thought would filter down to the Bluetooth stack somehow?
Best regards Mark
I have got it working now and will post the 'C' code that works on an ESP32 when I have tidied it up so that other people may make use of it.
Thanks for the advice about connecting. That is the conclusion that I had arrived at.
I can't profess to fully understand what is going on in the Python code on the Pi as 'C' is my speciality, but I'm going to try to modify it to include some of the 'standard' GATT messages. I will try with 180A (2A24, 2A26 etc) first to put in some manufacturer info.
Also, one thing puzzles me. My Pi 'device' does not report a name via Bluetooth. It's network name is 'oddjob' which I would have thought would filter down to the Bluetooth stack somehow?
Best regards Mark
Re: How can I make a Pi0W into a bluetooth server using python?
For classic Bluetooth, yes the 'Bluetooth name' defaults to the machine name. For BLE, my Pi is identified by the local name I assigned to the advertising data, 'Thermometer'. At least, that is how nRF Connect identifies it.
Re: How can I make a Pi0W into a bluetooth server using python?
'C' code (Arduino) for my ESP32 (A Heltec Kit32 with OLED) - as promised. A bit rough and ready but it works with the Pi code that Douglas6 posted.
Code: Select all
/*
* Program to operate ESP32 in client mode and get served information from a Raspberry Pi
* Program by: Mark Hollingworth
* The code for the Raspberry Pi can be found here :
* https://www.raspberrypi.org/forums/viewtopic.php?f=62&t=254431
* Dated: 18-10-2019
* NOTE: The MY_RASPBERRY_PI_ADDRESS is specific to my Raspberry Pi and will need to be changed in the onResult() function
* NOTE: There is a bug in the BLE characteristic library found here in a Win10 installation of the Arduino code :
* C:\Users\YOURNAME\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\BLE\src\BLEremotecharacteristic.cpp
* Search the following (at line 33 in my file) and add ": m_rawData(nullptr)"
* BLERemoteCharacteristic::BLERemoteCharacteristic(
* uint16_t handle,
* BLEUUID uuid,
* esp_gatt_char_prop_t charProp,
* BLERemoteService* pRemoteService) : m_rawData(nullptr) {
*/
#define MAX_DEVICES 5
#include <BLEDevice.h>
//Service UUID of Pi temperature
static BLEUUID serviceUUID("00000001-710e-4a5b-8d75-3e5b444bc3cf");
//Characteristic UUID of Pi temperature R
static BLEUUID char2UUID("00000002-710e-4a5b-8d75-3e5b444bc3cf");
//Characteristic UUID of Pi temperature unit R/W 'C' or 'F'
static BLEUUID char3UUID("00000003-710e-4a5b-8d75-3e5b444bc3cf");
static BLERemoteCharacteristic* _pRemoteCharacteristic;
BLEScan* _pBLEScan;
static BLEAddress* _pServer_BLE_Address[MAX_DEVICES];
String _strScanned_BLE_Address;
boolean _blnPaired;
int _intDeviceCount;
int _intPairedDeviceIndex;
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,uint8_t* pData,size_t length,bool isNotify)
{
Serial.print("Notify callback for characteristic : ");
#ifdef DEBUG_SERIAL
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
#endif
Serial.println((char*)pData);
}
bool connectToserver (BLEAddress pAddress)
{
BLEClient* pClient = BLEDevice::createClient();
Serial.println("Created client");
// Connect to the BLE Server.
pClient->connect(pAddress);
Serial.println("Connected to Pi");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService != nullptr)
{
Serial.println("Found our TEMPERATURE service");
// Obtain a reference to the temperature unit characteristic in the service of the remote BLE server.
_pRemoteCharacteristic = pRemoteService->getCharacteristic(char3UUID);
if (_pRemoteCharacteristic != nullptr)
{
Serial.print("Found characteristic TEMPERATURE UNIT :");
if (_pRemoteCharacteristic->canRead())
{
Serial.print(" read (");
Serial.print(_pRemoteCharacteristic->readValue().c_str());
Serial.print(")");
}
if (_pRemoteCharacteristic->canWrite())
{
Serial.print(" write");
// So change it from the default F to C
_pRemoteCharacteristic->writeValue('C', false);
Serial.print(" (change it to 'C') ");
}
if (_pRemoteCharacteristic->canNotify())
{
Serial.print(" notify");
_pRemoteCharacteristic->registerForNotify(notifyCallback);
}
Serial.println("");
}
// Obtain a reference to the temperature characteristic in the service of the remote BLE server.
_pRemoteCharacteristic = pRemoteService->getCharacteristic(char2UUID);
if (_pRemoteCharacteristic != nullptr)
{
Serial.print("Found characteristic TEMPERATURE :");
if (_pRemoteCharacteristic->canRead())
{
Serial.print(" read (");
Serial.print(_pRemoteCharacteristic->readValue().c_str());
Serial.print(")");
}
if (_pRemoteCharacteristic->canWrite())
{
Serial.print(" write");
}
if (_pRemoteCharacteristic->canNotify())
{
Serial.print(" notify");
_pRemoteCharacteristic->registerForNotify(notifyCallback);
}
Serial.println("");
}
return true;
}
return false;
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
void onResult(BLEAdvertisedDevice advertisedDevice)
{
// NOTE change this for YOUR Raspberry Pi
const String MY_RASPBERRY_PI_ADDRESS = "b8:27:eb:cf:ca:ad";
if (_blnPaired == false)
{
Serial.printf("Scan Result: %s \n", advertisedDevice.toString().c_str());
_pServer_BLE_Address[_intDeviceCount] = new BLEAddress(advertisedDevice.getAddress());
_strScanned_BLE_Address = _pServer_BLE_Address[_intDeviceCount]->toString().c_str();
if (_strScanned_BLE_Address == MY_RASPBERRY_PI_ADDRESS)
{
_intPairedDeviceIndex = _intDeviceCount;
}
_intDeviceCount++;
if (_intDeviceCount == MAX_DEVICES)
{
_intDeviceCount--;
Serial.println("Maximum number of devices found");
}
}
}
};
void setup()
{
_blnPaired = false;
_intDeviceCount = 0;
_intPairedDeviceIndex = -1;
Serial.begin(115200);
Serial.println("ESP32 BLE Server program (for Raspberry Pi)");
BLEDevice::init("");
_pBLEScan = BLEDevice::getScan();
_pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
_pBLEScan->setActiveScan(true);
}
void loop()
{
BLEScanResults foundDevices;
foundDevices = _pBLEScan->start(5);
while (foundDevices.getCount() >= 1)
{
if (_intPairedDeviceIndex != -1 && _blnPaired == false)
{
Serial.println("Found DEVICE...connecting to Server as Client");
if (connectToserver(*_pServer_BLE_Address[_intPairedDeviceIndex]))
{
_blnPaired = true;
break;
}
else
{
Serial.println("Pairing failed");
break;
}
}
}
}