This program is designed to work with RedBearLab BLE Controller App - Chat App. Type something from the Terminal to send to the BLEController App or vice verse. Characteristics received from App will print on Terminal. This Program scans some analog and digital inputs and save them in flash with timestamp. A RTC has been implemented. Using chat application (available for smart phones) some commands can be send to BLE Nano in order to perform some tasks. Other types of commands can be send via serial interface from a PC, especially data extraction from flash.

Dependencies:   BLE_API mbed nRF51822

Fork of nRF51822_SimpleChat_VT by Valentin Tanasa

nRF51822_SimpleChat Extended With Data Measurements & Logger

This repo is derived from the initial SimpleChat Application and is build for BLE Nano Device, used in peripheral mode. This Application scan and measures some inputs and save them in flash with timestamp. A RTC has been implemented. Using chat application (available for smart phones) some commands can be send to BLE Nano in order to perform some tasks. Other types of commands can be send via serial interface from a PC, especially data extraction from flash.

Usage/Description:

After flashing or power on, the ble device will start to advertise and also its local time counter starts. While initializing, application will search through all flash pages, last data previosly written. From this pages will retrieve the last data and time available.

A Timer Tick (period set to 1 second) is used for updating RTC and for data measurements. When the application starts the data will not be saved in flash until a command is given to start (xf2). When started, it is recommended after connecting to ble device to set the time and date;

After the date and time updated, activate measurement logging (xf2).

Please be aware that for 5-6 seconds, each 100 seconds the connection is stopped by the application. This is due to fact that writing to flash is safe when radio connection is off. When g_MyDataIdx is between 95..100, connection should remain closed.

The Application can use somewhere around 100 flash pages (100K). This means, if data is sampled each second, the pages will start to overwrite after 100*100 seconds = 2.7 hours. Anyway the data is inserted into logger when it is different compared to previous measurement. Therefore the time the flash memory can log is bigger than 2.7 hours.

When retrieving the data log via serial, the format is as follows:

  • page starts with:
    2016_ 4_22 H: 7 => year, month, day, and hour
    26:51;363; 1; 15 => minutes: seconds; A3,A4,A5 (no info about digital inputs)
  • following rows up to the next page:
    0: 5;364; 1; 15 => minutes: seconds - time delta (time elapsed since last measurement); A3, A4, A5;

Hardware Connections

The BLE Nano Device is connected to some peripheral components as follows:

  • Light Sensor ( A3 input)
  • Temperature Sensor (A4 input)
  • Gnd Voltage (or anything else) (A5 input)
  • Buzzer (D6 output)
  • Push Button (D5 input)
  • [Optional]: MKUSB 20 Board (for Voltage Supply and for Serial Communication with a PC)

Supported Commands

  1. From RedBear Chat Application following messages are valid:
  • Any message that not start with 'x' is echoed with 'R:' as prefix, and also is send via Serial Interface to PC
  • Any message that start with 'x' is interpreted as command:
    • xi0 / xi* except {1,2,3,4} => prints the analog inputs and one digital input (the led status) as uint16 values
    • xi1 /xi2 / xi3 / xi4 =>prints the uint16 value for light, temp, gndV, led status
    • xl => toggle led status
    • xs[0-9][0-9] => buzzer; depending on digits, a digital pwm signal is send to buzzer; to deactivate: xs00
    • xtg => returns the current time
    • xti[0-9]{6} => insert time - exp: xti181004 means: 18H10M and 4 seconds
    • xdg => returns the current date
    • xdi[0-9]{6} => insert date - exp: xti160424 means: 2016 Y, 04 Month, 24 Day
    • xf1 => prints the value of g_MyDataIdx (a value now between 0..99) representing the steps until a new page will be written in flash with new data; It also print the current flash page that will be written (between 155 and 255)
    • xf2 => activate measurements logging
    • xf3 => deactivate measurements logging
    • x* => for invalid syntax a sound for 3 seconds is activated, with a message error
  1. From PC serial interface (with MKUSB 20 Board), following commands apply:
  • xf[0-9] => request printing on serial of a specific flash page ( 0 - current page; 1 - previous page, etc)
  • xd => request dump of all recorded logs (starting with current page)
  • xg => prints the value of g_MyDataIdx (a value now between 0..99) representing the steps until a new page will be written in flash with new data;
  • xca => open Radio Advertising (should be used when the Advertising is Off)
  • xcc => Close Radio connection (should be used when Connection is in Connected state)
  • xcs => Stop Radio Advertising (should be used when Advertising is active)

Other Commands:

  • button push => closes the connection/advertising and turn off the led. If push again reset the previous conditions;

References

The mbed BLE API is meant to be used in projects on developer.mbed.org. Please see examples and sample project files there. A good starting point are these pages:

For this Application:

Committer:
tanasaro10
Date:
Mon Apr 11 17:21:14 2016 +0000
Revision:
8:f28ad4600b0f
Parent:
7:609dff35b660
Child:
9:303d3628986a
This build add some features:; -> for any message that starts with 'x' it is treated as command:; xtg: return time:  HH:MM:SS; xdg: get date: 20XX:MM:DD; xtiHHMMSS : set the time; xdiYYMMDD: set date; etc.

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
RedBearLab 1:1c058e553423 5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
RedBearLab 1:1c058e553423 6 and associated documentation files (the "Software"), to deal in the Software without restriction,
RedBearLab 1:1c058e553423 7 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
RedBearLab 1:1c058e553423 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
RedBearLab 1:1c058e553423 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
RedBearLab 1:1c058e553423 13 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
RedBearLab 1:1c058e553423 14 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
RedBearLab 1:1c058e553423 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.
RedBearLab 1:1c058e553423 25 */
RedBearLab 1:1c058e553423 26
RedBearLab 0:cffe8ac1bdf0 27 #include "mbed.h"
RedBearLab 2:4b66b69c7ecb 28 #include "ble/BLE.h"
tanasaro10 8:f28ad4600b0f 29 #include <myData.h>
tanasaro10 8:f28ad4600b0f 30 //#include "LocalFileSystem.h"
RedBearLab 0:cffe8ac1bdf0 31
RedBearLab 0:cffe8ac1bdf0 32 #define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */
RedBearLab 0:cffe8ac1bdf0 33 #define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
RedBearLab 0:cffe8ac1bdf0 34 #define BLE_UUIDS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */
RedBearLab 0:cffe8ac1bdf0 35
RedBearLab 0:cffe8ac1bdf0 36 #define TXRX_BUF_LEN 20
RedBearLab 0:cffe8ac1bdf0 37
RedBearLab 2:4b66b69c7ecb 38 BLE ble;
RedBearLab 0:cffe8ac1bdf0 39
RedBearLab 0:cffe8ac1bdf0 40 Serial pc(USBTX, USBRX);
RedBearLab 0:cffe8ac1bdf0 41
RedBearLab 0:cffe8ac1bdf0 42 // The Nordic UART Service
RedBearLab 0:cffe8ac1bdf0 43 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 44 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 45 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 46 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 47
tanasaro10 8:f28ad4600b0f 48 static const int8_t txPower = 0xCD;
RedBearLab 0:cffe8ac1bdf0 49
RedBearLab 0:cffe8ac1bdf0 50 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
RedBearLab 0:cffe8ac1bdf0 51 uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
RedBearLab 0:cffe8ac1bdf0 52
RedBearLab 0:cffe8ac1bdf0 53 static uint8_t rx_buf[TXRX_BUF_LEN];
RedBearLab 0:cffe8ac1bdf0 54 static uint8_t rx_len=0;
RedBearLab 0:cffe8ac1bdf0 55
tanasaro10 8:f28ad4600b0f 56 static uint32_t gTimeInstant = 5; // 1 second
tanasaro10 8:f28ad4600b0f 57
tanasaro10 8:f28ad4600b0f 58 //LocalFileSystem local("local");
tanasaro10 8:f28ad4600b0f 59
tanasaro10 8:f28ad4600b0f 60 static myData_t g_MyData[MAXBUFFER];
tanasaro10 8:f28ad4600b0f 61
tanasaro10 8:f28ad4600b0f 62 uint16_t g_MyDataIdx=0;
tanasaro10 8:f28ad4600b0f 63
tanasaro10 8:f28ad4600b0f 64 //uint8_t infoCollector[TXRX_BUF_LEN][10];
tanasaro10 8:f28ad4600b0f 65
tanasaro10 8:f28ad4600b0f 66 DigitalOut led(LED1);
tanasaro10 8:f28ad4600b0f 67 PwmOut buzzer(p15);
tanasaro10 8:f28ad4600b0f 68
tanasaro10 8:f28ad4600b0f 69 AnalogIn VP3(A3);
tanasaro10 8:f28ad4600b0f 70 AnalogIn VP4(A4);
tanasaro10 8:f28ad4600b0f 71 AnalogIn VP5(A5);
tanasaro10 8:f28ad4600b0f 72
tanasaro10 8:f28ad4600b0f 73 Timeout timeout_err; // timeout for buzz on error
tanasaro10 8:f28ad4600b0f 74 Ticker periodicActions, eachInstant;
tanasaro10 8:f28ad4600b0f 75
tanasaro10 8:f28ad4600b0f 76 mtime_manager_t g_myTimeVar;
tanasaro10 8:f28ad4600b0f 77 mdate_manager_t g_myDateVar;
tanasaro10 8:f28ad4600b0f 78
tanasaro10 8:f28ad4600b0f 79 InterruptIn event(p7);
RedBearLab 0:cffe8ac1bdf0 80
RedBearLab 0:cffe8ac1bdf0 81 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 82
RedBearLab 0:cffe8ac1bdf0 83 GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
RedBearLab 0:cffe8ac1bdf0 84
RedBearLab 0:cffe8ac1bdf0 85 GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
RedBearLab 0:cffe8ac1bdf0 86
RedBearLab 0:cffe8ac1bdf0 87 GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
RedBearLab 0:cffe8ac1bdf0 88
RedBearLab 0:cffe8ac1bdf0 89
tanasaro10 8:f28ad4600b0f 90 //extern bool isInputValid(uint8_t * buffer);
tanasaro10 8:f28ad4600b0f 91
tanasaro10 8:f28ad4600b0f 92 bool isInputValid(uint8_t * buffer){
tanasaro10 8:f28ad4600b0f 93 bool retValue= false;
tanasaro10 8:f28ad4600b0f 94
tanasaro10 8:f28ad4600b0f 95 switch (buffer[0]){
tanasaro10 8:f28ad4600b0f 96 case 'i':
tanasaro10 8:f28ad4600b0f 97 switch (buffer[1]){
tanasaro10 8:f28ad4600b0f 98 case '3':
tanasaro10 8:f28ad4600b0f 99 case '4':
tanasaro10 8:f28ad4600b0f 100 case '5':
tanasaro10 8:f28ad4600b0f 101 retValue = true;
tanasaro10 8:f28ad4600b0f 102 break;
tanasaro10 8:f28ad4600b0f 103 default:
tanasaro10 8:f28ad4600b0f 104 retValue = false;
tanasaro10 8:f28ad4600b0f 105 }
tanasaro10 8:f28ad4600b0f 106 break;
tanasaro10 8:f28ad4600b0f 107 case 'l':
tanasaro10 8:f28ad4600b0f 108 retValue = true;
tanasaro10 8:f28ad4600b0f 109 break;
tanasaro10 8:f28ad4600b0f 110 case 's':
tanasaro10 8:f28ad4600b0f 111 if (((buffer[1]>'9')||(buffer[1]<'0'))||((buffer[2]>'9')||(buffer[2]<'0')))
tanasaro10 8:f28ad4600b0f 112 retValue = false;
tanasaro10 8:f28ad4600b0f 113 else
tanasaro10 8:f28ad4600b0f 114 retValue = true;
tanasaro10 8:f28ad4600b0f 115 break;
tanasaro10 8:f28ad4600b0f 116 case 't': //timestamp
tanasaro10 8:f28ad4600b0f 117 retValue = true;
tanasaro10 8:f28ad4600b0f 118 break;
tanasaro10 8:f28ad4600b0f 119 case 'd': //date
tanasaro10 8:f28ad4600b0f 120 retValue= true;
tanasaro10 8:f28ad4600b0f 121 break;
tanasaro10 8:f28ad4600b0f 122 default:
tanasaro10 8:f28ad4600b0f 123 // error
tanasaro10 8:f28ad4600b0f 124 retValue = false;
tanasaro10 8:f28ad4600b0f 125 }
tanasaro10 8:f28ad4600b0f 126 return retValue;
tanasaro10 8:f28ad4600b0f 127 }
tanasaro10 8:f28ad4600b0f 128
RedBearLab 0:cffe8ac1bdf0 129
RedBearLab 0:cffe8ac1bdf0 130 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
RedBearLab 0:cffe8ac1bdf0 131 {
RedBearLab 0:cffe8ac1bdf0 132 pc.printf("Disconnected \r\n");
RedBearLab 0:cffe8ac1bdf0 133 pc.printf("Restart advertising \r\n");
RedBearLab 0:cffe8ac1bdf0 134 ble.startAdvertising();
RedBearLab 0:cffe8ac1bdf0 135 }
RedBearLab 0:cffe8ac1bdf0 136
tanasaro10 8:f28ad4600b0f 137 void buzz_int(uint8_t period, uint8_t duty_cycle){
tanasaro10 8:f28ad4600b0f 138 if (period!=0) {
tanasaro10 8:f28ad4600b0f 139 buzzer = (9.0 - (float)duty_cycle)/9.0;
tanasaro10 8:f28ad4600b0f 140 buzzer.period((float)period);
tanasaro10 8:f28ad4600b0f 141 } else {
tanasaro10 8:f28ad4600b0f 142 buzzer = 0;
tanasaro10 8:f28ad4600b0f 143 }
tanasaro10 8:f28ad4600b0f 144 }
tanasaro10 8:f28ad4600b0f 145
tanasaro10 8:f28ad4600b0f 146 float readInput_f(uint8_t channelID){
tanasaro10 8:f28ad4600b0f 147 float retVal=0.0;
tanasaro10 8:f28ad4600b0f 148 switch (channelID){
tanasaro10 8:f28ad4600b0f 149 case 3:
tanasaro10 8:f28ad4600b0f 150 retVal = VP3.read();
tanasaro10 8:f28ad4600b0f 151 break;
tanasaro10 8:f28ad4600b0f 152 case 4:
tanasaro10 8:f28ad4600b0f 153 retVal = VP4.read();
tanasaro10 8:f28ad4600b0f 154 break;
tanasaro10 8:f28ad4600b0f 155 case 5:
tanasaro10 8:f28ad4600b0f 156 retVal = VP5.read();
tanasaro10 8:f28ad4600b0f 157 break;
tanasaro10 8:f28ad4600b0f 158 }
tanasaro10 8:f28ad4600b0f 159 return ((retVal*3.3));
tanasaro10 8:f28ad4600b0f 160 }
tanasaro10 8:f28ad4600b0f 161
tanasaro10 8:f28ad4600b0f 162 void at_timeout_err(){
tanasaro10 8:f28ad4600b0f 163 // stop buzz
tanasaro10 8:f28ad4600b0f 164 buzz_int(0,0);
tanasaro10 8:f28ad4600b0f 165 }
tanasaro10 8:f28ad4600b0f 166
tanasaro10 8:f28ad4600b0f 167
tanasaro10 8:f28ad4600b0f 168 void at_eachInstant(){
tanasaro10 8:f28ad4600b0f 169 //static uint32_t counter = 0;
tanasaro10 8:f28ad4600b0f 170 // update time
tanasaro10 8:f28ad4600b0f 171 if (g_myTimeVar.updateTime ==false){
tanasaro10 8:f28ad4600b0f 172 g_myTimeVar.newTime.sec = (g_myTimeVar.currentTime.sec + gTimeInstant)% 60;
tanasaro10 8:f28ad4600b0f 173 g_myTimeVar.newTime.min = (g_myTimeVar.currentTime.min + ((gTimeInstant + g_myTimeVar.currentTime.sec) / 60))%60;
tanasaro10 8:f28ad4600b0f 174 if (g_myTimeVar.newTime.min< g_myTimeVar.currentTime.min ) {
tanasaro10 8:f28ad4600b0f 175 g_myTimeVar.currentTime.hour++;
tanasaro10 8:f28ad4600b0f 176 }
tanasaro10 8:f28ad4600b0f 177 g_myTimeVar.newTime.hour = (g_myTimeVar.currentTime.hour + (gTimeInstant / 3600+g_myTimeVar.newTime.min/60))%24;
tanasaro10 8:f28ad4600b0f 178 if (g_myTimeVar.newTime.hour < g_myTimeVar.currentTime.hour){
tanasaro10 8:f28ad4600b0f 179 g_myDateVar.newDate.day = (g_myDateVar.currentDate.day + 1)%(eNrDaysPerMonth[g_myDateVar.currentDate.month]+1);
tanasaro10 8:f28ad4600b0f 180 if (g_myDateVar.newDate.day < g_myDateVar.currentDate.day ){
tanasaro10 8:f28ad4600b0f 181 g_myDateVar.newDate.month = (g_myDateVar.currentDate.month+ 1)%13+1;
tanasaro10 8:f28ad4600b0f 182 if (g_myDateVar.newDate.month< g_myDateVar.currentDate.month){
tanasaro10 8:f28ad4600b0f 183 g_myDateVar.newDate.year = (g_myDateVar.currentDate.year+ 1);
tanasaro10 8:f28ad4600b0f 184 }
tanasaro10 8:f28ad4600b0f 185 }
tanasaro10 8:f28ad4600b0f 186 memcpy(&g_myDateVar.currentDate,&g_myDateVar.newDate, sizeof(date_t));
tanasaro10 8:f28ad4600b0f 187 }
tanasaro10 8:f28ad4600b0f 188 memcpy(&g_myTimeVar.currentTime,&g_myTimeVar.newTime, sizeof(mtime_t));
tanasaro10 8:f28ad4600b0f 189 } else {
tanasaro10 8:f28ad4600b0f 190 memcpy(&g_myTimeVar.currentTime,&g_myTimeVar.newTime, sizeof(mtime_t));
tanasaro10 8:f28ad4600b0f 191 g_myTimeVar.updateTime =false;
tanasaro10 8:f28ad4600b0f 192 }
tanasaro10 8:f28ad4600b0f 193 if (g_myDateVar.updateDate ==true){ // there is a new Date ?
tanasaro10 8:f28ad4600b0f 194 memcpy(&g_myDateVar.currentDate,&g_myDateVar.newDate, sizeof(date_t));
tanasaro10 8:f28ad4600b0f 195 g_myDateVar.updateDate =true;
tanasaro10 8:f28ad4600b0f 196 }
tanasaro10 8:f28ad4600b0f 197
tanasaro10 8:f28ad4600b0f 198 // save some data
tanasaro10 8:f28ad4600b0f 199 memcpy(&g_MyData[g_MyDataIdx].date,&g_myDateVar.currentDate, sizeof(date_t));
tanasaro10 8:f28ad4600b0f 200 memcpy(&g_MyData[g_MyDataIdx].time,&g_myTimeVar.currentTime, sizeof(mtime_t));
tanasaro10 8:f28ad4600b0f 201 g_MyData[g_MyDataIdx].light = readInput_f(3);
tanasaro10 8:f28ad4600b0f 202 g_MyData[g_MyDataIdx].gndV = readInput_f(5);
tanasaro10 8:f28ad4600b0f 203 g_MyData[g_MyDataIdx].temp = readInput_f(4);
tanasaro10 8:f28ad4600b0f 204 g_MyData[g_MyDataIdx].led_on = led;
tanasaro10 8:f28ad4600b0f 205
tanasaro10 8:f28ad4600b0f 206 /*
tanasaro10 8:f28ad4600b0f 207 int i=0;
tanasaro10 8:f28ad4600b0f 208 char buf[45];
tanasaro10 8:f28ad4600b0f 209 if (g_MyDataIdx==MAXBUFFER-1){
tanasaro10 8:f28ad4600b0f 210 // write2File
tanasaro10 8:f28ad4600b0f 211 FILE *fp = fopen("out.txt","a+");
tanasaro10 8:f28ad4600b0f 212 for (i=0;i<MAXBUFFER;i++){
tanasaro10 8:f28ad4600b0f 213 sprintf(buf,"20%2d-%2d-%2d %2d:%2d:%2d %4.3f %4.3f %4.3f %2d \r\n",g_MyData[i].date.year,
tanasaro10 8:f28ad4600b0f 214 g_MyData[i].date.month,g_MyData[i].date.day, g_MyData[i].time.hour, g_MyData[i].time.min,
tanasaro10 8:f28ad4600b0f 215 g_MyData[i].time.sec, g_MyData[i].light, g_MyData[i].gndV, g_MyData[i].temp, g_MyData[i].led_on);
tanasaro10 8:f28ad4600b0f 216 fwrite(buf,sizeof(uint8_t),strlen(buf),fp);
tanasaro10 8:f28ad4600b0f 217 }
tanasaro10 8:f28ad4600b0f 218 fclose(fp);
tanasaro10 8:f28ad4600b0f 219
tanasaro10 8:f28ad4600b0f 220 }*/
tanasaro10 8:f28ad4600b0f 221 g_MyDataIdx = (g_MyDataIdx+1)%MAXBUFFER;
tanasaro10 8:f28ad4600b0f 222 }
tanasaro10 8:f28ad4600b0f 223 /*
tanasaro10 8:f28ad4600b0f 224 void at_periodicActions(){
tanasaro10 8:f28ad4600b0f 225 char myBuf[TXRX_BUF_LEN];
tanasaro10 8:f28ad4600b0f 226 int index=0, length;
tanasaro10 8:f28ad4600b0f 227 float value[3];
tanasaro10 8:f28ad4600b0f 228
tanasaro10 8:f28ad4600b0f 229 value[0] = readInput_f(3);
tanasaro10 8:f28ad4600b0f 230 value[1] = readInput_f(4);
tanasaro10 8:f28ad4600b0f 231 sprintf(myBuf,">I3:%4.3f;I4:%4.3f",value[0],value[1]);
tanasaro10 8:f28ad4600b0f 232 length =18;
tanasaro10 8:f28ad4600b0f 233 memcpy(&infoCollector[0][index],&myBuf,length);
tanasaro10 8:f28ad4600b0f 234 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), &infoCollector[0][index], length);
tanasaro10 8:f28ad4600b0f 235 wait(0.3);
tanasaro10 8:f28ad4600b0f 236
tanasaro10 8:f28ad4600b0f 237 index ++;
tanasaro10 8:f28ad4600b0f 238 value[2] = readInput_f(5);
tanasaro10 8:f28ad4600b0f 239 sprintf(myBuf,">I5:%4.3f;",value[2]);
tanasaro10 8:f28ad4600b0f 240 length= 10;
tanasaro10 8:f28ad4600b0f 241 memcpy(&infoCollector[0][index],&myBuf,length);
tanasaro10 8:f28ad4600b0f 242 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), &infoCollector[0][index], length);
tanasaro10 8:f28ad4600b0f 243 wait(0.3);
tanasaro10 8:f28ad4600b0f 244 index ++;
tanasaro10 8:f28ad4600b0f 245 length = 9;
tanasaro10 8:f28ad4600b0f 246 if (led==0){
tanasaro10 8:f28ad4600b0f 247 sprintf(myBuf,"%s",">LED: ON");
tanasaro10 8:f28ad4600b0f 248 memcpy(&infoCollector[0][index],&myBuf,length);
tanasaro10 8:f28ad4600b0f 249 }
tanasaro10 8:f28ad4600b0f 250 else {
tanasaro10 8:f28ad4600b0f 251 sprintf(myBuf,"%s",">LED:OFF");
tanasaro10 8:f28ad4600b0f 252 memcpy(&infoCollector[0][index],&myBuf,length);
tanasaro10 8:f28ad4600b0f 253 }
tanasaro10 8:f28ad4600b0f 254 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), &infoCollector[0][index], length);
tanasaro10 8:f28ad4600b0f 255 wait(0.3);
tanasaro10 8:f28ad4600b0f 256 }
tanasaro10 8:f28ad4600b0f 257 */
tanasaro10 8:f28ad4600b0f 258 int decode(uint8_t * buffer, uint16_t* length){
tanasaro10 8:f28ad4600b0f 259
tanasaro10 8:f28ad4600b0f 260 int retVal = 0;
tanasaro10 8:f28ad4600b0f 261 char myBuf[TXRX_BUF_LEN+1];
tanasaro10 8:f28ad4600b0f 262 float value;
tanasaro10 8:f28ad4600b0f 263
tanasaro10 8:f28ad4600b0f 264 buffer[0]=buffer[3];
tanasaro10 8:f28ad4600b0f 265 buffer[1]=' ';
tanasaro10 8:f28ad4600b0f 266 buffer[2]=':';
tanasaro10 8:f28ad4600b0f 267 switch (buffer[3]){
tanasaro10 8:f28ad4600b0f 268 case 'i': // Analog Input Read Request
tanasaro10 8:f28ad4600b0f 269 buffer[1]=buffer[4];
tanasaro10 8:f28ad4600b0f 270 if (isInputValid(&buffer[3])){
tanasaro10 8:f28ad4600b0f 271 value = readInput_f((buffer[4]-'0'));
tanasaro10 8:f28ad4600b0f 272 sprintf(myBuf,"%f",value);
tanasaro10 8:f28ad4600b0f 273 memcpy(&buffer[3],&myBuf,7); // e.g. 3.12345
tanasaro10 8:f28ad4600b0f 274 *length= 7+3;
tanasaro10 8:f28ad4600b0f 275 }
tanasaro10 8:f28ad4600b0f 276 else {
tanasaro10 8:f28ad4600b0f 277 retVal= -1;
tanasaro10 8:f28ad4600b0f 278 }
tanasaro10 8:f28ad4600b0f 279 break;
tanasaro10 8:f28ad4600b0f 280 case 'l': // toogle led
tanasaro10 8:f28ad4600b0f 281 led = ! led;
tanasaro10 8:f28ad4600b0f 282 if (led==0){
tanasaro10 8:f28ad4600b0f 283 sprintf(myBuf,"%s","ON");
tanasaro10 8:f28ad4600b0f 284 memcpy(&buffer[3],&myBuf,2);
tanasaro10 8:f28ad4600b0f 285 }
tanasaro10 8:f28ad4600b0f 286 else {
tanasaro10 8:f28ad4600b0f 287 sprintf(myBuf,"%s","OFF");
tanasaro10 8:f28ad4600b0f 288 memcpy(&buffer[3],&myBuf,3);
tanasaro10 8:f28ad4600b0f 289 }
tanasaro10 8:f28ad4600b0f 290 *length = 3 + 3;
tanasaro10 8:f28ad4600b0f 291 break;
tanasaro10 8:f28ad4600b0f 292 case 's': // buzzer
tanasaro10 8:f28ad4600b0f 293 buffer[1]=buffer[4];
tanasaro10 8:f28ad4600b0f 294 if (isInputValid(&buffer[3])){
tanasaro10 8:f28ad4600b0f 295 buzz_int((buffer[4]-'0'),(buffer[5]-'0'));
tanasaro10 8:f28ad4600b0f 296 buffer[2]=buffer[5];
tanasaro10 8:f28ad4600b0f 297 sprintf(myBuf,"%s:%f","S",buzzer.read());
tanasaro10 8:f28ad4600b0f 298 memcpy(&buffer[3],&myBuf,7);
tanasaro10 8:f28ad4600b0f 299 *length= 7+3;
tanasaro10 8:f28ad4600b0f 300 retVal= 1;
tanasaro10 8:f28ad4600b0f 301 }
tanasaro10 8:f28ad4600b0f 302 else {
tanasaro10 8:f28ad4600b0f 303 retVal= -1;
tanasaro10 8:f28ad4600b0f 304 }
tanasaro10 8:f28ad4600b0f 305 break;
tanasaro10 8:f28ad4600b0f 306 case 't': // time operations
tanasaro10 8:f28ad4600b0f 307 buffer[1]=buffer[4];
tanasaro10 8:f28ad4600b0f 308 retVal=1;
tanasaro10 8:f28ad4600b0f 309 switch (buffer[1]){
tanasaro10 8:f28ad4600b0f 310 case 'i': // time insert
tanasaro10 8:f28ad4600b0f 311 memcpy(myBuf,&buffer[5],2);
tanasaro10 8:f28ad4600b0f 312 g_myTimeVar.newTime.hour=atoi(myBuf); // TODO check if it is a number
tanasaro10 8:f28ad4600b0f 313 memcpy(myBuf,&buffer[7],2);
tanasaro10 8:f28ad4600b0f 314 g_myTimeVar.newTime.min=atoi(myBuf); // TODO check if it is a number
tanasaro10 8:f28ad4600b0f 315 memcpy(myBuf,&buffer[9],2);
tanasaro10 8:f28ad4600b0f 316 g_myTimeVar.newTime.sec=atoi(myBuf); // TODO check if it is a number
tanasaro10 8:f28ad4600b0f 317 g_myTimeVar.updateTime = true;
tanasaro10 8:f28ad4600b0f 318 *length = 3+2;
tanasaro10 8:f28ad4600b0f 319 break;
tanasaro10 8:f28ad4600b0f 320 case 'g': // time get
tanasaro10 8:f28ad4600b0f 321 sprintf(myBuf,"H:%2d:%2d:%2d",g_myTimeVar.currentTime.hour,g_myTimeVar.currentTime.min,g_myTimeVar.currentTime.sec);
tanasaro10 8:f28ad4600b0f 322 memcpy(&buffer[3],myBuf,11);
tanasaro10 8:f28ad4600b0f 323 *length = 3+11;
tanasaro10 8:f28ad4600b0f 324 break;
tanasaro10 8:f28ad4600b0f 325 default:
tanasaro10 8:f28ad4600b0f 326 retVal = -1; //error
tanasaro10 8:f28ad4600b0f 327 }
tanasaro10 8:f28ad4600b0f 328 break;
tanasaro10 8:f28ad4600b0f 329 case 'd': // date operations
tanasaro10 8:f28ad4600b0f 330 buffer[1]=buffer[4];
tanasaro10 8:f28ad4600b0f 331 retVal=1;
tanasaro10 8:f28ad4600b0f 332 switch (buffer[1]){
tanasaro10 8:f28ad4600b0f 333 case 'i': // date insert
tanasaro10 8:f28ad4600b0f 334 memcpy(myBuf,&buffer[5],2);
tanasaro10 8:f28ad4600b0f 335 g_myDateVar.newDate.year=atoi(myBuf); // TODO check if it is a number
tanasaro10 8:f28ad4600b0f 336 memcpy(myBuf,&buffer[7],2);
tanasaro10 8:f28ad4600b0f 337 g_myDateVar.newDate.month=atoi(myBuf); // TODO check if it is a number
tanasaro10 8:f28ad4600b0f 338 memcpy(myBuf,&buffer[9],2);
tanasaro10 8:f28ad4600b0f 339 g_myDateVar.newDate.day=atoi(myBuf); // TODO check if it is a number
tanasaro10 8:f28ad4600b0f 340 g_myDateVar.updateDate = true;
tanasaro10 8:f28ad4600b0f 341 *length = 3+2;
tanasaro10 8:f28ad4600b0f 342 break;
tanasaro10 8:f28ad4600b0f 343 case 'g': // time get
tanasaro10 8:f28ad4600b0f 344 sprintf(myBuf,"D:20%2d:%2d:%2d",g_myDateVar.currentDate.year,g_myDateVar.currentDate.month,g_myDateVar.currentDate.day);
tanasaro10 8:f28ad4600b0f 345 memcpy(&buffer[3],myBuf,13);
tanasaro10 8:f28ad4600b0f 346 *length = 3+13;
tanasaro10 8:f28ad4600b0f 347 break;
tanasaro10 8:f28ad4600b0f 348 default:
tanasaro10 8:f28ad4600b0f 349 retVal = -1; //error
tanasaro10 8:f28ad4600b0f 350 }
tanasaro10 8:f28ad4600b0f 351 break;
tanasaro10 8:f28ad4600b0f 352 default:
tanasaro10 8:f28ad4600b0f 353 retVal = -1;
tanasaro10 8:f28ad4600b0f 354 }
tanasaro10 8:f28ad4600b0f 355 if (retVal == -1){
tanasaro10 8:f28ad4600b0f 356 sprintf(myBuf,"%s","Incorect");
tanasaro10 8:f28ad4600b0f 357 memcpy(&buffer[3],&myBuf,8);
tanasaro10 8:f28ad4600b0f 358 *length= 8+3;
tanasaro10 8:f28ad4600b0f 359 buzz_int(5,3);
tanasaro10 8:f28ad4600b0f 360 timeout_err.attach(&at_timeout_err, 2);
tanasaro10 8:f28ad4600b0f 361 }
tanasaro10 8:f28ad4600b0f 362 return retVal;
tanasaro10 8:f28ad4600b0f 363 }
RedBearLab 2:4b66b69c7ecb 364 void WrittenHandler(const GattWriteCallbackParams *Handler)
RedBearLab 0:cffe8ac1bdf0 365 {
tanasaro10 8:f28ad4600b0f 366 uint8_t buf[TXRX_BUF_LEN+1];
RedBearLab 0:cffe8ac1bdf0 367 uint16_t bytesRead, index;
RedBearLab 0:cffe8ac1bdf0 368
RedBearLab 2:4b66b69c7ecb 369 if (Handler->handle == txCharacteristic.getValueAttribute().getHandle())
RedBearLab 0:cffe8ac1bdf0 370 {
tanasaro10 6:a574229993b8 371 ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), &buf[2], &bytesRead);
RedBearLab 0:cffe8ac1bdf0 372 memset(txPayload, 0, TXRX_BUF_LEN);
tanasaro10 6:a574229993b8 373 memcpy(txPayload, &buf[2], TXRX_BUF_LEN);
tanasaro10 8:f28ad4600b0f 374 if (buf[2] == 'x'){
tanasaro10 8:f28ad4600b0f 375 decode(buf,&bytesRead);
tanasaro10 8:f28ad4600b0f 376 } else {
tanasaro10 8:f28ad4600b0f 377 //echo back
tanasaro10 8:f28ad4600b0f 378 buf[0]='R';
tanasaro10 8:f28ad4600b0f 379 buf[1]=':';
tanasaro10 8:f28ad4600b0f 380 bytesRead+=2;
tanasaro10 8:f28ad4600b0f 381 }
tanasaro10 8:f28ad4600b0f 382 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, bytesRead);
tanasaro10 6:a574229993b8 383 // print on PC monitor
tanasaro10 6:a574229993b8 384 //pc.printf("WriteHandler \r\n");
tanasaro10 6:a574229993b8 385 //pc.printf("Length: %d \r\n", bytesRead);
tanasaro10 6:a574229993b8 386 pc.printf("R: ");
RedBearLab 0:cffe8ac1bdf0 387 for(index=0; index<bytesRead; index++)
RedBearLab 0:cffe8ac1bdf0 388 {
RedBearLab 0:cffe8ac1bdf0 389 pc.putc(txPayload[index]);
RedBearLab 0:cffe8ac1bdf0 390 }
tanasaro10 8:f28ad4600b0f 391 pc.printf("\r\n");
tanasaro10 8:f28ad4600b0f 392
RedBearLab 0:cffe8ac1bdf0 393 }
RedBearLab 0:cffe8ac1bdf0 394 }
RedBearLab 0:cffe8ac1bdf0 395
RedBearLab 0:cffe8ac1bdf0 396 void uartCB(void)
RedBearLab 0:cffe8ac1bdf0 397 {
RedBearLab 0:cffe8ac1bdf0 398 while(pc.readable())
RedBearLab 0:cffe8ac1bdf0 399 {
RedBearLab 0:cffe8ac1bdf0 400 rx_buf[rx_len++] = pc.getc();
RedBearLab 0:cffe8ac1bdf0 401 if(rx_len>=20 || rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n')
tanasaro10 6:a574229993b8 402 {
tanasaro10 6:a574229993b8 403 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), rx_buf, rx_len);
tanasaro10 6:a574229993b8 404 //pc.printf("Rec: Length: %d \r\n",rx_len);
tanasaro10 6:a574229993b8 405 rx_len = 2;
tanasaro10 6:a574229993b8 406 rx_buf[0]='S';
tanasaro10 6:a574229993b8 407 rx_buf[1]=':';
RedBearLab 0:cffe8ac1bdf0 408 break;
RedBearLab 0:cffe8ac1bdf0 409 }
RedBearLab 0:cffe8ac1bdf0 410 }
RedBearLab 0:cffe8ac1bdf0 411 }
RedBearLab 0:cffe8ac1bdf0 412
tanasaro10 8:f28ad4600b0f 413 void button(){
tanasaro10 8:f28ad4600b0f 414 uint8_t buf[TXRX_BUF_LEN+1];
tanasaro10 8:f28ad4600b0f 415 buf[0]='B';
tanasaro10 8:f28ad4600b0f 416 buf[1]=':';
tanasaro10 8:f28ad4600b0f 417 buf[2]='O';
tanasaro10 8:f28ad4600b0f 418 buf[3]='N';
tanasaro10 8:f28ad4600b0f 419 ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 4);
tanasaro10 8:f28ad4600b0f 420 }
tanasaro10 8:f28ad4600b0f 421
tanasaro10 8:f28ad4600b0f 422 void g_varInit(){
tanasaro10 8:f28ad4600b0f 423 g_myTimeVar.currentTime = (mtime_t){0,0,0};
tanasaro10 8:f28ad4600b0f 424 g_myTimeVar.updateTime = false;
tanasaro10 8:f28ad4600b0f 425 g_myDateVar.currentDate =(date_t){3,10,16};
tanasaro10 8:f28ad4600b0f 426 g_myDateVar.updateDate = false;
tanasaro10 8:f28ad4600b0f 427 }
tanasaro10 8:f28ad4600b0f 428
tanasaro10 8:f28ad4600b0f 429
RedBearLab 0:cffe8ac1bdf0 430 int main(void)
RedBearLab 0:cffe8ac1bdf0 431 {
RedBearLab 0:cffe8ac1bdf0 432 ble.init();
RedBearLab 0:cffe8ac1bdf0 433 ble.onDisconnection(disconnectionCallback);
RedBearLab 0:cffe8ac1bdf0 434 ble.onDataWritten(WrittenHandler);
tanasaro10 8:f28ad4600b0f 435 event.rise(&button);
tanasaro10 8:f28ad4600b0f 436 periodicActions.attach(&at_eachInstant,gTimeInstant); // each second
tanasaro10 6:a574229993b8 437 pc.baud(19200);
RedBearLab 0:cffe8ac1bdf0 438 pc.printf("SimpleChat Init \r\n");
tanasaro10 8:f28ad4600b0f 439 g_varInit();
RedBearLab 0:cffe8ac1bdf0 440
RedBearLab 0:cffe8ac1bdf0 441 pc.attach( uartCB , pc.RxIrq);
RedBearLab 0:cffe8ac1bdf0 442 // setup advertising
RedBearLab 0:cffe8ac1bdf0 443 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
RedBearLab 0:cffe8ac1bdf0 444 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
RedBearLab 0:cffe8ac1bdf0 445 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
tanasaro10 6:a574229993b8 446 (const uint8_t *)"MyBleVT", sizeof("MyBleVT") - 1);
RedBearLab 0:cffe8ac1bdf0 447 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
RedBearLab 0:cffe8ac1bdf0 448 (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
tanasaro10 6:a574229993b8 449 //ble.accumulateAdvertisingPayload(GapAdvertisingData::TX_POWER_LEVEL,(const uint8_t *)txPower, sizeof(txPower));
tanasaro10 6:a574229993b8 450 ble.setTxPower(txPower);
RedBearLab 0:cffe8ac1bdf0 451 // 100ms; in multiples of 0.625ms.
RedBearLab 0:cffe8ac1bdf0 452 ble.setAdvertisingInterval(160);
RedBearLab 0:cffe8ac1bdf0 453
RedBearLab 0:cffe8ac1bdf0 454 ble.addService(uartService);
RedBearLab 0:cffe8ac1bdf0 455
RedBearLab 0:cffe8ac1bdf0 456 ble.startAdvertising();
RedBearLab 0:cffe8ac1bdf0 457 pc.printf("Advertising Start \r\n");
RedBearLab 0:cffe8ac1bdf0 458
RedBearLab 0:cffe8ac1bdf0 459 while(1)
RedBearLab 0:cffe8ac1bdf0 460 {
RedBearLab 0:cffe8ac1bdf0 461 ble.waitForEvent();
RedBearLab 0:cffe8ac1bdf0 462 }
RedBearLab 0:cffe8ac1bdf0 463 }