#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// Codice Server
#define SERVICE_UUID "79c79196-51cb-4f67-9520-9bc63e6597c1"
#define CHARACTERISTIC_UUID "e3038128-ca03-4f22-9f0d-b6547426dc6a"
#define led_Sinistra 2
#define led_Destra 4
#define led_Su 18
#define led_Giu 14
#define led_Fuoco 12
#define led_Connessione 26 // LED di connessione
#define pin_OE 23 // Pin OE del TXS0108E e controllo livello logico
#define pin_A5 32 // Pin A5 del Bridge Connector
#define pin_IORQ 33 // Pin IORQ del Bridge Connector
BLEServer *pServer;
BLEService *pService;
BLECharacteristic *pCharacteristic;
int c = 0;
int i = 0;
bool connected = false;
const long timeout = 4 * 60 * 1000; // Timeout di 5 minuti in millisecondi
// Variabili per la gestione del lampeggiamento del LED con millis()
unsigned long previousMillis = 0; // Variabile per salvare l'ultimo tempo di lampeggio
const long interval = 100; // Intervallo di lampeggio in millisecondi
bool ledState = LOW; // Stato del LED
void setup() {
Serial.begin(115200);
Serial.println("Avvio del Server BLE!");
BLEDevice::init("ESP32-BLE-Server");
pServer = BLEDevice::createServer();
pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pinMode(led_Sinistra, OUTPUT);
pinMode(led_Destra, OUTPUT);
pinMode(led_Su, OUTPUT);
pinMode(led_Giu, OUTPUT);
pinMode(led_Fuoco, OUTPUT);
pinMode(led_Connessione, OUTPUT); // LED di connessione
pinMode(pin_OE, OUTPUT); // Pin OE per controllo TXS0108E
pinMode(pin_A5, INPUT); // Pin A5 del Bridge Connector dello ZX Spectrum
pinMode(pin_IORQ, INPUT); // Pin IORQ del Bridge Connector dello ZX Spectrum
digitalWrite(pin_OE, LOW); // Disabilita il TXS0108E di default
pCharacteristic->setValue("In attesa del segnale!");
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Caratteristica definita! Ora puoi leggerla nel Client!");
}
// Variabili per memorizzare lo stato dei LED
bool led_Destra_State = LOW;
bool led_Sinistra_State = LOW;
bool led_Su_State = LOW;
bool led_Giu_State = LOW;
bool led_Fuoco_State = LOW;
void loop() {
// Controlla e aggiorna l'abilitazione del TXS0108E
bool A5 = digitalRead(pin_A5);
bool IORQ = digitalRead(pin_IORQ);
Serial.print("A5: ");
Serial.println(A5);
Serial.print("IORQ: ");
Serial.println(IORQ);
Serial.print("Connected: ");
Serial.println(connected);
Serial.println("C :");
Serial.println(c);
Serial.println(led_Destra_State);
Serial.println(led_Sinistra_State);
Serial.println(led_Giu_State);
Serial.println(led_Su_State);
Serial.println(led_Fuoco_State);
if (A5 == 0 && IORQ == 0 && connected) {
digitalWrite(pin_OE, HIGH); // Abilita il TXS0108E
} else {
digitalWrite(pin_OE, LOW); // Disabilita il TXS0108E
}
Serial.print("OE: ");
Serial.println(digitalRead(pin_OE));
// Ottenere il valore della caratteristica
String value = pCharacteristic->getValue().c_str();
Serial.println("Il nuovo valore della caratteristica è: ");
Serial.println(value);
Serial.println("i è uguale a : ");
Serial.println(i);
// Calcola quante volte non arriva la caratteristica (value="nessun segnale")
if (value == "nessun segnale" && connected == true) {
i = i + 1;
} else if (value != "nessun segnale" && connected == true) {
i = 0;
}
// Verifica lo stato di connessione del server
unsigned long currentMillis = millis();
if (value == "In attesa del segnale!" && connected == false) {
// Lampeggiamento del LED quando il server è scollegato usando millis()
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
ledState = !ledState; // Inverti lo stato del LED
digitalWrite(led_Connessione, ledState); // Aggiorna il LED
}
}
// Verifica lo stato di connessione del server se "nessun segnale" è arrivato al timeout di 5 minuti
else if (value == "nessun segnale" && connected == true && i >= int(timeout / 11)) {
// Il client è scollegato o non trasmette, spegni LED e TXS0108E
digitalWrite(led_Connessione, LOW);
digitalWrite(pin_OE, LOW);
ledState = LOW; // Reset dello stato del LED
} else if (value == "nessun segnale") {
// Accendi il LED e il pin OE quando il server è connesso
digitalWrite(led_Connessione, HIGH);
if (A5 == 0 && IORQ == 0 && connected) {
digitalWrite(pin_OE, HIGH); // Abilita TXS0108E
}
connected = true;
}
Serial.println("Tempo è uguale: ");
Serial.println(millis());
// Controlla se il client è ancora connesso
if (pServer->getConnectedCount() > 0) {
// Significa che c'è almeno un client connesso al server
if (!connected) {
connected = true;
Serial.println("Client connesso!");
c = 1; // Reset della variabile c
digitalWrite(led_Connessione, HIGH); // Accendi LED connessione
if (A5 == LOW && IORQ == LOW) {
digitalWrite(pin_OE, HIGH); // Abilita TXS0108E
}
}
} else {
// Significa che non ci sono client connessi al server
if (connected) {
connected = false;
Serial.println("Client scollegato!");
c = 2;
digitalWrite(led_Connessione, LOW); // Spegni LED connessione
digitalWrite(pin_OE, LOW); // Disabilita TXS0108E
ledState = LOW; // Reset dello stato del LED
previousMillis = currentMillis; // Reset del timer
}
}
// Riavvia il server BLE se il client è stato scollegato
if (c == 2) {
Serial.println(c);
Serial.println("Riavvio del server BLE...");
BLEDevice::deinit(); // Disabilita il server BLE
delay(1000); // Attende un secondo prima di riavviare
BLEDevice::init("ESP32-BLE-Server"); // Reinizializza il server BLE
pServer = BLEDevice::createServer();
pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("In attesa del segnale!");
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
c = 0; // Reset della variabile c
Serial.println("Server BLE riavviato!");
}
// Aggiorna lo stato dei LED in base al valore
if (value == "destra_su_fuoco") {
led_Destra_State = HIGH;
led_Su_State = HIGH;
led_Fuoco_State = HIGH;
led_Sinistra_State = LOW;
led_Giu_State = LOW;
} else if (value == "destra_giù_fuoco") {
led_Destra_State = HIGH;
led_Giu_State = HIGH;
led_Fuoco_State = HIGH;
led_Sinistra_State = LOW;
led_Su_State = LOW;
} else if (value == "sinistra_giù_fuoco") {
led_Sinistra_State = HIGH;
led_Giu_State = HIGH;
led_Fuoco_State = HIGH;
led_Destra_State = LOW;
led_Su_State = LOW;
} else if (value == "sinistra_su_fuoco") {
led_Sinistra_State = HIGH;
led_Su_State = HIGH;
led_Fuoco_State = HIGH;
led_Destra_State = LOW;
led_Giu_State = LOW;
} else if (value == "destra_fuoco") {
led_Destra_State = HIGH;
led_Fuoco_State = HIGH;
led_Sinistra_State = LOW;
led_Su_State = LOW;
led_Giu_State = LOW;
} else if (value == "sinistra_fuoco") {
led_Sinistra_State = HIGH;
led_Fuoco_State = HIGH;
led_Destra_State = LOW;
led_Su_State = LOW;
led_Giu_State = LOW;
} else if (value == "su_fuoco") {
led_Su_State = HIGH;
led_Fuoco_State = HIGH;
led_Destra_State = LOW;
led_Sinistra_State = LOW;
led_Giu_State = LOW;
} else if (value == "giù_fuoco") {
led_Giu_State = HIGH;
led_Fuoco_State = HIGH;
led_Destra_State = LOW;
led_Sinistra_State = LOW;
led_Su_State = LOW;
} else if (value == "destra_su") {
led_Destra_State = HIGH;
led_Su_State = HIGH;
led_Fuoco_State = LOW;
led_Sinistra_State = LOW;
led_Giu_State = LOW;
} else if (value == "destra_giù") {
led_Destra_State = HIGH;
led_Giu_State = HIGH;
led_Fuoco_State = LOW;
led_Sinistra_State = LOW;
led_Su_State = LOW;
} else if (value == "sinistra_giù") {
led_Sinistra_State = HIGH;
led_Giu_State = HIGH;
led_Fuoco_State = LOW;
led_Destra_State = LOW;
led_Su_State = LOW;
} else if (value == "sinistra_su") {
led_Sinistra_State = HIGH;
led_Su_State = HIGH;
led_Fuoco_State = LOW;
led_Destra_State = LOW;
led_Giu_State = LOW;
} else if (value == "destra") {
led_Destra_State = HIGH;
led_Fuoco_State = LOW;
led_Sinistra_State = LOW;
led_Su_State = LOW;
led_Giu_State = LOW;
} else if (value == "sinistra") {
led_Sinistra_State = HIGH;
led_Fuoco_State = LOW;
led_Destra_State = LOW;
led_Su_State = LOW;
led_Giu_State = LOW;
} else if (value == "su") {
led_Su_State = HIGH;
led_Fuoco_State = LOW;
led_Destra_State = LOW;
led_Sinistra_State = LOW;
led_Giu_State = LOW;
} else if (value == "giù") {
led_Giu_State = HIGH;
led_Fuoco_State = LOW;
led_Destra_State = LOW;
led_Sinistra_State = LOW;
led_Su_State = LOW;
} else if (value == "fuoco") {
led_Fuoco_State = HIGH;
led_Destra_State = LOW;
led_Sinistra_State = LOW;
led_Su_State = LOW;
led_Giu_State = LOW;
} else {
// Se il valore non corrisponde a nessuna condizione, spegni tutti i LED
led_Destra_State = LOW;
led_Sinistra_State = LOW;
led_Su_State = LOW;
led_Giu_State = LOW;
led_Fuoco_State = LOW;
}
// Aggiorna i LED con i valori dello stato
digitalWrite(led_Destra, led_Destra_State);
digitalWrite(led_Sinistra, led_Sinistra_State);
digitalWrite(led_Su, led_Su_State);
digitalWrite(led_Giu, led_Giu_State);
digitalWrite(led_Fuoco, led_Fuoco_State);
}