This program is given as a sample exercise. It has all the functionality to be used on a BLE Nano device and to connect to SimpleChat application for Android/ iOS from RebBearLab. The aim of the exercise is to read a voltage and then to convert as good as possible the appropriate temperature in Celsius degrees. AI5 pin is considered for reading the voltage for the termistor. The ADC of AI5 is called every second. The function to be updated : update_measurements() from main.cpp file.

Dependencies:   BLE_API mbed nRF51822

Fork of nRF51822_DataLogger_with_Chat by Valentin Tanasa

Committer:
tanasaro10
Date:
Mon Apr 25 19:34:39 2016 +0000
Revision:
9:303d3628986a
Parent:
8:f28ad4600b0f
Child:
10:c7d53e4e0602
Major rework on the code and extended functionality added. Detailed explanations are given in read_me.md file.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RedBearLab 1:1c058e553423 1 /*
RedBearLab 0:cffe8ac1bdf0 2
RedBearLab 1:1c058e553423 3 Copyright (c) 2012-2014 RedBearLab
RedBearLab 1:1c058e553423 4
tanasaro10 9:303d3628986a 5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
tanasaro10 9:303d3628986a 6 and associated documentation files (the "Software"), to deal in the Software without restriction,
tanasaro10 9:303d3628986a 7 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
tanasaro10 9:303d3628986a 8 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
RedBearLab 1:1c058e553423 9 subject to the following conditions:
RedBearLab 1:1c058e553423 10 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
RedBearLab 1:1c058e553423 11
tanasaro10 9:303d3628986a 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
tanasaro10 9:303d3628986a 13 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
tanasaro10 9:303d3628986a 14 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
tanasaro10 9:303d3628986a 15 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
RedBearLab 1:1c058e553423 16 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
RedBearLab 1:1c058e553423 17
RedBearLab 1:1c058e553423 18 */
RedBearLab 1:1c058e553423 19
RedBearLab 1:1c058e553423 20 /*
RedBearLab 1:1c058e553423 21 * The application works with the BLEController iOS/Android App.
RedBearLab 1:1c058e553423 22 * Type something from the Terminal to send
RedBearLab 1:1c058e553423 23 * to the BLEController App or vice verse.
RedBearLab 1:1c058e553423 24 * Characteristics received from App will print on Terminal.
tanasaro10 9:303d3628986a 25 * Read read_me.md file for more informations about the extended feature
RedBearLab 1:1c058e553423 26 */
tanasaro10 9:303d3628986a 27
tanasaro10 9:303d3628986a 28
RedBearLab 2:4b66b69c7ecb 29 #include "ble/BLE.h"
tanasaro10 8:f28ad4600b0f 30 #include <myData.h>
tanasaro10 9:303d3628986a 31 #include <Gap.h>
tanasaro10 9:303d3628986a 32 #include "ble_flash.h"
tanasaro10 9:303d3628986a 33 #include "ble_flash.c"
RedBearLab 0:cffe8ac1bdf0 34
RedBearLab 0:cffe8ac1bdf0 35 #define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */
RedBearLab 0:cffe8ac1bdf0 36 #define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
RedBearLab 0:cffe8ac1bdf0 37 #define BLE_UUIDS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */
RedBearLab 0:cffe8ac1bdf0 38
tanasaro10 9:303d3628986a 39 #define TXRX_BUF_LEN 20 /** For radio message transmission*/
tanasaro10 9:303d3628986a 40
tanasaro10 9:303d3628986a 41 #define MyASSERT(cond , serialpc, errVal) assert_error_app((bool)cond, serialpc, (uint16_t)errVal, __LINE__, __FILE__)
RedBearLab 0:cffe8ac1bdf0 42
RedBearLab 2:4b66b69c7ecb 43 BLE ble;
RedBearLab 0:cffe8ac1bdf0 44
RedBearLab 0:cffe8ac1bdf0 45 Serial pc(USBTX, USBRX);
RedBearLab 0:cffe8ac1bdf0 46
RedBearLab 0:cffe8ac1bdf0 47 // The Nordic UART Service
RedBearLab 0:cffe8ac1bdf0 48 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
RedBearLab 0:cffe8ac1bdf0 49 static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
RedBearLab 0:cffe8ac1bdf0 50 static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
RedBearLab 0:cffe8ac1bdf0 51 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
RedBearLab 0:cffe8ac1bdf0 52
tanasaro10 8:f28ad4600b0f 53 static const int8_t txPower = 0xCD;
RedBearLab 0:cffe8ac1bdf0 54
RedBearLab 0:cffe8ac1bdf0 55 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
RedBearLab 0:cffe8ac1bdf0 56 uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
RedBearLab 0:cffe8ac1bdf0 57
RedBearLab 0:cffe8ac1bdf0 58 static uint8_t rx_buf[TXRX_BUF_LEN];
RedBearLab 0:cffe8ac1bdf0 59 static uint8_t rx_len=0;
RedBearLab 0:cffe8ac1bdf0 60
tanasaro10 9:303d3628986a 61 static uint32_t gTimeInstant = 1; // TimerTick Resolution, in seconds
tanasaro10 8:f28ad4600b0f 62
tanasaro10 9:303d3628986a 63 bool g_bIsConnected = false;
tanasaro10 9:303d3628986a 64 bool g_bIsAdvertising = false;
tanasaro10 9:303d3628986a 65 bool g_LogActive = false;
tanasaro10 9:303d3628986a 66 static myDataLog_t g_MyData;
tanasaro10 9:303d3628986a 67 uint8_t g_MyDataIdx=0;
tanasaro10 8:f28ad4600b0f 68
tanasaro10 9:303d3628986a 69 // pins connected for measuring
tanasaro10 8:f28ad4600b0f 70 DigitalOut led(LED1);
tanasaro10 8:f28ad4600b0f 71 PwmOut buzzer(p15);
tanasaro10 9:303d3628986a 72 InterruptIn event(p29); // button
tanasaro10 8:f28ad4600b0f 73 AnalogIn VP3(A3);
tanasaro10 8:f28ad4600b0f 74 AnalogIn VP4(A4);
tanasaro10 8:f28ad4600b0f 75 AnalogIn VP5(A5);
tanasaro10 9:303d3628986a 76 AnalogIn* VP[3]= {&VP3,&VP4,&VP5};
tanasaro10 9:303d3628986a 77 #define NUM_OF_READINGS (4u)
tanasaro10 9:303d3628986a 78 myPayload_t g_currMeasures; // last measurements
tanasaro10 8:f28ad4600b0f 79
tanasaro10 8:f28ad4600b0f 80 Timeout timeout_err; // timeout for buzz on error
tanasaro10 9:303d3628986a 81 Ticker periodicActions;
tanasaro10 8:f28ad4600b0f 82
tanasaro10 8:f28ad4600b0f 83 mtime_manager_t g_myTimeVar;
tanasaro10 8:f28ad4600b0f 84 mdate_manager_t g_myDateVar;
tanasaro10 8:f28ad4600b0f 85
tanasaro10 9:303d3628986a 86 GattCharacteristic txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
RedBearLab 0:cffe8ac1bdf0 87
RedBearLab 0:cffe8ac1bdf0 88 GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
tanasaro10 9:303d3628986a 89
RedBearLab 0:cffe8ac1bdf0 90 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
RedBearLab 0:cffe8ac1bdf0 91
RedBearLab 0:cffe8ac1bdf0 92 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
RedBearLab 0:cffe8ac1bdf0 93
tanasaro10 9:303d3628986a 94 void sendRadioMsg(const uint8_t* buf, uint16_t length)
tanasaro10 9:303d3628986a 95 {
tanasaro10 9:303d3628986a 96 uint8_t retVal;
tanasaro10 9:303d3628986a 97 retVal = ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, length);
tanasaro10 9:303d3628986a 98 //pc.printf("Err=%d\r\n",retVal);
tanasaro10 9:303d3628986a 99 MyASSERT((retVal!=0),&pc, retVal);
tanasaro10 8:f28ad4600b0f 100 }
tanasaro10 8:f28ad4600b0f 101
RedBearLab 0:cffe8ac1bdf0 102 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
RedBearLab 0:cffe8ac1bdf0 103 {
RedBearLab 0:cffe8ac1bdf0 104 pc.printf("Disconnected \r\n");
tanasaro10 9:303d3628986a 105 g_bIsConnected = false;
tanasaro10 9:303d3628986a 106 g_bIsAdvertising = false;
RedBearLab 0:cffe8ac1bdf0 107 }
RedBearLab 0:cffe8ac1bdf0 108
tanasaro10 9:303d3628986a 109 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
tanasaro10 9:303d3628986a 110 {
tanasaro10 9:303d3628986a 111 pc.printf("Connected \r\n");
tanasaro10 9:303d3628986a 112 g_bIsConnected = true;
tanasaro10 9:303d3628986a 113 g_bIsAdvertising = false;
tanasaro10 8:f28ad4600b0f 114 }
tanasaro10 8:f28ad4600b0f 115
tanasaro10 9:303d3628986a 116 void at_timeout_err()
tanasaro10 9:303d3628986a 117 {
tanasaro10 9:303d3628986a 118 // stop buzz
tanasaro10 9:303d3628986a 119 buzz_int(&buzzer, 0,0);
tanasaro10 9:303d3628986a 120 }
tanasaro10 9:303d3628986a 121 void connectionUpdate(connection_update_t option){
tanasaro10 9:303d3628986a 122 switch (option){
tanasaro10 9:303d3628986a 123 case eStartAdvertising:{
tanasaro10 9:303d3628986a 124 if ((g_bIsConnected == false)&&(g_bIsAdvertising == false)) {
tanasaro10 9:303d3628986a 125 pc.printf("Start Advertising\r");
tanasaro10 9:303d3628986a 126 ble.startAdvertising();
tanasaro10 9:303d3628986a 127 g_bIsAdvertising = true;
tanasaro10 9:303d3628986a 128 }
tanasaro10 9:303d3628986a 129 break;
tanasaro10 9:303d3628986a 130 }
tanasaro10 9:303d3628986a 131 case eStopAdvertising:{
tanasaro10 9:303d3628986a 132 if (g_bIsAdvertising == true){
tanasaro10 9:303d3628986a 133 pc.printf("Stop Advertising\r");
tanasaro10 9:303d3628986a 134 ble.stopAdvertising();
tanasaro10 9:303d3628986a 135 g_bIsAdvertising = false;
tanasaro10 9:303d3628986a 136 }
tanasaro10 9:303d3628986a 137 break;
tanasaro10 9:303d3628986a 138 }
tanasaro10 9:303d3628986a 139 case eDisconnect:{
tanasaro10 9:303d3628986a 140 if (g_bIsConnected == true) {
tanasaro10 9:303d3628986a 141 pc.printf("Close connection\r");
tanasaro10 9:303d3628986a 142 ble.disconnect((Gap::DisconnectionReason_t)0x12);
tanasaro10 9:303d3628986a 143 } else if (g_bIsAdvertising == true){
tanasaro10 9:303d3628986a 144 pc.printf("Stop Advertising\r");
tanasaro10 9:303d3628986a 145 ble.stopAdvertising();
tanasaro10 9:303d3628986a 146 g_bIsAdvertising = false;
tanasaro10 9:303d3628986a 147 }
tanasaro10 8:f28ad4600b0f 148 break;
tanasaro10 9:303d3628986a 149 }
tanasaro10 8:f28ad4600b0f 150 }
tanasaro10 9:303d3628986a 151 }
tanasaro10 9:303d3628986a 152 void write_data_to_flash(uint32_t *tick)
tanasaro10 9:303d3628986a 153 {
tanasaro10 9:303d3628986a 154 uint32_t retVal=0;
tanasaro10 9:303d3628986a 155 uint8_t page_num=0;
tanasaro10 9:303d3628986a 156
tanasaro10 9:303d3628986a 157 if (g_MyDataIdx==0) {
tanasaro10 9:303d3628986a 158 //initiate connection
tanasaro10 9:303d3628986a 159 connectionUpdate(eStartAdvertising);
tanasaro10 9:303d3628986a 160 // time and date used to initialize the g_MyData variable
tanasaro10 9:303d3628986a 161 memcpy(&g_MyData.startData.date,&g_myDateVar.currentDate, sizeof(date_t));
tanasaro10 9:303d3628986a 162 memcpy(&g_MyData.startData.time,&g_myTimeVar.currentTime, sizeof(mtime_t));
tanasaro10 9:303d3628986a 163 memcpy(&g_MyData.startData.data,&g_currMeasures, sizeof(myPayload_t));
tanasaro10 9:303d3628986a 164 } else {
tanasaro10 9:303d3628986a 165 // it should be logged here the time difference from last record...
tanasaro10 9:303d3628986a 166 g_MyData.myData[g_MyDataIdx].min = (uint16_t)(*tick*gTimeInstant / 60);
tanasaro10 9:303d3628986a 167 g_MyData.myData[g_MyDataIdx].sec = (*tick*gTimeInstant% 60);
tanasaro10 9:303d3628986a 168 memcpy(&g_MyData.myData[g_MyDataIdx].data,&g_currMeasures, sizeof(myPayload_t));
tanasaro10 9:303d3628986a 169 }
tanasaro10 9:303d3628986a 170 *tick = 0;
tanasaro10 9:303d3628986a 171
tanasaro10 9:303d3628986a 172 if (g_MyDataIdx==(MAXBUFFER-5)) {
tanasaro10 9:303d3628986a 173 //initiate disconnection
tanasaro10 9:303d3628986a 174 connectionUpdate(eDisconnect);
tanasaro10 9:303d3628986a 175 }
tanasaro10 9:303d3628986a 176
tanasaro10 9:303d3628986a 177 if (g_MyDataIdx==(MAXBUFFER-1)) {
tanasaro10 9:303d3628986a 178 // write2Flash the current page num
tanasaro10 9:303d3628986a 179 page_num=flash_currPage();
tanasaro10 9:303d3628986a 180 // write2Flash the current page data
tanasaro10 9:303d3628986a 181 retVal=ble_flash_page_write(page_num, (uint32_t*)&(g_MyData), 251u);
tanasaro10 9:303d3628986a 182 pc.printf("retValWr: %d, Pg:%d, Min: %d \r\n",retVal, page_num,g_myTimeVar.currentTime.min);
tanasaro10 9:303d3628986a 183 flash_go_nextPage();
tanasaro10 9:303d3628986a 184 //save_flash_curr_pageNr(g_myDateVar.currentDate);
tanasaro10 9:303d3628986a 185 }
tanasaro10 9:303d3628986a 186 g_MyDataIdx = (g_MyDataIdx+1)%(MAXBUFFER);
tanasaro10 8:f28ad4600b0f 187 }
tanasaro10 8:f28ad4600b0f 188
tanasaro10 9:303d3628986a 189
tanasaro10 9:303d3628986a 190 void on_error_radioMsg()
tanasaro10 9:303d3628986a 191 {
tanasaro10 9:303d3628986a 192 char myBuf[TXRX_BUF_LEN];
tanasaro10 9:303d3628986a 193
tanasaro10 9:303d3628986a 194 sprintf(myBuf,"%s","WrongSyntax");
tanasaro10 9:303d3628986a 195 buzz_int(&buzzer,5,3);
tanasaro10 9:303d3628986a 196 timeout_err.attach(&at_timeout_err, 2);
tanasaro10 9:303d3628986a 197 sendRadioMsg((uint8_t*)&myBuf[0], 12);
tanasaro10 8:f28ad4600b0f 198 }
tanasaro10 8:f28ad4600b0f 199
tanasaro10 8:f28ad4600b0f 200
tanasaro10 9:303d3628986a 201 void flash_page_serial_dump(uint32_t* p_curr_addr)
tanasaro10 9:303d3628986a 202 {
tanasaro10 9:303d3628986a 203 myDataLogShort_t initialData;
tanasaro10 9:303d3628986a 204 myDataL_t dataOut[2];
tanasaro10 9:303d3628986a 205 uint8_t i;
tanasaro10 9:303d3628986a 206
tanasaro10 9:303d3628986a 207 p_curr_addr += 2; // skip the magic number and the word count
tanasaro10 9:303d3628986a 208 memcpy((uint32_t*)&initialData, p_curr_addr, 6*sizeof(uint32_t));
tanasaro10 9:303d3628986a 209 pc.printf("20%2d_%2d_%2d H:%2d P:%4x\r",initialData.startData.date.year, initialData.startData.date.month, initialData.startData.date.day, initialData.startData.time.hour, p_curr_addr);
tanasaro10 9:303d3628986a 210 pc.printf("%2d:%2d;%3d;%3d;%3d \r",initialData.startData.time.min, initialData.startData.time.sec, initialData.startData.data.light, initialData.startData.data.gndV, initialData.startData.data.temp);
tanasaro10 9:303d3628986a 211 pc.printf("%2d:%2d;%3d;%3d;%3d;%2d\r",initialData.myData.min, initialData.myData.sec, initialData.myData.data.light, initialData.myData.data.gndV, initialData.myData.data.temp);
tanasaro10 9:303d3628986a 212 p_curr_addr += 6;
tanasaro10 9:303d3628986a 213
tanasaro10 9:303d3628986a 214 for (i=0; i<49; i++) {
tanasaro10 9:303d3628986a 215 memcpy((uint32_t*)&dataOut, p_curr_addr, 5*sizeof(uint32_t));
tanasaro10 9:303d3628986a 216 pc.printf("%2d:%2d;%3d;%3d;%3d;%2d\r",dataOut[0].min, dataOut[0].sec, dataOut[0].data.light, dataOut[0].data.gndV, dataOut[0].data.temp, i);
tanasaro10 9:303d3628986a 217 pc.printf("%2d:%2d;%3d;%3d;%3d\r",dataOut[1].min, dataOut[1].sec, dataOut[1].data.light, dataOut[1].data.gndV, dataOut[1].data.temp);
tanasaro10 9:303d3628986a 218 p_curr_addr += 5;
tanasaro10 9:303d3628986a 219 }
tanasaro10 9:303d3628986a 220 }
tanasaro10 9:303d3628986a 221
tanasaro10 9:303d3628986a 222 int update_measurements()
tanasaro10 9:303d3628986a 223 {
tanasaro10 9:303d3628986a 224 int retVal;
tanasaro10 9:303d3628986a 225 static myPayload_t prevMeasures=(myPayload_t) {0, 0, 0, 0, 0 };
tanasaro10 9:303d3628986a 226
tanasaro10 9:303d3628986a 227 g_currMeasures = (myPayload_t) {
tanasaro10 9:303d3628986a 228 VP[0]->read_u16(), VP[2]->read_u16(), VP[1]->read_u16(), led, 0
tanasaro10 9:303d3628986a 229 };
tanasaro10 9:303d3628986a 230 retVal = memcmp(&g_currMeasures,&prevMeasures,sizeof(myPayload_t));
tanasaro10 9:303d3628986a 231 memcpy(&prevMeasures,&g_currMeasures,sizeof(myPayload_t));
tanasaro10 9:303d3628986a 232 return retVal;
tanasaro10 9:303d3628986a 233 }
tanasaro10 9:303d3628986a 234
tanasaro10 9:303d3628986a 235 void at_eachInstant()
tanasaro10 9:303d3628986a 236 {
tanasaro10 9:303d3628986a 237 static uint32_t tick=0;
tanasaro10 9:303d3628986a 238 int retVal;
tanasaro10 9:303d3628986a 239
tanasaro10 8:f28ad4600b0f 240 // update time
tanasaro10 9:303d3628986a 241 update_time(&g_myTimeVar, &g_myDateVar, gTimeInstant);
tanasaro10 9:303d3628986a 242
tanasaro10 9:303d3628986a 243 //update measurements
tanasaro10 9:303d3628986a 244 retVal = update_measurements();
tanasaro10 9:303d3628986a 245
tanasaro10 9:303d3628986a 246 // if there are changes in data save
tanasaro10 9:303d3628986a 247 if ((retVal!=0)&&(g_LogActive==true)) {
tanasaro10 9:303d3628986a 248 write_data_to_flash(&tick);
tanasaro10 9:303d3628986a 249 }
tanasaro10 9:303d3628986a 250 tick++;
tanasaro10 9:303d3628986a 251 }
tanasaro10 9:303d3628986a 252
tanasaro10 9:303d3628986a 253 // Radio commands decode
tanasaro10 9:303d3628986a 254 void decode(uint8_t * buffer, uint16_t length)
tanasaro10 9:303d3628986a 255 {
tanasaro10 9:303d3628986a 256 uint16_t len;
tanasaro10 9:303d3628986a 257 char myBuf[TXRX_BUF_LEN];
tanasaro10 9:303d3628986a 258
tanasaro10 9:303d3628986a 259 switch (buffer[0]) {
tanasaro10 9:303d3628986a 260 case 'i': {// Analog Input Read Request
tanasaro10 9:303d3628986a 261 switch (buffer[1]) {
tanasaro10 9:303d3628986a 262 case '0': {
tanasaro10 9:303d3628986a 263 // display all inputs
tanasaro10 9:303d3628986a 264 sprintf(myBuf,"All:%3d,%3d,%3d,%2d", g_currMeasures.light,g_currMeasures.gndV,g_currMeasures.temp,g_currMeasures.led_on);
tanasaro10 9:303d3628986a 265 len = 18;
tanasaro10 9:303d3628986a 266 break;
tanasaro10 9:303d3628986a 267 }
tanasaro10 9:303d3628986a 268 case '1': {
tanasaro10 9:303d3628986a 269 sprintf(myBuf,"Input 1 = %3d", g_currMeasures.light);
tanasaro10 9:303d3628986a 270 len = 13;
tanasaro10 9:303d3628986a 271 break;
tanasaro10 9:303d3628986a 272 }
tanasaro10 9:303d3628986a 273 case '2': {
tanasaro10 9:303d3628986a 274 sprintf(myBuf,"Input 2 = %3d", g_currMeasures.gndV);
tanasaro10 9:303d3628986a 275 len = 13;
tanasaro10 9:303d3628986a 276 break;
tanasaro10 9:303d3628986a 277 }
tanasaro10 9:303d3628986a 278 case '3': {
tanasaro10 9:303d3628986a 279 sprintf(myBuf,"Input 3 = %3d", g_currMeasures.temp);
tanasaro10 9:303d3628986a 280 len = 13;
tanasaro10 9:303d3628986a 281 break;
tanasaro10 9:303d3628986a 282 }
tanasaro10 9:303d3628986a 283 case '4': {
tanasaro10 9:303d3628986a 284 sprintf(myBuf,"Input 4 = %2d", g_currMeasures.led_on);
tanasaro10 9:303d3628986a 285 len = 12;
tanasaro10 9:303d3628986a 286 break;
tanasaro10 9:303d3628986a 287 }
tanasaro10 9:303d3628986a 288 default: {
tanasaro10 9:303d3628986a 289 sprintf(myBuf,"All:%3d,%3d,%3d,%2d", g_currMeasures.light,g_currMeasures.gndV,g_currMeasures.temp,g_currMeasures.led_on);
tanasaro10 9:303d3628986a 290 len = 18;
tanasaro10 9:303d3628986a 291 break;
tanasaro10 8:f28ad4600b0f 292 }
tanasaro10 8:f28ad4600b0f 293 }
tanasaro10 9:303d3628986a 294 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 295 break;
tanasaro10 9:303d3628986a 296 }
tanasaro10 9:303d3628986a 297 case 'l': {// toogle led
tanasaro10 9:303d3628986a 298 led = ! led;
tanasaro10 9:303d3628986a 299 if (led==0) {
tanasaro10 9:303d3628986a 300 sprintf(myBuf,"%s","ON");
tanasaro10 9:303d3628986a 301 len = 2;
tanasaro10 9:303d3628986a 302 } else {
tanasaro10 9:303d3628986a 303 sprintf(myBuf,"%s","OFF");
tanasaro10 9:303d3628986a 304 len = 3;
tanasaro10 9:303d3628986a 305 }
tanasaro10 9:303d3628986a 306 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 307 break;
tanasaro10 9:303d3628986a 308 }
tanasaro10 9:303d3628986a 309 case 's': {// buzzer
tanasaro10 9:303d3628986a 310 if (((buffer[1]>'9')||(buffer[1]<'0'))||((buffer[2]>'9')||(buffer[2]<'0'))){
tanasaro10 9:303d3628986a 311 MyASSERT(true,&pc, buffer[1]); // notify on serial interface
tanasaro10 9:303d3628986a 312 on_error_radioMsg(); // notify on radio
tanasaro10 9:303d3628986a 313 break;
tanasaro10 9:303d3628986a 314 } else {
tanasaro10 9:303d3628986a 315 buzz_int(&buzzer, (buffer[1]-'0'),(buffer[2]-'0'));
tanasaro10 9:303d3628986a 316 sprintf(myBuf,"%s:%f","S",buzzer.read());
tanasaro10 9:303d3628986a 317 len= 7;
tanasaro10 9:303d3628986a 318 }
tanasaro10 9:303d3628986a 319 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 320 break;
tanasaro10 9:303d3628986a 321 }
tanasaro10 9:303d3628986a 322 case 't': {// time operations
tanasaro10 9:303d3628986a 323 switch (buffer[1]) {
tanasaro10 9:303d3628986a 324 case 'i': {// time insert
tanasaro10 9:303d3628986a 325 memcpy(myBuf,&buffer[2],2);
tanasaro10 9:303d3628986a 326 g_myTimeVar.newTime.hour=atoi(myBuf); // TODO check if it is a number
tanasaro10 9:303d3628986a 327 memcpy(myBuf,&buffer[4],2);
tanasaro10 9:303d3628986a 328 g_myTimeVar.newTime.min=atoi(myBuf); // TODO check if it is a number
tanasaro10 9:303d3628986a 329 memcpy(myBuf,&buffer[6],2);
tanasaro10 9:303d3628986a 330 g_myTimeVar.newTime.sec=atoi(myBuf); // TODO check if it is a number
tanasaro10 9:303d3628986a 331 g_myTimeVar.updateTime = true;
tanasaro10 9:303d3628986a 332 sprintf(myBuf,"TimeInserted");
tanasaro10 9:303d3628986a 333 len= 12;
tanasaro10 9:303d3628986a 334 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 335 break;
tanasaro10 9:303d3628986a 336 }
tanasaro10 9:303d3628986a 337 case 'g': {// time get
tanasaro10 9:303d3628986a 338 sprintf(myBuf,"H:%2d:%2d:%2d",g_myTimeVar.currentTime.hour,g_myTimeVar.currentTime.min,g_myTimeVar.currentTime.sec);
tanasaro10 9:303d3628986a 339 len = 11;
tanasaro10 9:303d3628986a 340 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 341 break;
tanasaro10 9:303d3628986a 342 }
tanasaro10 9:303d3628986a 343 default:
tanasaro10 9:303d3628986a 344 MyASSERT(true,&pc, buffer[1]); // notify on serial interface
tanasaro10 9:303d3628986a 345 on_error_radioMsg(); // notify on radio
tanasaro10 9:303d3628986a 346 }
tanasaro10 9:303d3628986a 347 break;
tanasaro10 8:f28ad4600b0f 348 }
tanasaro10 9:303d3628986a 349 case 'd': {// date operations
tanasaro10 9:303d3628986a 350 switch (buffer[1]) {
tanasaro10 9:303d3628986a 351 case 'i': { // date insert
tanasaro10 9:303d3628986a 352 memcpy(myBuf,&buffer[2],2);
tanasaro10 9:303d3628986a 353 g_myDateVar.newDate.year=atoi(myBuf); // TODO check if it is a number
tanasaro10 9:303d3628986a 354 memcpy(myBuf,&buffer[4],2);
tanasaro10 9:303d3628986a 355 g_myDateVar.newDate.month=atoi(myBuf); // TODO check if it is a number
tanasaro10 9:303d3628986a 356 memcpy(myBuf,&buffer[6],2);
tanasaro10 9:303d3628986a 357 g_myDateVar.newDate.day=atoi(myBuf); // TODO check if it is a number
tanasaro10 9:303d3628986a 358 g_myDateVar.updateDate = true;
tanasaro10 9:303d3628986a 359 sprintf(myBuf,"DateInserted");
tanasaro10 9:303d3628986a 360 len= 12;
tanasaro10 9:303d3628986a 361 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 362 break;
tanasaro10 9:303d3628986a 363 }
tanasaro10 9:303d3628986a 364 case 'g': { // time get
tanasaro10 9:303d3628986a 365 sprintf(myBuf,"D:20%2d:%2d:%2d",g_myDateVar.currentDate.year,g_myDateVar.currentDate.month,g_myDateVar.currentDate.day);
tanasaro10 9:303d3628986a 366 len = 13;
tanasaro10 9:303d3628986a 367 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 368 break;
tanasaro10 9:303d3628986a 369 }
tanasaro10 9:303d3628986a 370 default:
tanasaro10 9:303d3628986a 371 MyASSERT(true,&pc, buffer[1]); // notify on serial interface
tanasaro10 9:303d3628986a 372 on_error_radioMsg(); // notify on radio
tanasaro10 9:303d3628986a 373 }
tanasaro10 9:303d3628986a 374 break;
tanasaro10 9:303d3628986a 375 }
tanasaro10 9:303d3628986a 376
tanasaro10 9:303d3628986a 377 case 'f': {// file operations
tanasaro10 9:303d3628986a 378 switch (buffer[1]) {
tanasaro10 9:303d3628986a 379 case '1': {
tanasaro10 9:303d3628986a 380 //pc.printf("S Payload_t: %d \r\n",sizeof(myPayload_t));
tanasaro10 9:303d3628986a 381 //pc.printf("S myDataL_t: %d \r\n",sizeof(myDataL_t));
tanasaro10 9:303d3628986a 382
tanasaro10 9:303d3628986a 383 sprintf(myBuf,"g_idx=%2d Page=%3d",g_MyDataIdx, flash_currPage());
tanasaro10 9:303d3628986a 384 len = 18;
tanasaro10 9:303d3628986a 385 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 386 break;
tanasaro10 9:303d3628986a 387 }
tanasaro10 9:303d3628986a 388 case '2':{// start measuring
tanasaro10 9:303d3628986a 389 sprintf(myBuf,"Start Meas");
tanasaro10 9:303d3628986a 390 len = 12;
tanasaro10 9:303d3628986a 391 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 392 g_LogActive = true;
tanasaro10 9:303d3628986a 393 break;
tanasaro10 9:303d3628986a 394 }
tanasaro10 9:303d3628986a 395 case '3':{// stop measuring
tanasaro10 9:303d3628986a 396 sprintf(myBuf,"Stop Meas");
tanasaro10 9:303d3628986a 397 len = 11;
tanasaro10 9:303d3628986a 398 sendRadioMsg((uint8_t *)myBuf, len);
tanasaro10 9:303d3628986a 399 g_LogActive = false;
tanasaro10 9:303d3628986a 400 break;
tanasaro10 9:303d3628986a 401 }
tanasaro10 9:303d3628986a 402
tanasaro10 9:303d3628986a 403 default: {
tanasaro10 9:303d3628986a 404 // error
tanasaro10 9:303d3628986a 405 }
tanasaro10 9:303d3628986a 406 }
tanasaro10 9:303d3628986a 407 break;
tanasaro10 9:303d3628986a 408 }
tanasaro10 9:303d3628986a 409 default: {
tanasaro10 9:303d3628986a 410 MyASSERT(true,&pc, buffer[1]); // notify on serial interface
tanasaro10 9:303d3628986a 411 on_error_radioMsg(); // notify on radio;
tanasaro10 9:303d3628986a 412 }
tanasaro10 8:f28ad4600b0f 413 }
tanasaro10 8:f28ad4600b0f 414 }
tanasaro10 8:f28ad4600b0f 415
tanasaro10 9:303d3628986a 416 // decode serial command that starts with x
tanasaro10 9:303d3628986a 417 static void decode_s(uint8_t * buffer, uint16_t length)
tanasaro10 9:303d3628986a 418 {
tanasaro10 9:303d3628986a 419 uint8_t page_nr;
tanasaro10 9:303d3628986a 420 char myBuf[5];
tanasaro10 9:303d3628986a 421 uint32_t * p_curr_addr;
tanasaro10 8:f28ad4600b0f 422
tanasaro10 9:303d3628986a 423 switch (buffer[0]) {
tanasaro10 9:303d3628986a 424 case 'f': { // info about selected flash page
tanasaro10 9:303d3628986a 425 if ((buffer[1]<='9')&&(buffer[1]>='0')) {
tanasaro10 9:303d3628986a 426 memcpy(myBuf,&buffer[1],3);
tanasaro10 9:303d3628986a 427 page_nr= atoi(myBuf);
tanasaro10 9:303d3628986a 428 uint8_t p_word_count;
tanasaro10 9:303d3628986a 429
tanasaro10 9:303d3628986a 430 pc.printf("buffer[1]: %c \r\n",buffer[1]);
tanasaro10 9:303d3628986a 431
tanasaro10 9:303d3628986a 432 p_curr_addr= (uint32_t *)((uint16_t)BLE_FLASH_PAGE_SIZE * (flash_currPage() - page_nr));
tanasaro10 9:303d3628986a 433 pc.printf("page_addr: %x, pgNr = %d \r\n",p_curr_addr,(flash_currPage() - page_nr));
tanasaro10 9:303d3628986a 434 p_curr_addr += 1;
tanasaro10 9:303d3628986a 435 pc.printf("page_addr: %x \r\n",p_curr_addr);
tanasaro10 9:303d3628986a 436 p_word_count = (uint8_t)(*(p_curr_addr));
tanasaro10 9:303d3628986a 437 pc.printf("nr_of_words: %d \r\n",p_word_count);
tanasaro10 9:303d3628986a 438 flash_page_serial_dump((p_curr_addr-1));
tanasaro10 9:303d3628986a 439 }
tanasaro10 9:303d3628986a 440 break;
tanasaro10 9:303d3628986a 441 }
tanasaro10 9:303d3628986a 442 case 'd': { // full dump
tanasaro10 9:303d3628986a 443 uint16_t page0;
tanasaro10 9:303d3628986a 444 pc.printf("Full dump \r\n");
tanasaro10 9:303d3628986a 445
tanasaro10 9:303d3628986a 446 page0 = flash_currPage();
tanasaro10 9:303d3628986a 447 for (page_nr=1; page_nr<=(MAX_PAGE_NUM-MIN_PAGE_NUM+1); page_nr++) {
tanasaro10 9:303d3628986a 448 if ((page0-page_nr)< MIN_PAGE_NUM){
tanasaro10 9:303d3628986a 449 page0 = MAX_PAGE_NUM + page_nr;
tanasaro10 8:f28ad4600b0f 450 }
tanasaro10 9:303d3628986a 451 p_curr_addr= (uint32_t *)((uint16_t)BLE_FLASH_PAGE_SIZE * (page0-page_nr));
tanasaro10 9:303d3628986a 452 flash_page_serial_dump(p_curr_addr);
tanasaro10 9:303d3628986a 453 }
tanasaro10 9:303d3628986a 454 break;
tanasaro10 9:303d3628986a 455 }
tanasaro10 9:303d3628986a 456 case 'g':{
tanasaro10 9:303d3628986a 457 pc.printf("g_MyDataIdx= %d\r", g_MyDataIdx);
tanasaro10 9:303d3628986a 458 break;
tanasaro10 9:303d3628986a 459 }
tanasaro10 9:303d3628986a 460 case 'c': {
tanasaro10 9:303d3628986a 461 switch (buffer[1]){
tanasaro10 9:303d3628986a 462 case 'a': {
tanasaro10 9:303d3628986a 463 connectionUpdate(eStartAdvertising);
tanasaro10 9:303d3628986a 464 break;
tanasaro10 9:303d3628986a 465 }
tanasaro10 9:303d3628986a 466 case 'c' : {
tanasaro10 9:303d3628986a 467 connectionUpdate(eDisconnect);
tanasaro10 9:303d3628986a 468 break;
tanasaro10 8:f28ad4600b0f 469 }
tanasaro10 9:303d3628986a 470 case 's' : {
tanasaro10 9:303d3628986a 471 connectionUpdate(eStopAdvertising);
tanasaro10 9:303d3628986a 472 break;
tanasaro10 8:f28ad4600b0f 473 }
tanasaro10 9:303d3628986a 474 default: pc.printf("Not recognized cmd !\r");
tanasaro10 9:303d3628986a 475 }
tanasaro10 9:303d3628986a 476 break;
tanasaro10 9:303d3628986a 477 }
tanasaro10 9:303d3628986a 478 default: {
tanasaro10 9:303d3628986a 479 // nothing
tanasaro10 8:f28ad4600b0f 480 }
tanasaro10 9:303d3628986a 481 }
tanasaro10 8:f28ad4600b0f 482 }
tanasaro10 9:303d3628986a 483
RedBearLab 2:4b66b69c7ecb 484 void WrittenHandler(const GattWriteCallbackParams *Handler)
tanasaro10 9:303d3628986a 485 {
tanasaro10 9:303d3628986a 486 uint8_t buf[TXRX_BUF_LEN+1]= {'R',':',0};
tanasaro10 9:303d3628986a 487 uint16_t bytesRead;
tanasaro10 9:303d3628986a 488
tanasaro10 9:303d3628986a 489 if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) {
tanasaro10 6:a574229993b8 490 ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), &buf[2], &bytesRead);
RedBearLab 0:cffe8ac1bdf0 491 memset(txPayload, 0, TXRX_BUF_LEN);
tanasaro10 9:303d3628986a 492 memcpy(txPayload, &buf[2], bytesRead);
tanasaro10 9:303d3628986a 493 if (txPayload[0] == 'x') {
tanasaro10 9:303d3628986a 494 decode(&txPayload[1],bytesRead);
tanasaro10 9:303d3628986a 495 }
tanasaro10 9:303d3628986a 496 //echo back
tanasaro10 9:303d3628986a 497 bytesRead+=2;
tanasaro10 9:303d3628986a 498 sendRadioMsg(buf, bytesRead);
tanasaro10 9:303d3628986a 499
tanasaro10 6:a574229993b8 500 // print on PC monitor
tanasaro10 9:303d3628986a 501 buf[bytesRead]='\r';
tanasaro10 9:303d3628986a 502 //buf[bytesRead+1]='\n';
tanasaro10 9:303d3628986a 503 pc.printf("%s",buf);
RedBearLab 0:cffe8ac1bdf0 504 }
RedBearLab 0:cffe8ac1bdf0 505 }
RedBearLab 0:cffe8ac1bdf0 506
RedBearLab 0:cffe8ac1bdf0 507 void uartCB(void)
tanasaro10 9:303d3628986a 508 {
tanasaro10 9:303d3628986a 509 while(pc.readable()) {
tanasaro10 9:303d3628986a 510 rx_buf[rx_len++] = pc.getc();
tanasaro10 9:303d3628986a 511 if(rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n') {
tanasaro10 9:303d3628986a 512 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), rx_buf, rx_len);
tanasaro10 9:303d3628986a 513 if ((rx_buf[0]=='x')) {
tanasaro10 9:303d3628986a 514 decode_s(&rx_buf[1],(rx_len-1)); // serial decode
tanasaro10 9:303d3628986a 515 }
tanasaro10 9:303d3628986a 516 rx_len= 0;
RedBearLab 0:cffe8ac1bdf0 517 break;
RedBearLab 0:cffe8ac1bdf0 518 }
RedBearLab 0:cffe8ac1bdf0 519 }
RedBearLab 0:cffe8ac1bdf0 520 }
RedBearLab 0:cffe8ac1bdf0 521
tanasaro10 9:303d3628986a 522 void button()
tanasaro10 9:303d3628986a 523 {
tanasaro10 8:f28ad4600b0f 524 uint8_t buf[TXRX_BUF_LEN+1];
tanasaro10 8:f28ad4600b0f 525 buf[0]='B';
tanasaro10 8:f28ad4600b0f 526 buf[1]=':';
tanasaro10 8:f28ad4600b0f 527 buf[2]='O';
tanasaro10 8:f28ad4600b0f 528 buf[3]='N';
tanasaro10 9:303d3628986a 529 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 4);
tanasaro10 8:f28ad4600b0f 530 }
tanasaro10 8:f28ad4600b0f 531
tanasaro10 9:303d3628986a 532 void g_varInit()
tanasaro10 9:303d3628986a 533 {
tanasaro10 9:303d3628986a 534 g_myDateVar.updateDate = false;
tanasaro10 8:f28ad4600b0f 535 g_myTimeVar.updateTime = false;
tanasaro10 9:303d3628986a 536 /* retreive latest date, time and page flash available */
tanasaro10 9:303d3628986a 537 search_latest_in_flash(&g_myDateVar.currentDate, &g_myTimeVar.currentTime );
tanasaro10 8:f28ad4600b0f 538 }
tanasaro10 8:f28ad4600b0f 539
RedBearLab 0:cffe8ac1bdf0 540 int main(void)
RedBearLab 0:cffe8ac1bdf0 541 {
RedBearLab 0:cffe8ac1bdf0 542 ble.init();
tanasaro10 9:303d3628986a 543 g_varInit();
RedBearLab 0:cffe8ac1bdf0 544 ble.onDisconnection(disconnectionCallback);
tanasaro10 9:303d3628986a 545 ble.onConnection(connectionCallback);
tanasaro10 9:303d3628986a 546 ble.onDataWritten(WrittenHandler);
tanasaro10 8:f28ad4600b0f 547 event.rise(&button);
tanasaro10 9:303d3628986a 548
tanasaro10 6:a574229993b8 549 pc.baud(19200);
RedBearLab 0:cffe8ac1bdf0 550 pc.printf("SimpleChat Init \r\n");
tanasaro10 9:303d3628986a 551
RedBearLab 0:cffe8ac1bdf0 552 pc.attach( uartCB , pc.RxIrq);
tanasaro10 9:303d3628986a 553 // setup advertising
RedBearLab 0:cffe8ac1bdf0 554 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
RedBearLab 0:cffe8ac1bdf0 555 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
RedBearLab 0:cffe8ac1bdf0 556 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
tanasaro10 9:303d3628986a 557 (const uint8_t *)"MyBleVT", sizeof("MyBleVT") - 1);
RedBearLab 0:cffe8ac1bdf0 558 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
tanasaro10 9:303d3628986a 559 (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
tanasaro10 9:303d3628986a 560 //ble.accumulateAdvertisingPayload(GapAdvertisingData::TX_POWER_LEVEL,(const uint8_t *)txPower, sizeof(txPower));
tanasaro10 9:303d3628986a 561 ble.setTxPower(txPower);
tanasaro10 9:303d3628986a 562 // 100ms; in multiples of 0.625ms.
RedBearLab 0:cffe8ac1bdf0 563 ble.setAdvertisingInterval(160);
tanasaro10 9:303d3628986a 564 /*
tanasaro10 9:303d3628986a 565 // activate radio notifications - usefull for flashwrite
tanasaro10 9:303d3628986a 566 void (*ptrFunc)(bool);
tanasaro10 9:303d3628986a 567 ptrFunc = ble_flash_on_radio_active_evt;
tanasaro10 9:303d3628986a 568 //needed for flash write
tanasaro10 9:303d3628986a 569 //ble.onRadioNotification(ptrFunc);
tanasaro10 9:303d3628986a 570 */
RedBearLab 0:cffe8ac1bdf0 571 ble.addService(uartService);
tanasaro10 9:303d3628986a 572 ble.startAdvertising();
RedBearLab 0:cffe8ac1bdf0 573 pc.printf("Advertising Start \r\n");
tanasaro10 9:303d3628986a 574 periodicActions.attach(&at_eachInstant,gTimeInstant);
tanasaro10 9:303d3628986a 575 while(1) {
tanasaro10 9:303d3628986a 576 ble.waitForEvent();
RedBearLab 0:cffe8ac1bdf0 577 }
RedBearLab 0:cffe8ac1bdf0 578 }