Hello, I've read all the similar topics and I'm here to ask your help. I'm trying to connect my Arduino RP2040 to App Inventor, but when I try to send rssi data as strings to App Inventor nothing happens except an error: "Service ..., characteristic ...the are not published by the connected device". I've tried also to use integers or bytes but nothing works.
Notes: with nRF Connect all works fine, so the UUIDS are right and the code is working well.
These are my blocks:
And this is my Arduino code, it need to check the RSSI if is it low send a notification trough Telegram and Blynk, to do that I need to turn off the BLE module of my rp2040, then restart it again after the notification sent.
#include <ArduinoBLE.h>
#include <WiFiNINA.h>
#include <WiFiSSLClient.h>
#include <UniversalTelegramBot.h>
#include <math.h>
// ------ credenziali Blynk ------
#define BLYNK_TEMPLATE_ID "XXXXXXXX"
#define BLYNK_TEMPLATE_NAME "BLE geolocalization"
#define BLYNK_AUTH_TOKEN "XXXXXXXXXXX"
#include <BlynkSimpleWiFiNINA.h> // deve rimanere qui fissa non spostare
// ------ credenziali Wi-Fi ------
char ssid[] = "XXXXXXX";
char password[] = "XXXXXXXXXX";
// ------ credenziali Telegram ------
#define BOT_TOKEN "XXXXXX:XXXXXXXXXXXXXXXXXXXXXXX" // token bot Telegram
#define CHAT_ID "XXXXXXXX"
// ------ inizializzazione variabili ------
WiFiSSLClient client; // gestisce la connessione sicura (SSL)
UniversalTelegramBot bot(BOT_TOKEN, client);
BLEService alertService("12345678-1234-5678-1234-56789abcdef0"); // UUID custom
BLEStringCharacteristic alertChar("abcdef01-1234-5678-1234-56789abcdef0", // 7
BLERead | BLENotify, 20);
const int SOGLIA = -65; // soglia di allontanamento
const int SOGLIA_OK = -60; // soglia di ritorno (hysteresis)
bool alertPending = false;
bool alertSent = false;
String strValue = "0";
const int measured_pw = -57; // potenza misurata a 1 metro di distanza
const float n = 2.0; // attenuazione dello spazio libero (2-4) indoor
// ------ funzioni ------
bool inviaNotifica(int rssi, float distance) {
Serial.println("Connessione WiFi per inviare notifica...");
int status = WiFi.begin(ssid,password); // accendo il modulo Wi-Fi
unsigned long startAttempt = millis();
// aspetto la corretta attivazione del Wi-Fi entro 10 secondi
while (status != WL_CONNECTED && millis() - startAttempt < 10000) {
delay(500);
status = WiFi.status(); // controlla lo stato della connessione
Serial.print(".");
}
// se connessione non riuscita vai avanti senza ritentare
if (status != WL_CONNECTED) {
Serial.println("\nErrore WiFi: impossibile inviare notifica, continuo il programma...");
return false;
} else {
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password); // avvia la sessione Blynk solo se il wi-fi è attivo
Serial.println("WiFi connesso âś…");
}
delay(200);
// ------ notifica Telegram ------
String messagge = "Attenzione! Il telefono si è allontanato.\n";
messagge += "Ultimo RSSI = " + String(rssi) + " dBm.\n" + "La distanza stimata è pari a " + String(distance,2) + " metri";
bool ok = bot.sendMessage(CHAT_ID, messagge, ""); // comando di invia notifica
Serial.println(ok ? "Notifica inviata" : "Errore invio notifica Telegram"); // informa l'utente sull'esito della notifica
// ------ notifica Blynk IoT -------
Blynk.virtualWrite(V0, distance);
Blynk.virtualWrite(V1, rssi);
Blynk.logEvent("distance_alert", "⚠️ Ti sei allontanato troppo! d = " + String(distance,2) + " metri");
delay(1000); // aspetta prima di chiudere la sessione con il server di Blynk
Blynk.disconnect();
WiFi.disconnect();
delay(500); // permette la corretta disconessione
WiFi.end(); // termina il modulo Wi-Fi
return ok;
}
// avvia il modulo BLE del RP2040
void startBLE() {
if(!BLE.begin()){
Serial.println("Starting BLE module failed!");
while(1);
}
Serial.println("Successfully BLE module activeted!");
BLE.setLocalName("RP2040");
BLE.setAdvertisedService(alertService); // setto caretteristica e servizio
alertService.addCharacteristic(alertChar);
BLE.addService(alertService);
BLE.advertise(); // Arduino inizia a fare advertising
}
// ------ setup ------
void setup() {
Serial.begin(115200);
while(!Serial); // aspetta che il monitor seriale sia pronto
startBLE(); // inizializzo il modulo BLE
alertChar.writeValue(strValue);
}
// ------ loop ------
void loop() {
BLEDevice central = BLE.central();
// ottiene rssi se connesso e calcolo distanza
if (central && central.connected()) {
int rssi = central.rssi();
strValue = String(rssi);
float distance = pow(10,((measured_pw-rssi)/(n*10)));
if (rssi == 127){
Serial.println("Telefono disconnesso! (RSSI= 127)");
} else {
Serial.print("RSSI = ");
Serial.println(rssi);
}
alertChar.writeValue(strValue);
delay(200); // serve per far arrivare correttamente ad app inventor il messaggio
// logica soglia
if (rssi < SOGLIA && !alertSent) {
alertPending = true;
} else if (rssi > SOGLIA_OK) {
alertSent = false; // reset
}
// invio notifica se serve
if (alertPending) {
BLE.end(); // spengo il modulo BLE così da evitare conflitti
if (inviaNotifica(rssi,distance)) {
Serial.print("La distanza stimata del dispositivo è : ");
Serial.print(distance);
Serial.println(" metri");
alertSent = true;
alertPending = false;
} else {
alertPending = false; // se la inviaNotifica fallisce il programma va avanti
}
startBLE();
}
}
else {
Serial.println("Telefono non connesso, ritenta connessione...");
}
delay(3000); // ogni 3 sec ripeto il ciclo
}