This is sample code for interfacing ROHM's SENSORSHLD1-EVK-101 with Nordic Semiconductor's nRF51-DK Development Kit Host BTLE Board
Dependencies: BLE_API mbed nRF51822
Fork of Nordic_UART_TEMPLATE_ROHM by
Code Example for ROHM Mutli-Sensor Shield on the Nordic Semiconductor nRF51-DK
This code was written to be used with the Nordic Semiconductor nRF51-DK.
This is the basic example code for interfacing ROHM's Multi-sensor Shield Board onto this board.
Additional information about the ROHM MultiSensor Shield Board can be found at the following link: https://github.com/ROHMUSDC/ROHM_SensorPlatform_Multi-Sensor-Shield
For code example for the ROHM SENSORSHLD0-EVK-101, please see the following link: https://developer.mbed.org/teams/ROHMUSDC/code/Nordic_UART_TEMPLATE_ROHM/
Operation
Ultimately, this code will initialize all the sensors on the Multi-sensor shield board and then poll the sensors. The sensor data will then be returned to the BTLE COM port link and will be view-able on any BTLE enabled phone that can connect to the Nordic UART Application.
Supported ROHM Sensor Devices
- BDE0600G Temperature Sensor
- BM1383GLV Pressure Sensor
- BU52014 Hall Sensor
- ML8511 UV Sensor
- RPR-0521 ALS/PROX Sensor
- BH1745NUC Color Sensor
- KMX62 Accel/Mag Sensor
- KX122 Accel Sensor
- BM1422 MI Magnetometer Sensor
- KXG03 Gyro/Accel Sensor
Updates from SHLD0 to SHLD1
- Pressure Sensor Changes: Fixed Register Map Changes for BM1383AGLV, See Pressure Sensor Datasheet for more details - TEMP and PRES output switched
- Added new #ifdef section for Magnetometer
- Changed Gyro Device Address (7bit addr now 0x4F, not 0x4E)
Sensor Applicable Code Sections
- Added a Section in "Main" to act as initialization
- Added to the "Periodic Callback" to read sensor data and return to Phone/Host
Questions/Feedback
Please feel free to let us know any questions/feedback/comments/concerns on the ROHM shield implementation by contacting the following e-mail:
Diff: main.cpp
- Revision:
- 5:d39ffc5638a3
- Parent:
- 4:eabae2996ecc
- Child:
- 6:6860e53dc7ae
diff -r eabae2996ecc -r d39ffc5638a3 main.cpp --- a/main.cpp Thu Aug 13 18:24:14 2015 +0000 +++ b/main.cpp Thu Sep 24 22:23:31 2015 +0000 @@ -15,7 +15,7 @@ */ /* - * Added Functions for ROHM's Multi-Sensor Shield Board + * Added Functions for interfacing with ROHM's Multi-Sensor Shield Board * Supports the following Sensor Devices * > BDE0600G Temperature Sensor * > BM1383GLV Pressure Sensor @@ -27,9 +27,15 @@ * > KX122 Accel Sensor * > KXG03 Gyro (Currently Unavailable as IC hasn't docked yet) * + * + * Last Upadtaed: 9/11/15 + * * New Code: * Added a Section in "Main" to act as initialization * Added to the "Periodic Callback" to read sensor data and return to Phone/Host + * + * Additional information about the ROHM MultiSensor Shield Board can be found at the following link: + * https://github.com/ROHMUSDC/ROHM_SensorPlatform_Multi-Sensor-Shield */ @@ -38,15 +44,12 @@ #define AnalogUV //ML8511 #define HallSensor //BU52011 //Change 1: Change to use GPIO for BU52014 #define RPR0521 //RPR0521 //Change 2: Remove This and add in the RPR-0521 -#define KMX62 //Change 3: Add Code For BH1745, KX022, BM1383GLV, KMX62 - -//Devices To Add -// PRessure Sensor -// Accel Only - KX122 -// Check Functions for KMX62 -// Color Sensor +#define KMX62 //Change 3: Add Code For -BH1745-, -KX022, BM1383GLV, -KMX62- +#define color +#define KX022 +#define Pressure -// Gyro last... + #include "mbed.h" @@ -55,8 +58,9 @@ #include "nrf_temp.h" #include "I2C.h" + #define MAX_REPLY_LEN (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN) //Actually equal to 20 -#define SENSOR_READ_INTERVAL_S (10.0F) +#define SENSOR_READ_INTERVAL_S (5.0F) #define ADV_INTERVAL_MS (1000UL) #define UART_BAUD_RATE (19200UL) #define DEVICE_NAME ("DEMO SENSOR") // This can be read AFTER connecting to the device. @@ -100,7 +104,10 @@ bool RepStart = true; bool NoRepStart = false; -#ifdef RPR0521 +int i=1; + + +#ifdef RPR0521 //als digital int RPR0521_addr_w = 0x70; //7bit addr = 0x38, with write bit 0 int RPR0521_addr_r = 0x71; //7bit addr = 0x38, with read bit 1 @@ -128,20 +135,93 @@ char KMX62_Addr_Mag_ReadData = 0x10; char KMX62_Content_Mag_ReadData[6]; -int MEMS_Accel_Xout = 0; -int MEMS_Accel_Yout = 0; -int MEMS_Accel_Zout = 0; -float MEMS_Accel_Conv_Xout = 0; -float MEMS_Accel_Conv_Yout = 0; -float MEMS_Accel_Conv_Zout = 0; -int MEMS_Mag_Xout = 0; -int MEMS_Mag_Yout = 0; -int MEMS_Mag_Zout = 0; +short int MEMS_Accel_Xout = 0; +short int MEMS_Accel_Yout = 0; +short int MEMS_Accel_Zout = 0; +double MEMS_Accel_Conv_Xout = 0; +double MEMS_Accel_Conv_Yout = 0; +double MEMS_Accel_Conv_Zout = 0; +short int MEMS_Mag_Xout = 0; +short int MEMS_Mag_Yout = 0; +short int MEMS_Mag_Zout = 0; float MEMS_Mag_Conv_Xout = 0; float MEMS_Mag_Conv_Yout = 0; float MEMS_Mag_Conv_Zout = 0; #endif +#ifdef color +int BH1745_addr_w = 0x72; //write +int BH1745_addr_r = 0x73; //read + +char BH1745_persistence[2] = {0x61, 0x03}; +char BH1745_mode1[2] = {0x41, 0x00}; +char BH1745_mode2[2] = {0x42, 0x92}; +char BH1745_mode3[2] = {0x43, 0x02}; + +char BH1745_Content_ReadData[6]; +char BH1745_Addr_color_ReadData = 0x50; + +int BH1745_Red; +int BH1745_Blue; +int BH1745_Green; + +#endif + +#ifdef KX022 +int KX022_addr_w = 0x3C; //write +int KX022_addr_r = 0x3D; //read + +char KX022_Accel_CNTL1[2] = {0x18, 0x41}; +char KX022_Accel_ODCNTL[2] = {0x1B, 0x02}; +char KX022_Accel_CNTL3[2] = {0x1A, 0xD8}; +char KX022_Accel_TILT_TIMER[2] = {0x22, 0x01}; +char KX022_Accel_CNTL2[2] = {0x18, 0xC1}; + +char KX022_Content_ReadData[6]; +char KX022_Addr_Accel_ReadData = 0x06; + +float KX022_Accel_X; +float KX022_Accel_Y; +float KX022_Accel_Z; + +short int KX022_Accel_X_RawOUT = 0; +short int KX022_Accel_Y_RawOUT = 0; +short int KX022_Accel_Z_RawOUT = 0; + +int KX022_Accel_X_LB = 0; +int KX022_Accel_X_HB = 0; +int KX022_Accel_Y_LB = 0; +int KX022_Accel_Y_HB = 0; +int KX022_Accel_Z_LB = 0; +int KX022_Accel_Z_HB = 0; + +#endif + +#ifdef Pressure +int Press_addr_w = 0xBA; //write +int Press_addr_r = 0xBB; //read + +char PWR_DOWN[2] = {0x12, 0x01}; +char SLEEP[2] = {0x13, 0x01}; +char Mode_Control[2] = {0x14, 0xC4}; + +char Press_Content_ReadData[6]; +char Press_Addr_ReadData =0x1A; + +int BM1383_Temp_highByte; +int BM1383_Temp_lowByte; +int BM1383_Pres_highByte; +int BM1383_Pres_lowByte; +int BM1383_Pres_leastByte; + +float BM1383_Temp_Out; +float BM1383_Temp_Conv_Out; +float BM1383_Pres_Conv_Out; + +float BM1383_Var; +float BM1383_Deci; +#endif + /** * This callback is used whenever a disconnection occurs. */ @@ -226,18 +306,50 @@ uint32_t len = 0; -/* +if(i==1) +{ +/* #ifdef AnalogALS if (m_ble.getGapState().connected) { BH1620_ALS_value = BH1620_ALS.read_u16(); BH1620_output = (float)BH1620_ALS_value * 1.543; - len = snprintf((char*) buf, MAX_REPLY_LEN, "ALS = %.2f lx", BH1620_output); + len = snprintf((char*) buf, MAX_REPLY_LEN, "Analog ALS = %.2f lx", BH1620_output); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); } #endif */ +#ifdef color +if (m_ble.getGapState().connected) { + //Read color Portion from the IC + i2c.write(BH1745_addr_w, &BH1745_Addr_color_ReadData, 1, RepStart); + i2c.read(BH1745_addr_r, &BH1745_Content_ReadData[0], 6, NoRepStart); + + //separate all data read into colors + + BH1745_Red = (BH1745_Content_ReadData[1]<<8) | (BH1745_Content_ReadData[0]); + BH1745_Green = (BH1745_Content_ReadData[3]<<8) | (BH1745_Content_ReadData[2]); + BH1745_Blue = (BH1745_Content_ReadData[5]<<8) | (BH1745_Content_ReadData[4]); + + + //transmit data + len = snprintf((char*) buf, MAX_REPLY_LEN, "Red= %d", BH1745_Red); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + + len = snprintf((char*) buf, MAX_REPLY_LEN, "Green= %d", BH1745_Green); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + len = snprintf((char*) buf, MAX_REPLY_LEN, "Blue= %d", BH1745_Blue); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + +} +#endif + #ifdef AnalogTemp if (m_ble.getGapState().connected) { BDE0600_Temp_value = BDE0600_Temp.read_u16(); @@ -252,8 +364,8 @@ #ifdef AnalogUV if (m_ble.getGapState().connected) { ML8511_UV_value = ML8511_UV.read_u16(); - ML8511_output = (float)ML8511_UV_value * 0.00283; //(value * (2.9V/1024)) //Note to self: when playing with this, a negative value is seen... Honestly, I think this has to do with my ADC converstion... - ML8511_output = (ML8511_output-2.2)/(0.129) + 15; // Added +5 to the offset so when inside (aka, no UV, readings show 0)... this is the wrong approach... and the readings don't make sense... Fix this. + ML8511_output = (float)ML8511_UV_value * 0.0029; //(value * (2.9V/1024)) //Note to self: when playing with this, a negative value is seen... Honestly, I think this has to do with my ADC converstion... + ML8511_output = (ML8511_output-2.2)/(0.129) + 10; // Added +5 to the offset so when inside (aka, no UV, readings show 0)... this is the wrong approach... and the readings don't make sense... Fix this. len = snprintf((char*) buf, MAX_REPLY_LEN, "UV = %.1f mW/cm2", ML8511_output); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); @@ -276,12 +388,12 @@ ALS_Return = (ALS_ReturnData_raw[0]<<8) | ALS_ReturnData_raw[1]; ALS_Return = ALS_Return/1.2; - len = snprintf((char*) buf, MAX_REPLY_LEN, "DALS= %0.2f lx", ALS_Return); + len = snprintf((char*) buf, MAX_REPLY_LEN, "DAL1= %0.2f lx", ALS_Return); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); } #endif -#ifdef RPR0521 +#ifdef RPR0521 //als digital if (m_ble.getGapState().connected) { i2c.write(RPR0521_addr_w, &RPR0521_Addr_ReadData, 1, RepStart); @@ -310,9 +422,17 @@ len = snprintf((char*) buf, MAX_REPLY_LEN, "DALS= %0.2f lx", RPR0521_ALS_OUT); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + } #endif +i++; + +} + +else if(i==2) +{ + #ifdef KMX62 if (m_ble.getGapState().connected) { //Read Accel Portion from the IC @@ -328,10 +448,10 @@ //Note: Conversion to G is as follows: // Axis_ValueInG = MEMS_Accel_axis / 1024 // However, since we did not remove the LSB previously, we need to divide by 4 again - // Thus, we will divide the output by 4095 (1024*4) to convert and cancel out the LSB - MEMS_Accel_Conv_Xout = (float)MEMS_Accel_Xout/4096/2; - MEMS_Accel_Conv_Yout = (float)MEMS_Accel_Yout/4096/2; - MEMS_Accel_Conv_Zout = (float)MEMS_Accel_Zout/4096/2; + // Thus, we will divide the output by 4096 (1024*4) to convert and cancel out the LSB + MEMS_Accel_Conv_Xout = ((float)MEMS_Accel_Xout/4096/2); + MEMS_Accel_Conv_Yout = ((float)MEMS_Accel_Yout/4096/2); + MEMS_Accel_Conv_Zout = ((float)MEMS_Accel_Zout/4096/2); //Read MAg portion from the IC i2c.write(KMX62_addr_w, &KMX62_Addr_Mag_ReadData, 1, RepStart); @@ -347,47 +467,126 @@ // Axis_ValueInG = MEMS_Accel_axis / 1024 // However, since we did not remove the LSB previously, we need to divide by 4 again // Thus, we will divide the output by 4095 (1024*4) to convert and cancel out the LSB - MEMS_Mag_Conv_Xout = (float)MEMS_Mag_Xout*0.146; - MEMS_Mag_Conv_Yout = (float)MEMS_Mag_Yout*0.146; - MEMS_Mag_Conv_Zout = (float)MEMS_Mag_Zout*0.146; + MEMS_Mag_Conv_Xout = (float)MEMS_Mag_Xout/4096*0.146; + MEMS_Mag_Conv_Yout = (float)MEMS_Mag_Yout/4096*0.146; + MEMS_Mag_Conv_Zout = (float)MEMS_Mag_Zout/4096*0.146; + + // transmit data + len = snprintf((char*) buf, MAX_REPLY_LEN, "KMX61SensorData:"); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); len = snprintf((char*) buf, MAX_REPLY_LEN, " AccX= %0.2f g", MEMS_Accel_Conv_Xout); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); len = snprintf((char*) buf, MAX_REPLY_LEN, " AccY= %0.2f g", MEMS_Accel_Conv_Yout); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); len = snprintf((char*) buf, MAX_REPLY_LEN, " AccZ= %0.2f g", MEMS_Accel_Conv_Zout); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); len = snprintf((char*) buf, MAX_REPLY_LEN, " MagX= %0.2f g", MEMS_Mag_Conv_Xout); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); len = snprintf((char*) buf, MAX_REPLY_LEN, " MagY= %0.2f g", MEMS_Mag_Conv_Yout); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); len = snprintf((char*) buf, MAX_REPLY_LEN, " MagZ= %0.2f g", MEMS_Mag_Conv_Zout); m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - wait_ms(1000); + wait_ms(20); + } #endif - if (m_ble.getGapState().connected) { - len = snprintf((char*) buf, MAX_REPLY_LEN, " "); //Print and Extra Line to show new data - m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); - } +i++; + } +else if(i==3) +{ + + + +#ifdef KX022 +if (m_ble.getGapState().connected) { + //Read KX022 Portion from the IC + i2c.write(KX022_addr_w, &KX022_Addr_Accel_ReadData, 1, RepStart); + i2c.read(KX022_addr_r, &KX022_Content_ReadData[0], 6, NoRepStart); + + + //reconfigure the data (taken from arduino code) + KX022_Accel_X_RawOUT = (KX022_Content_ReadData[1]<<8) | (KX022_Content_ReadData[0]); + KX022_Accel_Y_RawOUT = (KX022_Content_ReadData[3]<<8) | (KX022_Content_ReadData[2]); + KX022_Accel_Z_RawOUT = (KX022_Content_ReadData[5]<<8) | (KX022_Content_ReadData[4]); + + //apply needed changes (taken from arduino code) + KX022_Accel_X = (float)KX022_Accel_X_RawOUT / 16384; + KX022_Accel_Y = (float)KX022_Accel_Y_RawOUT / 16384; + KX022_Accel_Z = (float)KX022_Accel_Z_RawOUT / 16384; + + + + //transmit the data + len = snprintf((char*) buf, MAX_REPLY_LEN, "KX022-X= %0.2f", KX022_Accel_X); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + len = snprintf((char*) buf, MAX_REPLY_LEN, "KX022-Y= %0.2f", KX022_Accel_Y); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + len = snprintf((char*) buf, MAX_REPLY_LEN, "KX022-Z= %0.2f", KX022_Accel_Z); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + } +#endif + +#ifdef Pressure +if (m_ble.getGapState().connected) { + //Read color Portion from the IC + i2c.write(Press_addr_w, &Press_Addr_ReadData, 1, RepStart); + i2c.read(Press_addr_r, &Press_Content_ReadData[0], 6, NoRepStart); + + + + BM1383_Temp_Out = (Press_Content_ReadData[1]<<8) | (Press_Content_ReadData[0]); + BM1383_Temp_Conv_Out = (float)BM1383_Temp_Out/32; + + BM1383_Var = (Press_Content_ReadData[2]<<3) | (Press_Content_ReadData[3] >> 5); + BM1383_Deci = ((Press_Content_ReadData[3] & 0x1f) << 6 | ((Press_Content_ReadData[4] >> 2))); + BM1383_Deci = (float)BM1383_Deci* 0.00048828125; //0.00048828125 = 2^-11 + BM1383_Pres_Conv_Out = (BM1383_Var + BM1383_Deci); //question pending here... + + len = snprintf((char*) buf, MAX_REPLY_LEN, "Temp_out= %0.2f", BM1383_Temp_Out); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + len = snprintf((char*) buf, MAX_REPLY_LEN, "Temp_conv= %0.2f", BM1383_Temp_Conv_Out); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); + + len = snprintf((char*) buf, MAX_REPLY_LEN, "Press_conv= %0.2f", BM1383_Pres_Conv_Out); + m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len); + wait_ms(25); +} +#endif + +i=1; + +} + + + +} void error(ble_error_t err, uint32_t line) { m_error_led = 1; @@ -430,7 +629,7 @@ sw4Press.fall(&PBTrigger); -#ifdef RPR0521 +#ifdef RPR0521 //als digital // 1. Mode Control (0x41), write (0xC6): ALS EN, PS EN, 100ms measurement for ALS and PS, PS_PULSE=1 // 2. ALS_PS_CONTROL (0x42), write (0x03): LED Current = 200mA // 3. PERSIST (0x43), write (0x20): PS Gain x4 @@ -444,6 +643,32 @@ i2c.write(KMX62_addr_w, &KMX62_CNTL2[0], 2, false); #endif +#ifdef color + // 1. CNTL2 (0x3A), write (0x5F): 4g, Max RES, EN temp mag and accel + i2c.write(BH1745_addr_w, &BH1745_persistence[0], 2, false); + i2c.write(BH1745_addr_w, &BH1745_mode1[0], 2, false); + i2c.write(BH1745_addr_w, &BH1745_mode2[0], 2, false); + i2c.write(BH1745_addr_w, &BH1745_mode3[0], 2, false); +#endif + +#ifdef KX022 + +i2c.write(KX022_addr_w, &KX022_Accel_CNTL1[0], 2, false); +i2c.write(KX022_addr_w, &KX022_Accel_ODCNTL[0], 2, false); +i2c.write(KX022_addr_w, &KX022_Accel_CNTL3[0], 2, false); +i2c.write(KX022_addr_w, &KX022_Accel_TILT_TIMER[0], 2, false); +i2c.write(KX022_addr_w, &KX022_Accel_CNTL2[0], 2, false); + +#endif + +#ifdef Pressure + +i2c.write(Press_addr_w, &PWR_DOWN[0], 2, false); +i2c.write(Press_addr_w, &SLEEP[0], 2, false); +i2c.write(Press_addr_w, &Mode_Control[0], 2, false); + +#endif + //Start BTLE Initialization Section m_ble.init(); m_ble.onDisconnection(disconnectionCallback); @@ -494,4 +719,4 @@ while (true) { m_ble.waitForEvent(); } -} +} \ No newline at end of file