Buongiorno, sto creando un progetto nella quale devono essere inviati dei dati (anche semplici 0 e 1) da Arduino nano 33 BLE Rev2 ad un Arduino Uno R4 Wifi, ho provato in tutti i modi, con svariati codici, ma nulla, il segnale sembra non connettersi.
Per questa connessione ho inizialmente utilizzato degli UUID per sincronizzarli, l'Arduino BLE sembrerebbe inviare dati, ma senza essere ricevuti.
Nel caso non fosse possibile una connessione simile, tra due Arduino, andrebbe bene anche un bluetooth tra Arduino BLE e un modulo bluetooth connesso ad Arduino Uno.
Mi farebbe comodo una conferma su ciò che sto provando, è possibile? chiedo scusa per eventuali errori, ma è la prima volta che uso trasmissioni bluetooth.
Mai provato, comunque prova a vedere tra gli esempi della libreria Bluetooth Arduino ... anche perché BLE sulla UNO WiFi è supportato da poco tempo ...
Chiedo scusa se includo del codice nella sezione hardware, ma pensavo il problema fosse "fisico".
Comunque, a livello di connessioni ho semplicemente attaccato le 2 schede a due porte COM diverse (ho provato anche su due PC differenti), mentre per quanto riguarda il codice, non trovando documentazioni a riguardo, mi sono affidata all'AI, cercando di capire come si muovesse:
Se ho capito bene suddivide nel classico Server-Client, creando un UUID comune.
Avendo entrambi un bluetooth di tipo BLE, mi suggerisce di utilizzare la sua libreria.
Il problema che sto riscontrando è nell'Arduino R4, che non sembra reagire nemmeno nel serial monitor stampando le stringhe, a differenza del nano 33 Ble che stampa, e sembrerebbe ricercare connessioni.
Questi sono i codici:
CODICE ARDUINO NANO 33 BLE REV2 (SERVER)
#include <ArduinoBLE.h>
// Dichiarazione della caratteristica BLE per inviare una stringa
BLEService customService("180D"); // UUID del servizio personalizzato
BLECharacteristic stringCharacteristic("2A57", // UUID della caratteristica
BLERead | BLENotify,
20); // Lunghezza massima della stringa
void setup() {
Serial.begin(9600);
while (!Serial);
// Inizia il modulo BLE
if (!BLE.begin()) {
Serial.println("Impossibile avviare BLE!");
while (1);
}
// Imposta il nome del dispositivo BLE
BLE.setLocalName("Nano33BLE");
BLE.setAdvertisedService(customService);
// Aggiunge la caratteristica al servizio
customService.addCharacteristic(stringCharacteristic);
BLE.addService(customService);
// Avvia l'advertising del dispositivo BLE
BLE.advertise();
Serial.println("In attesa di connessione...");
}
void loop() {
// Verifica se c'è una connessione BLE
BLEDevice central = BLE.central();
if (central) {
Serial.println("Dispositivo connesso!");
while (central.connected()) {
// Invia la stringa "Ciao Uno R4" ogni secondo
stringCharacteristic.writeValue("Ciao Uno R4");
Serial.println("Inviato: Ciao Uno R4");
delay(1000);
}
Serial.println("Dispositivo disconnesso.");
}
}
CODICE ARDUINO UNO R4 WIFI (CLIENT)
#include <ArduinoBLE.h>
BLEDevice peripheral;
BLECharacteristic stringCharacteristic;
void setup() {
Serial.begin(9600);
while (!Serial);
// Inizia il modulo BLE
if (!BLE.begin()) {
Serial.println("Impossibile avviare BLE!");
while (1);
}
Serial.println("In attesa di un dispositivo BLE...");
// Avvia la scansione dei dispositivi BLE con il servizio specifico UUID
BLE.scanForUuid("180D");
}
void loop() {
// Cerca un dispositivo BLE disponibile
peripheral = BLE.available();
if (peripheral) {
// Connessione al dispositivo
Serial.println("Dispositivo trovato, connessione in corso...");
if (peripheral.connect()) {
Serial.println("Connesso al dispositivo BLE!");
// Scopri i servizi e le caratteristiche del dispositivo
if (peripheral.discoverAttributes()) {
Serial.println("Attributi scoperti.");
// Trova la caratteristica specifica per la stringa
stringCharacteristic = peripheral.characteristic("2A57");
// Se la caratteristica è disponibile, leggi i dati
if (stringCharacteristic) {
while (peripheral.connected()) {
if (stringCharacteristic.canRead()) {
char buffer[20]; // Buffer per la stringa ricevuta
int length = stringCharacteristic.readValue(buffer, sizeof(buffer) - 1);
buffer[length] = '\0'; // Terminatore di stringa
// Stampa la stringa ricevuta
Serial.print("Ricevuto: ");
Serial.println(buffer);
}
delay(1000);
}
} else {
Serial.println("Caratteristica non trovata.");
}
} else {
Serial.println("Impossibile scoprire gli attributi.");
}
} else {
Serial.println("Connessione fallita!");
}
}
delay(500); // Attesa tra scansioni
}
Con la AI NON vai da nessuna parte ... o sai TU come affrontare la cosa o difficilmente ne esci.
Come ti ho già detto, in Arduino BLE Library, ci sono svariati esempi sia per la parte "central" che "peripheral" ... devi studiarti quelli e capire bene come funziona
Io le AI ogni tanto le uso, ma quando vado di fretta e principalmente per "pigrizia".
Il concetto di fondo è che conosco prima quale potrebbe essere una risposta corretta e quindi continuo ad istruire il bot fino a quando non produce l'output che mi aspetto e che funziona.
A volte invece, non c'è proprio verso di fargli trovare una soluzione buona; il bot continua a riproporre sempre le stesse cose fino a quando comincia ad inventare istruzioni che nemmeno esistono.
A quel punto mi rimbocco le maniche e vado avanti con il cervello biologico
Spesso ritorno dal bot e gli dico: guarda questo codice, questo è quello che ti chiedevo e cosi funziona. Lui ringrazia ed intanto impara, che poi la caratteristica più interessante delle AI è proprio che imparano dall'esperienza.
Comunque, ho avuto finalmente modo di riguardare con calma il tuo codice prodotto dalla IA ed il problema principale è che il dispositivo che fa da central che tu hai identificato come client, quando trova il peripheral associato non interrompe la scansione con l'istruzione:
BLE.stopScan();
Se un dispositivo sta eseguendo la scansione infatti, non può stabilire una connessione con altri dispositivi.
Per completare lo sketch prodotto dalla IA quindi devi quindi gestire questa cosa:
quando un dispositivo viene trovato [ if (peripheral) ] interrompi la scansione ed avvii la connessione BLE;
quando la connessione viene persa per un qualsiasi motivo, fai ripartire la scansione (altrimenti non saresti più in grado di riconnetterti).
Il consiglio comunque è quello di fare riferimento agli esempi inclusi nella libreria che stai usando, tenendo conto che ciò che tu identifichi come "server" nel mondo BLE è peripheral mentre il "client" è il central.
Il concetto d base è che Il peripheral espone le caratteristiche BLE inviando dei pacchetti di advertising, il central fa la scansione cercando dispositivi con le caratteristiche interessate.
E' importante capire questo aspetto perché nel BLE non esiste l'architettura client/server a dispetto di alcuni esempi che si trovano online, ma quello di central/peripheral e ciascun dispositivo può essere sia l'uno che l'altro anche contemporaneamente.
La situazione è abbastanza drammatica ahah.
Mi sono studiata le funzioni della libreria e la logica che c'è dietro , se ho capito bene dovrebbe essere cosi:
Server (peripheral) --> offre dei servizi, composti da caratteristiche (ovvero i singoli dati, in questo caso lo userò per mandare degli int in console).
Client (central) --> si connette al server, rileva i servizi, e modifica i dati (nel mio caso necessita solo la lettura).
Ho scritto quindi un codice basato sull'idea, aiutandomi con gli esempi della libreria.
Il client riesce a connettersi al server senza problemi, ma non vede i servizi che ha pubblicato, continua infatti a darmi in loop questo output:
SERVER:
Connected to central: f4:12:fa:75:58:3d
scrivo cose
CLIENT:
Peripheral device found!
Device MAC address: 9e:aa:e3:4a:e2:9d
Device name: AD
Advertised service UUID: 19b10000-e8f2-537e-4f6c-d104768a1214
Connecting to peripheral device...
Connected to peripheral device!
Discovering peripheral device attributes...
Peripheral device attributes discovery failed!
Non capisco a questo punto se la colpa sia del server che non pubblica correttamente i suoi servizi, oppure del client che non ha la capacità di vederle.
Questo è il codice al momento:
SERVER:
//Arduino 33 BLE rev2 - SERVER (peripheral)
#include <ArduinoBLE.h>
const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
BLEService NeuroService(deviceServiceUuid); // definisce servizio
BLEByteCharacteristic NeuroDataCHR(deviceServiceCharacteristicUuid, BLERead | BLEWrite);
void setup() {
Serial.begin(9600);
while (!Serial);
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
// Crea nome dispositivo e server
BLE.setLocalName("AD");
BLE.setAdvertisedService(NeuroService);
// aggiunge caratteristica a servizioa
NeuroService.addCharacteristic(NeuroDataCHR);
// aggiunge servizio
BLE.addService(NeuroService);
//val iniziale caratteristica
NeuroDataCHR.writeValue(-1);
// pubblica
BLE.advertise();
Serial.println("start advertising");
}
void loop() {
// listen for Bluetooth® Low Energy peripherals to connect:
BLEDevice central = BLE.central();
// se si connette
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address()); // central MAC address
while (central.connected()) {
/*NeuroDataCHR.writeValue((byte)0x01);
Serial.print("scrivo 0x01");
delay(5000);
NeuroDataCHR.writeValue((byte)0x02);
Serial.print("scrivo 0x02");*/
Serial.println("scrivo cose");
delay(10000);
}
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
CLIENT:
// Arduino Uno R4 - CLIENT (central)
#include <ArduinoBLE.h>
const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
void setup() {
Serial.begin(9600);
while (!Serial);
BLE.begin(); // inizializzazione
Serial.println("cerco...");
}
void loop() {
connectToPeripheral();
}
void connectToPeripheral(){
BLEDevice peripheral;
Serial.println("- Discovering peripheral device...");
do
{
BLE.scanForUuid(deviceServiceUuid); //cerca servizio
peripheral = BLE.available();
} while (!peripheral);
if (peripheral) { //Stampa delle specifiche server a cui si connette
Serial.println("* Peripheral device found!");
Serial.print("* Device MAC address: ");
Serial.println(peripheral.address());
Serial.print("* Device name: ");
Serial.println(peripheral.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(peripheral.advertisedServiceUuid());
Serial.println(" ");
BLE.stopScan();
controlPeripheral(peripheral);
}
}
void controlPeripheral(BLEDevice peripheral) {
Serial.println("- Connecting to peripheral device...");
if (peripheral.connect()) {
Serial.println("* Connected to peripheral device!");
Serial.println(" ");
} else {
Serial.println("* Connection to peripheral device failed!");
Serial.println(" ");
return;
}
//verifica se trova attributi, quindi servizi etc.
Serial.println("- Discovering peripheral device attributes...");
if (peripheral.discoverAttributes()) {
Serial.println("* Peripheral device attributes discovered!");
Serial.println(" ");
} else {
Serial.println("* Peripheral device attributes discovery failed!");
Serial.println(" ");
peripheral.disconnect();
return;
}
int serviceCount = peripheral.serviceCount();
Serial.print(serviceCount);
Serial.println(" services discovered");
//ricerca della caratteristica
BLECharacteristic NeuroDataCHR = peripheral.characteristic(deviceServiceCharacteristicUuid);
if (!NeuroDataCHR) {
Serial.println("* Peripheral device does not have NeuroDataCHR characteristic!");
peripheral.disconnect();
return;
} else if (!NeuroDataCHR.canWrite()) {
Serial.println("* Peripheral does not have a writable NeuroDataCHR characteristic!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) {
Serial.print("* reading value to NeuroDataCHR characteristic: ");
}
Serial.println("- Peripheral device disconnected!");
}
Problema risolto!
Alla fine non ho avuto bisogno di installare l'app, sono riuscita a sistemare qualche ora prima, ma ti ringrazio comunque!! tornerà utile.
Spiegazione soluzione: (nel caso servisse a qualcuno)
SERVER:
Ho impostato un UUID più semplice per evitare errori di battitura durante l'associazione al servizio
Ho spostato più in basso e ridotto il delay, che ho scoperto essere il problema principale (devo ancora capirne il motivo)
CLIENT:
Ho aggiunto una "subscribe()" associato al "BLE.Notify", attivando così le notifiche per modifiche di valori, facendo stampare al client SOLO quando il dato viene modificato, e non più in loop
GENERICO:
Se entrambi non si rilevavano riavviavo l'Arduino dal pulsante.
Se il primo punto non funzionava, ricaricavo il codice.
Se il secondo punto non funzionava, disconnettevo dall'USB, ripristino della scheda da pulsante, e ricarico codice.
Spero sia d'aiuto, lascio anche il codice attuale (a breve lo posterò su GitHub con relativi aggiornamenti, nel caso servisse):
SERVER
//Arduino 33 BLE rev2 - SERVER (peripheral)
#include <ArduinoBLE.h>
const char* deviceServiceUuid = "fff0";
const char* deviceServiceCharacteristicUuid = "fff1";
int randomNumber=0, oldRandomNumber=-1, lastWrittenValue=-1; //valori per simulazione spedizione dati
BLEService NeuroService(deviceServiceUuid); // definisce servizio
BLEByteCharacteristic NeuroDataCHR(deviceServiceCharacteristicUuid, BLERead | BLEWrite | BLENotify); // definisce caratteristic (dato)
void setup() {
Serial.begin(9600);
while (!Serial);
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
// Crea nome dispositivo
BLE.setLocalName("Neuro Arduino");
// crea e pubblica gli attributi
BLE.setAdvertisedService(NeuroService);
NeuroService.addCharacteristic(NeuroDataCHR);
BLE.addService(NeuroService);
NeuroDataCHR.writeValue(-1); //val iniziale caratteristica
BLE.advertise(); // pubblica
Serial.println("start advertising");
}
void loop() {
BLEDevice central = BLE.central(); //cerca client
if (central) { //se connesso
Serial.print("Connected to central: ");
Serial.println(central.address()); // client MAC address
while (central.connected()) {
//SIMULAZIONE INVIO DATI RANDOM 0-1
randomNumber = random(0, 50);
//stampa ed invia i numeri (alternandosi)
if (randomNumber != oldRandomNumber) {
if (randomNumber == 1 && lastWrittenValue != 1) {
NeuroDataCHR.writeValue(1);
Serial.println("scrivo: 1");
lastWrittenValue = 1;
} else if (randomNumber != 1 && lastWrittenValue != 0) {
NeuroDataCHR.writeValue(0);
Serial.println("scrivo: NULL");
lastWrittenValue = 0;
}
oldRandomNumber = randomNumber;
}
delay(100);
}
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
CLIENT
// Arduino Uno R4 - CLIENT (central)
#include <ArduinoBLE.h>
void setup() {
Serial.begin(9600);
while (!Serial)
;
BLE.begin(); // inizializzazione
Serial.println("cerco...");
}
void loop() {
connectToPeripheral();
}
void connectToPeripheral() {
BLEDevice peripheral;
Serial.println("- Discovering peripheral device...");
do {
BLE.scanForUuid("fff0"); //cerca servizio
peripheral = BLE.available();
} while (!peripheral);
if (peripheral) { //Stampa delle specifiche server a cui si connette
Serial.println("* Peripheral device found!");
Serial.print("* Device MAC address: ");
Serial.println(peripheral.address());
Serial.print("* Device name: ");
Serial.println(peripheral.localName());
Serial.print("* Advertised service UUID: ");
Serial.println(peripheral.advertisedServiceUuid());
Serial.println(" ");
BLE.stopScan();
controlPeripheral(peripheral);
}
}
void controlPeripheral(BLEDevice peripheral) {
Serial.println("- Connecting to peripheral device...");
if (peripheral.connect()) {
Serial.println("* Connected to peripheral device!");
Serial.println(" ");
} else {
Serial.println("* Connection to peripheral device failed!");
Serial.println(" ");
return;
}
//verifica se trova attributi, quindi servizi etc.
Serial.println("- Discovering peripheral device attributes...");
if (peripheral.discoverAttributes()) {
Serial.println("* Peripheral device attributes discovered!");
Serial.println(" ");
} else {
Serial.println("* Peripheral device attributes discovery failed!");
Serial.println(" ");
peripheral.disconnect();
return;
}
int serviceCount = peripheral.serviceCount();
//stampa numero di servizi trovati
Serial.print(serviceCount);
Serial.println(" services discovered");
//ricerca della caratteristica "NeuroDataCHR"
BLECharacteristic NeuroDataCHR = peripheral.characteristic("fff1");
if (!NeuroDataCHR) {
Serial.println("* Peripheral device does not have NeuroDataCHR characteristic!");
peripheral.disconnect();
return;
} else if (!NeuroDataCHR.canRead()) {
Serial.println("* Peripheral does not have a writable NeuroDataCHR characteristic!");
peripheral.disconnect();
return;
} else if (!NeuroDataCHR.canSubscribe()) { //Subscribe = notifiche per far funzionare valueUpdated()
Serial.println("NeuroDataCHR characteristic is not subscribable!");
peripheral.disconnect();
return;
} else if (!NeuroDataCHR.subscribe()) {
Serial.println("NeuroDataCHR subscription failed!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) {
if (NeuroDataCHR.valueUpdated()) {
byte value = 0;
NeuroDataCHR.readValue(value);
if (value == 1) {
Serial.println("leggo: 1");
} else if (value == 0) {
Serial.println("leggo: NULL");
} else {
Serial.print("non leggo bene valori, risulta: ");
Serial.println(value);
}
}
}
Serial.println("- Peripheral device disconnected!");
}