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
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 }
Generated on Fri Jul 15 2022 16:41:10 by 1.7.2