Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API VL6180 mbed nRF51822
Fork of BLE_Sensor_VL6180_window by
Diff: main.cpp
- Revision:
- 10:79e8f92ef156
- Parent:
- 9:b6302fc4e754
- Child:
- 11:4f925834167d
--- a/main.cpp Mon Jul 10 04:19:07 2017 +0000
+++ b/main.cpp Sat Jul 29 21:49:44 2017 +0000
@@ -1,10 +1,8 @@
-/*
+/*
+Eric Tsai
- Eric Tsai
- todo: hash mac to create unqiue identifier for "my" sensors.
-
-BLE sensor
-
+7/29/2017: added clock algorithm to corresond with gateway spoof checking
+
*/
//required to call the ecb functions
@@ -19,7 +17,7 @@
#include "TMP_nrf51/TMP_nrf51.h"
//comment out when done with debug uart, else eats batteries
-#define MyDebugEnb 1
+#define MyDebugEnb 0
//Pin "P0.4" on nRF51822 = mbed "p4".
//InterruptIn is pulled-up. GND the pin to activate.
@@ -29,9 +27,16 @@
//InterruptIn button2(p11);
// purple board ******
-InterruptIn button1(p23);
-InterruptIn button2(p24);
+//InterruptIn button1(p23);
+//InterruptIn button2(p24);
+// universal
+InterruptIn button1(p0);
+InterruptIn button2(p1);
+
+// Rigado BMD200 ******
+//InterruptIn button1(p4);
+//InterruptIn button2(p5);
//Serial device(p9, p11); // tx, rx, purple board and Rigado
#if MyDebugEnb
@@ -39,12 +44,13 @@
Serial device(p9, p11); //nRF51822 uart : TX=p9. RX=p11
#endif
-//InterruptIn button(p4); //Pin P0.4 on = mbed "p3";
-
+static Timer myTimer; //timed advertising
static Ticker tic_adv; //stop adv
static Ticker tic_debounce; //debounce I/O
static Ticker tic_periodic; //regular updates
+static Ticker tic_clock_reset; //resets clock
+const uint16_t Periodicity = 180; //clock periodicity used for spoof checking, should be 1800 seconds for 30minutes
//static TMP_nrf51 tempSensor;
static bool flag_update_io = false;
static bool flag_periodic_call = false;
@@ -69,6 +75,9 @@
//full with nullls
static uint8_t AdvData[] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; /* Example of hex data */
char buffer[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //battery analog reading
+char bat_volt_char[6] = {0, 0, 0, 0, 0, 0};
+uint8_t Adv_First_Section[10];
+uint8_t mac_reverse[6] = {0x0,0x0,0x0,0x0,0x0,0x0};
uint8_t magnet_near=0;
@@ -81,6 +90,7 @@
static uint8_t src_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
static uint8_t des_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
+uint8_t Xmit_Cnt = 1;
//const static uint8_t AdvData[] = {"ChangeThisData"}; /* Example of character data */
@@ -176,6 +186,15 @@
flag_periodic_call = true;
}
+void clock_reset_Callback(void)
+{
+#if MyDebugEnb
+ device.printf("===== reset timer =====");
+ device.printf("\r\n");
+#endif
+ myTimer.reset();
+};
+
void setupApplicationData(ApplicationData_t &appData)
{
// two byte ID: 0xFEFE
@@ -249,18 +268,69 @@
//https://developer.mbed.org/users/MarceloSalazar/notebook/measuring-battery-voltage-with-nordic-nrf51x/
void my_analogin_init(void)
{
- NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
+
NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
(ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ //(ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
(ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
(ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
+ //(ADC_CONFIG_PSEL_AnalogInput4 << ADC_CONFIG_PSEL_Pos) |
(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+ NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
}
uint16_t my_analogin_read_u16(void)
{
- NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
- NRF_ADC->CONFIG |= ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos;
+ //10 bit resolution, route Vdd as analog input, set ADC ref to VBG band gap
+ //disable analog pin select "PSEL" because we're using Vdd as analog input
+ //no external voltage reference
+ NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+ (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ //(ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+ (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
+ //(ADC_CONFIG_PSEL_AnalogInput4 << ADC_CONFIG_PSEL_Pos) |
+ (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+
+ //NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
+ //NRF_ADC->CONFIG |= ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos;
+ NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
+ NRF_ADC->TASKS_START = 1;
+
+
+ //while loop doesn't actually loop until reading comlete, use a wait.
+ while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {};
+ wait_ms(2);
+
+ //save off RESULT before disabling.
+ //uint16_t myresult = (uint16_t)NRF_ADC->RESULT;
+
+ //disable ADC to lower bat consumption
+ NRF_ADC->TASKS_STOP = 1;
+ //NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; //disable to shutdown ADC & lower bat consumption
+
+ return (uint16_t)NRF_ADC->RESULT; // 10 bit
+ //return myresult;
+}
+
+uint16_t my_analog_pin_read(void)
+{
+
+ //10 bit resolution, route PSEL pin as 1/3 input sel,
+ //set ADC ref to VBG band gap
+ //set AnalogInput4 as input pin (this is P0.03)
+ //no external voltage reference
+ NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+ //(ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+ (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+ //ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
+ (ADC_CONFIG_PSEL_AnalogInput4 << ADC_CONFIG_PSEL_Pos) |
+ (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+ //set pin select to AnalogInput4 = pin 7 = p0.03 = AIN4
+ //NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
+ //NRF_ADC->CONFIG |= ADC_CONFIG_PSEL_AnalogInput4 << ADC_CONFIG_PSEL_Pos;
+ NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
NRF_ADC->TASKS_START = 1;
@@ -279,6 +349,34 @@
//return myresult;
}
+
+//hash_first_section(Adv_First_Section, mac_reverse, bat_reading);
+void hash_first_section(uint8_t * dest, const uint8_t * mac_addr, const char * bat_volt_str)
+{
+ dest[0] = mac_addr[3];
+ dest[1] = mac_addr[2];
+ dest[2] = mac_addr[1];
+ dest[3] = mac_addr[0];
+ dest[4] = bat_volt_str[0];
+ dest[5] = bat_volt_str[1];
+ dest[6] = bat_volt_str[2];
+ dest[7] = bat_volt_str[3];
+ dest[8] = 0x10;
+ dest[9] = 0x11;
+#if MyDebugEnb
+
+ device.printf("hash array: ");
+ for (int i=0; i<10; i++)
+ {
+ device.printf("%x ", dest[i]);
+ }
+ device.printf("\r\n");
+#endif
+}
+
+
+uint16_t clock_remainder = 0;
+
int main(void)
{
@@ -290,7 +388,7 @@
- Timer myTimer; //timed advertising
+ //Timer myTimer; //moved to global
myTimer.start();
@@ -333,11 +431,38 @@
while (ble.hasInitialized() == false) { /* spin loop */ }
//every X seconds, sends period update, up to 1800 (30 minutes)
- tic_periodic.attach(periodic_Callback, 10);
+ tic_periodic.attach(periodic_Callback, 1600);
+ tic_clock_reset.attach(clock_reset_Callback, Periodicity);
+
+ //how to generate random number using die tempearature
+ uint32_t myTempRand;
+ uint32_t * p_temp;
+ //get temperature for random number
+ //SVCALL(SD_TEMP_GET, myTempRand, sd_temp_get(p_temp));
+ //sd_temp_get(& myTempRand);
+
+ ble.getAddress(0,mac_reverse); //NOTE: last byte of MAC (as shown on phone app) is at mac[0], not mac[6];
+#if MyDebugEnb
+ device.printf("mac = ");
+ for (int i=0; i<6; i++) //prints out MAC address in reverse order; opps.
+ {
+ device.printf("%x:", mac_reverse[i]);
+ }
+ device.printf("\r\n");
+#endif
while (true) {
+ //seconds counts to 35 minutes: mySeconds=2142, then 63392 which should be 2450 but isn't.
+ //00001000,01011110 -> 11110111,10100000
+ uint16_t mySeconds =(uint16_t)(myTimer.read_ms()/1000); //problem: mySeconds is only 2 byte
+ //xmit_cnt++;
+ //if (mySeconds > 1800)
+ //{
+ // myTimer.reset();
+ //clock_remainder = mySeconds - 1800;
+ //}
+ //mySeconds = mySeconds + clock_remainder; l3kjl3
- uint16_t mySeconds =(uint16_t)(myTimer.read_ms()/1000); //problem: mySeconds is only 2 byte
//reading the ADV value, only goes up to 0-255;
//reading the uart: current time in seconds: -1782, goes negative.
//need to be able to count 1800 seconds since that's the length of timer.
@@ -378,23 +503,29 @@
button1.mode(PullNone); //float pin to save battery
//button2.disable_irq() //don't know if disables IRQ on port or pin
- button2.fall(buttonReleasedCallback); //disable interrupt
- button2.rise(buttonReleasedCallback); //disable interrupt
- button2.mode(PullUp); //float pin to save battery
+ button2.fall(buttonReleasedCallback); //enable interrupt
+ button2.rise(buttonReleasedCallback); //enable interrupt
+ button2.mode(PullUp); //pull up on pin to get interrupt
+#if MyDebugEnb
+ device.printf("=== button 1! %d seconds=== \r\n", mySeconds);
+#endif
}
else if ( (button1_state == 1) && (button2_state == 0) ) //assume other pin is open circuit
{
magnet_near = 0;
//AdvData[4] = 0x22; //dont' set ADV data directly. Using json now, need spacing
//button1.disable_irq() //don't know if disables IRQ on port or pin
- button1.fall(buttonReleasedCallback); //disable interrupt
- button1.rise(buttonReleasedCallback); //disable interrupt
- button1.mode(PullUp); //float pin to save battery
+ button1.fall(buttonReleasedCallback); //enable interrupt
+ button1.rise(buttonReleasedCallback); //enable interrupt
+ button1.mode(PullUp); //pull up on pin to get interrupt
//button2.disable_irq() //don't know if disables IRQ on port or pin
button2.fall(NULL); //disable interrupt
button2.rise(NULL); //disable interrupt
button2.mode(PullNone); //float pin to save battery
+#if MyDebugEnb
+ device.printf("=== button 2! === %d seconds\r\n", mySeconds);
+#endif
}
else //odd state, shouldn't happen, suck battery and pullup both pins
{
@@ -409,6 +540,9 @@
button2.fall(buttonReleasedCallback); //disable interrupt
button2.rise(buttonReleasedCallback); //disable interrupt
button2.mode(PullUp); //float pin to save battery
+#if MyDebugEnb
+ device.printf("no buttons!! %d seconds\r\n", mySeconds);
+#endif
}
@@ -416,8 +550,15 @@
/* Do blocking calls or whatever hardware-specific action is
* necessary to poll the sensor. */
+ Xmit_Cnt++; //increment transmit counter when updating I/O
+
+
+ //read battery voltage
//analog reading consumes 940uA if not disabled
+
+
bat_reading = (float)my_analogin_read_u16();
+
bat_reading = (bat_reading * 3.6) / 1024.0;
#if MyDebugEnb
device.printf("bat reading: %f \r\n", bat_reading);
@@ -431,104 +572,131 @@
//AdvData[10] = buffer[2];//"3"=0x33
//AdvData[11] = buffer[3];//"2"=0x32
+ //try this
+ //https://developer.mbed.org/users/mbed_official/code/mbed-src/file/cb4253f91ada/targets/hal/TARGET_NORDIC/TARGET_NRF51822/analogin_api.c
+ NRF_ADC->TASKS_STOP = 1;
+ float analogreading;
+ analogreading = (float)my_analog_pin_read();
+ analogreading = (analogreading * 3.6) / 1024.0;
+ #if MyDebugEnb
+ device.printf("separate analog reading: %.02f \r\n", analogreading);
+ #endif
+
//disable ADC
NRF_ADC->TASKS_STOP = 1;
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; //disable to shutdown ADC & lower bat consumption
+
+
//***********************************
//form JSON string in ADV_DATA
//1) volts starts at AdvData[8]
- memset(&AdvData[0], 0, sizeof(AdvData));
- uint8_t JSON_loc=0; //DEC"vo": <---
- AdvData[JSON_loc] = 0x44; //D
- JSON_loc++;
- AdvData[JSON_loc] = 0x45; //E
- JSON_loc++;
- AdvData[JSON_loc] = 0x43; //C
- JSON_loc++;
- AdvData[JSON_loc] = mySeconds & 0xFF; //reserved for timer
- JSON_loc++;
- AdvData[JSON_loc] = (mySeconds >> 8) & 0xFF;; //reserved for timer
- JSON_loc++;
- AdvData[JSON_loc] = 0x22; //"
- JSON_loc++;
- AdvData[JSON_loc] = 0x76; //V volt
- JSON_loc++;
- AdvData[JSON_loc] = 0x6f; //o
- JSON_loc++;
- AdvData[JSON_loc] = 0x6C; //l
- JSON_loc++;
- AdvData[JSON_loc] = 0x74; //t
- JSON_loc++;
- AdvData[JSON_loc] = 0x22; //"
- JSON_loc++;
- AdvData[JSON_loc] = 0x3a; //:
- JSON_loc++;
-
-
-
//write battery voltage
uint8_t total_chars;
- memset(&buffer[0], 0, sizeof(buffer)); //clear out buffer
- total_chars = sprintf (buffer, "%.2f", bat_reading); //returns total number of characters
+ memset(&bat_volt_char[0], 0, sizeof(bat_volt_char)); //clear out buffer
+ total_chars = sprintf (bat_volt_char, "%.2f", bat_reading); //returns total number of characters
#if MyDebugEnb
- device.printf("char buff: %c%c%c%c \r\n", buffer[0], buffer[1], buffer[2], buffer[3]);
+ device.printf("char buff: %c%c%c%c \r\n", bat_volt_char[0], bat_volt_char[1], bat_volt_char[2], bat_volt_char[3]);
device.printf("num chars: %d \r\n", total_chars);
#endif
- for (int i=0; i < total_chars; i++)
- {
- AdvData[JSON_loc] = buffer[i];
- JSON_loc++;
-#if MyDebugEnb
- device.printf("JSON_loc: %d buf[]:%c \r\n", JSON_loc, buffer[i]);
-#endif
- } //JSON_loc left at location of next character
+
+
+ //memset(&Adv_First_Section[0], 0, sizeof(Adv_First_Section)); //not needed to reset
+ hash_first_section(Adv_First_Section, mac_reverse, bat_volt_char);
+
+
- //DEC"vo":3.11,"
- AdvData[JSON_loc] = 0x2c; //,
+ //------------------------------------------------------------------
+ //start writing out ADVData array
+ //------------------------------------------------------------------
+
+ memset(&AdvData[0], 0, sizeof(AdvData));
+ uint8_t JSON_loc=0; //AdvData[0]
+
+ AdvData[0] = Adv_First_Section[0]; //AdvData[0] = manf ID 01
+ JSON_loc++; //1
+ AdvData[1] = Adv_First_Section[1]; //AdvData[1] = manf ID 02
+ JSON_loc++; //2
+ AdvData[2] = Adv_First_Section[2]; //AdvData[2] = reserved
+ JSON_loc++; //3...
+ AdvData[3] = Adv_First_Section[3]; //AdvData[3] = reserved
+ JSON_loc++;
+ AdvData[4] = Adv_First_Section[4]; //AdvData[4] = voltage 01
+ JSON_loc++;
+ AdvData[5] = Adv_First_Section[5]; //AdvData[5] = voltage 02
+ JSON_loc++;
+ AdvData[6] = Adv_First_Section[6]; //AdvData[6] = voltage 03
+ JSON_loc++;
+ AdvData[7] = Adv_First_Section[7]; //AdvData[7] = voltage 04
+ JSON_loc++;
+ AdvData[8] = Adv_First_Section[8]; //AdvData[8] = reserved
+ JSON_loc++;
+ AdvData[9] = Adv_First_Section[9]; //AdvData[9] = reserved
JSON_loc++;
-
- AdvData[JSON_loc] = 0x22; //" start mag
- JSON_loc++;
-
- AdvData[JSON_loc] = 0x6d; //m
+
+#if MyDebugEnb
+
+ device.printf("ADV first 10 array: ");
+ for (int i=0; i<10; i++)
+ {
+ device.printf("%x ", AdvData[i]);
+ }
+ device.printf("\r\n");
+#endif
+
+
+ JSON_loc = 10;
+ //start of encrypted data
+ //AdvData[10]
+ AdvData[10] = mySeconds & 0xFF; //reserved for timer
JSON_loc++;
-
- AdvData[JSON_loc] = 0x61; //a
+ AdvData[11] = (mySeconds >> 8) & 0xFF; //reserved for timer
+ JSON_loc++;
+ AdvData[12] = Xmit_Cnt;
JSON_loc++;
+ //start of jason data
+ JSON_loc = 13;
+ AdvData[JSON_loc] = 0x22; //" start mag pos=13
+ JSON_loc++; //14
- AdvData[JSON_loc] = 0x67; //g
- JSON_loc++;
+ AdvData[JSON_loc] = 0x6d; //m, pos=14
+ JSON_loc++; //15
+
+ AdvData[JSON_loc] = 0x61; //a, pos=15
+ JSON_loc++; //16
+
+ AdvData[JSON_loc] = 0x67; //g, pos=16
+ JSON_loc++; //17
if (flag_periodic_call)
{
//AdvData[JSON_loc] = 0x2f; // "/"
//JSON_loc++;
- AdvData[JSON_loc] = 0x2f; // "/"
- JSON_loc++;
- AdvData[JSON_loc] = 0x70; // "p"
- JSON_loc++;
+ AdvData[JSON_loc] = 0x2f; // "/" pos=17
+ JSON_loc++;//pos=18
+ AdvData[JSON_loc] = 0x70; // "p" poes=18
+ JSON_loc++;//pos=19
}//end if period call
- AdvData[JSON_loc] = 0x22; //"
- JSON_loc++;
+ AdvData[JSON_loc] = 0x22; //" pos = 17 or 19
+ JSON_loc++; //20
- AdvData[JSON_loc] = 0x3a; //:
- JSON_loc++;
+ AdvData[JSON_loc] = 0x3a; //: pos = 18 or 20
+ JSON_loc++; //22
//prep magnet location (1 or 0) for char[]
memset(&buffer[0], 0, sizeof(buffer)); //clear out buffer
//magnet_near is an integer
- total_chars = sprintf (buffer, "%d", magnet_near); //returns total number of characters
+ total_chars = sprintf (buffer, "%d", magnet_near); //returns total number of characters, which is 1 character.
for (int i=0; i < total_chars; i++)
{
AdvData[JSON_loc] = buffer[i];
- JSON_loc++;
+ JSON_loc++; //23
} //JSON_loc left at location of next character
//MUST null terminate for JSON to read correctly, else get intermittent JSON parse errors at gateway
@@ -541,10 +709,10 @@
ApplicationData_t appData;
setupApplicationData(appData);
-
+
for (int i=0; i<16; i++)
{
- src_buf[i] = AdvData[i+3];
+ src_buf[i] = AdvData[i+10]; //start of encrypted section is at AdvData[10]
}
//nrf_ecb_set_key(key_buf);
@@ -558,7 +726,7 @@
#endif
for (int i=0; i<16; i++)
{
- AdvData[i+3] = des_buf[i];
+ AdvData[i+10] = des_buf[i];
}
//ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *) &appData, sizeof(ApplicationData_t));
@@ -572,16 +740,9 @@
//ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address)
//ble.gap().getAddress(myType, myAddress);
//ble.gap().getAddress(Gap::AddressType_t *typeP, Gap::Address_t address);
- uint8_t mac[6] = {0x0,0x0,0x0,0x0,0x0,0x0};
- ble.getAddress(0,mac); //NOTE: last byte of MAC (as shown on phone app) is at mac[0], not mac[6];
-#if MyDebugEnb
- device.printf("mac = ");
- for (int i=0; i<6; i++)
- {
- device.printf("%x:", mac[i]);
- }
- device.printf("\r\n");
-#endif
+
+
+
ble.gap().startAdvertising();
tic_adv.attach(stop_adv_Callback, 2); /* trigger turn off advertisement after X seconds */
