La Arduino Nano BLE 33 e' una scheda interessante perche' oltre al Bluetooth LE sono disponibili una IMU (LMS9DS1), un microfono digitale (MP34DT05), un sensore di colore e prossimita' (APDS9960), un sensore di pressione atmosferica (LPS22HB), un sensore di umidita' relativa e temperatura (HTS221)
Lo sketch su Arduino apre un servizio su BLE con numero 180F ed una caratteristica 2A19 in cui vengono salvati i dati di un contatore progressivo da 0 a 255 (questo per fare in modo che sul lato PC si sia in grado di vedere se si perdono pacchetti)
Lato Arduino
================================================
#include <ArduinoBLE.h>
BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify);
long previousMillis = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
while (1);
}
BLE.setLocalName("Random");
BLE.setAdvertisedService(numero);
numero.addCharacteristic(casuale);
BLE.addService(numero);
casuale.writeValue(0); // set initial value for this characteristic
BLE.advertise();
}
void loop() {
int i = 0;
BLEDevice central = BLE.central();
if (central) {
digitalWrite(LED_BUILTIN, HIGH);
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 20) {
i++;
casuale.writeValue(i%255);
previousMillis = currentMillis;
}
}
digitalWrite(LED_BUILTIN, LOW);
}
}
================================================
Per verificare che i dati vengano inviati correttamente si puo' usare gattool
================================================
gatttool -b ED:CB:86:2A:68:C1 -I
[ED:CB:86:2A:68:C1][LE]> connect
Attempting to connect to ED:CB:86:2A:68:C1
Connection successful
[ED:CB:86:2A:68:C1][LE]> char-read-uuid 2A19
handle: 0x000b value: 41
================================================
A questo punto con la libreria Bluepy si possono leggere i dati inviati dalla Arduino
================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral
addr = "ED:CB:86:2A:68:C1"
conn = Peripheral(addr, "public")
print ("-Servizi")
services = conn.getServices()
for service in services:
print(service.uuid)
print("-Caratteristica")
charac_dic = service.getCharacteristics()
for charac in charac_dic:
print(charac.uuid)
if charac.uuid == "2a19":
print ("Trovata")
Data_char = charac
print(Data_char)
Data_handle = Data_char.getHandle()
print Data_handle
while True:
print (ord(charac.read()))
================================================
la trasmissione dati in questo modo e' piuttosto lenta..circa un dato ogni decimo di secondo.
Usando la tecnica di subscribe and notify la Arduino invia i dati al PC senza la necessita' per quest'ultimo di richiederli. Con questa tecnica non si perde nessun pacchetto
================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral
import struct
def listAll(p):
for svc in p.getServices():
print(svc.uuid.getCommonName())
for ch in svc.getCharacteristics():
print(" " + str(ch.valHandle) + ": " + ch.uuid.getCommonName())
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
print(ord(data))
addr = "ED:CB:86:2A:68:C1"
p = btle.Peripheral(addr,"public")
services=p.getServices()
for service in services:
print(service.uuid)
p.setDelegate( MyDelegate() )
listAll(p)
svc = p.getServiceByUUID("0000180f-0000-1000-8000-00805f9b34fb")
ch = svc.getCharacteristics()[0]
p.writeCharacteristic(ch.valHandle+1, b'\x01\x00', withResponse=True)
while True:
if p.waitForNotifications(1.0):
continue
print "Waiting..."
from bluepy.btle import UUID, Peripheral
import struct
def listAll(p):
for svc in p.getServices():
print(svc.uuid.getCommonName())
for ch in svc.getCharacteristics():
print(" " + str(ch.valHandle) + ": " + ch.uuid.getCommonName())
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
print(ord(data))
addr = "ED:CB:86:2A:68:C1"
p = btle.Peripheral(addr,"public")
services=p.getServices()
for service in services:
print(service.uuid)
p.setDelegate( MyDelegate() )
listAll(p)
svc = p.getServiceByUUID("0000180f-0000-1000-8000-00805f9b34fb")
ch = svc.getCharacteristics()[0]
p.writeCharacteristic(ch.valHandle+1, b'\x01\x00', withResponse=True)
while True:
if p.waitForNotifications(1.0):
continue
print "Waiting..."