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:
Fri May 06 18:14:18 2016 +0000
Revision:
11:baafa4f7a15e
Parent:
10:c7d53e4e0602
Child:
12:27e9c3db28b9
minor updates

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