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
main.cpp
00001 /* 00002 00003 Copyright (c) 2012-2014 RedBearLab 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00006 and associated documentation files (the "Software"), to deal in the Software without restriction, 00007 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 00009 subject to the following conditions: 00010 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 00011 00012 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 00013 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 00014 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 00015 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00016 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 00018 */ 00019 00020 /* 00021 * The application works with the BLEController iOS/Android App. 00022 * Type something from the Terminal to send 00023 * to the BLEController App or vice verse. 00024 * Characteristics received from App will print on Terminal. 00025 * Read read_me.md file for more informations about the extended feature 00026 */ 00027 00028 00029 #include "ble/BLE.h" 00030 //#include "LowPowerTicker.h" 00031 #include <myData.h> 00032 #include <Gap.h> 00033 //#include "ble_flash.h" 00034 #include "ble_flash.c" 00035 #include "BatteryService.h" 00036 //#include "DFUService.h" 00037 00038 BLE ble; 00039 //DFUService dfu(ble); 00040 00041 #define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */ 00042 #define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */ 00043 #define BLE_UUIDS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */ 00044 00045 #define TXRX_BUF_LEN 20 /** For radio message transmission*/ 00046 00047 #define MyASSERT(cond , serialpc, errVal) assert_error_app((bool)cond, serialpc, (uint16_t)errVal, __LINE__, __FILE__) 00048 00049 00050 Serial pc(USBTX, USBRX); 00051 00052 //uint8_t batteryLevel=100; 00053 uint16_t nr_of_hits = 0; 00054 uint32_t g_nrOfHits=0; 00055 float gmaxV=0,gminV=3,gmedianV=0.18; // Voltage of the PhotoResistorstatic float measure: max, min, median; 00056 00057 bool bTimeReady = false; 00058 // The Nordic UART Service 00059 static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E}; 00060 static const uint8_t uart_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E}; 00061 static const uint8_t uart_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E}; 00062 static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71}; 00063 00064 static const int8_t txPower = 0xCD; 00065 //BatteryService *batteryService = NULL; 00066 00067 //uint8_t txPayload[TXRX_BUF_LEN] = {0, p28}; 00068 uint8_t txPayload[TXRX_BUF_LEN] = {0,}; 00069 uint8_t rxPayload[TXRX_BUF_LEN] = {0,}; 00070 00071 static uint8_t rx_buf[TXRX_BUF_LEN]; 00072 static uint8_t rx_len=0; 00073 00074 static uint32_t gTimeInstant = 1; // TimerTick Resolution, in seconds 00075 00076 00077 bool g_bIsConnected = false; 00078 bool g_bIsAdvertising = false; 00079 bool g_bConnDisabled = false; 00080 bool g_LogActive = false;// g_bAccEnabled=false, g_bCalib = false; 00081 static myDataLog_t g_MyData; 00082 uint8_t g_MyDataIdx=0; 00083 00084 00085 // pins connected for measuring 00086 DigitalOut led(LED1), //redLed(D4);//, accBuzzAlarm(D3), accLEDAlarm(D5); 00087 00088 //uint8_t tempAlarm, accAlarm; 00089 00090 //PwmOut buzzer(D1); // changed from P15 00091 AnalogIn photoVoltage(A5); // photo voltaga measurement 00092 00093 myPayload_t g_currMeasures2; // last measurements 00094 00095 //Timeout timeout_err; // timeout for buzz on error 00096 Ticker periodicActions, doMeasures; 00097 mdatetime_manager_t g_myDateTimeVar; 00098 //uint8_t gBatteryValue=0; 00099 GattCharacteristic txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE); 00100 00101 GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); 00102 00103 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic}; 00104 00105 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *)); 00106 00107 void decode(uint8_t * buffer, uint16_t length); 00108 00109 void alarm(){ 00110 00111 //accBuzzAlarm = 1; 00112 //accLEDAlarm = 0; 00113 //timeout_err.attach(&at_timeout_err, 2); 00114 } 00115 00116 void sendRadioMsg(const uint8_t* buf, uint16_t length) 00117 { 00118 uint8_t retVal; 00119 retVal = ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, length); 00120 //pc.printf("Err=%d\r\n",retVal); 00121 MyASSERT((retVal!=0),&pc, retVal); 00122 } 00123 00124 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) 00125 { 00126 pc.printf("Disconnected \r\n"); 00127 g_bIsConnected = false; 00128 g_bIsAdvertising = false; 00129 pc.printf("R: %d\r",reason); 00130 if (reason != 0x16) { 00131 ble.startAdvertising(); 00132 g_bIsAdvertising = true; 00133 } 00134 } 00135 00136 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00137 { 00138 pc.printf("Connected \r\n"); 00139 g_bIsConnected = true; 00140 g_bIsAdvertising = false; 00141 } 00142 00143 void connectionUpdate(connection_update_t option) 00144 { 00145 if (g_bConnDisabled == false) { 00146 switch (option) { 00147 case eStartAdvertising: { 00148 if ((g_bIsConnected == false)&&(g_bIsAdvertising == false)) { 00149 pc.printf("Start Advertising\r"); 00150 ble.startAdvertising(); 00151 g_bIsAdvertising = true; 00152 } 00153 break; 00154 } 00155 case eStopAdvertising: { 00156 if (g_bIsAdvertising == true) { 00157 pc.printf("Stop Advertising\r"); 00158 ble.stopAdvertising(); 00159 g_bIsAdvertising = false; 00160 } 00161 break; 00162 } 00163 case eDisconnect: { 00164 if (g_bIsConnected == true) { 00165 pc.printf("Close connection\r"); 00166 ble.disconnect((Gap::DisconnectionReason_t)0x12); 00167 } else if (g_bIsAdvertising == true) { 00168 pc.printf("Stop Advertising\r"); 00169 ble.stopAdvertising(); 00170 g_bIsAdvertising = false; 00171 } 00172 break; 00173 } 00174 } 00175 } 00176 } 00177 void write_data_to_flash(uint32_t *tick, myPayload_t * currMeasures) 00178 { 00179 uint8_t page_num=0; 00180 00181 if (g_MyDataIdx==0) { 00182 //initiate connection 00183 connectionUpdate(eStartAdvertising); 00184 // time and date used to initialize the g_MyData variable 00185 memcpy(&g_MyData.startData.datetime,&g_myDateTimeVar.currentDateTime, sizeof(mdate_time_t)); 00186 memcpy(&g_MyData.startData.data,currMeasures, sizeof(myPayload_t)); 00187 } else { 00188 // it should be logged here the time difference from last record... 00189 g_MyData.myData[g_MyDataIdx-1].minutes = (uint16_t)(*tick*gTimeInstant / 60); 00190 g_MyData.myData[g_MyDataIdx-1].seconds = (*tick*gTimeInstant% 60); 00191 memcpy(&g_MyData.myData[g_MyDataIdx-1].data,currMeasures, sizeof(myPayload_t)); 00192 } 00193 *tick = 0; 00194 00195 if (g_MyDataIdx==(MAXBUFFER-3)) { 00196 //initiate disconnection 00197 connectionUpdate(eDisconnect); 00198 } 00199 00200 if (g_MyDataIdx == MAXBUFFER) { 00201 // write2Flash the current page num 00202 //connectionUpdate(eDisconnect); 00203 00204 page_num=flash_currPage(); 00205 // write2Flash the current page data 00206 ble_flash_page_write(page_num, (uint32_t*)&(g_MyData), 253); 00207 memset(&g_MyData,0,sizeof(myDataLog_t)); 00208 //pc.printf("retValWr: %d, Pg:%d, Min: %d \r\n",retVal, page_num,g_myDateTimeVar.currentDateTime.minutes); 00209 flash_go_nextPage(); 00210 } 00211 g_MyDataIdx = (g_MyDataIdx+1)%(MAXBUFFER+1); 00212 } 00213 00214 00215 void on_error_radioMsg() 00216 { 00217 char myBuf[TXRX_BUF_LEN]; 00218 sprintf(myBuf,"%s","WrongSyntax"); 00219 //buzz_int(&buzzer,5,3); 00220 //timeout_err.attach(&at_timeout_err, 2); 00221 sendRadioMsg((uint8_t*)&myBuf[0], 12); 00222 } 00223 00224 void flash_page_serial_dump(uint32_t* p_curr_addr) 00225 { 00226 myDataLogShort_t initialData; 00227 mdate_time_t * pdate; 00228 myDataL_t dataOut[2]; 00229 uint8_t i; 00230 00231 p_curr_addr += 2; // skip the magic number and the word count 00232 memcpy((uint32_t*)&initialData, p_curr_addr, 3*sizeof(uint32_t)); 00233 pdate = &initialData.startData.datetime; 00234 pc.printf("20%2d_%2d_%2d H:%2d P:%4x\r",pdate->year, pdate->month, pdate->day, pdate->hours, p_curr_addr); 00235 pc.printf("%2d:%2d;%3d;%2d:%2d;%3d;\r",pdate->minutes, pdate->seconds, initialData.startData.data.hits,initialData.myData.minutes, initialData.myData.seconds, initialData.myData.data.hits); 00236 p_curr_addr += 3; 00237 00238 for (i=0; i<125; i++) { 00239 memcpy((uint32_t*)&dataOut, p_curr_addr, 2*sizeof(uint32_t)); 00240 pc.printf("%2d:%2d;%3d;%2d:%2d;%3d;\r",dataOut[0].minutes, dataOut[0].seconds, dataOut[0].data.hits,dataOut[1].minutes, dataOut[1].seconds, dataOut[1].data.hits); 00241 p_curr_addr += 2; 00242 } 00243 } 00244 00245 int sign(int nr){ 00246 int retVal=0; 00247 if (nr>0) retVal=1; 00248 else if (nr<0) retVal=-1; 00249 00250 return retVal; 00251 } 00252 00253 float read_real_value(void){ 00254 uint32_t wrk,reg0,reg1,reg2; 00255 reg0 = NRF_ADC->ENABLE; // save register value 00256 reg1 = NRF_ADC->CONFIG; // save register value 00257 reg2 = NRF_ADC->RESULT; // save register value 00258 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; 00259 NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | 00260 (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | 00261 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) | 00262 (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) | 00263 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); 00264 NRF_ADC->EVENTS_END = 0; 00265 NRF_ADC->TASKS_START = 1; 00266 while (!NRF_ADC->EVENTS_END) {;} 00267 wrk = NRF_ADC->RESULT; // 10 bit result 00268 NRF_ADC->ENABLE = reg0; // recover register value 00269 NRF_ADC->CONFIG = reg1; // recover register value 00270 NRF_ADC->RESULT = reg2; // recover register value 00271 NRF_ADC->EVENTS_END = 0; 00272 return ((float)wrk / 1024 * 1.2 * 3.0); 00273 } 00274 00275 uint8_t read100(void) 00276 { 00277 float wrk_vdd, v0p= 2.7 ,v100p= 3.3; 00278 wrk_vdd = read_real_value(); 00279 if (wrk_vdd <= v0p){ 00280 return 0; 00281 } else if (wrk_vdd >= v100p){ 00282 led = 0; 00283 return 100; 00284 00285 } 00286 led = 1; 00287 wrk_vdd = (wrk_vdd - v0p) / (v100p - v0p); 00288 return (uint8_t)(wrk_vdd * 100); 00289 } 00290 00291 00292 void at_eachInstant() 00293 { 00294 static uint32_t tick=0; 00295 static uint8_t ltick=0; 00296 uint8_t rcBuff[2]={'r','0'}; 00297 //static myPayload_t prevMeasures2=(myPayload_t) { 0, 0, 0, 0}; 00298 00299 // update time 00300 update_time(&g_myDateTimeVar, gTimeInstant); 00301 00302 //batteryService->updateBatteryLevel(gBatteryValue ); 00303 //update measurements 00304 if (g_LogActive==true){ 00305 // if there are changes in data save 00306 if (0!=g_currMeasures2.hits){ 00307 write_data_to_flash(&tick, &g_currMeasures2); 00308 } 00309 if (g_bIsConnected == true){ 00310 // print info 00311 rcBuff[1]='0'+ltick; 00312 decode(rcBuff,2); 00313 ltick =(ltick+1)%4; 00314 } 00315 tick++; 00316 00317 } 00318 } 00319 00320 void update_measurements() 00321 { 00322 nr_of_hits ++; 00323 g_nrOfHits ++; 00324 /*if (bNewSample==false){ 00325 //g_currMeasures2.hits =nr_of_hits; 00326 nr_of_hits = 1; 00327 bNewSample = true; 00328 } */ 00329 00330 //gBatteryValue = read100(); 00331 00332 } 00333 00334 void at_eachADC(){ 00335 static bool isLow = false; 00336 static bool bPrevState=isLow; 00337 static uint8_t counter = 0; 00338 static float measure; 00339 00340 00341 measure = photoVoltage.read(); 00342 if (g_LogActive==false){ 00343 if (measure > gmaxV) { 00344 maxV=measure; 00345 } 00346 if (measure < minV) { 00347 gminV=measure; 00348 } 00349 //gmedian = gminV + (gminV + gmaxV)*10/4; % 25% 00350 } 00351 00352 isLow = (measure < gmedianV); 00353 if ((bPrevState != isLow)&&(isLow == true)){ 00354 nr_of_hits ++; 00355 g_nrOfHits ++; 00356 } 00357 bPrevState = isLow; 00358 00359 counter = (counter + 1)%100; 00360 if (counter==0){ 00361 // 1 second is passed 00362 bTimeReady=true; 00363 g_currMeasures2.hits =nr_of_hits; 00364 nr_of_hits = 0; 00365 } 00366 } 00367 00368 // Radio commands decode 00369 void decode(uint8_t * buffer, uint16_t length) 00370 { 00371 char myBuf[TXRX_BUF_LEN]; 00372 uint16_t len; 00373 switch (buffer[0]) { 00374 case 'r': {// Read Operations 00375 switch (buffer[1]) { 00376 case '0':{ 00377 sprintf(myBuf,"NH:%2d,TNH:%8d\r\n", g_currMeasures2.hits,g_nrOfHits); 00378 len = 19; 00379 break; 00380 } 00381 case '1':{ 00382 sprintf(myBuf,"P:%1.2f_%1.2f_%1.2f\r\n", gmaxV,photoVoltage.read(),gminV); 00383 len = 18; 00384 break; 00385 } 00386 case '2':{ 00387 sprintf(myBuf,"g_idx=%2d Page=%3d",g_MyDataIdx, flash_currPage()); 00388 len = 18; 00389 break; 00390 } 00391 case '3': { 00392 sprintf(myBuf,"V:%2.3f\r\n", read_real_value()); 00393 len = 11; 00394 break; 00395 } 00396 case '4': { 00397 sprintf(myBuf,"PhVol:%2.2f,Av:%2.2f\r\n",photoVoltage.read(),gmedian); 00398 len = 20; 00399 break; 00400 } 00401 case '5': { 00402 //sprintf(myBuf,"Vmx_mn:%1.2f_%1.2f\r\n",maxV,minV); 00403 //len = 18; 00404 break; 00405 } 00406 00407 default:{ 00408 sprintf(myBuf,"Nothing \r\n"); 00409 len = 10; 00410 break; 00411 } 00412 } 00413 sendRadioMsg((uint8_t *)myBuf, len); 00414 break; 00415 } 00416 case 'l': {// toogle led 00417 led = ! led; 00418 if (led==0) { 00419 sprintf(myBuf,"%s","OFF"); 00420 len = 2; 00421 } else { 00422 sprintf(myBuf,"%s","ON"); 00423 len = 3; 00424 } 00425 sendRadioMsg((uint8_t *)myBuf, len); 00426 break; 00427 } 00428 case 'i':{ // Insert data values 00429 switch (buffer[1]){ 00430 case 'm':{ // median change 00431 memcpy(myBuf,&buffer[2],2); 00432 gmedian=(float)atoi(myBuf)/10; // TODO check if it is a number 00433 break; 00434 } 00435 00436 default: { 00437 // on_error_radioMsg(); // notify on radio 00438 } 00439 } 00440 break; 00441 } 00442 case 'd': 00443 case 't': {// date /time operations 00444 switch (buffer[1]) { 00445 case 'i': { // date insert 00446 uint8_t i; 00447 uint8_t * pdata = &g_myDateTimeVar.newDateTime.year; // to insert data 00448 00449 if (buffer[0]=='t') { 00450 sprintf(myBuf," TimeInserted"); 00451 pdata +=3; 00452 } else {sprintf(myBuf," DateInserted");} 00453 len= 14; 00454 00455 for (i=0;i<3;i++){ 00456 memcpy(myBuf,&buffer[2+2*i],2); 00457 *pdata=atoi(myBuf); // TODO check if it is a number 00458 pdata= pdata+1; 00459 } 00460 g_myDateTimeVar.updateDateTime = true; 00461 00462 sendRadioMsg((uint8_t *)myBuf, len); 00463 break; 00464 } 00465 case 'g': { // time/date get 00466 uint8_t * pdata1 = &g_myDateTimeVar.currentDateTime.year; // to get data 00467 if (buffer[0]=='t') { 00468 pdata1 +=3; 00469 sprintf(myBuf,"H:%2d:%2d:%2d",*pdata1,*(pdata1+1),*(pdata1+2)); 00470 len = 11; 00471 }else { 00472 sprintf(myBuf,"D:20%2d:%2d:%2d",*pdata1,*(pdata1+1),*(pdata1+2)); 00473 len = 13; 00474 } 00475 sendRadioMsg((uint8_t *)myBuf, len); 00476 break; 00477 } 00478 default: 00479 MyASSERT(true,&pc, buffer[1]); // notify on serial interface 00480 on_error_radioMsg(); // notify on radio 00481 } 00482 break; 00483 } 00484 00485 case 'f': {// file operations 00486 switch (buffer[1]) { 00487 case '1': { 00488 sprintf(myBuf,"g_idx=%2d Page=%3d",g_MyDataIdx, flash_currPage()); 00489 len = 18; 00490 sendRadioMsg((uint8_t *)myBuf, len); 00491 break; 00492 } 00493 case '2': { // start measuring 00494 sprintf(myBuf,"Start Meas"); 00495 len = 12; 00496 sendRadioMsg((uint8_t *)myBuf, len); 00497 g_LogActive = true; 00498 00499 break; 00500 } 00501 case '3': { // stop measuring 00502 doMeasures.detach(); 00503 sprintf(myBuf,"Stop Meas"); 00504 len = 11; 00505 sendRadioMsg((uint8_t *)myBuf, len); 00506 g_LogActive = false; 00507 ble_flash_page_write(flash_currPage(), (uint32_t*)&(g_MyData), 253); 00508 memset(&g_MyData,0,sizeof(myDataLog_t)); 00509 flash_go_nextPage(); 00510 break; 00511 } 00512 case '4':{ 00513 break; 00514 } 00515 case '5':{ // read one measure 00516 00517 break; 00518 } 00519 default: { 00520 // error 00521 } 00522 } 00523 break; 00524 } 00525 default: { 00526 MyASSERT(true,&pc, buffer[1]); // notify on serial interface 00527 on_error_radioMsg(); // notify on radio; 00528 } 00529 } 00530 } 00531 00532 // decode serial command that starts with x 00533 static void decode_s(uint8_t * buffer, uint16_t length) 00534 { 00535 uint8_t page_nr; 00536 char myBuf[5]; 00537 uint32_t * p_curr_addr; 00538 00539 switch (buffer[0]) { 00540 case 'f': { // info about selected flash page 00541 if ((buffer[1]<='9')&&(buffer[1]>='0')) { 00542 memcpy(myBuf,&buffer[1],3); 00543 page_nr= atoi(myBuf); 00544 uint8_t p_word_count; 00545 00546 pc.printf("buffer[1]: %c \r\n",buffer[1]); 00547 00548 p_curr_addr= (uint32_t *)((uint16_t)BLE_FLASH_PAGE_SIZE * (flash_currPage() - page_nr)); 00549 pc.printf("page_addr: %x, pgNr = %d \r\n",p_curr_addr,(flash_currPage() - page_nr)); 00550 p_curr_addr += 1; 00551 pc.printf("page_addr: %x \r\n",p_curr_addr); 00552 p_word_count = (uint8_t)(*(p_curr_addr)); 00553 pc.printf("nr_of_words: %d \r\n",p_word_count); 00554 flash_page_serial_dump((p_curr_addr-1)); 00555 } 00556 break; 00557 } 00558 case 'd': { // full dump 00559 uint16_t page0; 00560 pc.printf("Full dump \r\n"); 00561 00562 page0 = flash_currPage(); 00563 for (page_nr=0; page_nr<=(MAX_PAGE_NUM-MIN_PAGE_NUM); page_nr++) { 00564 if ((page0-page_nr)< MIN_PAGE_NUM) { 00565 page0 = MAX_PAGE_NUM + page_nr; 00566 } 00567 p_curr_addr= (uint32_t *)((uint16_t)BLE_FLASH_PAGE_SIZE * (page0-page_nr)); 00568 flash_page_serial_dump(p_curr_addr); 00569 } 00570 break; 00571 } 00572 case 'g': { 00573 pc.printf("g_MyDataIdx= %d\r", g_MyDataIdx); 00574 break; 00575 } 00576 case 'c': { 00577 switch (buffer[1]) { 00578 case 'a': { 00579 connectionUpdate(eStartAdvertising); 00580 break; 00581 } 00582 case 'c' : { 00583 connectionUpdate(eDisconnect); 00584 break; 00585 } 00586 case 's' : { 00587 connectionUpdate(eStopAdvertising); 00588 break; 00589 } 00590 default: 00591 pc.printf("Not recognized cmd !\r"); 00592 } 00593 break; 00594 } 00595 default: { 00596 // nothing 00597 } 00598 } 00599 } 00600 00601 void WrittenHandler(const GattWriteCallbackParams *Handler) 00602 { 00603 uint8_t buf[TXRX_BUF_LEN+1]= {'R',':',0}; 00604 uint16_t bytesRead; 00605 00606 if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) { 00607 ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), &buf[2], &bytesRead); 00608 memset(txPayload, 0, TXRX_BUF_LEN); 00609 memcpy(txPayload, &buf[2], bytesRead); 00610 if (txPayload[0] == 'x') { 00611 decode(&txPayload[1],bytesRead); 00612 } 00613 //echo back 00614 bytesRead+=2; 00615 sendRadioMsg(buf, bytesRead); 00616 00617 // print on PC monitor 00618 buf[bytesRead]='\r'; 00619 pc.printf("%s",buf); 00620 } 00621 } 00622 00623 void uartCB(void) 00624 { 00625 while(pc.readable()) { 00626 rx_buf[rx_len++] = pc.getc(); 00627 if(rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n') { 00628 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), rx_buf, rx_len); 00629 if ((rx_buf[0]=='x')) { 00630 decode_s(&rx_buf[1],(rx_len-1)); // serial decode 00631 } 00632 rx_len= 0; 00633 break; 00634 } 00635 } 00636 } 00637 00638 00639 void g_varInit() 00640 { 00641 g_myDateTimeVar.updateDateTime = true; 00642 /* retreive latest date, time and page flash available */ 00643 search_latest_in_flash(&g_myDateTimeVar.newDateTime); 00644 } 00645 00646 int main(void) 00647 { 00648 ble.init(); 00649 g_varInit(); 00650 led= 1; 00651 00652 ble.onDisconnection(disconnectionCallback); 00653 ble.onConnection(connectionCallback); 00654 ble.onDataWritten(WrittenHandler); 00655 //event.rise(&button); 00656 00657 00658 //event.rise(&accInt1); 00659 pc.baud(19200); 00660 pc.printf("SimpleChat Init \r\n"); 00661 00662 pc.attach( uartCB , pc.RxIrq); 00663 // setup advertising 00664 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); 00665 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00666 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, 00667 (const uint8_t *)"CntBle3", sizeof("CntBle3") - 1); 00668 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, 00669 (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid)); 00670 //ble.accumulateAdvertisingPayload(GapAdvertisingData::TX_POWER_LEVEL,(const uint8_t *)txPower, sizeof(txPower)); 00671 ble.setTxPower(txPower); 00672 // 100ms; in multiples of 0.625ms. 00673 ble.setAdvertisingInterval(160); 00674 /* 00675 // activate radio notifications - usefull for flashwrite 00676 void (*ptrFunc)(bool); 00677 ptrFunc = ble_flash_on_radio_active_evt; 00678 //needed for flash write 00679 //ble.onRadioNotification(ptrFunc); 00680 */ 00681 ble.addService(uartService); 00682 //batteryService = new BatteryService(ble, batteryLevel); 00683 ble.startAdvertising(); 00684 pc.printf("Advertising Start \r\n"); 00685 //periodicActions.attach(&at_eachInstant,gTimeInstant); 00686 doMeasures.attach_us(&at_eachADC,10000); 00687 //gBatteryValue = read100(); 00688 while(1) { 00689 ble.waitForEvent(); 00690 if (bTimeReady==true){ 00691 bTimeReady=false; 00692 at_eachInstant(); 00693 } 00694 } 00695 }
Generated on Sat Jul 23 2022 06:55:25 by 1.7.2