Code used for Sensor Expo 2016 - Balloon Game. More details can be found here: https://github.com/ROHMUSDC/ROHM-SensorExpo2016-Pressure-Sensor-Demo/

Dependencies:   BLE_API mbed nRF51822

Fork of Nordic_UART_TEMPLATE_ROHM_SHLD1Update by ROHMUSDC

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* 
00002  * mbed Microcontroller Library
00003  * Copyright (c) 2006-2013 ARM Limited
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017  
00018  //BALLOON GAME!
00019  /*
00020  *  Code Example for ROHM Sensor Expo Balloon Game
00021  * 
00022  *  Description: This Application interfaces ROHM's BM1383AGLV with Nordic's nRF51-DK
00023  *  This Code supports the following sensor devices:
00024  *      > BM1383AGLV Pressure Sensor
00025  *
00026  *  This Code allows the user to configure two known pressure distances and save pressure readings
00027  *  onto the application.  Then it will automatically extrapolate these values and allow the user to see
00028  *  the height of the board.  When connected to a balloon, greater heights can be achieved and the board
00029  *  will return the current height of the board.
00030  *   
00031  *  Additional information about the this Balloon Game can be found at the following link:
00032  *      asdfasdfasdf
00033  * 
00034  *  Last Upadtaed: 6/19/2016 
00035  *  Author: ROHM USDC
00036  *  Contact Information: engineering@rohmsemiconductor.com
00037  *  GitHub Link: https://github.com/ROHMUSDC/ROHM-SensorExpo2016-Pressure-Sensor-Demo/
00038  *  MBED Repository Link: https://developer.mbed.org/teams/ROHMUSDC/code/ROHMSensorShield_BALLOONGAME/
00039  */
00040 
00041 #define nRF52DevKit         //Comment out and change target to Nordic NRf51822 for DemoBoard.  Comment in and change target to Nordic nRF51-DK for Nordic DK Board (and ROHM SHLD0 or SHLD1)
00042 #define NRFDK               //Comment out and change target to Nordic NRf51822 for DemoBoard.  Comment in and change target to Nordic nRF51-DK for Nordic DK Board (and ROHM SHLD0 or SHLD1)
00043 #define Pressure            //BM1383, Barometric Pressure Sensor
00044 #define BM1383A             //Comment in for SHLD1. Comment out for SHLD0 and DemoBoard.
00045 
00046 #include "mbed.h"
00047 #include "BLEDevice.h"
00048 #include "UARTService.h"
00049 #include "nrf_temp.h"
00050 #include "I2C.h"
00051 #include <string>
00052 
00053 #define MAX_REPLY_LEN           (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN)    //Actually equal to 20
00054 #define SENSOR_READ_INTERVAL_S  (1.0F) 
00055 #define ADV_INTERVAL_MS         (1000UL)
00056 #define UART_BAUD_RATE          (19200UL)
00057 #define DEVICE_NAME             ("ROHM DEMO  ") // This can be read AFTER connecting to the device.
00058 #define SHORT_NAME              ("BALLOONK")    // Keep this short: max 8 chars if a 128bit UUID is also advertised.
00059 #define DEBUG(...)              { m_serial_port.printf(__VA_ARGS__); }
00060 
00061 // Function Prototypes
00062 void PBTrigger();               //Interrupt function for PB4
00063 void BTLE_DataWrittenHandler();
00064 
00065 // Global Variables
00066 BLEDevice   m_ble;
00067 Serial      m_serial_port(p9, p11);  // TX pin, RX pin Original
00068 //Serial      m_serial_port(p8, p10);  // TX pin, RX pin 
00069 DigitalOut  m_cmd_led(LED1);
00070 DigitalOut  m_error_led(LED2);
00071 UARTService *m_uart_service_ptr;
00072 DigitalIn   testButton(p20);
00073 InterruptIn sw4Press(p20);
00074 #ifdef NRFDK
00075 I2C         i2c(p30,p7);
00076 #endif
00077 #ifndef NRFDK
00078 I2C         i2c(p7,p30);
00079 #endif
00080 bool        RepStart = true;
00081 bool        NoRepStart = false;
00082 int         i = 1;
00083 unsigned char   printQue = 0;
00084 string      ReceivedValue;
00085 char        FormattedData[30];
00086 uint8_t     buf[MAX_REPLY_LEN];
00087 uint32_t    len = 0;
00088 
00089 //Sensor Variables
00090 #ifdef Pressure
00091 int         Press_addr_w = 0xBA;
00092 int         Press_addr_r = 0xBB;
00093 
00094 char        PWR_ON[2] = {0x12, 0x01};
00095 char        PWR_OFF[2] = {0x12, 0x00};
00096 char        SLEEP_OFF[2] = {0x13, 0x01};
00097 char        SLEEP_ON[2] = {0x13, 0x00};
00098 
00099 char        Press_Content_ReadData[6];
00100 #ifdef BM1383A
00101 char        Press_Addr_ReadData =0x1A;
00102 char        Mode_Control[2] = {0x14, 0xCA};
00103 #endif
00104 #ifndef BM1383A
00105 char        Press_Addr_ReadData =0x1C;
00106 char        PWR_DOWN[2] = {0x12, 0x01};
00107 char        SLEEP[2] = {0x13, 0x01};
00108 char        Mode_Control[2] = {0x14, 0xC4}; 
00109 #endif
00110 
00111 int         BM1383_Temp_highByte;
00112 int         BM1383_Temp_lowByte;
00113 int         BM1383_Pres_highByte;
00114 int         BM1383_Pres_lowByte;
00115 int         BM1383_Pres_leastByte; 
00116 
00117 short int   BM1383_Temp_Out;
00118 float       BM1383_Temp_Conv_Out;
00119 float       BM1383_Pres_Conv_Out;
00120 
00121 float       BM1383_Var;
00122 float       BM1383_Deci;
00123 
00124 uint32_t    BM1383_TempPressure;
00125 
00126 
00127 #endif
00128 
00129 //Balloon Game Variables
00130 float       BM1383_Pres_0Level;
00131 float       BM1383_Pres_KnownLevel;
00132 float       HeightBase = 0;
00133 float       HeightKnown_Total = 68;
00134 float       HeightKnown_Foot = 60;
00135 float       HeightKnown_Inches = 8;
00136 float       slope;
00137 float       yInt;
00138 float       pressureCurr;
00139 float       HeightExtrapolated; //Assuming linear pressure curve
00140 float       HeightExtrapolated_Foot = 60;
00141 float       HeightExtrapolated_Inches = 8;
00142 
00143 
00144 /**
00145  * This callback is used whenever a disconnection occurs.
00146  */
00147 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00148 {
00149     switch (reason) {
00150     case Gap::REMOTE_USER_TERMINATED_CONNECTION:
00151         DEBUG("Disconnected (REMOTE_USER_TERMINATED_CONNECTION)\n\r");
00152         break;
00153     case Gap::LOCAL_HOST_TERMINATED_CONNECTION:
00154         DEBUG("Disconnected (LOCAL_HOST_TERMINATED_CONNECTION)\n\r");
00155         break;
00156     case Gap::CONN_INTERVAL_UNACCEPTABLE:
00157         DEBUG("Disconnected (CONN_INTERVAL_UNACCEPTABLE)\n\r");
00158         break;
00159     }
00160 
00161     DEBUG("Restarting the advertising process\n\r");
00162     m_ble.startAdvertising();
00163 }
00164 
00165 /**
00166  * This callback is used whenever the host writes data to one of our GATT characteristics.
00167  */
00168 void dataWrittenCallback(const GattCharacteristicWriteCBParams *params)
00169 {
00170     // Ensure that initialization is finished and the host has written to the TX characteristic.
00171     if ((m_uart_service_ptr != NULL) && (params->charHandle == m_uart_service_ptr->getTXCharacteristicHandle())) {
00172         int i;
00173         ReceivedValue.clear();
00174         for(i = 0; i < params->len; i++)
00175         {
00176             ReceivedValue += params->data[i];
00177         }
00178         printQue = 1;
00179     }
00180 }
00181 
00182 /**
00183  * This callback is used whenever a write to a GATT characteristic causes data to be sent to the host.
00184  */
00185 void dataSentCallback(unsigned count)
00186 {
00187     // NOTE: The count always seems to be 1 regardless of data.
00188     DEBUG("%d bytes sent to host\n\r", count);
00189 }
00190 
00191 
00192 /**
00193  * This callback is scheduled to be called periodically via a low-priority interrupt.
00194  */
00195 void periodicCallback(void)
00196 {
00197     //uint8_t  buf[MAX_REPLY_LEN];
00198     //uint32_t len = 0;
00199 }
00200 
00201 void error(ble_error_t err, uint32_t line)
00202 {
00203     m_error_led = 1;
00204     DEBUG("Error %d on line number %d\n\r", err, line);
00205 }
00206 
00207 void PBTrigger()
00208 {
00209     uint8_t  buf[MAX_REPLY_LEN];
00210     uint32_t len = 0;
00211     
00212     m_cmd_led = !m_cmd_led;
00213     
00214     if (m_ble.getGapState().connected) {
00215         len = snprintf((char*) buf, MAX_REPLY_LEN, "Button Pressed!");
00216         m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len);
00217     }
00218 }
00219 
00220 int main(void)
00221 {
00222     ble_error_t err;
00223     Ticker      ticker;
00224 
00225     m_serial_port.baud(UART_BAUD_RATE);
00226 
00227     DEBUG("Initialising...\n\r");
00228 
00229     m_cmd_led      = 0;
00230     m_error_led    = 0;
00231 
00232     ticker.attach(periodicCallback, SENSOR_READ_INTERVAL_S);
00233 
00234     sw4Press.fall(&PBTrigger);
00235 
00236     #ifdef Pressure  //no Initialization because we keep in low power mode until we need to measure pressure
00237     //i2c.write(Press_addr_w, &PWR_OFF[0], 2, false);
00238     //i2c.write(Press_addr_w, &SLEEP_ON[0], 2, false);
00239     //i2c.write(Press_addr_w, &Mode_Control[0], 2, false);
00240     #endif
00241 
00242     #ifndef BM1383A
00243     i2c.write(Press_addr_w, &PWR_DOWN[0], 2, false);
00244     i2c.write(Press_addr_w, &SLEEP[0], 2, false);
00245     i2c.write(Press_addr_w, &Mode_Control[0], 2, false);
00246     #endif
00247     
00248     //Start BTLE Initialization Section
00249     m_ble.init();
00250     m_ble.onDisconnection(disconnectionCallback);
00251     m_ble.onDataWritten(dataWrittenCallback);
00252     m_ble.onDataSent(dataSentCallback);
00253 
00254     // Set the TX power in dBm units.
00255     // Possible values (in decreasing order): 4, 0, -4, -8, -12, -16, -20.
00256     err = m_ble.setTxPower(4);
00257     if (BLE_ERROR_NONE != err) {
00258         error(err, __LINE__);
00259     }
00260 
00261     // Setup advertising (GAP stuff).
00262     err = m_ble.setDeviceName(DEVICE_NAME);
00263     if (BLE_ERROR_NONE != err) {
00264         error(err, __LINE__);
00265     }
00266 
00267     err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00268     if (BLE_ERROR_NONE != err) {
00269         error(err, __LINE__);
00270     }
00271 
00272     m_ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00273 
00274     err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00275                                                 (const uint8_t *)SHORT_NAME,
00276                                                 (sizeof(SHORT_NAME) - 1));
00277     if (BLE_ERROR_NONE != err) {
00278         error(err, __LINE__);
00279     }
00280 
00281     err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00282                                                 (const uint8_t *)UARTServiceUUID_reversed,
00283                                                 sizeof(UARTServiceUUID_reversed));
00284     if (BLE_ERROR_NONE != err) {
00285         error(err, __LINE__);
00286     }
00287 
00288     m_ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADV_INTERVAL_MS));
00289     m_ble.startAdvertising();
00290 
00291     // Create a UARTService object (GATT stuff).
00292     UARTService uartService(m_ble);
00293     m_uart_service_ptr = &uartService;
00294 
00295     while (true) {
00296         m_ble.waitForEvent();
00297         
00298         #ifdef Pressure
00299         /*
00300         //Read color Portion from the IC
00301         i2c.write(Press_addr_w, &Press_Addr_ReadData, 1, RepStart);
00302         i2c.read(Press_addr_r, &Press_Content_ReadData[0], 3, NoRepStart);
00303         
00304         BM1383_Var  = (Press_Content_ReadData[0]<<3) | (Press_Content_ReadData[1] >> 5);
00305         BM1383_Deci = ((Press_Content_ReadData[1] & 0x1f) << 6 | ((Press_Content_ReadData[2] >> 2)));
00306         BM1383_Deci = (float)BM1383_Deci* 0.00048828125;  //0.00048828125 = 2^-11
00307         BM1383_Pres_Conv_Out = (BM1383_Var + BM1383_Deci);   //question pending here...
00308         */
00309         #endif
00310         
00311         
00312         if(printQue)    //Handle Data Written Interrupt
00313         {
00314             BTLE_DataWrittenHandler();
00315             printQue = 0;
00316         }
00317     }
00318 }
00319 
00320 void BTLE_DataWrittenHandler(){    
00321     int i;
00322     if (ReceivedValue.length() == 1) {
00323         switch (ReceivedValue[0]) { 
00324             case 'F':
00325                 len = snprintf((char*) buf, MAX_REPLY_LEN, "  Pres= %0.2f hPa", BM1383_Pres_Conv_Out);
00326                 break;
00327             
00328             case 'r': //System Reset
00329                 NVIC_SystemReset(); //Q. What is this? no break statement?
00330                                     //A. SoftReset... No need for break because this resets the program...
00331                 break;
00332                 
00333             default:
00334                 len = snprintf((char*) buf, MAX_REPLY_LEN, "1b,ERROR");
00335                 break;
00336         }
00337     }
00338     else if (ReceivedValue.length() > 1) {
00339         
00340         //BTLE Interface Code, Added 5/29/2016
00341         for(i = 0; i < 29; i++)
00342         {
00343             FormattedData[i] = '\0';
00344         }
00345         
00346         if(ReceivedValue.compare(0,4,"CAL0") == 0)
00347         {
00348             pressureCurr = 0;
00349             #ifdef BM1383A
00350             i2c.write(Press_addr_w, &PWR_ON[0], 2, false);
00351             i2c.write(Press_addr_w, &SLEEP_OFF[0], 2, false);
00352             i2c.write(Press_addr_w, &Mode_Control[0], 2, false);
00353             #endif
00354             for(i = 0; i < 10; i++)
00355             {
00356                 #ifdef Pressure
00357                 wait_ms(200);
00358                 i2c.write(Press_addr_w, &Press_Addr_ReadData, 1, RepStart);
00359                 i2c.read(Press_addr_r, &Press_Content_ReadData[0], 3, NoRepStart);
00360                 BM1383_TempPressure = (Press_Content_ReadData[0]<<14)|(Press_Content_ReadData[1]<<6)|(Press_Content_ReadData[2]);
00361                 BM1383_Pres_Conv_Out = (float)BM1383_TempPressure / (float)2048;
00362                 #endif
00363                 pressureCurr += BM1383_Pres_Conv_Out;
00364             }
00365             i2c.write(Press_addr_w, &PWR_OFF[0], 2, false);
00366             i2c.write(Press_addr_w, &SLEEP_ON[0], 2, false);
00367             BM1383_Pres_0Level = pressureCurr/10;
00368             len = snprintf((char*) buf, MAX_REPLY_LEN, "BaseLvl=%.3f",BM1383_Pres_0Level);  
00369         }
00370         
00371         else if(ReceivedValue.compare(0,4,"CAL1") == 0)
00372         {
00373             pressureCurr = 0;
00374             #ifdef BM1383A
00375             i2c.write(Press_addr_w, &PWR_ON[0], 2, false);
00376             i2c.write(Press_addr_w, &SLEEP_OFF[0], 2, false);
00377             i2c.write(Press_addr_w, &Mode_Control[0], 2, false);
00378             #endif
00379             for(i = 0; i < 10; i++)
00380             {
00381                 #ifdef Pressure
00382                 wait_ms(200);
00383                 i2c.write(Press_addr_w, &Press_Addr_ReadData, 1, RepStart);
00384                 i2c.read(Press_addr_r, &Press_Content_ReadData[0], 3, NoRepStart);
00385                 BM1383_TempPressure = (Press_Content_ReadData[0]<<14)|(Press_Content_ReadData[1]<<6)|(Press_Content_ReadData[2]);
00386                 BM1383_Pres_Conv_Out = (float)BM1383_TempPressure / (float)2048;
00387                 #endif
00388                 pressureCurr += BM1383_Pres_Conv_Out;
00389             }
00390             i2c.write(Press_addr_w, &PWR_OFF[0], 2, false);
00391             i2c.write(Press_addr_w, &SLEEP_ON[0], 2, false);
00392             BM1383_Pres_KnownLevel = pressureCurr/10;
00393             len = snprintf((char*) buf, MAX_REPLY_LEN, "KnownLv=%.3f",BM1383_Pres_KnownLevel);              
00394         }
00395         
00396         
00397         else if(ReceivedValue.compare(0,4,"HEI?") == 0)
00398         {
00399             HeightKnown_Total = HeightKnown_Foot + HeightKnown_Inches;
00400             slope = (HeightKnown_Total - HeightBase) / (BM1383_Pres_KnownLevel - BM1383_Pres_0Level);
00401             yInt = HeightBase - (slope * BM1383_Pres_0Level);
00402             pressureCurr = 0;
00403             #ifdef BM1383A
00404             i2c.write(Press_addr_w, &PWR_ON[0], 2, false);
00405             i2c.write(Press_addr_w, &SLEEP_OFF[0], 2, false);
00406             i2c.write(Press_addr_w, &Mode_Control[0], 2, false);
00407             #endif
00408             for(i = 0; i < 10; i++)
00409             {
00410                 #ifdef Pressure
00411                 wait_ms(200);
00412                 i2c.write(Press_addr_w, &Press_Addr_ReadData, 1, RepStart);
00413                 i2c.read(Press_addr_r, &Press_Content_ReadData[0], 3, NoRepStart);
00414                 BM1383_TempPressure = (Press_Content_ReadData[0]<<14)|(Press_Content_ReadData[1]<<6)|(Press_Content_ReadData[2]);
00415                 BM1383_Pres_Conv_Out = (float)BM1383_TempPressure / (float)2048;
00416                 #endif
00417                 pressureCurr += BM1383_Pres_Conv_Out;
00418             }
00419             i2c.write(Press_addr_w, &PWR_OFF[0], 2, false);
00420             i2c.write(Press_addr_w, &SLEEP_ON[0], 2, false);
00421             pressureCurr = pressureCurr/10;
00422             
00423             HeightExtrapolated = ((pressureCurr * slope) + yInt)/12;
00424             //len = snprintf((char*) buf, MAX_REPLY_LEN, "Height=%f FT",HeightExtrapolated);
00425             //m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len);
00426             
00427             HeightExtrapolated_Foot = int(HeightExtrapolated);
00428             HeightExtrapolated_Inches = (HeightExtrapolated - HeightExtrapolated_Foot)* 12;
00429             len = snprintf((char*) buf, MAX_REPLY_LEN, "H=%.0fFT, %.0fIN",HeightExtrapolated_Foot,HeightExtrapolated_Inches);
00430         }
00431         
00432         else if(ReceivedValue.compare(0,2,"FT") == 0)
00433         {
00434             HeightKnown_Foot = (ReceivedValue[2]-48) * 12;  //Convert ASCII to INT, then Convert to Inches
00435             sprintf(FormattedData, "%2.0f", HeightKnown_Foot);
00436             len = snprintf((char*) buf, MAX_REPLY_LEN, "FT = %s inchs", FormattedData);
00437             wait_ms(200);
00438         }
00439         
00440         else if(ReceivedValue.compare(0,2,"IN") == 0)
00441         {
00442             if((ReceivedValue[3]>= 48) && (ReceivedValue[3]<=57)){
00443                 HeightKnown_Inches = ((ReceivedValue[2]-48)*10) + (ReceivedValue[3]-48);    //Convert ASCII to INT, then Convert to Inches  
00444                 
00445             }
00446             else{
00447                 HeightKnown_Inches = (ReceivedValue[2]-48); //Convert ASCII to INT
00448             }
00449             sprintf(FormattedData, "%2.0f", HeightKnown_Inches);
00450             len = snprintf((char*) buf, MAX_REPLY_LEN, "IN = %s inchs", FormattedData);
00451             wait_ms(200);
00452         }
00453         
00454         else
00455         {
00456             len = snprintf((char*) buf, MAX_REPLY_LEN, "??? = %s", ReceivedValue.c_str());
00457             //m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len);
00458         }
00459 
00460     }
00461     else
00462     {
00463         len = snprintf((char*) buf, MAX_REPLY_LEN, "ERR:NUL");
00464     }
00465     m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len);
00466 }