App for BLE Nano to monitor the power consumption for a specific location, by intercepting the led flashes of a standard power meter. It counts and log the flashes for each second. It works with RedBear App for smart phone (Simple Chat App).

Dependencies:   BLE_API lib_mma8451q 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 }