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: LSM9DS1 Si7006A20 aconno_SEGGER_RTT aconno_bsp adc52832_common
main.cpp
00001 /* 00002 * aconno.de 00003 * Made by Jurica Resetar 00004 * Edited by Karlo Milicevic 00005 * Edited by Dominik Bartolovic 00006 * All right reserved 00007 * 00008 */ 00009 00010 #include "mbed.h" 00011 #include "ble/BLE.h" 00012 #include "acd52832_bsp.h" 00013 #include "GapAdvertisingData.h" 00014 #include "Si7006A20.h" 00015 #include "LSM9DS1.h" 00016 #include "math.h" 00017 #include "nrf52_digital.h" 00018 #include "adc52832_common/utilities.h" 00019 #include "MPL115A1.h" 00020 #include "acd_nrf52_saadc.h" 00021 #include "service.h" 00022 #include <events/mbed_events.h> 00023 #include "aconnoConfig.h" 00024 00025 uint8_t gConnected = 0; 00026 00027 static NRF52_SAADC analogIn; 00028 static NRF52_DigitalOut lightPower(p28); 00029 static NRF52_DigitalOut temperaturePower(p31); 00030 static NRF52_DigitalOut shdn(p6); 00031 static NRF52_DigitalOut power(p2); 00032 static NRF52_DigitalOut cs(p7); 00033 static Si7006 *si; 00034 static LSM9DS1 *mems; 00035 static SPI *spi; 00036 static MPL115A1 *mpl115a1; 00037 00038 static EventQueue eventQueue(32 * EVENTS_EVENT_SIZE); 00039 uint8_t myMacAddress[6] = {}; 00040 MACService *macServicePtr; 00041 00042 #if DEBUG_PRINT 00043 #include "SEGGER_RTT.h" 00044 #define printf(...) SEGGER_RTT_printf(0, __VA_ARGS__) 00045 #else 00046 #define printf(...) 00047 #endif 00048 00049 static vector3_s memsAccelerometerInit; 00050 static vector3_s memsGyroscopeInit; 00051 static vector3_s memsMagnetometerInit; 00052 00053 static GapAdvertisingData adv_data = GapAdvertisingData(); 00054 00055 struct __attribute__((packed, aligned(1))) iBeaconMSD_t 00056 { 00057 // AppleID is constant 00058 uint16_t appleID; 00059 // secondID is constant 00060 uint8_t secondID; 00061 // DataSize is constant 00062 uint8_t dataSize; 00063 uint8_t UUID[16]; 00064 uint16_t major; 00065 uint16_t minor; 00066 int8_t RSSI; 00067 }static iBeaconMSD = {.appleID = 0x004C, 00068 .secondID = 0x02, 00069 .dataSize = 0x15, 00070 .UUID = {UUID_INIT}, 00071 .major = MAJOR, 00072 .minor = MINOR, 00073 .RSSI = RSSI_INIT}; 00074 00075 struct __attribute__((packed, aligned(1))) advertising_packet 00076 { 00077 uint32_t header; 00078 uint8_t type; 00079 union{ 00080 struct{ 00081 int16_t gyroscope[3]; 00082 int16_t accelerometer[3]; 00083 int16_t magnetometer[3]; 00084 uint16_t acc_lsb_value; 00085 }; 00086 struct{ 00087 float temperature; 00088 float humidity; 00089 float pressure; 00090 float light; 00091 uint8_t battery; 00092 }; 00093 }; 00094 }; 00095 00096 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) 00097 { 00098 BLE &ble = context->ble; 00099 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); 00100 } 00101 00102 static advertising_packet advertisementPacket; 00103 const int advDataSize = sizeof(advertising_packet); 00104 00105 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00106 { 00107 // Restart Advertising on disconnection 00108 gConnected = 0; 00109 BLE::Instance().gap().startAdvertising(); 00110 } 00111 00112 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params) 00113 { 00114 printf("Connection callback.\n"); 00115 gConnected = 1; 00116 } 00117 00118 /** 00119 * Callback triggered when the ble initialization process has finished 00120 */ 00121 void bleInitCompleteSensors(BLE::InitializationCompleteCallbackContext *params) 00122 { 00123 BLE& ble = params->ble; 00124 ble_error_t error = params->error; 00125 00126 if (error != BLE_ERROR_NONE){ 00127 return; 00128 } 00129 00130 /* Ensure that it is the default instance of BLE */ 00131 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE){ 00132 return; 00133 } 00134 00135 uint8_t mac[6] = {0,0,0,0,0,0}; 00136 uint8_t initAdvData[] = {0}; 00137 BLEProtocol::AddressType_t temp_address_type; 00138 ble.gap().getAddress(&temp_address_type, myMacAddress); 00139 macServicePtr = new MACService(ble, mac, initAdvData); 00140 macServicePtr->updateMacAddress(myMacAddress); // Update MAC address 00141 00142 ble.gap().onConnection(onConnectionCallback); 00143 ble.gap().onDisconnection(disconnectionCallback); 00144 00145 /* setup advertising */ 00146 ble.gap().accumulateAdvertisingPayload( 00147 GapAdvertisingData::BREDR_NOT_SUPPORTED); 00148 ble.gap().accumulateAdvertisingPayload( 00149 GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, 00150 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); 00151 ble.gap().setAdvertisingType( 00152 GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00153 ble.gap().setAdvertisingInterval(ADV_INTERVAL); 00154 printf("Init started....\t\t"); 00155 ble.gap().setTxPower(TX_POWER_DB); // Set TX power to TX_POWER_DB 00156 ble.gap().startAdvertising(); 00157 printf("Init done.\n"); 00158 } 00159 00160 float getLight() 00161 { 00162 return ((float)analogIn.getData()[1])/ADC_RESOLUTION * VALUE_TO_PERCENTAGE; 00163 } 00164 00165 float voltage2temp(float vOut) 00166 { 00167 return ((float)vOut - (float)V0)/((float)TC); 00168 } 00169 00170 float getTemperature() 00171 { 00172 return voltage2temp(((float)analogIn.getData()[2])/ADC_RESOLUTION * (float)VCC); 00173 } 00174 00175 uint8_t getBattery() 00176 { 00177 uint16_t batteryVoltage = analogIn.getData()[0]; 00178 const uint16_t zero_percent_limit = 739; 00179 const uint16_t onehundred_percent_limit = 810; 00180 const uint16_t percentage_increments = 5; 00181 uint8_t percentage; 00182 00183 if (batteryVoltage < zero_percent_limit) 00184 { 00185 percentage = 0; 00186 } 00187 else if(batteryVoltage > onehundred_percent_limit) 00188 { 00189 percentage = 100; 00190 } 00191 else 00192 { 00193 batteryVoltage -= zero_percent_limit; 00194 percentage = (batteryVoltage*100)/(onehundred_percent_limit - zero_percent_limit); 00195 percentage = percentage/percentage_increments*percentage_increments; 00196 } 00197 00198 return percentage; 00199 } 00200 00201 float getHumidity() 00202 { 00203 float result; 00204 si->getHumidity(&result); 00205 return result; 00206 } 00207 00208 void readGyroscope(vector3_s *gyroscopeData) 00209 { 00210 mems->readGyroscope((int16_t *)gyroscopeData); 00211 *gyroscopeData -= memsGyroscopeInit; 00212 } 00213 00214 void readAccelerometer(vector3_s *accelerometerData) 00215 { 00216 mems->readAccelerometer((int16_t *)accelerometerData); 00217 *accelerometerData -= memsAccelerometerInit; 00218 } 00219 00220 void readMagnetometer(vector3_s *magnetometerData){ 00221 mems->readMagnetometer((int16_t *)magnetometerData); 00222 *magnetometerData -= memsMagnetometerInit; 00223 } 00224 00225 void calibrateAccelerometer(){ 00226 vector3_s accelerometerData; 00227 for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter) 00228 { 00229 readAccelerometer(&accelerometerData); 00230 memsAccelerometerInit += accelerometerData; 00231 } 00232 memsAccelerometerInit /= CALIBRATION_STEPS; 00233 } 00234 00235 void calibrateGyroscope(){ 00236 vector3_s gyroscopeData; 00237 for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter) 00238 { 00239 readGyroscope(&gyroscopeData); 00240 memsGyroscopeInit += gyroscopeData; 00241 } 00242 memsGyroscopeInit /= CALIBRATION_STEPS; 00243 } 00244 00245 void calibrateMag(){ 00246 vector3_s magnetometerData; 00247 for(uint8_t counter = 0; counter < CALIBRATION_STEPS; ++counter) 00248 { 00249 readMagnetometer(&magnetometerData); 00250 memsMagnetometerInit += magnetometerData; 00251 } 00252 memsMagnetometerInit /= CALIBRATION_STEPS; 00253 } 00254 00255 void updateData(){ 00256 static uint16_t serviceUuid = macServicePtr->SERVICE_UUID; 00257 static uint8_t advertisementType = 0; 00258 int16_t temp_acc[3]; 00259 BLE &ble = BLE::Instance(); 00260 00261 if(!advertisementType && !gConnected) 00262 { 00263 power = 1; 00264 wait_ms(WAKEUP_TIME_DELAY_MS); 00265 mems->startAccelerometer(); 00266 mems->startGyroscope(); 00267 mems->startMagnetometer(); 00268 00269 printf("Sensor format 1.\n"); 00270 ble.gap().clearAdvertisingPayload(); 00271 /* setup advertising */ 00272 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)&(serviceUuid), sizeof(serviceUuid)); 00273 ble.gap().accumulateAdvertisingPayload( 00274 GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, 00275 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); 00276 ble.gap().setAdvertisingType( 00277 GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00278 00279 adv_data = ble.getAdvertisingData(); 00280 advertisementPacket.type = 0x00; 00281 00282 wait_ms(WAKEUP_TIME_DELAY_MS); 00283 00284 readGyroscope((vector3_s *)advertisementPacket.gyroscope); 00285 readAccelerometer((vector3_s *)temp_acc); 00286 readMagnetometer((vector3_s *)advertisementPacket.magnetometer); 00287 advertisementPacket.acc_lsb_value = (0xF9E); 00288 // ^--- That's in ug cuz MSB is 1 00289 #if INVERT_AXES 00290 advertisementPacket.accelerometer[0] = temp_acc[1]; 00291 advertisementPacket.accelerometer[1] = temp_acc[0]; 00292 advertisementPacket.accelerometer[2] = temp_acc[2]; 00293 #endif 00294 00295 adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, 00296 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); 00297 ble.setAdvertisingData(adv_data); 00298 00299 power = 0; 00300 wait_ms(WAKEUP_TIME_DELAY_MS); 00301 } 00302 else if (advertisementType == 1 && !gConnected) 00303 { 00304 power = 1; 00305 wait_ms(WAKEUP_TIME_DELAY_MS); 00306 temperaturePower = 1; 00307 lightPower = 1; 00308 shdn = 1; // Wake up the pressure sensor 00309 00310 wait_ms(WAKEUP_TIME_DELAY_MS); 00311 00312 printf("Sensor format 2.\n"); 00313 analogIn.updateData(); 00314 adv_data = ble.getAdvertisingData(); 00315 advertisementPacket.type = 0x01; 00316 advertisementPacket.temperature = getTemperature(); 00317 advertisementPacket.light = getLight(); 00318 advertisementPacket.humidity = getHumidity(); 00319 advertisementPacket.pressure = mpl115a1->getPressure(); 00320 advertisementPacket.battery = getBattery(); 00321 00322 adv_data.updateData(adv_data.MANUFACTURER_SPECIFIC_DATA, 00323 (uint8_t *)&advertisementPacket, sizeof(advertisementPacket)); 00324 ble.setAdvertisingData(adv_data); 00325 00326 power = 0; 00327 wait_ms(WAKEUP_TIME_DELAY_MS); 00328 temperaturePower = 0; 00329 lightPower = 0; 00330 shdn = 0; // Wake up the pressure sensor 00331 } 00332 00333 else if (!gConnected) 00334 { 00335 printf("Beacon format!\n"); 00336 ble.gap().clearAdvertisingPayload(); 00337 ble.gap().accumulateAdvertisingPayload( 00338 GapAdvertisingData::BREDR_NOT_SUPPORTED); 00339 ble.gap().accumulateAdvertisingPayload( 00340 GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, 00341 (uint8_t*)&iBeaconMSD, sizeof(iBeaconMSD_t)); 00342 ble.gap().startAdvertising(); 00343 } 00344 if(++advertisementType > 2) advertisementType = 0; 00345 00346 macServicePtr->setAdvData((uint8_t*)&advertisementPacket); 00347 } 00348 00349 int main() 00350 { 00351 Thread bleT; 00352 00353 power = 1; 00354 wait_ms(WAKEUP_TIME_DELAY_MS); 00355 temperaturePower = 1; 00356 lightPower = 1; 00357 shdn = 1; // Wake up the pressure sensor 00358 00359 analogIn.addChannel(9); // Set VDD as source to SAADC 00360 analogIn.addChannel(6); // Light 00361 analogIn.addChannel(7); // Temp 00362 analogIn.calibrate(); 00363 00364 BLE &ble = BLE::Instance(); 00365 ble.init(bleInitCompleteSensors); 00366 while(ble.hasInitialized() == false){ 00367 /* spin loop */ 00368 } 00369 ble.onEventsToProcess(scheduleBleEventsProcessing); 00370 advertisementPacket.header = APPLICATION_ID; 00371 00372 I2C i2c(I2C_DATA, I2C_CLK); 00373 si = new Si7006(&i2c); 00374 mems = new LSM9DS1(&i2c); 00375 spi = new SPI(SPI_MOSI, SPI_MISO, SPI_SCLK); 00376 mpl115a1 = new MPL115A1(*spi, cs); 00377 00378 eventQueue.call_every(UPDATE_SENSORS_TIME_MS, updateData); 00379 00380 // This call stops main thread 00381 eventQueue.dispatch_forever(); 00382 }
Generated on Fri Jul 15 2022 07:56:49 by
1.7.2