#include "BLEDevice.h"
/* Specifica l'UUID del servizio del server */
// Codice client
static BLEUUID serviceUUID("79c79196-51cb-4f67-9520-9bc63e6597c1");
/* Specifica l'UUID della caratteristica del server */
static BLEUUID charUUID("e3038128-ca03-4f22-9f0d-b6547426dc6a");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
int buttonStateL;
int buttonStateR;
int buttonStateU;
int buttonStateD;
int buttonStateF;
#define buttonL 18
#define buttonR 19
#define buttonU 21
#define buttonD 22
#define buttonF 23
#define led_Connessione 33
int i = 0;
const long interval = 100; // Intervallo di lampeggiamento in millisecondi
const long timeout = 1 * 60 * 1000; // Timeout di 5 minuti in millisecond
unsigned long previousMillis = 0;
bool ledState = false;
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify)
{
Serial.print("Callback di notifica per la caratteristica ");
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" di lunghezza dati ");
Serial.println(length);
Serial.print("dati: ");
Serial.println((char*)pData);
}
class MyClientCallback : public BLEClientCallbacks
{
void onConnect(BLEClient* pclient)
{
}
void onDisconnect(BLEClient* pclient)
{
connected = false;
Serial.println("Disconnesso");
}
};
/* Avvia la connessione al server BLE */
bool connectToServer()
{
Serial.print("Formazione di una connessione a ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Cliente creato");
pClient->setClientCallbacks(new MyClientCallback());
/* Connetti al server BLE remoto */
pClient->connect(myDevice); // se passi BLEAdvertisedDevice invece dell'indirizzo, verrà riconosciuto il tipo di indirizzo del dispositivo peer (pubblico o privato)
Serial.println(" - Connesso al server");
/* Ottieni un riferimento al servizio che stiamo cercando nel server BLE remoto */
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr)
{
Serial.print("Impossibile trovare il nostro servizio UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Trovato il nostro servizio");
/* Ottieni un riferimento alla caratteristica nel servizio del server BLE remoto */
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr)
{
Serial.print("Impossibile trovare la nostra caratteristica UUID: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Trovata la nostra caratteristica");
/* Leggi il valore della caratteristica */
/* Il valore iniziale è 'Ciao, mondo!' */
if (pRemoteCharacteristic->canRead())
{
std::string value = pRemoteCharacteristic->readValue();
Serial.print("Il valore della caratteristica era: ");
Serial.println(value.c_str());
}
if (pRemoteCharacteristic->canNotify())
{
pRemoteCharacteristic->registerForNotify(notifyCallback);
}
connected = true;
return true;
}
/* Scansiona i server BLE e trova il primo che pubblicizza il servizio che stiamo cercando. */
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
/* Chiamato per ciascun server BLE pubblicizzato. */
void onResult(BLEAdvertisedDevice advertisedDevice)
{
Serial.print("Dispositivo BLE pubblicizzato trovato: ");
Serial.println(advertisedDevice.toString().c_str());
/* Abbiamo trovato un dispositivo, vediamo ora se contiene il servizio che stiamo cercando. */
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID))
{
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
}
}
};
void setup()
{
Serial.begin(115200);
Serial.println("Avvio dell'applicazione cliente Arduino BLE...");
BLEDevice::init("ESP32-BLE-Client");
pinMode(buttonL, INPUT_PULLUP);
pinMode(buttonR, INPUT_PULLUP);
pinMode(buttonU, INPUT_PULLUP);
pinMode(buttonD, INPUT_PULLUP);
pinMode(buttonF, INPUT_PULLUP);
pinMode(led_Connessione, OUTPUT);
/* Recupera uno Scanner e imposta il callback che vogliamo utilizzare per essere informati quando abbiamo
rilevato un nuovo dispositivo. Specifica che desideriamo una scansione attiva e avviamo la
scansione per eseguire per 5 secondi. */
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
}
void loop()
{
/* Se il flag "doConnect" è true, allora abbiamo scansionato e trovato il desiderato
Server BLE con cui vogliamo connetterci. Ora ci connettiamo ad esso. Una volta che siamo
connessi, impostiamo il flag connected su true. */
if (doConnect == true)
{
if (connectToServer())
{
Serial.println("Siamo ora connessi al server BLE.");
}
else
{
Serial.println("Non siamo riusciti a connetterci al server; non faremo altro.");
}
doConnect = false;
}
/* Se siamo connessi a un server BLE peer, aggiorna la caratteristica ogni volta che siamo raggiunti
con l'ora corrente dall'avvio */
unsigned long currentMillis = millis();
// Controllo del lampeggio del LED
if (!connected)
{
// Se disconnesso, lampeggio del LED
if (currentMillis - previousMillis >= interval)
{
// Inverte lo stato del LED
ledState = !ledState;
digitalWrite(led_Connessione, ledState ? HIGH : LOW);
// Aggiorna il tempo precedente
previousMillis = currentMillis;
}
}
if (connected)
{
String newValue = "";
buttonStateL = digitalRead(buttonL);
buttonStateR = digitalRead(buttonR);
buttonStateU = digitalRead(buttonU);
buttonStateD = digitalRead(buttonD);
buttonStateF = digitalRead(buttonF);
if (buttonStateR == LOW && buttonStateU == LOW && buttonStateF == LOW) {
newValue = "destra_su_fuoco";
}
else if (buttonStateR == LOW && buttonStateD == LOW && buttonStateF == LOW) {
newValue = "destra_giù_fuoco";
}
else if (buttonStateL == LOW && buttonStateU == LOW && buttonStateF == LOW) {
newValue = "sinistra_su_fuoco";
}
else if (buttonStateL == LOW && buttonStateD == LOW && buttonStateF == LOW) {
newValue = "sinistra_giù_fuoco";
}
else if (buttonStateU == LOW && buttonStateF == LOW) {
newValue = "su_fuoco";
}
else if (buttonStateD == LOW && buttonStateF == LOW) {
newValue = "giù_fuoco";
}
else if (buttonStateL == LOW && buttonStateF == LOW) {
newValue = "sinistra_fuoco";
}
else if (buttonStateR == LOW && buttonStateF == LOW) {
newValue = "destra_fuoco";
}
else if (buttonStateR == LOW && buttonStateU == LOW) {
newValue = "destra_su";
}
else if (buttonStateR == LOW && buttonStateD == LOW) {
newValue = "destra_giù";
}
else if (buttonStateL == LOW && buttonStateU == LOW) {
newValue = "sinistra_su";
}
else if (buttonStateL == LOW && buttonStateD == LOW) {
newValue = "sinistra_giù";
}
else if (buttonStateL == LOW)
{
newValue = "sinistra";
}
else if (buttonStateR == LOW)
{
newValue = "destra";
}
else if (buttonStateU == LOW)
{
newValue = "su";
}
else if (buttonStateD == LOW)
{
newValue = "giù";
}
else if (buttonStateF == LOW)
{
newValue = "fuoco";
}
else
{
newValue = "nessun segnale";
}
Serial.println(newValue);
Serial.println("i è uguale a : ");
Serial.println(i);
Serial.println("Tempo è uguale: ");
Serial.println(millis());
{
if (newValue == "nessun segnale")
{
i = i + 1;
}
else if (newValue != "nessun segnale")
{
i = 0;
}
if (newValue == "nessun segnale" && i < int(timeout / 35))
{
// Il server è collegato ed ancora siamo sotto il timeout
digitalWrite(led_Connessione, HIGH); // Accendi il led connessione
}
if (newValue == "nessun segnale" && i >= int(timeout / 35))
{
// Il server, o è scollegato, oppure non sta trasmettendo la caratteristica, spegni il led connessione
digitalWrite(led_Connessione, LOW); // Spegni il led
}
/* Imposta il valore della caratteristica come l'array di byte che è effettivamente una stringa */
pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
/* Puoi vedere questo valore aggiornato nella Caratteristica del Server */
}
}
else if (doScan)
{
BLEDevice::getScan()->start(0); // modo migliore per farlo in Arduino
}
}