Exercise 6 BLE UART
Dependencies: BLE_API X_NUCLEO_IDB0XA1 mbed
Fork of Amaldi_6_BLE_UART_IDB0XA1 by
BLE-UART-IDB0XA1.cpp
- Committer:
- pinofal
- Date:
- 2018-05-12
- Revision:
- 10:2d4a768ae727
File content as of revision 10:2d4a768ae727:
// Tested: NUCLEO-F401RE #include "mbed.h" #include "ble/BLE.h" #include "ble/services/UARTService.h" #include "Serial.h" #define UART_BUFFER (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN*10) const static char DEVICE_NAME[] = "UART"; UARTService *uartServicePtr; // Periferiche DigitalOut Led1(LED1); // LED su scheda Serial pcUSB(USBTX,USBRX); // USB di comunicazione con PC DigitalOut myLED(PB_2); //LED aggiunto esternamente DigitalIn myButton(USER_BUTTON); // USER BUTTON su scheda DigitalOut myRelay(PA_15); // Relay Esterno // Array e indice di comunicazione con UART static uint8_t uartBuff[UART_BUFFER]; static uint8_t uartBuffPos=0; // routine di Error Handling void onBleError(ble_error_t error); // Ticker segnale di vita Ticker LifeTicker; /****************************************************/ /* Ticker attivo quando presente la connessione BLE */ /****************************************************/ void ConnectedBLE(void) { // segnale di vita: accende e spegne il LED Led1 = !Led1; } /************************/ /* Rx da USB e Tx a BLE */ /************************/ void uartRx(void) { // cattura i caratteri dalla USB fino alla fine del messaggio: a '\r' oppure '\n' oppure fino al raggiungimento della massima dimensione del messaggio if(pcUSB.readable()) { uartBuff[uartBuffPos] = pcUSB.getc(); if((uartBuff[uartBuffPos] == '\r') || (uartBuff[uartBuffPos] == '\n') || (uartBuffPos >= UART_BUFFER)) { // inserisce un NUL nell'ultima posizine della stringa uartBuff[uartBuffPos] = '\0'; // We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN, otherwise we need to wait uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); // invia conferma alla USB-PC con la stringa inviata al BLE pcUSB.printf("TX : %s to BLE\r\n", uartBuff); // resetta la stringa uartBuff inserendo 0 ai primi UART_BUFFER caratteri memset(uartBuff, 0, UART_BUFFER); uartBuffPos = 0; } else { // se non è stata raggiunta la fine del messaggio, incrementa il contatore per ricevere il prossimo carattere uartBuffPos++; } } } /*****************************************/ /* Connessione BLE avvenuta con successo */ /*****************************************/ void BleConnectionCallback(const Gap::ConnectionCallbackParams_t *params) { pcUSB.printf("BLE Client Connected!\n\r"); pcUSB.printf("Please type a string and press return\r\n"); // segnale di connessione BLE: accende/spegne il LED con periodo 1sec LifeTicker.attach(ConnectedBLE, 1); } /**********************************/ /* disconnessione del Cliente BLE */ /**********************************/ void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { (void)params; pcUSB.printf("BLE Client Disconnected!\r\n"); // spegne il segnale di connessione BLE: accende/spegne il LED con periodo 1sec LifeTicker.detach(); // restart advertising BLE::Instance().gap().startAdvertising(); Led1=0; } /************************/ /* Rx da BLE e Rx a USB */ /************************/ void BleOnDataWrittenCallback(const GattWriteCallbackParams *params) { // Stringa di risposta in caso di ricezione not OK #define REPLYNOTOK "Rx not Ok :(" // Stringa di risposta in caso di ricezione OK #define REPLYOK "Rx Ok :)" // Stringa di riferimento #define REFERENCESTRING "bho" char caReply[UART_BUFFER]; //uint8_t uaAux[UART_BUFFER]; int nReplyLength; //Risultato del confronto tra srtinghe int nResult; // resetta stringa ausiliaria per comporre le risposte memset(caReply, 0, UART_BUFFER); // riceve stringa da BLE if (params->handle == uartServicePtr->getTXCharacteristicHandle()) { // invia al PC la stringa ricevuta pcUSB.printf("RX: %s from BLE\r\n", params->data); //confronta la stringa ricevuta con una stringa di riferimento nResult=strcmp((char*)(params->data),REFERENCESTRING); if(nResult==0) // ==0 in caso di confronto di stringhe con esito positivo { // se la stringa ricevuta è uguale a quella di riferimento, accende LED myLED = 1; // accendi LED myRelay = 1; // accendi Relay // comunica al PC l'azione eseguita pcUSB.printf("Relay = ON ; LED = ON \r\n"); // Aggiunge NULL alla stringa di risposta OK strcpy(caReply,REPLYOK); nReplyLength = strlen(REPLYOK); caReply[nReplyLength]='\0'; // We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN, otherwise we need to wait uartServicePtr->write(caReply, (nReplyLength/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); } else { // se la stringa ricevuta è uguale a quella di riferimento, spegne LED myLED = 0; // spegni LED myRelay = 0; // spegni Relay // comunica al PC l'azione eseguita pcUSB.printf("Relay = OFF ; LED = OFF \r\n"); // Aggiunge NULL alla stringa di risposta NOT OK strcpy(caReply,REPLYNOTOK); nReplyLength = strlen(REPLYNOTOK); caReply[nReplyLength]='\0'; // We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN, otherwise we need to wait uartServicePtr->write(caReply, (nReplyLength/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); } // !!! PROVARE A INSERIRE IL CASE OF DELL'ESERCIZIO 5 // !!!!! PROVARE in questo punto a inviare un feedback al BLE !!!!!!! // !!!! uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); } } /************************/ /* Errore su canale BLE */ /************************/ void onBleError(ble_error_t error) { pcUSB.printf("BLE Error: %d\r\n"); /* Inserire Handling di errore */ } /******************************************/ /* Inizializzazione del servizio BLE UART */ /******************************************/ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ onBleError(error); return; } /* Ensure that it is the default instance of BLE */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onConnection(BleConnectionCallback); ble.gap().onDisconnection(BleDisconnectionCallback); ble.gattServer().onDataWritten(BleOnDataWrittenCallback); pcUSB.printf("BLE UARTService: "); /* Setup primary service. */ UARTService uartService(ble); uartServicePtr = &uartService; pcUSB.printf("Started\r\n"); /* setup advertising */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(500); /* 500ms. */ ble.gap().startAdvertising(); // rimane in attesa di eventi su BLE while (true) { ble.waitForEvent(); } } /********/ /* MAIN */ /********/ int main(void) { // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto pcUSB.baud(9600); //921600 bps // messaggio di benvenuto pcUSB.printf("\r\nHallo Amaldi Students - Exercise 6 \r\n"); pcUSB.printf("\r\n*** Bluetooth - PC serial communication ***\r\n"); //imposta il funzionamento del pulsante come "PullDown": Aperto = '0'. L'altra modalità di funzinamento è PullUp myButton.mode(PullDown); // inizializza variabili Led1=0; // IRQ associata alla ricezione di caratteri da seriale su USB da PC pcUSB.attach(uartRx,Serial::RxIrq); /****** START Inizializza BLE **********/ BLE &ble = BLE::Instance(); ble.init(bleInitComplete); /******* END Inizializza BLE ***********/ }