This program connects to a few sensors via I2C and sends the data collected to a WNC Cellular Module which is located on an Avnet WNC-Shield card.

Dependencies:   FXOS8700CQ MODSERIAL mbed

/media/uploads/kevinkeryk/avnet_logo_tagline_rgb.png

Avnet Cellular IoT Instructions

  • One problematic area is setting the MY_SERVER_URL. When you copy the URL from the flow, you must make sure the MY_SERVER_URL is also set to the appropriate server. It can be either "run-east.att.io" or "run-west.att.io".

Useful Links

Adding Additional Sensors

The FLOW_DEVICE_NAME field must contain the name of the instance of the Virtual Starter Kit in FLOW you will be communicating with. Usually this is "vstarterkit001", but if you have problems communicating you can verify this is correct. Note: This device will not be created until you click the “Initialize” input on the Virtual Device tab of the Starter Kit project in FLOW. At that point, it becomes available in M2X and you can see it as the DEVICE SERIAL field under Devices as in the image below. /media/uploads/JMF/vstarterkit.png

Sensors: When executing, the FRDM-K64F board uploads sensor measurements to AT&T’s Flow environment every 5 seconds, using the Cellular shield board. You can adjust how often you want to do this by editing the SENSOR_UPDATE_INTERVAL_MS value in the header file.

Temperature and humidity: By default, the board reports readings from the HTS221 temperature and humidity sensor. These two values are sent to the HTTP IN /climate port in FLOW with field names “temp” and “humidity”. Temperature is in degrees Fahrenheit and humidity is a %. This default assignment is: iSensorsToReport = TEMP_HUMIDITY_ONLY;

Accelerometer: If you want to expand and use the onboard motion sensor, you can also send 3-axis accelerometer information from the board as “accelX”, “accelY”, and “accelZ”. This is useful if you want to know the stationary position of the board with regards to gravity, or whether it is in motion. These readings are in g’s. To send these values, change the assignment to: iSensorsToReport = TEMP_HUMIDITY_ACCELEROMETER;

PMOD Sensors: If you have a Silicon Labs sensor module that can plug into the PMOD connector on the Cellular shield, you are able to measure proximity, UV light, ambient visible and infrared light from the Si1145 sensor. This PMOD also has a temperature and humidity sensor, but in this case it is redundant. When enabled, the fields “proximity”, “light_uv”, “light_vis” and “light_ir” are also sent. To enable all these sensors, change the assignment to: iSensorsToReport = TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS;

Connecting the PMOD sensors: Because the pinouts do not align, the SiLabs PMOD sensor board cannot be plugged into the J10 PMOD receptacle on the shield directly. The following wiring instructions must be followed:

SignalJ10ShieldPMOD Color in the image below
VCCPin 6Pin 6Red
GNDPin 5Pin 5Black
SDAPin4Pin 3Green
SCLPin3Pin 2Yellow

/media/uploads/JMF/xyz.jpg

AT&T M2X and FLOW Instructions

M2X & FLOW Instructions

Link to AT&T M2X

M2X

Link to AT&T Flow

FLOW

Avnet WNC-Shield Information

Getting Started with the Avnet WNC-Shield Software

  • This project uses Revision 119 of the MBED library because of I2C implementation differences with the tip (Revision 121).
  • This project uses Revision 4 of the FXOS8700CQ library for sensors.

Easily Modifiable Parameters

Inside the mbed Avnet_ATT_Cellular_IOT project, the parameters needed to customize your board are in the config_me.h file.

  • FLOW parameters: This project assumes you are using a fork of the Starter Kit Base project, which is a reference design created using AT&T’s FLOW (https://flow.att.com) that allows the creation of online virtualization and other IoT functionality. The default parameters in the config_me.h file are done for a specific instance of this project. When you fork the original project, you get your own instance and it will have its own base address. At the bottom of the FLOW environment, when you click on the Endpoints tab, URL information that is specific to your instance is displayed. Of note is the Base URL. In the example below (as in the default mbed project), the Base URL is: https://run-west.att.io/1e464b19cdcde/774c88d68202/86694923d5bf28a/in/flow You have to take note of two parts of this address. The run-west.att.io part is the server URL, and you have to make sure the
  • MY_SERVER_URL field in config_me.h matches this. The rest of the base URL, in green above, needs to be pasted into the FLOW_BASE_URL field.

There is also a FLOW_INPUT_NAME field. This should match the name of the HTTP IN port in the FLOW project that you want to send sensor data to. The default is "/climate", as in the FLOW image below.

/media/uploads/JMF/sf.png

Where is the Binary I compiled

When the COMPILE button is pressed, it compiles your project and links it. The result is placed in the DOWNLOAD folder you use when downloading files from the Internet. It will be called AvnetATT_shape_hackathon_K64F.bin.

Additional Information on Compiling/Configuring

Comprehensive instructions can be found at: Quick Start Instructions

Committer:
stefanrousseau
Date:
Mon Jul 11 06:53:41 2016 +0000
Revision:
4:f83bedd9cab4
Child:
11:e6602513730f
Added a sensors file that will write the FRDM-K64F motion sensor and the values from the SiLabs PMOD into a structure.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stefanrousseau 4:f83bedd9cab4 1 #include "mbed.h"
stefanrousseau 4:f83bedd9cab4 2 #include "sensors.h"
stefanrousseau 4:f83bedd9cab4 3
stefanrousseau 4:f83bedd9cab4 4 //I2C for pmod sensors:
stefanrousseau 4:f83bedd9cab4 5 #define Si1145_PMOD_I2C_ADDR 0xC0 //this is for 7-bit addr 0x60 for the Si7020
stefanrousseau 4:f83bedd9cab4 6 #define Si7020_PMOD_I2C_ADDR 0x80 //this is for 7-bit addr 0x4 for the Si7020
stefanrousseau 4:f83bedd9cab4 7
stefanrousseau 4:f83bedd9cab4 8 I2C pmod_i2c(PTC11, PTC10); //SDA, SCL
stefanrousseau 4:f83bedd9cab4 9
stefanrousseau 4:f83bedd9cab4 10 #include "FXOS8700CQ.h"
stefanrousseau 4:f83bedd9cab4 11 // Pin names for the motion sensor FRDM-K64F board:
stefanrousseau 4:f83bedd9cab4 12 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1)
stefanrousseau 4:f83bedd9cab4 13 // Storage for the data from the sensor
stefanrousseau 4:f83bedd9cab4 14 SRAWDATA accel_data;
stefanrousseau 4:f83bedd9cab4 15 SRAWDATA magn_data;
stefanrousseau 4:f83bedd9cab4 16 //InterruptIn fxos_int1(PTC6); // unused, common with SW2 on FRDM-K64F
stefanrousseau 4:f83bedd9cab4 17 InterruptIn fxos_int2(PTC13); // should just be the Data-Ready interrupt
stefanrousseau 4:f83bedd9cab4 18 bool fxos_int2_triggered = false;
stefanrousseau 4:f83bedd9cab4 19 void trigger_fxos_int2(void)
stefanrousseau 4:f83bedd9cab4 20 {
stefanrousseau 4:f83bedd9cab4 21 fxos_int2_triggered = true;
stefanrousseau 4:f83bedd9cab4 22 //us_ellapsed = t.read_us();
stefanrousseau 4:f83bedd9cab4 23 }
stefanrousseau 4:f83bedd9cab4 24
stefanrousseau 4:f83bedd9cab4 25 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 26 * Perform I2C single read.
stefanrousseau 4:f83bedd9cab4 27 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 28 unsigned char I2C_ReadSingleByte(unsigned char ucDeviceAddress)
stefanrousseau 4:f83bedd9cab4 29 {
stefanrousseau 4:f83bedd9cab4 30 char rxbuffer [1];
stefanrousseau 4:f83bedd9cab4 31 pmod_i2c.read(ucDeviceAddress, rxbuffer, 1 );
stefanrousseau 4:f83bedd9cab4 32 return (unsigned char)rxbuffer[0];
stefanrousseau 4:f83bedd9cab4 33 } //I2C_ReadSingleByte()
stefanrousseau 4:f83bedd9cab4 34
stefanrousseau 4:f83bedd9cab4 35 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 36 * Perform I2C single read from address.
stefanrousseau 4:f83bedd9cab4 37 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 38 unsigned char I2C_ReadSingleByteFromAddr(unsigned char ucDeviceAddress, unsigned char Addr)
stefanrousseau 4:f83bedd9cab4 39 {
stefanrousseau 4:f83bedd9cab4 40 char txbuffer [1];
stefanrousseau 4:f83bedd9cab4 41 char rxbuffer [1];
stefanrousseau 4:f83bedd9cab4 42 txbuffer[0] = (char)Addr;
stefanrousseau 4:f83bedd9cab4 43 pmod_i2c.write(ucDeviceAddress, txbuffer, 1 );
stefanrousseau 4:f83bedd9cab4 44 pmod_i2c.read(ucDeviceAddress, rxbuffer, 1 );
stefanrousseau 4:f83bedd9cab4 45 return (unsigned char)rxbuffer[0];
stefanrousseau 4:f83bedd9cab4 46 } //I2C_ReadSingleByteFromAddr()
stefanrousseau 4:f83bedd9cab4 47
stefanrousseau 4:f83bedd9cab4 48 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 49 * Perform I2C read of more than 1 byte.
stefanrousseau 4:f83bedd9cab4 50 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 51 int I2C_ReadMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength)
stefanrousseau 4:f83bedd9cab4 52 {
stefanrousseau 4:f83bedd9cab4 53 int status;
stefanrousseau 4:f83bedd9cab4 54 status = pmod_i2c.read(ucDeviceAddress, ucData, ucLength);
stefanrousseau 4:f83bedd9cab4 55 return status;
stefanrousseau 4:f83bedd9cab4 56 } //I2C_ReadMultipleBytes()
stefanrousseau 4:f83bedd9cab4 57
stefanrousseau 4:f83bedd9cab4 58 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 59 * Perform I2C write of a single byte.
stefanrousseau 4:f83bedd9cab4 60 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 61 int I2C_WriteSingleByte(unsigned char ucDeviceAddress, unsigned char Data, bool bSendStop)
stefanrousseau 4:f83bedd9cab4 62 {
stefanrousseau 4:f83bedd9cab4 63 int status;
stefanrousseau 4:f83bedd9cab4 64 char txbuffer [1];
stefanrousseau 4:f83bedd9cab4 65 txbuffer[0] = (char)Data; //data
stefanrousseau 4:f83bedd9cab4 66 status = pmod_i2c.write(ucDeviceAddress, txbuffer, 1, !bSendStop); //true: do not send stop
stefanrousseau 4:f83bedd9cab4 67 return status;
stefanrousseau 4:f83bedd9cab4 68 } //I2C_WriteSingleByte()
stefanrousseau 4:f83bedd9cab4 69
stefanrousseau 4:f83bedd9cab4 70 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 71 * Perform I2C write of 1 byte to an address.
stefanrousseau 4:f83bedd9cab4 72 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 73 int I2C_WriteSingleByteToAddr(unsigned char ucDeviceAddress, unsigned char Addr, unsigned char Data, bool bSendStop)
stefanrousseau 4:f83bedd9cab4 74 {
stefanrousseau 4:f83bedd9cab4 75 int status;
stefanrousseau 4:f83bedd9cab4 76 char txbuffer [2];
stefanrousseau 4:f83bedd9cab4 77 txbuffer[0] = (char)Addr; //address
stefanrousseau 4:f83bedd9cab4 78 txbuffer[1] = (char)Data; //data
stefanrousseau 4:f83bedd9cab4 79 //status = pmod_i2c.write(ucDeviceAddress, txbuffer, 2, false); //stop at end
stefanrousseau 4:f83bedd9cab4 80 status = pmod_i2c.write(ucDeviceAddress, txbuffer, 2, !bSendStop); //true: do not send stop
stefanrousseau 4:f83bedd9cab4 81 return status;
stefanrousseau 4:f83bedd9cab4 82 } //I2C_WriteSingleByteToAddr()
stefanrousseau 4:f83bedd9cab4 83
stefanrousseau 4:f83bedd9cab4 84 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 85 * Perform I2C write of more than 1 byte.
stefanrousseau 4:f83bedd9cab4 86 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 87 int I2C_WriteMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength, bool bSendStop)
stefanrousseau 4:f83bedd9cab4 88 {
stefanrousseau 4:f83bedd9cab4 89 int status;
stefanrousseau 4:f83bedd9cab4 90 status = pmod_i2c.write(ucDeviceAddress, ucData, ucLength, !bSendStop); //true: do not send stop
stefanrousseau 4:f83bedd9cab4 91 return status;
stefanrousseau 4:f83bedd9cab4 92 } //I2C_WriteMultipleBytes()
stefanrousseau 4:f83bedd9cab4 93
stefanrousseau 4:f83bedd9cab4 94 bool bSi7020_present = false;
stefanrousseau 4:f83bedd9cab4 95 void Init_Si7020(void)
stefanrousseau 4:f83bedd9cab4 96 {
stefanrousseau 4:f83bedd9cab4 97 char SN_7020 [8];
stefanrousseau 4:f83bedd9cab4 98 //SN part 1:
stefanrousseau 4:f83bedd9cab4 99 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFA, 0x0F, false);
stefanrousseau 4:f83bedd9cab4 100 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[0], 4);
stefanrousseau 4:f83bedd9cab4 101
stefanrousseau 4:f83bedd9cab4 102 //SN part 1:
stefanrousseau 4:f83bedd9cab4 103 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFC, 0xC9, false);
stefanrousseau 4:f83bedd9cab4 104 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[4], 4);
stefanrousseau 4:f83bedd9cab4 105
stefanrousseau 4:f83bedd9cab4 106 char Ver_7020 [2];
stefanrousseau 4:f83bedd9cab4 107 //FW version:
stefanrousseau 4:f83bedd9cab4 108 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0x84, 0xB8, false);
stefanrousseau 4:f83bedd9cab4 109 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Ver_7020[0], 2);
stefanrousseau 4:f83bedd9cab4 110
stefanrousseau 4:f83bedd9cab4 111 if (SN_7020[4] != 0x14)
stefanrousseau 4:f83bedd9cab4 112 {
stefanrousseau 4:f83bedd9cab4 113 bSi7020_present = false;
stefanrousseau 4:f83bedd9cab4 114 printf("Si7020 sensor not found\n");
stefanrousseau 4:f83bedd9cab4 115 }
stefanrousseau 4:f83bedd9cab4 116 else
stefanrousseau 4:f83bedd9cab4 117 {
stefanrousseau 4:f83bedd9cab4 118 bSi7020_present = true;
stefanrousseau 4:f83bedd9cab4 119 printf("Si7020 SN = 0x%02X%02X%02X%02X%02X%02X%02X%02X\n", SN_7020[0], SN_7020[1], SN_7020[2], SN_7020[3], SN_7020[4], SN_7020[5], SN_7020[6], SN_7020[7]);
stefanrousseau 4:f83bedd9cab4 120 printf("Si7020 Version# = 0x%02X\n", Ver_7020[0]);
stefanrousseau 4:f83bedd9cab4 121 } //bool bSi7020_present = true
stefanrousseau 4:f83bedd9cab4 122
stefanrousseau 4:f83bedd9cab4 123 } //Init_Si7020()
stefanrousseau 4:f83bedd9cab4 124
stefanrousseau 4:f83bedd9cab4 125 void Read_Si7020(void)
stefanrousseau 4:f83bedd9cab4 126 {
stefanrousseau 4:f83bedd9cab4 127 if (bSi7020_present)
stefanrousseau 4:f83bedd9cab4 128 {
stefanrousseau 4:f83bedd9cab4 129 char Humidity [2];
stefanrousseau 4:f83bedd9cab4 130 char Temperature [2];
stefanrousseau 4:f83bedd9cab4 131 //Command to measure humidity (temperature also gets measured):
stefanrousseau 4:f83bedd9cab4 132 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xF5, false); //no hold, must do dummy read
stefanrousseau 4:f83bedd9cab4 133 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 1); //dummy read, should get an nack until it is done
stefanrousseau 4:f83bedd9cab4 134 wait (0.05); //wait for measurement. Can also keep reading until no NACK is received
stefanrousseau 4:f83bedd9cab4 135 //I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xE5, false); //Hold mod, the device does a clock stretch on the read until it is done (crashes the I2C bus...
stefanrousseau 4:f83bedd9cab4 136 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 2); //read humidity
stefanrousseau 4:f83bedd9cab4 137 //printf("Read Si7020 Humidity = 0x%02X%02X\n", Humidity[0], Humidity[1]);
stefanrousseau 4:f83bedd9cab4 138 int rh_code = (Humidity[0] << 8) + Humidity[1];
stefanrousseau 4:f83bedd9cab4 139 float fRh = (125.0*rh_code/65536.0) - 6.0; //from datasheet
stefanrousseau 4:f83bedd9cab4 140 //printf("Si7020 Humidity = %*.*f %%\n", 4, 2, fRh); //double % sign for escape //printf("%*.*f\n", myFieldWidth, myPrecision, myFloatValue);
stefanrousseau 4:f83bedd9cab4 141 sprintf(SENSOR_DATA.Humidity_Si7020, "%0.2f", fRh);
stefanrousseau 4:f83bedd9cab4 142
stefanrousseau 4:f83bedd9cab4 143 //Command to read temperature when humidity is already done:
stefanrousseau 4:f83bedd9cab4 144 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xE0, false);
stefanrousseau 4:f83bedd9cab4 145 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Temperature[0], 2); //read temperature
stefanrousseau 4:f83bedd9cab4 146 //printf("Read Si7020 Temperature = 0x%02X%02X\n", Temperature[0], Temperature[1]);
stefanrousseau 4:f83bedd9cab4 147 int temp_code = (Temperature[0] << 8) + Temperature[1];
stefanrousseau 4:f83bedd9cab4 148 float fTemp = (175.72*temp_code/65536.0) - 46.85; //from datasheet in Celcius
stefanrousseau 4:f83bedd9cab4 149 //printf("Si7020 Temperature = %*.*f deg C\n", 4, 2, fTemp);
stefanrousseau 4:f83bedd9cab4 150 sprintf(SENSOR_DATA.Temperature_Si7020, "%0.2f", fTemp);
stefanrousseau 4:f83bedd9cab4 151 } //bool bSi7020_present = true
stefanrousseau 4:f83bedd9cab4 152
stefanrousseau 4:f83bedd9cab4 153 } //Read_Si7020()
stefanrousseau 4:f83bedd9cab4 154
stefanrousseau 4:f83bedd9cab4 155 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 156 * The following are aliases so that the Si1145 coding examples can be used as-is.
stefanrousseau 4:f83bedd9cab4 157 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 158 unsigned char ReadFrom_Si1145_Register(unsigned char reg) //returns byte from I2C Register 'reg'
stefanrousseau 4:f83bedd9cab4 159 {
stefanrousseau 4:f83bedd9cab4 160 unsigned char result = I2C_ReadSingleByteFromAddr(Si1145_PMOD_I2C_ADDR, reg);
stefanrousseau 4:f83bedd9cab4 161 return (result);
stefanrousseau 4:f83bedd9cab4 162 } //ReadFrom_Si1145_Register()
stefanrousseau 4:f83bedd9cab4 163
stefanrousseau 4:f83bedd9cab4 164 void WriteTo_Si1145_Register(unsigned char reg, unsigned char value) //writes 'value' into I2C Register reg'
stefanrousseau 4:f83bedd9cab4 165 {
stefanrousseau 4:f83bedd9cab4 166 I2C_WriteSingleByteToAddr(Si1145_PMOD_I2C_ADDR, reg, value, true);
stefanrousseau 4:f83bedd9cab4 167 } //WriteTo_Si1145_Register()
stefanrousseau 4:f83bedd9cab4 168
stefanrousseau 4:f83bedd9cab4 169 #define REG_PARAM_WR 0x17
stefanrousseau 4:f83bedd9cab4 170 #define REG_PARAM_RD 0x2E
stefanrousseau 4:f83bedd9cab4 171 #define REG_COMMAND 0x18
stefanrousseau 4:f83bedd9cab4 172 #define REG_RESPONSE 0x20
stefanrousseau 4:f83bedd9cab4 173 #define REG_HW_KEY 0x07
stefanrousseau 4:f83bedd9cab4 174 #define HW_KEY_VAL0 0x17
stefanrousseau 4:f83bedd9cab4 175 #define REG_MEAS_RATE_LSB 0x08
stefanrousseau 4:f83bedd9cab4 176 #define REG_MEAS_RATE_MSB 0x09
stefanrousseau 4:f83bedd9cab4 177 #define REG_PS_LED21 0x0F
stefanrousseau 4:f83bedd9cab4 178 #define REG_PS_LED3 0x10
stefanrousseau 4:f83bedd9cab4 179 #define MAX_LED_CURRENT 0xF
stefanrousseau 4:f83bedd9cab4 180 #define PARAM_CH_LIST 0x01
stefanrousseau 4:f83bedd9cab4 181 #define REG_ALS_VIS_DATA0 0x22
stefanrousseau 4:f83bedd9cab4 182 #define REG_ALS_VIS_DATA1 0x23
stefanrousseau 4:f83bedd9cab4 183 #define REG_ALS_IR_DATA0 0x24
stefanrousseau 4:f83bedd9cab4 184 #define REG_ALS_IR_DATA1 0x25
stefanrousseau 4:f83bedd9cab4 185 #define REG_PS1_DATA0 0x26
stefanrousseau 4:f83bedd9cab4 186 #define REG_PS1_DATA1 0x27
stefanrousseau 4:f83bedd9cab4 187 #define REG_PS2_DATA0 0x28
stefanrousseau 4:f83bedd9cab4 188 #define REG_PS2_DATA1 0x29
stefanrousseau 4:f83bedd9cab4 189 #define REG_PS3_DATA0 0x2A
stefanrousseau 4:f83bedd9cab4 190 #define REG_PS3_DATA1 0x2B
stefanrousseau 4:f83bedd9cab4 191 #define REG_UVINDEX0 0x2C
stefanrousseau 4:f83bedd9cab4 192 #define REG_UVINDEX1 0x2D
stefanrousseau 4:f83bedd9cab4 193 int Si1145_ParamSet(unsigned char address, unsigned char value) //writes 'value' into Parameter 'address'
stefanrousseau 4:f83bedd9cab4 194 {
stefanrousseau 4:f83bedd9cab4 195 char txbuffer [3];
stefanrousseau 4:f83bedd9cab4 196 txbuffer[0] = (char)REG_PARAM_WR; //destination
stefanrousseau 4:f83bedd9cab4 197 txbuffer[1] = (char)value;
stefanrousseau 4:f83bedd9cab4 198 txbuffer[2] = (char)(0xA0 + (address & 0x1F));
stefanrousseau 4:f83bedd9cab4 199 int retval;
stefanrousseau 4:f83bedd9cab4 200 //if((retval = _waitUntilSleep(si114x_handle))!=0) return retval;
stefanrousseau 4:f83bedd9cab4 201 retval = I2C_WriteMultipleBytes(Si1145_PMOD_I2C_ADDR, &txbuffer[0], 3, true);
stefanrousseau 4:f83bedd9cab4 202 if(retval!=0) return retval;
stefanrousseau 4:f83bedd9cab4 203 while(1)
stefanrousseau 4:f83bedd9cab4 204 {
stefanrousseau 4:f83bedd9cab4 205 retval=ReadFrom_Si1145_Register(REG_PARAM_RD);
stefanrousseau 4:f83bedd9cab4 206 if (retval==value) break;
stefanrousseau 4:f83bedd9cab4 207 }
stefanrousseau 4:f83bedd9cab4 208 return (0);
stefanrousseau 4:f83bedd9cab4 209 } //Si1145_ParamSet()
stefanrousseau 4:f83bedd9cab4 210
stefanrousseau 4:f83bedd9cab4 211 void PsAlsForce(void) //equivalent to WriteTo_Si1145_Register(REG_COMMAND,0x07). This forces PS and ALS measurements
stefanrousseau 4:f83bedd9cab4 212 {
stefanrousseau 4:f83bedd9cab4 213 WriteTo_Si1145_Register(REG_COMMAND,0x07);
stefanrousseau 4:f83bedd9cab4 214 } //PsAlsForce()
stefanrousseau 4:f83bedd9cab4 215
stefanrousseau 4:f83bedd9cab4 216 bool bSi1145_present = false;
stefanrousseau 4:f83bedd9cab4 217 void Init_Si1145(void)
stefanrousseau 4:f83bedd9cab4 218 {
stefanrousseau 4:f83bedd9cab4 219 unsigned char readbyte;
stefanrousseau 4:f83bedd9cab4 220 //Read Si1145 part ID:
stefanrousseau 4:f83bedd9cab4 221 readbyte = ReadFrom_Si1145_Register(0x00);
stefanrousseau 4:f83bedd9cab4 222 if (readbyte != 0x45)
stefanrousseau 4:f83bedd9cab4 223 {
stefanrousseau 4:f83bedd9cab4 224 bSi1145_present = false;
stefanrousseau 4:f83bedd9cab4 225 printf("Si1145 sensor not found\n");
stefanrousseau 4:f83bedd9cab4 226 }
stefanrousseau 4:f83bedd9cab4 227 else
stefanrousseau 4:f83bedd9cab4 228 {
stefanrousseau 4:f83bedd9cab4 229 bSi1145_present = true;
stefanrousseau 4:f83bedd9cab4 230 printf("Si1145 Part ID : 0x%02X\n", readbyte);
stefanrousseau 4:f83bedd9cab4 231 //Initialize Si1145 by writing to HW_KEY (I2C Register 0x07 = 0x17)
stefanrousseau 4:f83bedd9cab4 232 WriteTo_Si1145_Register(REG_HW_KEY, HW_KEY_VAL0);
stefanrousseau 4:f83bedd9cab4 233
stefanrousseau 4:f83bedd9cab4 234 // Initialize LED Current
stefanrousseau 4:f83bedd9cab4 235 // I2C Register 0x0F = 0xFF
stefanrousseau 4:f83bedd9cab4 236 // I2C Register 0x10 = 0x0F
stefanrousseau 4:f83bedd9cab4 237 WriteTo_Si1145_Register(REG_PS_LED21,(MAX_LED_CURRENT<<4) + MAX_LED_CURRENT);
stefanrousseau 4:f83bedd9cab4 238 WriteTo_Si1145_Register(REG_PS_LED3, MAX_LED_CURRENT);
stefanrousseau 4:f83bedd9cab4 239
stefanrousseau 4:f83bedd9cab4 240 // Parameter 0x01 = 0x37
stefanrousseau 4:f83bedd9cab4 241 //Si1145_ParamSet(PARAM_CH_LIST, ALS_IR_TASK + ALS_VIS_TASK + PS1_TASK + PS2_TASK + PS3_TASK);
stefanrousseau 4:f83bedd9cab4 242 //Si1145_ParamSet(0x01, 0x37); //CHLIST is address 0x01 in the parameter RAM. It defines which sensors are enabled (here, some)
stefanrousseau 4:f83bedd9cab4 243 Si1145_ParamSet(0x01, 0x7F); //CHLIST is address 0x01 in the parameter RAM. It defines which sensors are enabled (here, all but UV. One can only use AUX or UV but here we use AUX because UV does not work...)
stefanrousseau 4:f83bedd9cab4 244 // I2C Register 0x18 = 0x0x07 //This is PSALS_FORCE to the Command register => Force a single PS (proximity sensor) and ALS (ambient light sensor) reading - The factory code has this as 0x05 which only does PS...
stefanrousseau 4:f83bedd9cab4 245 PsAlsForce(); // can also be written as WriteTo_Si1145_Register(REG_COMMAND,0x07);
stefanrousseau 4:f83bedd9cab4 246 WriteTo_Si1145_Register(REG_COMMAND, 0x0F);//command to put it into auto mode
stefanrousseau 4:f83bedd9cab4 247 //Set MES_RATE to 0x1000. I.e. the device will automatically wake up every 16 * 256* 31.25 us = 0.128 seconds to measure
stefanrousseau 4:f83bedd9cab4 248 WriteTo_Si1145_Register(REG_MEAS_RATE_LSB, 0x00);
stefanrousseau 4:f83bedd9cab4 249 WriteTo_Si1145_Register(REG_MEAS_RATE_MSB, 0x10);
stefanrousseau 4:f83bedd9cab4 250 } //bSi1145_present = true
stefanrousseau 4:f83bedd9cab4 251 } //Init_Si1145()
stefanrousseau 4:f83bedd9cab4 252
stefanrousseau 4:f83bedd9cab4 253 void Read_Si1145(void)
stefanrousseau 4:f83bedd9cab4 254 {
stefanrousseau 4:f83bedd9cab4 255 if (bSi1145_present)
stefanrousseau 4:f83bedd9cab4 256 {
stefanrousseau 4:f83bedd9cab4 257 // Once the measurements are completed, here is how to reconstruct them
stefanrousseau 4:f83bedd9cab4 258 // Note very carefully that 16-bit registers are in the 'Little Endian' byte order
stefanrousseau 4:f83bedd9cab4 259 // It may be more efficient to perform block I2C Reads, but this example shows
stefanrousseau 4:f83bedd9cab4 260 // individual reads of registers
stefanrousseau 4:f83bedd9cab4 261
stefanrousseau 4:f83bedd9cab4 262 int PS1 = ReadFrom_Si1145_Register(REG_PS1_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS1_DATA1);
stefanrousseau 4:f83bedd9cab4 263 int PS2 = ReadFrom_Si1145_Register(REG_PS2_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS2_DATA1);
stefanrousseau 4:f83bedd9cab4 264 int PS3 = ReadFrom_Si1145_Register(REG_PS3_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS3_DATA1);
stefanrousseau 4:f83bedd9cab4 265 //printf("PS1_Data = %d\n", PS1);
stefanrousseau 4:f83bedd9cab4 266 //printf("PS2_Data = %d\n", PS2);
stefanrousseau 4:f83bedd9cab4 267 //printf("PS3_Data = %d\n", PS3);
stefanrousseau 4:f83bedd9cab4 268 //OBJECT PRESENT?
stefanrousseau 4:f83bedd9cab4 269 if(PS1 < 22000){
stefanrousseau 4:f83bedd9cab4 270 //printf("Object Far\n");
stefanrousseau 4:f83bedd9cab4 271 sprintf(SENSOR_DATA.Proximity, "Object Far");
stefanrousseau 4:f83bedd9cab4 272 }
stefanrousseau 4:f83bedd9cab4 273 else if(PS1 < 24000)
stefanrousseau 4:f83bedd9cab4 274 {
stefanrousseau 4:f83bedd9cab4 275 //printf("Object in Vicinity\n");
stefanrousseau 4:f83bedd9cab4 276 sprintf(SENSOR_DATA.Proximity, "Object in Vicinity");
stefanrousseau 4:f83bedd9cab4 277 }
stefanrousseau 4:f83bedd9cab4 278 else if (PS1 < 30000)
stefanrousseau 4:f83bedd9cab4 279 {
stefanrousseau 4:f83bedd9cab4 280 //printf("Object Near\n");
stefanrousseau 4:f83bedd9cab4 281 sprintf(SENSOR_DATA.Proximity, "Object Near");
stefanrousseau 4:f83bedd9cab4 282 }
stefanrousseau 4:f83bedd9cab4 283 else
stefanrousseau 4:f83bedd9cab4 284 {
stefanrousseau 4:f83bedd9cab4 285 //printf("Object Very Near\n");
stefanrousseau 4:f83bedd9cab4 286 sprintf(SENSOR_DATA.Proximity, "Object Very Near");
stefanrousseau 4:f83bedd9cab4 287 }
stefanrousseau 4:f83bedd9cab4 288
stefanrousseau 4:f83bedd9cab4 289 //Force ALS read:
stefanrousseau 4:f83bedd9cab4 290 //WriteTo_Si1145_Register(REG_COMMAND, 0x06);
stefanrousseau 4:f83bedd9cab4 291 //wait (0.1);
stefanrousseau 4:f83bedd9cab4 292 int ALS_VIS = ReadFrom_Si1145_Register(REG_ALS_VIS_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_VIS_DATA1);
stefanrousseau 4:f83bedd9cab4 293 int ALS_IR = ReadFrom_Si1145_Register(REG_ALS_IR_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_IR_DATA1);
stefanrousseau 4:f83bedd9cab4 294 int UV_INDEX = ReadFrom_Si1145_Register(REG_UVINDEX0) + 256 * ReadFrom_Si1145_Register(REG_UVINDEX1);
stefanrousseau 4:f83bedd9cab4 295 //printf("ALS_VIS_Data = %d\n", ALS_VIS);
stefanrousseau 4:f83bedd9cab4 296 //printf("ALS_IR_Data = %d\n", ALS_IR);
stefanrousseau 4:f83bedd9cab4 297 //printf("UV_INDEX_Data = %d\n", UV_INDEX);
stefanrousseau 4:f83bedd9cab4 298
stefanrousseau 4:f83bedd9cab4 299 //printf("Ambient Light Visible Sensor = %d\n", ALS_VIS);
stefanrousseau 4:f83bedd9cab4 300 sprintf(SENSOR_DATA.AmbientLightVis, "%d", ALS_VIS);
stefanrousseau 4:f83bedd9cab4 301 //printf("Ambient Light Infrared Sensor = %d\n", ALS_IR);
stefanrousseau 4:f83bedd9cab4 302 sprintf(SENSOR_DATA.AmbientLightIr, "%d", ALS_IR);
stefanrousseau 4:f83bedd9cab4 303 //float fUV_value = (UV_INDEX -50.0)/10000.0;
stefanrousseau 4:f83bedd9cab4 304 float fUV_value = (UV_INDEX)/100.0; //this is the aux reading
stefanrousseau 4:f83bedd9cab4 305 //printf("UV_Data = %0.2f\n", fUV_value);
stefanrousseau 4:f83bedd9cab4 306 sprintf(SENSOR_DATA.UVindex, "%0.2f", fUV_value);
stefanrousseau 4:f83bedd9cab4 307 } //bSi1145_present = true
stefanrousseau 4:f83bedd9cab4 308 } //Read_Si1145()
stefanrousseau 4:f83bedd9cab4 309
stefanrousseau 4:f83bedd9cab4 310 //********************************************************************************************************************************************
stefanrousseau 4:f83bedd9cab4 311 //* Read the FXOS8700CQ - 6-axis combo Sensor Accelerometer and Magnetometer
stefanrousseau 4:f83bedd9cab4 312 //********************************************************************************************************************************************
stefanrousseau 4:f83bedd9cab4 313 void read_motion_sensor()
stefanrousseau 4:f83bedd9cab4 314 {
stefanrousseau 4:f83bedd9cab4 315 fxos.get_data(&accel_data, &magn_data);
stefanrousseau 4:f83bedd9cab4 316 //printf("Roll=%5d, Pitch=%5d, Yaw=%5d;\r\n", magn_data.x, magn_data.y, magn_data.z);
stefanrousseau 4:f83bedd9cab4 317 sprintf(SENSOR_DATA.MagnetometerX, "%5d", magn_data.x);
stefanrousseau 4:f83bedd9cab4 318 sprintf(SENSOR_DATA.MagnetometerY, "%5d", magn_data.y);
stefanrousseau 4:f83bedd9cab4 319 sprintf(SENSOR_DATA.MagnetometerZ, "%5d", magn_data.z);
stefanrousseau 4:f83bedd9cab4 320
stefanrousseau 4:f83bedd9cab4 321 //Try to normalize (/2048) the values so they will match the eCompass output:
stefanrousseau 4:f83bedd9cab4 322 float fAccelScaled_x, fAccelScaled_y, fAccelScaled_z;
stefanrousseau 4:f83bedd9cab4 323 fAccelScaled_x = (accel_data.x/2048.0);
stefanrousseau 4:f83bedd9cab4 324 fAccelScaled_y = (accel_data.y/2048.0);
stefanrousseau 4:f83bedd9cab4 325 fAccelScaled_z = (accel_data.z/2048.0);
stefanrousseau 4:f83bedd9cab4 326 //printf("Acc: X=%2.3f Y=%2.3f Z=%2.3f;\r\n", fAccelScaled_x, fAccelScaled_y, fAccelScaled_z);
stefanrousseau 4:f83bedd9cab4 327 sprintf(SENSOR_DATA.AccelX, "%2.3f", fAccelScaled_x);
stefanrousseau 4:f83bedd9cab4 328 sprintf(SENSOR_DATA.AccelY, "%2.3f", fAccelScaled_y);
stefanrousseau 4:f83bedd9cab4 329 sprintf(SENSOR_DATA.AccelZ, "%2.3f", fAccelScaled_z);
stefanrousseau 4:f83bedd9cab4 330 } //read_motion_sensor
stefanrousseau 4:f83bedd9cab4 331
stefanrousseau 4:f83bedd9cab4 332 void init_motion_sensor()
stefanrousseau 4:f83bedd9cab4 333 {
stefanrousseau 4:f83bedd9cab4 334 printf("FXOS8700CQ WhoAmI = %X\r\n", fxos.get_whoami());
stefanrousseau 4:f83bedd9cab4 335 // Iterrupt for active-low interrupt line from FXOS
stefanrousseau 4:f83bedd9cab4 336 // Configured with only one interrupt on INT2 signaling Data-Ready
stefanrousseau 4:f83bedd9cab4 337 //fxos_int2.fall(&trigger_fxos_int2);
stefanrousseau 4:f83bedd9cab4 338 fxos.enable();
stefanrousseau 4:f83bedd9cab4 339 } //init_motion_sensor
stefanrousseau 4:f83bedd9cab4 340
stefanrousseau 4:f83bedd9cab4 341 void sensors_init(void)
stefanrousseau 4:f83bedd9cab4 342 {
stefanrousseau 4:f83bedd9cab4 343 Init_Si7020();
stefanrousseau 4:f83bedd9cab4 344 Init_Si1145();
stefanrousseau 4:f83bedd9cab4 345 init_motion_sensor();
stefanrousseau 4:f83bedd9cab4 346 } //sensors_init
stefanrousseau 4:f83bedd9cab4 347
stefanrousseau 4:f83bedd9cab4 348 void read_sensors(void)
stefanrousseau 4:f83bedd9cab4 349 {
stefanrousseau 4:f83bedd9cab4 350 Read_Si7020();
stefanrousseau 4:f83bedd9cab4 351 Read_Si1145();
stefanrousseau 4:f83bedd9cab4 352 read_motion_sensor();
stefanrousseau 4:f83bedd9cab4 353 } //read_sensors