BLE UART adapted for controlling ObCP ENSMM user board with nrF UART
Dependencies: mbed X_NUCLEO_IDB0XA1 BLE_API LIS3DH_spi
Revision 13:38d6b18040c7, committed 2020-11-09
- Comitter:
- jimbaud
- Date:
- Mon Nov 09 18:12:58 2020 +0000
- Parent:
- 12:097314fded0c
- Commit message:
- BLE UART adapted for ObCP ENSMM user board
Changed in this revision
diff -r 097314fded0c -r 38d6b18040c7 BLE-UART-IDB0XA1.cpp --- a/BLE-UART-IDB0XA1.cpp Wed Nov 20 14:01:15 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -#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; - -// Def Peripheriques -DigitalOut Led1(LED1); // LED -Serial pcUSB(USBTX,USBRX); // Terminal PC -DigitalIn myButton(USER_BUTTON); // USER BUTTON - - -// Tableau et index de communication avec UART -static uint8_t uartBuff[UART_BUFFER]; -static uint8_t uartBuffPos=0; - -// Routine de traitement des erreurs -void onBleError(ble_error_t error); - -// Signal de vie -Ticker LifeTicker; - -/****************************************************/ -/* Ticker actif lorsque la connexion BLE est présente */ -/****************************************************/ -void ConnectedBLE(void) -{ - // Signal de vie: allumer et éteindre la LED - Led1 = !Led1; -} - -/***************************/ -/* Rx d'USB et Tx vers BLE */ -/***************************/ -void uartRx(void) -{ - // Capturez les caractères depuis le terminal jusqu'à la fin du message: a '\ r' ou '\ n' ou jusqu'à ce que la taille maximale du message soit atteinte - if(pcUSB.readable()) { - uartBuff[uartBuffPos] = pcUSB.getc(); - if((uartBuff[uartBuffPos] == '\r') || (uartBuff[uartBuffPos] == '\n') || (uartBuffPos >= UART_BUFFER)) { - // insère un NUL dans la dernière position de la chaîne - uartBuff[uartBuffPos] = '\0'; - // Envoie la chaîne entière même si elle est inférieure à BLE_UART_SERVICE_MAX_DATA_LEN, sinon attente - uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); - // Envoie une confirmation au terminal PC avec la chaîne envoyée au BLE - pcUSB.printf("TX : %s\r\n", uartBuff); - // Réinitialiser la chaîne uartBuff en entrant 0 dans les premiers caractères UART_BUFFER - memset(uartBuff, 0, UART_BUFFER); - uartBuffPos = 0; - } else { - // Si la fin du message n'a pas été atteinte, augmentez le compteur pour recevoir le caractère suivant - uartBuffPos++; - } - } -} - -/*************************/ -/* Connexion BLE réussie */ -/*************************/ -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"); - - // Signal de connexion BLE: allume / éteint la LED avec une période de 1 seconde - LifeTicker.attach(ConnectedBLE, 1); -} - -/*****************************/ -/* Déconnexion du client BLE */ -/*****************************/ -void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) -{ - (void)params; - pcUSB.printf("BLE Client Disconnected!\r\n"); - // Désactiver le signal de connexion BLE: allumer / éteindre la LED avec une période de 1 seconde - LifeTicker.detach(); - - // Redémarrer la publicité - BLE::Instance().gap().startAdvertising(); - Led1=0; -} - -/***************************/ -/* Rx de BLE et Rx vers USB*/ -/***************************/ -void BleOnDataWrittenCallback(const GattWriteCallbackParams *params) -{ - // Chaîne de réponse en cas de réception pas OK -#define REPLYNOTOK "Rx not Ok :(" - // Chaîne de réponse en cas de réception OK -#define REPLYOK "Rx Ok :)" - // Chaîne de référence -#define REFERENCESTRING "bho" - - char caReply[UART_BUFFER]; - //uint8_t uaAux[UART_BUFFER]; - int nReplyLength; - - // Résultat de la comparaison entre srting - int nResult; - - // Réinitialiser la chaîne auxiliaire pour composer les réponses - memset(caReply, 0, UART_BUFFER); - - // Reçoit une chaîne de BLE - if (params->handle == uartServicePtr->getTXCharacteristicHandle()) { - // Envoie la chaîne reçue au PC - pcUSB.printf("RX: %s\r\n", params->data); - - uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); - - } -} - -/***************************/ -/* Erreur sur le canal BLE */ -/***************************/ - -void onBleError(ble_error_t error) -{ - pcUSB.printf("BLE Error: %d\r\n"); - /* Entrer le traitement des erreurs */ -} - -/**************************************/ -/* Initialisation du service BLE UART */ -/**************************************/ - -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - - /* En cas d'erreur, transmettez le traitement d'erreur à onBleInitError*/ - onBleError(error); - return; - } - - /* Assurez-vous qu'il s'agit de l'instance par défaut de BLE */ - if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onConnection(BleConnectionCallback); - ble.gap().onDisconnection(BleDisconnectionCallback); - ble.gattServer().onDataWritten(BleOnDataWrittenCallback); - - pcUSB.printf("BLE UARTService: "); - - /* Configuration du service primaire. */ - UARTService uartService(ble); - uartServicePtr = &uartService; - - pcUSB.printf("Started\r\n"); - - /* Configurer la publicité */ - 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(); - - // Attend les événements sur BLE - while (true) { - ble.waitForEvent(); - } -} - -/********/ -/* MAIN */ -/********/ -int main(void) -{ - - // Configurer la vitesse de communication série sur USB-VirtualCom et envoyer un message de bienvenue - pcUSB.baud(9600); //9600 bps - - // Message de bienvenue - pcUSB.printf("\r\n*** Bluetooth to PC serial communication ***\r\n"); - - //Définit le fonctionnement du bouton sur "PullDown": Open = '0'. L’autre mode de fonctionnement est PullUp - myButton.mode(PullDown); - - // Initialiser LED - Led1=0; - - // IRQ associée à la réception de caractères de série à USB depuis un PC - pcUSB.attach(uartRx,Serial::RxIrq); - - /****** START Initialiser BLE **********/ - BLE &ble = BLE::Instance(); - ble.init(bleInitComplete); - /******* FIN initialise BLE ***********/ -} -
diff -r 097314fded0c -r 38d6b18040c7 Instructions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Instructions.txt Mon Nov 09 18:12:58 2020 +0000 @@ -0,0 +1,14 @@ + + +Ce programme fonctionne avec l'application nRF UART pour smartphone et l'ObCP ENSMM, +une fois l'application installée, elle apparait sour le nom ObCP dans la recherche d econnexion de nRF UART. + +Le relevé du capteurs accéleromètriques est envoyé toute les 1 seconde. + +Les commandes à envoyer depuis l'applications pour controler l'ObCP sont les suivantes : +LV ou LR ou LB ou PW pour la commande + la valeur de 000 à 255 + +Ex : allumer led verte de 20 : LV020 +Ex : eteindre led verte : LV000 +EX : activer la sortie pwm au maxi : PW255 + \ No newline at end of file
diff -r 097314fded0c -r 38d6b18040c7 LIS3DH_spi.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LIS3DH_spi.lib Mon Nov 09 18:12:58 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/franzle/code/LIS3DH_spi/#ce2396b1c9a1
diff -r 097314fded0c -r 38d6b18040c7 X_NUCLEO_IDB0XA1.lib --- a/X_NUCLEO_IDB0XA1.lib Wed Nov 20 14:01:15 2019 +0000 +++ b/X_NUCLEO_IDB0XA1.lib Mon Nov 09 18:12:58 2020 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/teams/ST/code/X_NUCLEO_IDB0XA1/#fa98703ece8e +https://os.mbed.com/teams/ENSMM/code/X_NUCLEO_IDB0XA1/#8886c0252544
diff -r 097314fded0c -r 38d6b18040c7 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Nov 09 18:12:58 2020 +0000 @@ -0,0 +1,213 @@ +#include "mbed.h" +#include "ble/BLE.h" +#include "ble/services/UARTService.h" +#include "Serial.h" +#include "LIS3DH.h" +#include "stdlib.h" + +#define UART_BUFFER (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN) + + +const static char DEVICE_NAME[] = "ObCP"; +UARTService *uartServicePtr; + +//PWM output +PwmOut PWMoutput(PB_1); //Main PWM output +PwmOut Green(PC_8); //PWM Red LED +PwmOut Red(PC_6); //PWM Green LED +PwmOut Blue(PC_9); //PWM Blue LED + +//Accelerometer + +#define MOSI PC_12 +#define MISO PC_11 +#define CS PC_5 +#define SCLK PC_10 + +// Def Peripheriques +DigitalIn myButton(PC_13); // USER BUTTON +//Init accelerometer +LIS3DH acc(MOSI, MISO, SCLK, CS, LIS3DH_DR_NR_LP_50HZ, LIS3DH_FS_2G); + +Ticker Acceleration; + +// Tableau et index de communication avec UART +static char uartBuff[UART_BUFFER]; +// Variables contenant accelerations +double accX, accY, accZ; +// Routine de traitement des erreurs +void onBleError(ble_error_t error); + +/****************************************************/ +/* Ticker actif lorsque la connexion BLE est présente */ +/****************************************************/ +void ConnectedBLE(void) +{ + // Signal de vie: allumer et éteindre la LED + Green.period(1.0f); // période = 1 seconde + Green.write(0.01f); // élaire 1% de la période +} + +void AccMeasurement(void) +{ + char outstrX[5]; + char outstrY[5]; + char outstrZ[5]; + + // Mesure des accélérations sur les 3 axes + accX = float(short((acc.read_reg(LIS3DH_OUT_X_H) << 8) | acc.read_reg(LIS3DH_OUT_X_L))) * 0.001F / 15; + accY = float(short((acc.read_reg(LIS3DH_OUT_Y_H) << 8) | acc.read_reg(LIS3DH_OUT_Y_L))) * 0.001F / 15; + accZ = float(short((acc.read_reg(LIS3DH_OUT_Z_H) << 8) | acc.read_reg(LIS3DH_OUT_Z_L))) * 0.001F / 15; + + //Transformation des valeurs numeriques en chaine de caracteres + sprintf(outstrX,"%5.2f",accX); + sprintf(outstrY,"%5.2f",accY); + sprintf(outstrZ,"%5.2f",accZ); + //Integre les trois chaines de caractere contenant les accelerations dans la chaine uartBuff + sprintf(uartBuff, "X%s Y%s Z%s", outstrX, outstrY, outstrZ) ; + //Envoie la chaine uartBuff sur le sevice TX UART BLE + uartServicePtr->write(uartBuff, UARTService::BLE_UART_SERVICE_MAX_DATA_LEN); + // Réinitialiser la chaîne uartBuff en entrant 0 dans les premiers caractères UART_BUFFER + memset(uartBuff, 0, UART_BUFFER); + +} + +/*************************/ +/* Connexion BLE réussie */ +/*************************/ +void BleConnectionCallback(const Gap::ConnectionCallbackParams_t *params) +{ + // Signal de connexion BLE: allume / éteint la LED avec une période de 1 seconde + ConnectedBLE(); + Acceleration.attach(AccMeasurement, 1); +} + +/*****************************/ +/* Déconnexion du client BLE */ +/*****************************/ +void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + (void)params; + // Redémarrer la publicité + Acceleration.detach(); + BLE::Instance().gap().startAdvertising(); + + PWMoutput.write(0.0f); + Green.write(0.0f); + Red.write(0.0f); + Blue.write(0.0f); +} + +/***************************/ +/* Rx de BLE et Rx vers USB*/ +/***************************/ +void BleOnDataWrittenCallback(const GattWriteCallbackParams *params) +{ + char reception[UART_BUFFER]; + char commande[2]; + float valeur; + + // Reçoit une chaîne de BLE + if (params->handle == uartServicePtr->getTXCharacteristicHandle()) { + // Copie de la chaine reçue dans reception + sprintf(reception,"%s", params->data); + // Copie dans la chaine commande des deux premier caracteres de la chaine reception + sprintf(commande,"%c%c", reception[0], reception[1]); + // Transformation des 3 caracteres suivants en valeur numerique + valeur = ((reception[2] - '0')* 100 + (reception[3] - '0')* 10 +(reception[4] - '0')) ; + valeur = valeur/255; + + if( strcmp(commande, "LR")==0) { + Red.period(0.01f); + Red.write(valeur); + } + if( strcmp(commande, "LV")==0) { + Green.period(0.01f); + Green.write(valeur); + } + if( strcmp(commande, "LB")==0) { + Blue.period(0.01f); + Blue.write(valeur); + } + if( strcmp(commande, "PW")==0) { + PWMoutput.period(0.001f); + PWMoutput.write(valeur); + } + + } +} + +/***************************/ +/* Erreur sur le canal BLE */ +/***************************/ + +void onBleError(ble_error_t error) +{ + Red.period(0.8f); // période = 0.8 seconde + Red.write(0.10f); // élaire 10% de la période + /* Entrer le traitement des erreurs */ +} + +/**************************************/ +/* Initialisation du service BLE UART */ +/**************************************/ + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + + /* En cas d'erreur, transmettez le traitement d'erreur à onBleInitError*/ + onBleError(error); + return; + } + + /* Assurez-vous qu'il s'agit de l'instance par défaut de BLE */ + if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onConnection(BleConnectionCallback); + ble.gap().onDisconnection(BleDisconnectionCallback); + ble.gattServer().onDataWritten(BleOnDataWrittenCallback); + + /* Configuration du service primaire. */ + UARTService uartService(ble); + uartServicePtr = &uartService; + + /* Configurer la publicité */ + 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(); + + // Attend les événements sur BLE + while (true) { + ble.waitForEvent(); + } +} + +/********/ +/* MAIN */ +/********/ +int main(void) +{ + //Définit le fonctionnement du bouton sur "PullDown": Open = '0'. L’autre mode de fonctionnement est PullUp + myButton.mode(PullDown); + + // Initialiser LED + Green.write(0.0f); + Red.write(0.0f); + Blue.write(0.0f); + + /****** START Initialiser BLE **********/ + BLE &ble = BLE::Instance(); + ble.init(bleInitComplete); + /******* FIN initialise BLE ***********/ + +} +