Silica Sensor Node board sends custom ble advertising for the Gateway board
Dependencies: X_NUCLEO_IKS01A2_SPI3W
Fork of sensor-node-ble by
Getting started with mbed SensorNode BLE
Information
History project:
- 26/01/2017 - First Release
This project uses the Bluetooth Low Energy in order to send advertaisments every second. These payloads are read by the Visible Things Gateway board, more about it here . Every advertaisments contains sensors data read form the SensorTile and the Silica Sensor Board. For details please read the document in the MAN folder,
The application:
- reads sensors data (accelerometer, gyroscope, lux, pressure, temperature, proximity, magnetometer)
- send these data by BLE
You can compile this project in three ways:
1. Using the Online compiler.
Information
Learn how to use the Online compiler reading https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/online_comp/ page.
2. Using the compiler on your PC
Information
Learn how to use the mbed-cli reading https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/cli/ page.
The name of the machine is SILICA_SENSOR_NODE.
3. Exporting to 3rd party tools (IDE)
Information
Learn how to use the mbed-cli reading https://docs.mbed.com/docs/mbed-os-handbook/en/latest/dev_tools/third_party/ page. We have exported the project for you, please read here
Warning
This example requires a Visible Things Gateway board. If you don't have this board you can use RF Connect app from an Android phone just to see the raw data sent from the SensorNode.
VL6180x/VL6180x.cpp
- Committer:
- rspelta
- Date:
- 2018-01-26
- Revision:
- 3:94aee6f716b7
File content as of revision 3:94aee6f716b7:
/****************************************************************************** * SFE_VL6180x.cpp * Library for VL6180x time of flight range finder. * Casey Kuhns @ SparkFun Electronics * 10/29/2014 * https://github.com/sparkfun/ * * The VL6180x by ST micro is a time of flight range finder that * uses pulsed IR light to determine distances from object at close * range. The average range of a sensor is between 0-200mm * * In this file are the functions in the VL6180x class * * Resources: * This library uses the Arduino Wire.h to complete I2C transactions. * * Development environment specifics: * IDE: Arduino 1.0.5 * Hardware Platform: Arduino Pro 3.3V/8MHz * VL6180x Breakout Version: 1.0 * * * This code is beerware. If you see me (or any other SparkFun employee) at the * local pub, and you've found our code helpful, please buy us a round! * * Distributed as-is; no warranty is given. ******************************************************************************/ #include "VL6180x.h" //VL6180x::VL6180x(PinName sda, PinName scl, uint8_t addr) : m_i2c(sda, scl), m_addr(addr) {} VL6180x::VL6180x(I2C *i2c, uint8_t addr) : m_i2c(i2c), m_addr(addr) { m_i2c->frequency(400000); PE1801_setRegister( GPIO_SET_DIR_LOW, 0x40 ); // only IO6 setted as output PE1801_setRegister( GPIO_SET_DIR_MID, 0 ); PE1801_setRegister( GPIO_SET_DIR_HIGH, 0 ); PE1801_setRegister( GPIO_SET_LOW, 0x40 ); // set 1 DEV_RESN } int VL6180x::VL6180xInit(void){ uint8_t data; //for temp data storage data = VL6180x_getRegister(VL6180X_SYSTEM_FRESH_OUT_OF_RESET); wait_ms(50); if(data != 1) { printf("error\n\r"); return VL6180x_FAILURE_RESET; } //Required by datasheet //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf VL6180x_setRegister(0x0207, 0x01); VL6180x_setRegister(0x0208, 0x01); VL6180x_setRegister(0x0096, 0x00); VL6180x_setRegister(0x0097, 0xfd); VL6180x_setRegister(0x00e3, 0x00); VL6180x_setRegister(0x00e4, 0x04); VL6180x_setRegister(0x00e5, 0x02); VL6180x_setRegister(0x00e6, 0x01); VL6180x_setRegister(0x00e7, 0x03); VL6180x_setRegister(0x00f5, 0x02); VL6180x_setRegister(0x00d9, 0x05); VL6180x_setRegister(0x00db, 0xce); VL6180x_setRegister(0x00dc, 0x03); VL6180x_setRegister(0x00dd, 0xf8); VL6180x_setRegister(0x009f, 0x00); VL6180x_setRegister(0x00a3, 0x3c); VL6180x_setRegister(0x00b7, 0x00); VL6180x_setRegister(0x00bb, 0x3c); VL6180x_setRegister(0x00b2, 0x09); VL6180x_setRegister(0x00ca, 0x09); VL6180x_setRegister(0x0198, 0x01); VL6180x_setRegister(0x01b0, 0x17); VL6180x_setRegister(0x01ad, 0x00); VL6180x_setRegister(0x00ff, 0x05); VL6180x_setRegister(0x0100, 0x05); VL6180x_setRegister(0x0199, 0x05); VL6180x_setRegister(0x01a6, 0x1b); VL6180x_setRegister(0x01ac, 0x3e); VL6180x_setRegister(0x01a7, 0x1f); VL6180x_setRegister(0x0030, 0x00); return 0; } VL6180x::~VL6180x(void) { }; void VL6180x::VL6180xDefautSettings(void){ //Recommended settings from datasheet //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf //Enable Interrupts on Conversion Complete (any source) VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO, (4 << 3)|(4) ); // Set GPIO1 high when sample complete VL6180x_setRegister(VL6180X_SYSTEM_MODE_GPIO1, 0x10); // Set GPIO1 high when sample complete VL6180x_setRegister(VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD, 0x30); //Set Avg sample period VL6180x_setRegister(VL6180X_SYSALS_ANALOGUE_GAIN, 0x46); // Set the ALS gain VL6180x_setRegister(VL6180X_SYSRANGE_VHV_REPEAT_RATE, 0xFF); // Set auto calibration period (Max = 255)/(OFF = 0) VL6180x_setRegister(VL6180X_SYSALS_INTEGRATION_PERIOD, 0x63); // Set ALS integration time to 100ms VL6180x_setRegister(VL6180X_SYSRANGE_VHV_RECALIBRATE, 0x01); // perform a single temperature calibration //Optional settings from datasheet //http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00122600.pdf VL6180x_setRegister(VL6180X_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x09); // Set default ranging inter-measurement period to 100ms VL6180x_setRegister(VL6180X_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A); // Set default ALS inter-measurement period to 100ms VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO, 0x24); // Configures interrupt on ‘New Sample Ready threshold event’ //Additional settings defaults from community VL6180x_setRegister(VL6180X_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32); VL6180x_setRegister(VL6180X_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01); VL6180x_setRegister16bit(VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x7B ); VL6180x_setRegister16bit(VL6180X_SYSALS_INTEGRATION_PERIOD, 0x64); VL6180x_setRegister(VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD,0x30); VL6180x_setRegister(VL6180X_SYSALS_ANALOGUE_GAIN,0x40); VL6180x_setRegister(VL6180X_FIRMWARE_RESULT_SCALER,0x01); } void VL6180x::getIdentification(struct VL6180xIdentification *temp){ temp->idModel = VL6180x_getRegister(VL6180X_IDENTIFICATION_MODEL_ID); temp->idModelRevMajor = VL6180x_getRegister(VL6180X_IDENTIFICATION_MODEL_REV_MAJOR); temp->idModelRevMinor = VL6180x_getRegister(VL6180X_IDENTIFICATION_MODEL_REV_MINOR); temp->idModuleRevMajor = VL6180x_getRegister(VL6180X_IDENTIFICATION_MODULE_REV_MAJOR); temp->idModuleRevMinor = VL6180x_getRegister(VL6180X_IDENTIFICATION_MODULE_REV_MINOR); temp->idDate = VL6180x_getRegister16bit(VL6180X_IDENTIFICATION_DATE); temp->idTime = VL6180x_getRegister16bit(VL6180X_IDENTIFICATION_TIME); } uint8_t VL6180x::changeAddress(uint8_t old_address, uint8_t new_address){ //NOTICE: IT APPEARS THAT CHANGING THE ADDRESS IS NOT STORED IN NON-VOLATILE MEMORY // POWER CYCLING THE DEVICE REVERTS ADDRESS BACK TO 0X29 if( old_address == new_address) return old_address; if( new_address > 127) return old_address; VL6180x_setRegister(VL6180X_I2C_SLAVE_DEVICE_ADDRESS, new_address); return VL6180x_getRegister(VL6180X_I2C_SLAVE_DEVICE_ADDRESS); } uint8_t VL6180x::getDistance() { uint8_t distance; VL6180x_setRegister(VL6180X_SYSRANGE_START, 0x01); //Start Single shot mode wait_ms(10); distance = VL6180x_getRegister(VL6180X_RESULT_RANGE_VAL); VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CLEAR, 0x07); return distance; } float VL6180x::getAmbientLight(vl6180x_als_gain VL6180X_ALS_GAIN) { //First load in Gain we are using, do it everytime incase someone changes it on us. //Note: Upper nibble shoudl be set to 0x4 i.e. for ALS gain of 1.0 write 0x46 VL6180x_setRegister(VL6180X_SYSALS_ANALOGUE_GAIN, (0x40 | VL6180X_ALS_GAIN)); // Set the ALS gain //Start ALS Measurement VL6180x_setRegister(VL6180X_SYSALS_START, 0x01); wait_ms(100); //give it time... VL6180x_setRegister(VL6180X_SYSTEM_INTERRUPT_CLEAR, 0x07); //Retrieve the Raw ALS value from the sensoe unsigned int alsRaw = VL6180x_getRegister16bit(VL6180X_RESULT_ALS_VAL); //Get Integration Period for calculation, we do this everytime incase someone changes it on us. unsigned int alsIntegrationPeriodRaw = VL6180x_getRegister16bit(VL6180X_SYSALS_INTEGRATION_PERIOD); float alsIntegrationPeriod = 100.0 / alsIntegrationPeriodRaw ; //Calculate actual LUX from Appnotes float alsGain = 0.0; switch (VL6180X_ALS_GAIN){ case GAIN_20: alsGain = 20.0; break; case GAIN_10: alsGain = 10.32; break; case GAIN_5: alsGain = 5.21; break; case GAIN_2_5: alsGain = 2.60; break; case GAIN_1_67: alsGain = 1.72; break; case GAIN_1_25: alsGain = 1.28; break; case GAIN_1: alsGain = 1.01; break; case GAIN_40: alsGain = 40.0; break; } //Calculate LUX from formula in AppNotes float alsCalculated = (float)0.32 * ((float)alsRaw / alsGain) * alsIntegrationPeriod; return alsCalculated; } // --- Private Functions --- // uint8_t VL6180x::VL6180x_getRegister(uint16_t registerAddr) { uint8_t data; char data_write[2]; char data_read[1]; data_write[0] = (registerAddr >> 8) & 0xFF; //MSB of register address data_write[1] = registerAddr & 0xFF; //LSB of register address m_i2c->write(m_addr, data_write, 2,0); m_i2c->read(m_addr,data_read,1,1); //Read Data from selected register data=data_read[0]; return data; /* #if 1 char reg[] = { 0, 0 }; char ret[] = { 0, 0 }; m_i2c->write(m_addr, ®[0], 2); m_i2c->read(m_addr, ret, 1 ); printf("%02x, %02x, %02x\n\r", ret[0], ret[1], m_addr ); #else char reg[] = { 0x0FU, 0 }; char ret[] = { 0, 0 }; m_i2c->frequency(400000); m_i2c->write(0xBE, ®[0], 1, 1); m_i2c->read(0xBE, ret, 1 ); printf("%02x, %02x, %02x\n\r", ret[0], ret[1], m_addr ); #endif return ret[0];*/ } uint16_t VL6180x::VL6180x_getRegister16bit(uint16_t registerAddr) { uint8_t data_low; uint8_t data_high; uint16_t data; char data_write[2]; char data_read[2]; data_write[0] = (registerAddr >> 8) & 0xFF; //MSB of register address data_write[1] = registerAddr & 0xFF; //LSB of register address m_i2c->write(m_addr, data_write, 2,0); m_i2c->read(m_addr,data_read,2,1); data_high = data_read[0]; //Read Data from selected register data_low = data_read[1]; //Read Data from selected register data = (data_high << 8)|data_low; return data; } void VL6180x::PE1801_setRegister(uint8_t registerAddr, uint8_t data) { char w2_data[2]; w2_data[0] = registerAddr; w2_data[1] = data; m_i2c->write( PE180_ADDRESS, w2_data, 2 ); } void VL6180x::VL6180x_setRegister(uint16_t registerAddr, uint8_t data) { char data_write[3]; data_write[0] = (registerAddr >> 8) & 0xFF; //MSB of register address data_write[1] = registerAddr & 0xFF; //LSB of register address data_write[2] = data & 0xFF; m_i2c->write(m_addr, data_write, 3); } void VL6180x::VL6180x_setRegister16bit(uint16_t registerAddr, uint16_t data) { char data_write[4]; data_write[0] = (registerAddr >> 8) & 0xFF; //MSB of register address data_write[1] = registerAddr & 0xFF; //LSB of register address data_write[2] = (data >> 8) & 0xFF; data_write[3] = data & 0xFF; m_i2c->write(m_addr, data_write, 4); }