Exercise 6 BLE UART

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_UART_IDB0XA1 by Waby Bubu

Committer:
pinofal
Date:
Sat May 12 13:05:57 2018 +0000
Revision:
10:2d4a768ae727
Amaldi Exercise 6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pinofal 10:2d4a768ae727 1 // Tested: NUCLEO-F401RE
pinofal 10:2d4a768ae727 2
pinofal 10:2d4a768ae727 3 #include "mbed.h"
pinofal 10:2d4a768ae727 4 #include "ble/BLE.h"
pinofal 10:2d4a768ae727 5 #include "ble/services/UARTService.h"
pinofal 10:2d4a768ae727 6 #include "Serial.h"
pinofal 10:2d4a768ae727 7
pinofal 10:2d4a768ae727 8 #define UART_BUFFER (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN*10)
pinofal 10:2d4a768ae727 9
pinofal 10:2d4a768ae727 10 const static char DEVICE_NAME[] = "UART";
pinofal 10:2d4a768ae727 11 UARTService *uartServicePtr;
pinofal 10:2d4a768ae727 12
pinofal 10:2d4a768ae727 13 // Periferiche
pinofal 10:2d4a768ae727 14 DigitalOut Led1(LED1); // LED su scheda
pinofal 10:2d4a768ae727 15 Serial pcUSB(USBTX,USBRX); // USB di comunicazione con PC
pinofal 10:2d4a768ae727 16 DigitalOut myLED(PB_2); //LED aggiunto esternamente
pinofal 10:2d4a768ae727 17 DigitalIn myButton(USER_BUTTON); // USER BUTTON su scheda
pinofal 10:2d4a768ae727 18 DigitalOut myRelay(PA_15); // Relay Esterno
pinofal 10:2d4a768ae727 19
pinofal 10:2d4a768ae727 20
pinofal 10:2d4a768ae727 21 // Array e indice di comunicazione con UART
pinofal 10:2d4a768ae727 22 static uint8_t uartBuff[UART_BUFFER];
pinofal 10:2d4a768ae727 23 static uint8_t uartBuffPos=0;
pinofal 10:2d4a768ae727 24
pinofal 10:2d4a768ae727 25 // routine di Error Handling
pinofal 10:2d4a768ae727 26 void onBleError(ble_error_t error);
pinofal 10:2d4a768ae727 27
pinofal 10:2d4a768ae727 28
pinofal 10:2d4a768ae727 29 // Ticker segnale di vita
pinofal 10:2d4a768ae727 30 Ticker LifeTicker;
pinofal 10:2d4a768ae727 31
pinofal 10:2d4a768ae727 32
pinofal 10:2d4a768ae727 33
pinofal 10:2d4a768ae727 34 /****************************************************/
pinofal 10:2d4a768ae727 35 /* Ticker attivo quando presente la connessione BLE */
pinofal 10:2d4a768ae727 36 /****************************************************/
pinofal 10:2d4a768ae727 37 void ConnectedBLE(void)
pinofal 10:2d4a768ae727 38 {
pinofal 10:2d4a768ae727 39 // segnale di vita: accende e spegne il LED
pinofal 10:2d4a768ae727 40 Led1 = !Led1;
pinofal 10:2d4a768ae727 41 }
pinofal 10:2d4a768ae727 42
pinofal 10:2d4a768ae727 43 /************************/
pinofal 10:2d4a768ae727 44 /* Rx da USB e Tx a BLE */
pinofal 10:2d4a768ae727 45 /************************/
pinofal 10:2d4a768ae727 46 void uartRx(void)
pinofal 10:2d4a768ae727 47 {
pinofal 10:2d4a768ae727 48 // cattura i caratteri dalla USB fino alla fine del messaggio: a '\r' oppure '\n' oppure fino al raggiungimento della massima dimensione del messaggio
pinofal 10:2d4a768ae727 49 if(pcUSB.readable())
pinofal 10:2d4a768ae727 50 {
pinofal 10:2d4a768ae727 51 uartBuff[uartBuffPos] = pcUSB.getc();
pinofal 10:2d4a768ae727 52 if((uartBuff[uartBuffPos] == '\r') || (uartBuff[uartBuffPos] == '\n') || (uartBuffPos >= UART_BUFFER))
pinofal 10:2d4a768ae727 53 {
pinofal 10:2d4a768ae727 54 // inserisce un NUL nell'ultima posizine della stringa
pinofal 10:2d4a768ae727 55 uartBuff[uartBuffPos] = '\0';
pinofal 10:2d4a768ae727 56 // We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN, otherwise we need to wait
pinofal 10:2d4a768ae727 57 uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
pinofal 10:2d4a768ae727 58 // invia conferma alla USB-PC con la stringa inviata al BLE
pinofal 10:2d4a768ae727 59 pcUSB.printf("TX : %s to BLE\r\n", uartBuff);
pinofal 10:2d4a768ae727 60 // resetta la stringa uartBuff inserendo 0 ai primi UART_BUFFER caratteri
pinofal 10:2d4a768ae727 61 memset(uartBuff, 0, UART_BUFFER);
pinofal 10:2d4a768ae727 62 uartBuffPos = 0;
pinofal 10:2d4a768ae727 63 }
pinofal 10:2d4a768ae727 64 else
pinofal 10:2d4a768ae727 65 {
pinofal 10:2d4a768ae727 66 // se non è stata raggiunta la fine del messaggio, incrementa il contatore per ricevere il prossimo carattere
pinofal 10:2d4a768ae727 67 uartBuffPos++;
pinofal 10:2d4a768ae727 68 }
pinofal 10:2d4a768ae727 69 }
pinofal 10:2d4a768ae727 70 }
pinofal 10:2d4a768ae727 71
pinofal 10:2d4a768ae727 72 /*****************************************/
pinofal 10:2d4a768ae727 73 /* Connessione BLE avvenuta con successo */
pinofal 10:2d4a768ae727 74 /*****************************************/
pinofal 10:2d4a768ae727 75 void BleConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
pinofal 10:2d4a768ae727 76 {
pinofal 10:2d4a768ae727 77 pcUSB.printf("BLE Client Connected!\n\r");
pinofal 10:2d4a768ae727 78 pcUSB.printf("Please type a string and press return\r\n");
pinofal 10:2d4a768ae727 79
pinofal 10:2d4a768ae727 80 // segnale di connessione BLE: accende/spegne il LED con periodo 1sec
pinofal 10:2d4a768ae727 81 LifeTicker.attach(ConnectedBLE, 1);
pinofal 10:2d4a768ae727 82 }
pinofal 10:2d4a768ae727 83
pinofal 10:2d4a768ae727 84 /**********************************/
pinofal 10:2d4a768ae727 85 /* disconnessione del Cliente BLE */
pinofal 10:2d4a768ae727 86 /**********************************/
pinofal 10:2d4a768ae727 87 void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
pinofal 10:2d4a768ae727 88 {
pinofal 10:2d4a768ae727 89 (void)params;
pinofal 10:2d4a768ae727 90 pcUSB.printf("BLE Client Disconnected!\r\n");
pinofal 10:2d4a768ae727 91 // spegne il segnale di connessione BLE: accende/spegne il LED con periodo 1sec
pinofal 10:2d4a768ae727 92 LifeTicker.detach();
pinofal 10:2d4a768ae727 93
pinofal 10:2d4a768ae727 94 // restart advertising
pinofal 10:2d4a768ae727 95 BLE::Instance().gap().startAdvertising();
pinofal 10:2d4a768ae727 96 Led1=0;
pinofal 10:2d4a768ae727 97 }
pinofal 10:2d4a768ae727 98
pinofal 10:2d4a768ae727 99 /************************/
pinofal 10:2d4a768ae727 100 /* Rx da BLE e Rx a USB */
pinofal 10:2d4a768ae727 101 /************************/
pinofal 10:2d4a768ae727 102 void BleOnDataWrittenCallback(const GattWriteCallbackParams *params)
pinofal 10:2d4a768ae727 103 {
pinofal 10:2d4a768ae727 104 // Stringa di risposta in caso di ricezione not OK
pinofal 10:2d4a768ae727 105 #define REPLYNOTOK "Rx not Ok :("
pinofal 10:2d4a768ae727 106 // Stringa di risposta in caso di ricezione OK
pinofal 10:2d4a768ae727 107 #define REPLYOK "Rx Ok :)"
pinofal 10:2d4a768ae727 108 // Stringa di riferimento
pinofal 10:2d4a768ae727 109 #define REFERENCESTRING "bho"
pinofal 10:2d4a768ae727 110
pinofal 10:2d4a768ae727 111 char caReply[UART_BUFFER];
pinofal 10:2d4a768ae727 112 //uint8_t uaAux[UART_BUFFER];
pinofal 10:2d4a768ae727 113 int nReplyLength;
pinofal 10:2d4a768ae727 114
pinofal 10:2d4a768ae727 115 //Risultato del confronto tra srtinghe
pinofal 10:2d4a768ae727 116 int nResult;
pinofal 10:2d4a768ae727 117
pinofal 10:2d4a768ae727 118 // resetta stringa ausiliaria per comporre le risposte
pinofal 10:2d4a768ae727 119 memset(caReply, 0, UART_BUFFER);
pinofal 10:2d4a768ae727 120
pinofal 10:2d4a768ae727 121 // riceve stringa da BLE
pinofal 10:2d4a768ae727 122 if (params->handle == uartServicePtr->getTXCharacteristicHandle())
pinofal 10:2d4a768ae727 123 {
pinofal 10:2d4a768ae727 124 // invia al PC la stringa ricevuta
pinofal 10:2d4a768ae727 125 pcUSB.printf("RX: %s from BLE\r\n", params->data);
pinofal 10:2d4a768ae727 126
pinofal 10:2d4a768ae727 127 //confronta la stringa ricevuta con una stringa di riferimento
pinofal 10:2d4a768ae727 128 nResult=strcmp((char*)(params->data),REFERENCESTRING);
pinofal 10:2d4a768ae727 129 if(nResult==0) // ==0 in caso di confronto di stringhe con esito positivo
pinofal 10:2d4a768ae727 130 {
pinofal 10:2d4a768ae727 131 // se la stringa ricevuta è uguale a quella di riferimento, accende LED
pinofal 10:2d4a768ae727 132 myLED = 1; // accendi LED
pinofal 10:2d4a768ae727 133 myRelay = 1; // accendi Relay
pinofal 10:2d4a768ae727 134
pinofal 10:2d4a768ae727 135 // comunica al PC l'azione eseguita
pinofal 10:2d4a768ae727 136 pcUSB.printf("Relay = ON ; LED = ON \r\n");
pinofal 10:2d4a768ae727 137
pinofal 10:2d4a768ae727 138 // Aggiunge NULL alla stringa di risposta OK
pinofal 10:2d4a768ae727 139 strcpy(caReply,REPLYOK);
pinofal 10:2d4a768ae727 140 nReplyLength = strlen(REPLYOK);
pinofal 10:2d4a768ae727 141 caReply[nReplyLength]='\0';
pinofal 10:2d4a768ae727 142
pinofal 10:2d4a768ae727 143 // We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN, otherwise we need to wait
pinofal 10:2d4a768ae727 144 uartServicePtr->write(caReply, (nReplyLength/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
pinofal 10:2d4a768ae727 145 }
pinofal 10:2d4a768ae727 146 else
pinofal 10:2d4a768ae727 147 {
pinofal 10:2d4a768ae727 148 // se la stringa ricevuta è uguale a quella di riferimento, spegne LED
pinofal 10:2d4a768ae727 149 myLED = 0; // spegni LED
pinofal 10:2d4a768ae727 150 myRelay = 0; // spegni Relay
pinofal 10:2d4a768ae727 151
pinofal 10:2d4a768ae727 152 // comunica al PC l'azione eseguita
pinofal 10:2d4a768ae727 153 pcUSB.printf("Relay = OFF ; LED = OFF \r\n");
pinofal 10:2d4a768ae727 154
pinofal 10:2d4a768ae727 155 // Aggiunge NULL alla stringa di risposta NOT OK
pinofal 10:2d4a768ae727 156 strcpy(caReply,REPLYNOTOK);
pinofal 10:2d4a768ae727 157 nReplyLength = strlen(REPLYNOTOK);
pinofal 10:2d4a768ae727 158 caReply[nReplyLength]='\0';
pinofal 10:2d4a768ae727 159
pinofal 10:2d4a768ae727 160 // We are sending the whole string even if less than BLE_UART_SERVICE_MAX_DATA_LEN, otherwise we need to wait
pinofal 10:2d4a768ae727 161 uartServicePtr->write(caReply, (nReplyLength/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
pinofal 10:2d4a768ae727 162
pinofal 10:2d4a768ae727 163 }
pinofal 10:2d4a768ae727 164 // !!! PROVARE A INSERIRE IL CASE OF DELL'ESERCIZIO 5
pinofal 10:2d4a768ae727 165 // !!!!! PROVARE in questo punto a inviare un feedback al BLE !!!!!!!
pinofal 10:2d4a768ae727 166 // !!!! uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
pinofal 10:2d4a768ae727 167
pinofal 10:2d4a768ae727 168 }
pinofal 10:2d4a768ae727 169 }
pinofal 10:2d4a768ae727 170
pinofal 10:2d4a768ae727 171 /************************/
pinofal 10:2d4a768ae727 172 /* Errore su canale BLE */
pinofal 10:2d4a768ae727 173 /************************/
pinofal 10:2d4a768ae727 174 void onBleError(ble_error_t error)
pinofal 10:2d4a768ae727 175 {
pinofal 10:2d4a768ae727 176 pcUSB.printf("BLE Error: %d\r\n");
pinofal 10:2d4a768ae727 177 /* Inserire Handling di errore */
pinofal 10:2d4a768ae727 178 }
pinofal 10:2d4a768ae727 179
pinofal 10:2d4a768ae727 180 /******************************************/
pinofal 10:2d4a768ae727 181 /* Inizializzazione del servizio BLE UART */
pinofal 10:2d4a768ae727 182 /******************************************/
pinofal 10:2d4a768ae727 183 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
pinofal 10:2d4a768ae727 184 {
pinofal 10:2d4a768ae727 185 BLE& ble = params->ble;
pinofal 10:2d4a768ae727 186 ble_error_t error = params->error;
pinofal 10:2d4a768ae727 187
pinofal 10:2d4a768ae727 188 if (error != BLE_ERROR_NONE)
pinofal 10:2d4a768ae727 189 {
pinofal 10:2d4a768ae727 190 /* In case of error, forward the error handling to onBleInitError */
pinofal 10:2d4a768ae727 191 onBleError(error);
pinofal 10:2d4a768ae727 192 return;
pinofal 10:2d4a768ae727 193 }
pinofal 10:2d4a768ae727 194
pinofal 10:2d4a768ae727 195 /* Ensure that it is the default instance of BLE */
pinofal 10:2d4a768ae727 196 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE)
pinofal 10:2d4a768ae727 197 {
pinofal 10:2d4a768ae727 198 return;
pinofal 10:2d4a768ae727 199 }
pinofal 10:2d4a768ae727 200
pinofal 10:2d4a768ae727 201 ble.gap().onConnection(BleConnectionCallback);
pinofal 10:2d4a768ae727 202 ble.gap().onDisconnection(BleDisconnectionCallback);
pinofal 10:2d4a768ae727 203 ble.gattServer().onDataWritten(BleOnDataWrittenCallback);
pinofal 10:2d4a768ae727 204
pinofal 10:2d4a768ae727 205 pcUSB.printf("BLE UARTService: ");
pinofal 10:2d4a768ae727 206 /* Setup primary service. */
pinofal 10:2d4a768ae727 207 UARTService uartService(ble);
pinofal 10:2d4a768ae727 208 uartServicePtr = &uartService;
pinofal 10:2d4a768ae727 209 pcUSB.printf("Started\r\n");
pinofal 10:2d4a768ae727 210
pinofal 10:2d4a768ae727 211 /* setup advertising */
pinofal 10:2d4a768ae727 212 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
pinofal 10:2d4a768ae727 213 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
pinofal 10:2d4a768ae727 214 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
pinofal 10:2d4a768ae727 215 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
pinofal 10:2d4a768ae727 216 ble.gap().setAdvertisingInterval(500); /* 500ms. */
pinofal 10:2d4a768ae727 217 ble.gap().startAdvertising();
pinofal 10:2d4a768ae727 218
pinofal 10:2d4a768ae727 219 // rimane in attesa di eventi su BLE
pinofal 10:2d4a768ae727 220 while (true)
pinofal 10:2d4a768ae727 221 {
pinofal 10:2d4a768ae727 222 ble.waitForEvent();
pinofal 10:2d4a768ae727 223 }
pinofal 10:2d4a768ae727 224 }
pinofal 10:2d4a768ae727 225
pinofal 10:2d4a768ae727 226 /********/
pinofal 10:2d4a768ae727 227 /* MAIN */
pinofal 10:2d4a768ae727 228 /********/
pinofal 10:2d4a768ae727 229 int main(void)
pinofal 10:2d4a768ae727 230 {
pinofal 10:2d4a768ae727 231
pinofal 10:2d4a768ae727 232 // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto
pinofal 10:2d4a768ae727 233 pcUSB.baud(9600); //921600 bps
pinofal 10:2d4a768ae727 234 // messaggio di benvenuto
pinofal 10:2d4a768ae727 235 pcUSB.printf("\r\nHallo Amaldi Students - Exercise 6 \r\n");
pinofal 10:2d4a768ae727 236 pcUSB.printf("\r\n*** Bluetooth - PC serial communication ***\r\n");
pinofal 10:2d4a768ae727 237
pinofal 10:2d4a768ae727 238 //imposta il funzionamento del pulsante come "PullDown": Aperto = '0'. L'altra modalità di funzinamento è PullUp
pinofal 10:2d4a768ae727 239 myButton.mode(PullDown);
pinofal 10:2d4a768ae727 240 // inizializza variabili
pinofal 10:2d4a768ae727 241 Led1=0;
pinofal 10:2d4a768ae727 242
pinofal 10:2d4a768ae727 243
pinofal 10:2d4a768ae727 244
pinofal 10:2d4a768ae727 245 // IRQ associata alla ricezione di caratteri da seriale su USB da PC
pinofal 10:2d4a768ae727 246 pcUSB.attach(uartRx,Serial::RxIrq);
pinofal 10:2d4a768ae727 247
pinofal 10:2d4a768ae727 248 /****** START Inizializza BLE **********/
pinofal 10:2d4a768ae727 249 BLE &ble = BLE::Instance();
pinofal 10:2d4a768ae727 250 ble.init(bleInitComplete);
pinofal 10:2d4a768ae727 251 /******* END Inizializza BLE ***********/
pinofal 10:2d4a768ae727 252 }
pinofal 10:2d4a768ae727 253