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:
fkellermavnet
Date:
Thu Aug 11 00:03:09 2016 +0000
Revision:
68:6e311c747045
Parent:
64:09004cd610df
Child:
69:5a3414cc7531
Added Avnet copyright headers on all source files.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fkellermavnet 68:6e311c747045 1 /* ===================================================================
fkellermavnet 68:6e311c747045 2 Copyright © 2016, AVNET Inc.
fkellermavnet 68:6e311c747045 3
fkellermavnet 68:6e311c747045 4 Licensed under the Apache License, Version 2.0 (the "License");
fkellermavnet 68:6e311c747045 5 you may not use this file except in compliance with the License.
fkellermavnet 68:6e311c747045 6 You may obtain a copy of the License at
fkellermavnet 68:6e311c747045 7
fkellermavnet 68:6e311c747045 8 http://www.apache.org/licenses/LICENSE-2.0
fkellermavnet 68:6e311c747045 9
fkellermavnet 68:6e311c747045 10 Unless required by applicable law or agreed to in writing,
fkellermavnet 68:6e311c747045 11 software distributed under the License is distributed on an
fkellermavnet 68:6e311c747045 12 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
fkellermavnet 68:6e311c747045 13 either express or implied. See the License for the specific
fkellermavnet 68:6e311c747045 14 language governing permissions and limitations under the License.
fkellermavnet 68:6e311c747045 15
fkellermavnet 68:6e311c747045 16 ======================================================================== */
fkellermavnet 68:6e311c747045 17
stefanrousseau 4:f83bedd9cab4 18 #include "mbed.h"
stefanrousseau 57:d184175b6b03 19 #include "sensors.h"
stefanrousseau 55:3abf9e3f42e6 20 #include "hardware.h"
stefanrousseau 57:d184175b6b03 21 #include "FXOS8700CQ.h"
stefanrousseau 61:f6b93129f954 22 #include "HTS221.h"
stefanrousseau 61:f6b93129f954 23 #include <string>
stefanrousseau 4:f83bedd9cab4 24
stefanrousseau 4:f83bedd9cab4 25 //I2C for pmod sensors:
stefanrousseau 4:f83bedd9cab4 26 #define Si1145_PMOD_I2C_ADDR 0xC0 //this is for 7-bit addr 0x60 for the Si7020
stefanrousseau 4:f83bedd9cab4 27 #define Si7020_PMOD_I2C_ADDR 0x80 //this is for 7-bit addr 0x4 for the Si7020
stefanrousseau 4:f83bedd9cab4 28
stefanrousseau 57:d184175b6b03 29 // Storage for the data from the motion sensor
stefanrousseau 4:f83bedd9cab4 30 SRAWDATA accel_data;
stefanrousseau 4:f83bedd9cab4 31 SRAWDATA magn_data;
stefanrousseau 4:f83bedd9cab4 32 //InterruptIn fxos_int1(PTC6); // unused, common with SW2 on FRDM-K64F
stefanrousseau 4:f83bedd9cab4 33 InterruptIn fxos_int2(PTC13); // should just be the Data-Ready interrupt
stefanrousseau 4:f83bedd9cab4 34 bool fxos_int2_triggered = false;
stefanrousseau 4:f83bedd9cab4 35 void trigger_fxos_int2(void)
stefanrousseau 4:f83bedd9cab4 36 {
stefanrousseau 4:f83bedd9cab4 37 fxos_int2_triggered = true;
stefanrousseau 57:d184175b6b03 38
stefanrousseau 4:f83bedd9cab4 39 }
stefanrousseau 4:f83bedd9cab4 40
stefanrousseau 4:f83bedd9cab4 41 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 42 * Perform I2C single read.
stefanrousseau 4:f83bedd9cab4 43 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 44 unsigned char I2C_ReadSingleByte(unsigned char ucDeviceAddress)
stefanrousseau 4:f83bedd9cab4 45 {
stefanrousseau 4:f83bedd9cab4 46 char rxbuffer [1];
stefanrousseau 11:e6602513730f 47 i2c.read(ucDeviceAddress, rxbuffer, 1 );
stefanrousseau 4:f83bedd9cab4 48 return (unsigned char)rxbuffer[0];
stefanrousseau 4:f83bedd9cab4 49 } //I2C_ReadSingleByte()
stefanrousseau 4:f83bedd9cab4 50
stefanrousseau 4:f83bedd9cab4 51 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 52 * Perform I2C single read from address.
stefanrousseau 4:f83bedd9cab4 53 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 54 unsigned char I2C_ReadSingleByteFromAddr(unsigned char ucDeviceAddress, unsigned char Addr)
stefanrousseau 4:f83bedd9cab4 55 {
stefanrousseau 4:f83bedd9cab4 56 char txbuffer [1];
stefanrousseau 4:f83bedd9cab4 57 char rxbuffer [1];
stefanrousseau 4:f83bedd9cab4 58 txbuffer[0] = (char)Addr;
stefanrousseau 11:e6602513730f 59 i2c.write(ucDeviceAddress, txbuffer, 1 );
stefanrousseau 11:e6602513730f 60 i2c.read(ucDeviceAddress, rxbuffer, 1 );
stefanrousseau 4:f83bedd9cab4 61 return (unsigned char)rxbuffer[0];
stefanrousseau 4:f83bedd9cab4 62 } //I2C_ReadSingleByteFromAddr()
stefanrousseau 4:f83bedd9cab4 63
stefanrousseau 4:f83bedd9cab4 64 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 65 * Perform I2C read of more than 1 byte.
stefanrousseau 4:f83bedd9cab4 66 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 67 int I2C_ReadMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength)
stefanrousseau 4:f83bedd9cab4 68 {
stefanrousseau 4:f83bedd9cab4 69 int status;
stefanrousseau 11:e6602513730f 70 status = i2c.read(ucDeviceAddress, ucData, ucLength);
stefanrousseau 4:f83bedd9cab4 71 return status;
stefanrousseau 4:f83bedd9cab4 72 } //I2C_ReadMultipleBytes()
stefanrousseau 4:f83bedd9cab4 73
stefanrousseau 4:f83bedd9cab4 74 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 75 * Perform I2C write of a single byte.
stefanrousseau 4:f83bedd9cab4 76 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 77 int I2C_WriteSingleByte(unsigned char ucDeviceAddress, unsigned char Data, bool bSendStop)
stefanrousseau 4:f83bedd9cab4 78 {
stefanrousseau 4:f83bedd9cab4 79 int status;
stefanrousseau 4:f83bedd9cab4 80 char txbuffer [1];
stefanrousseau 4:f83bedd9cab4 81 txbuffer[0] = (char)Data; //data
stefanrousseau 11:e6602513730f 82 status = i2c.write(ucDeviceAddress, txbuffer, 1, !bSendStop); //true: do not send stop
stefanrousseau 4:f83bedd9cab4 83 return status;
stefanrousseau 4:f83bedd9cab4 84 } //I2C_WriteSingleByte()
stefanrousseau 4:f83bedd9cab4 85
stefanrousseau 4:f83bedd9cab4 86 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 87 * Perform I2C write of 1 byte to an address.
stefanrousseau 4:f83bedd9cab4 88 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 89 int I2C_WriteSingleByteToAddr(unsigned char ucDeviceAddress, unsigned char Addr, unsigned char Data, bool bSendStop)
stefanrousseau 4:f83bedd9cab4 90 {
stefanrousseau 4:f83bedd9cab4 91 int status;
stefanrousseau 4:f83bedd9cab4 92 char txbuffer [2];
stefanrousseau 4:f83bedd9cab4 93 txbuffer[0] = (char)Addr; //address
stefanrousseau 4:f83bedd9cab4 94 txbuffer[1] = (char)Data; //data
stefanrousseau 11:e6602513730f 95 //status = i2c.write(ucDeviceAddress, txbuffer, 2, false); //stop at end
stefanrousseau 11:e6602513730f 96 status = i2c.write(ucDeviceAddress, txbuffer, 2, !bSendStop); //true: do not send stop
stefanrousseau 4:f83bedd9cab4 97 return status;
stefanrousseau 4:f83bedd9cab4 98 } //I2C_WriteSingleByteToAddr()
stefanrousseau 4:f83bedd9cab4 99
stefanrousseau 4:f83bedd9cab4 100 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 101 * Perform I2C write of more than 1 byte.
stefanrousseau 4:f83bedd9cab4 102 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 103 int I2C_WriteMultipleBytes(unsigned char ucDeviceAddress, char *ucData, unsigned char ucLength, bool bSendStop)
stefanrousseau 4:f83bedd9cab4 104 {
stefanrousseau 4:f83bedd9cab4 105 int status;
stefanrousseau 11:e6602513730f 106 status = i2c.write(ucDeviceAddress, ucData, ucLength, !bSendStop); //true: do not send stop
stefanrousseau 4:f83bedd9cab4 107 return status;
stefanrousseau 4:f83bedd9cab4 108 } //I2C_WriteMultipleBytes()
stefanrousseau 4:f83bedd9cab4 109
stefanrousseau 4:f83bedd9cab4 110 bool bSi7020_present = false;
stefanrousseau 4:f83bedd9cab4 111 void Init_Si7020(void)
stefanrousseau 4:f83bedd9cab4 112 {
stefanrousseau 4:f83bedd9cab4 113 char SN_7020 [8];
stefanrousseau 4:f83bedd9cab4 114 //SN part 1:
stefanrousseau 4:f83bedd9cab4 115 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFA, 0x0F, false);
stefanrousseau 4:f83bedd9cab4 116 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[0], 4);
stefanrousseau 4:f83bedd9cab4 117
stefanrousseau 4:f83bedd9cab4 118 //SN part 1:
stefanrousseau 4:f83bedd9cab4 119 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0xFC, 0xC9, false);
stefanrousseau 4:f83bedd9cab4 120 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &SN_7020[4], 4);
stefanrousseau 4:f83bedd9cab4 121
stefanrousseau 4:f83bedd9cab4 122 char Ver_7020 [2];
stefanrousseau 4:f83bedd9cab4 123 //FW version:
stefanrousseau 4:f83bedd9cab4 124 I2C_WriteSingleByteToAddr(Si7020_PMOD_I2C_ADDR, 0x84, 0xB8, false);
stefanrousseau 4:f83bedd9cab4 125 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Ver_7020[0], 2);
stefanrousseau 4:f83bedd9cab4 126
stefanrousseau 4:f83bedd9cab4 127 if (SN_7020[4] != 0x14)
stefanrousseau 4:f83bedd9cab4 128 {
stefanrousseau 4:f83bedd9cab4 129 bSi7020_present = false;
stefanrousseau 64:09004cd610df 130 PRINTF("Si7020 sensor not found\n");
stefanrousseau 4:f83bedd9cab4 131 }
stefanrousseau 4:f83bedd9cab4 132 else
stefanrousseau 4:f83bedd9cab4 133 {
stefanrousseau 4:f83bedd9cab4 134 bSi7020_present = true;
stefanrousseau 64:09004cd610df 135 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 64:09004cd610df 136 PRINTF("Si7020 Version# = 0x%02X\n", Ver_7020[0]);
stefanrousseau 4:f83bedd9cab4 137 } //bool bSi7020_present = true
stefanrousseau 4:f83bedd9cab4 138
stefanrousseau 4:f83bedd9cab4 139 } //Init_Si7020()
stefanrousseau 4:f83bedd9cab4 140
stefanrousseau 4:f83bedd9cab4 141 void Read_Si7020(void)
stefanrousseau 4:f83bedd9cab4 142 {
stefanrousseau 4:f83bedd9cab4 143 if (bSi7020_present)
stefanrousseau 4:f83bedd9cab4 144 {
stefanrousseau 4:f83bedd9cab4 145 char Humidity [2];
stefanrousseau 4:f83bedd9cab4 146 char Temperature [2];
stefanrousseau 4:f83bedd9cab4 147 //Command to measure humidity (temperature also gets measured):
stefanrousseau 4:f83bedd9cab4 148 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xF5, false); //no hold, must do dummy read
stefanrousseau 4:f83bedd9cab4 149 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 1); //dummy read, should get an nack until it is done
stefanrousseau 4:f83bedd9cab4 150 wait (0.05); //wait for measurement. Can also keep reading until no NACK is received
stefanrousseau 4:f83bedd9cab4 151 //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 152 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Humidity[0], 2); //read humidity
stefanrousseau 64:09004cd610df 153 //PRINTF("Read Si7020 Humidity = 0x%02X%02X\n", Humidity[0], Humidity[1]);
stefanrousseau 4:f83bedd9cab4 154 int rh_code = (Humidity[0] << 8) + Humidity[1];
stefanrousseau 4:f83bedd9cab4 155 float fRh = (125.0*rh_code/65536.0) - 6.0; //from datasheet
stefanrousseau 64:09004cd610df 156 //PRINTF("Si7020 Humidity = %*.*f %%\n", 4, 2, fRh); //double % sign for escape //PRINTF("%*.*f\n", myFieldWidth, myPrecision, myFloatValue);
stefanrousseau 4:f83bedd9cab4 157 sprintf(SENSOR_DATA.Humidity_Si7020, "%0.2f", fRh);
stefanrousseau 4:f83bedd9cab4 158
stefanrousseau 4:f83bedd9cab4 159 //Command to read temperature when humidity is already done:
stefanrousseau 4:f83bedd9cab4 160 I2C_WriteSingleByte(Si7020_PMOD_I2C_ADDR, 0xE0, false);
stefanrousseau 4:f83bedd9cab4 161 I2C_ReadMultipleBytes(Si7020_PMOD_I2C_ADDR, &Temperature[0], 2); //read temperature
stefanrousseau 64:09004cd610df 162 //PRINTF("Read Si7020 Temperature = 0x%02X%02X\n", Temperature[0], Temperature[1]);
stefanrousseau 4:f83bedd9cab4 163 int temp_code = (Temperature[0] << 8) + Temperature[1];
stefanrousseau 4:f83bedd9cab4 164 float fTemp = (175.72*temp_code/65536.0) - 46.85; //from datasheet in Celcius
stefanrousseau 64:09004cd610df 165 //PRINTF("Si7020 Temperature = %*.*f deg C\n", 4, 2, fTemp);
stefanrousseau 4:f83bedd9cab4 166 sprintf(SENSOR_DATA.Temperature_Si7020, "%0.2f", fTemp);
stefanrousseau 4:f83bedd9cab4 167 } //bool bSi7020_present = true
stefanrousseau 4:f83bedd9cab4 168
stefanrousseau 4:f83bedd9cab4 169 } //Read_Si7020()
stefanrousseau 4:f83bedd9cab4 170
stefanrousseau 4:f83bedd9cab4 171 /*------------------------------------------------------------------------------
stefanrousseau 4:f83bedd9cab4 172 * The following are aliases so that the Si1145 coding examples can be used as-is.
stefanrousseau 4:f83bedd9cab4 173 *------------------------------------------------------------------------------*/
stefanrousseau 4:f83bedd9cab4 174 unsigned char ReadFrom_Si1145_Register(unsigned char reg) //returns byte from I2C Register 'reg'
stefanrousseau 4:f83bedd9cab4 175 {
stefanrousseau 4:f83bedd9cab4 176 unsigned char result = I2C_ReadSingleByteFromAddr(Si1145_PMOD_I2C_ADDR, reg);
stefanrousseau 4:f83bedd9cab4 177 return (result);
stefanrousseau 4:f83bedd9cab4 178 } //ReadFrom_Si1145_Register()
stefanrousseau 4:f83bedd9cab4 179
stefanrousseau 4:f83bedd9cab4 180 void WriteTo_Si1145_Register(unsigned char reg, unsigned char value) //writes 'value' into I2C Register reg'
stefanrousseau 4:f83bedd9cab4 181 {
stefanrousseau 4:f83bedd9cab4 182 I2C_WriteSingleByteToAddr(Si1145_PMOD_I2C_ADDR, reg, value, true);
stefanrousseau 4:f83bedd9cab4 183 } //WriteTo_Si1145_Register()
stefanrousseau 4:f83bedd9cab4 184
stefanrousseau 4:f83bedd9cab4 185 #define REG_PARAM_WR 0x17
stefanrousseau 4:f83bedd9cab4 186 #define REG_PARAM_RD 0x2E
stefanrousseau 4:f83bedd9cab4 187 #define REG_COMMAND 0x18
stefanrousseau 4:f83bedd9cab4 188 #define REG_RESPONSE 0x20
stefanrousseau 4:f83bedd9cab4 189 #define REG_HW_KEY 0x07
stefanrousseau 4:f83bedd9cab4 190 #define HW_KEY_VAL0 0x17
stefanrousseau 4:f83bedd9cab4 191 #define REG_MEAS_RATE_LSB 0x08
stefanrousseau 4:f83bedd9cab4 192 #define REG_MEAS_RATE_MSB 0x09
stefanrousseau 4:f83bedd9cab4 193 #define REG_PS_LED21 0x0F
stefanrousseau 4:f83bedd9cab4 194 #define REG_PS_LED3 0x10
stefanrousseau 4:f83bedd9cab4 195 #define MAX_LED_CURRENT 0xF
stefanrousseau 4:f83bedd9cab4 196 #define PARAM_CH_LIST 0x01
stefanrousseau 4:f83bedd9cab4 197 #define REG_ALS_VIS_DATA0 0x22
stefanrousseau 4:f83bedd9cab4 198 #define REG_ALS_VIS_DATA1 0x23
stefanrousseau 4:f83bedd9cab4 199 #define REG_ALS_IR_DATA0 0x24
stefanrousseau 4:f83bedd9cab4 200 #define REG_ALS_IR_DATA1 0x25
stefanrousseau 4:f83bedd9cab4 201 #define REG_PS1_DATA0 0x26
stefanrousseau 4:f83bedd9cab4 202 #define REG_PS1_DATA1 0x27
stefanrousseau 4:f83bedd9cab4 203 #define REG_PS2_DATA0 0x28
stefanrousseau 4:f83bedd9cab4 204 #define REG_PS2_DATA1 0x29
stefanrousseau 4:f83bedd9cab4 205 #define REG_PS3_DATA0 0x2A
stefanrousseau 4:f83bedd9cab4 206 #define REG_PS3_DATA1 0x2B
stefanrousseau 4:f83bedd9cab4 207 #define REG_UVINDEX0 0x2C
stefanrousseau 4:f83bedd9cab4 208 #define REG_UVINDEX1 0x2D
stefanrousseau 4:f83bedd9cab4 209 int Si1145_ParamSet(unsigned char address, unsigned char value) //writes 'value' into Parameter 'address'
stefanrousseau 4:f83bedd9cab4 210 {
stefanrousseau 4:f83bedd9cab4 211 char txbuffer [3];
stefanrousseau 4:f83bedd9cab4 212 txbuffer[0] = (char)REG_PARAM_WR; //destination
stefanrousseau 4:f83bedd9cab4 213 txbuffer[1] = (char)value;
stefanrousseau 4:f83bedd9cab4 214 txbuffer[2] = (char)(0xA0 + (address & 0x1F));
stefanrousseau 4:f83bedd9cab4 215 int retval;
stefanrousseau 4:f83bedd9cab4 216 //if((retval = _waitUntilSleep(si114x_handle))!=0) return retval;
stefanrousseau 4:f83bedd9cab4 217 retval = I2C_WriteMultipleBytes(Si1145_PMOD_I2C_ADDR, &txbuffer[0], 3, true);
stefanrousseau 4:f83bedd9cab4 218 if(retval!=0) return retval;
stefanrousseau 4:f83bedd9cab4 219 while(1)
stefanrousseau 4:f83bedd9cab4 220 {
stefanrousseau 4:f83bedd9cab4 221 retval=ReadFrom_Si1145_Register(REG_PARAM_RD);
stefanrousseau 4:f83bedd9cab4 222 if (retval==value) break;
stefanrousseau 4:f83bedd9cab4 223 }
stefanrousseau 4:f83bedd9cab4 224 return (0);
stefanrousseau 4:f83bedd9cab4 225 } //Si1145_ParamSet()
stefanrousseau 4:f83bedd9cab4 226
stefanrousseau 4:f83bedd9cab4 227 void PsAlsForce(void) //equivalent to WriteTo_Si1145_Register(REG_COMMAND,0x07). This forces PS and ALS measurements
stefanrousseau 4:f83bedd9cab4 228 {
stefanrousseau 4:f83bedd9cab4 229 WriteTo_Si1145_Register(REG_COMMAND,0x07);
stefanrousseau 4:f83bedd9cab4 230 } //PsAlsForce()
stefanrousseau 4:f83bedd9cab4 231
stefanrousseau 4:f83bedd9cab4 232 bool bSi1145_present = false;
stefanrousseau 4:f83bedd9cab4 233 void Init_Si1145(void)
stefanrousseau 4:f83bedd9cab4 234 {
stefanrousseau 4:f83bedd9cab4 235 unsigned char readbyte;
stefanrousseau 4:f83bedd9cab4 236 //Read Si1145 part ID:
stefanrousseau 4:f83bedd9cab4 237 readbyte = ReadFrom_Si1145_Register(0x00);
stefanrousseau 4:f83bedd9cab4 238 if (readbyte != 0x45)
stefanrousseau 4:f83bedd9cab4 239 {
stefanrousseau 4:f83bedd9cab4 240 bSi1145_present = false;
stefanrousseau 64:09004cd610df 241 PRINTF("Si1145 sensor not found\n");
stefanrousseau 4:f83bedd9cab4 242 }
stefanrousseau 4:f83bedd9cab4 243 else
stefanrousseau 4:f83bedd9cab4 244 {
stefanrousseau 4:f83bedd9cab4 245 bSi1145_present = true;
stefanrousseau 64:09004cd610df 246 PRINTF("Si1145 Part ID : 0x%02X\n", readbyte);
stefanrousseau 4:f83bedd9cab4 247 //Initialize Si1145 by writing to HW_KEY (I2C Register 0x07 = 0x17)
stefanrousseau 4:f83bedd9cab4 248 WriteTo_Si1145_Register(REG_HW_KEY, HW_KEY_VAL0);
stefanrousseau 4:f83bedd9cab4 249
stefanrousseau 4:f83bedd9cab4 250 // Initialize LED Current
stefanrousseau 4:f83bedd9cab4 251 // I2C Register 0x0F = 0xFF
stefanrousseau 4:f83bedd9cab4 252 // I2C Register 0x10 = 0x0F
stefanrousseau 4:f83bedd9cab4 253 WriteTo_Si1145_Register(REG_PS_LED21,(MAX_LED_CURRENT<<4) + MAX_LED_CURRENT);
stefanrousseau 4:f83bedd9cab4 254 WriteTo_Si1145_Register(REG_PS_LED3, MAX_LED_CURRENT);
stefanrousseau 4:f83bedd9cab4 255
stefanrousseau 4:f83bedd9cab4 256 // Parameter 0x01 = 0x37
stefanrousseau 4:f83bedd9cab4 257 //Si1145_ParamSet(PARAM_CH_LIST, ALS_IR_TASK + ALS_VIS_TASK + PS1_TASK + PS2_TASK + PS3_TASK);
stefanrousseau 4:f83bedd9cab4 258 //Si1145_ParamSet(0x01, 0x37); //CHLIST is address 0x01 in the parameter RAM. It defines which sensors are enabled (here, some)
stefanrousseau 4:f83bedd9cab4 259 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 260 // 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 261 PsAlsForce(); // can also be written as WriteTo_Si1145_Register(REG_COMMAND,0x07);
stefanrousseau 4:f83bedd9cab4 262 WriteTo_Si1145_Register(REG_COMMAND, 0x0F);//command to put it into auto mode
stefanrousseau 4:f83bedd9cab4 263 //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 264 WriteTo_Si1145_Register(REG_MEAS_RATE_LSB, 0x00);
stefanrousseau 4:f83bedd9cab4 265 WriteTo_Si1145_Register(REG_MEAS_RATE_MSB, 0x10);
stefanrousseau 4:f83bedd9cab4 266 } //bSi1145_present = true
stefanrousseau 4:f83bedd9cab4 267 } //Init_Si1145()
stefanrousseau 4:f83bedd9cab4 268
stefanrousseau 4:f83bedd9cab4 269 void Read_Si1145(void)
stefanrousseau 4:f83bedd9cab4 270 {
stefanrousseau 4:f83bedd9cab4 271 if (bSi1145_present)
stefanrousseau 4:f83bedd9cab4 272 {
stefanrousseau 4:f83bedd9cab4 273 // Once the measurements are completed, here is how to reconstruct them
stefanrousseau 4:f83bedd9cab4 274 // Note very carefully that 16-bit registers are in the 'Little Endian' byte order
stefanrousseau 4:f83bedd9cab4 275 // It may be more efficient to perform block I2C Reads, but this example shows
stefanrousseau 4:f83bedd9cab4 276 // individual reads of registers
stefanrousseau 4:f83bedd9cab4 277
stefanrousseau 4:f83bedd9cab4 278 int PS1 = ReadFrom_Si1145_Register(REG_PS1_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS1_DATA1);
stefanrousseau 4:f83bedd9cab4 279 int PS2 = ReadFrom_Si1145_Register(REG_PS2_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS2_DATA1);
stefanrousseau 4:f83bedd9cab4 280 int PS3 = ReadFrom_Si1145_Register(REG_PS3_DATA0) + 256 * ReadFrom_Si1145_Register(REG_PS3_DATA1);
stefanrousseau 64:09004cd610df 281 //PRINTF("PS1_Data = %d\n", PS1);
stefanrousseau 64:09004cd610df 282 //PRINTF("PS2_Data = %d\n", PS2);
stefanrousseau 64:09004cd610df 283 //PRINTF("PS3_Data = %d\n", PS3);
stefanrousseau 4:f83bedd9cab4 284 //OBJECT PRESENT?
stefanrousseau 57:d184175b6b03 285 #if (0)
stefanrousseau 4:f83bedd9cab4 286 if(PS1 < 22000){
stefanrousseau 64:09004cd610df 287 //PRINTF("Object Far\n");
stefanrousseau 57:d184175b6b03 288 sprintf(SENSOR_DATA.Proximity, "Object Far\0");
stefanrousseau 4:f83bedd9cab4 289 }
stefanrousseau 4:f83bedd9cab4 290 else if(PS1 < 24000)
stefanrousseau 4:f83bedd9cab4 291 {
stefanrousseau 64:09004cd610df 292 //PRINTF("Object in Vicinity\n");
stefanrousseau 57:d184175b6b03 293 sprintf(SENSOR_DATA.Proximity, "Object in Vicinity\0");
stefanrousseau 4:f83bedd9cab4 294 }
stefanrousseau 4:f83bedd9cab4 295 else if (PS1 < 30000)
stefanrousseau 4:f83bedd9cab4 296 {
stefanrousseau 64:09004cd610df 297 //PRINTF("Object Near\n");
stefanrousseau 57:d184175b6b03 298 sprintf(SENSOR_DATA.Proximity, "Object Near\0");
stefanrousseau 4:f83bedd9cab4 299 }
stefanrousseau 4:f83bedd9cab4 300 else
stefanrousseau 4:f83bedd9cab4 301 {
stefanrousseau 64:09004cd610df 302 //PRINTF("Object Very Near\n");
stefanrousseau 57:d184175b6b03 303 sprintf(SENSOR_DATA.Proximity, "Object Very Near\0");
stefanrousseau 4:f83bedd9cab4 304 }
stefanrousseau 57:d184175b6b03 305 #else
stefanrousseau 57:d184175b6b03 306 sprintf(SENSOR_DATA.Proximity, "%d\0", PS1);
stefanrousseau 57:d184175b6b03 307 #endif
stefanrousseau 4:f83bedd9cab4 308
stefanrousseau 4:f83bedd9cab4 309 //Force ALS read:
stefanrousseau 4:f83bedd9cab4 310 //WriteTo_Si1145_Register(REG_COMMAND, 0x06);
stefanrousseau 4:f83bedd9cab4 311 //wait (0.1);
stefanrousseau 4:f83bedd9cab4 312 int ALS_VIS = ReadFrom_Si1145_Register(REG_ALS_VIS_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_VIS_DATA1);
stefanrousseau 4:f83bedd9cab4 313 int ALS_IR = ReadFrom_Si1145_Register(REG_ALS_IR_DATA0) + 256 * ReadFrom_Si1145_Register(REG_ALS_IR_DATA1);
stefanrousseau 4:f83bedd9cab4 314 int UV_INDEX = ReadFrom_Si1145_Register(REG_UVINDEX0) + 256 * ReadFrom_Si1145_Register(REG_UVINDEX1);
stefanrousseau 64:09004cd610df 315 //PRINTF("ALS_VIS_Data = %d\n", ALS_VIS);
stefanrousseau 64:09004cd610df 316 //PRINTF("ALS_IR_Data = %d\n", ALS_IR);
stefanrousseau 64:09004cd610df 317 //PRINTF("UV_INDEX_Data = %d\n", UV_INDEX);
stefanrousseau 4:f83bedd9cab4 318
stefanrousseau 64:09004cd610df 319 //PRINTF("Ambient Light Visible Sensor = %d\n", ALS_VIS);
stefanrousseau 4:f83bedd9cab4 320 sprintf(SENSOR_DATA.AmbientLightVis, "%d", ALS_VIS);
stefanrousseau 64:09004cd610df 321 //PRINTF("Ambient Light Infrared Sensor = %d\n", ALS_IR);
stefanrousseau 4:f83bedd9cab4 322 sprintf(SENSOR_DATA.AmbientLightIr, "%d", ALS_IR);
stefanrousseau 4:f83bedd9cab4 323 //float fUV_value = (UV_INDEX -50.0)/10000.0;
stefanrousseau 4:f83bedd9cab4 324 float fUV_value = (UV_INDEX)/100.0; //this is the aux reading
stefanrousseau 64:09004cd610df 325 //PRINTF("UV_Data = %0.2f\n", fUV_value);
stefanrousseau 4:f83bedd9cab4 326 sprintf(SENSOR_DATA.UVindex, "%0.2f", fUV_value);
stefanrousseau 4:f83bedd9cab4 327 } //bSi1145_present = true
stefanrousseau 4:f83bedd9cab4 328 } //Read_Si1145()
stefanrousseau 4:f83bedd9cab4 329
stefanrousseau 4:f83bedd9cab4 330 //********************************************************************************************************************************************
stefanrousseau 4:f83bedd9cab4 331 //* Read the FXOS8700CQ - 6-axis combo Sensor Accelerometer and Magnetometer
stefanrousseau 4:f83bedd9cab4 332 //********************************************************************************************************************************************
stefanrousseau 11:e6602513730f 333 bool bMotionSensor_present = false;
stefanrousseau 61:f6b93129f954 334 void Init_motion_sensor()
stefanrousseau 4:f83bedd9cab4 335 {
stefanrousseau 57:d184175b6b03 336 // Note: this class is instantiated here because if it is statically declared, the cellular shield init kills the I2C bus...
stefanrousseau 57:d184175b6b03 337 // Class instantiation with pin names for the motion sensor on the FRDM-K64F board:
stefanrousseau 57:d184175b6b03 338 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1)
stefanrousseau 11:e6602513730f 339 int iWhoAmI = fxos.get_whoami();
stefanrousseau 57:d184175b6b03 340
stefanrousseau 64:09004cd610df 341 PRINTF("FXOS8700CQ WhoAmI = %X\r\n", iWhoAmI);
stefanrousseau 4:f83bedd9cab4 342 // Iterrupt for active-low interrupt line from FXOS
stefanrousseau 4:f83bedd9cab4 343 // Configured with only one interrupt on INT2 signaling Data-Ready
stefanrousseau 4:f83bedd9cab4 344 //fxos_int2.fall(&trigger_fxos_int2);
stefanrousseau 11:e6602513730f 345 if (iWhoAmI != 0xC7)
stefanrousseau 11:e6602513730f 346 {
stefanrousseau 11:e6602513730f 347 bMotionSensor_present = false;
stefanrousseau 64:09004cd610df 348 PRINTF("FXOS8700CQ motion sensor not found\n");
stefanrousseau 11:e6602513730f 349 }
stefanrousseau 11:e6602513730f 350 else
stefanrousseau 11:e6602513730f 351 {
stefanrousseau 11:e6602513730f 352 bMotionSensor_present = true;
stefanrousseau 11:e6602513730f 353 fxos.enable();
stefanrousseau 11:e6602513730f 354 }
stefanrousseau 61:f6b93129f954 355 } //Init_motion_sensor()
stefanrousseau 4:f83bedd9cab4 356
stefanrousseau 61:f6b93129f954 357 void Read_motion_sensor()
stefanrousseau 11:e6602513730f 358 {
stefanrousseau 57:d184175b6b03 359 // Note: this class is instantiated here because if it is statically declared, the cellular shield init kills the I2C bus...
stefanrousseau 57:d184175b6b03 360 // Class instantiation with pin names for the motion sensor on the FRDM-K64F board:
stefanrousseau 57:d184175b6b03 361 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1)
stefanrousseau 11:e6602513730f 362 if (bMotionSensor_present)
stefanrousseau 11:e6602513730f 363 {
stefanrousseau 57:d184175b6b03 364 fxos.enable();
stefanrousseau 11:e6602513730f 365 fxos.get_data(&accel_data, &magn_data);
stefanrousseau 64:09004cd610df 366 //PRINTF("Roll=%5d, Pitch=%5d, Yaw=%5d;\r\n", magn_data.x, magn_data.y, magn_data.z);
stefanrousseau 11:e6602513730f 367 sprintf(SENSOR_DATA.MagnetometerX, "%5d", magn_data.x);
stefanrousseau 11:e6602513730f 368 sprintf(SENSOR_DATA.MagnetometerY, "%5d", magn_data.y);
stefanrousseau 11:e6602513730f 369 sprintf(SENSOR_DATA.MagnetometerZ, "%5d", magn_data.z);
stefanrousseau 11:e6602513730f 370
stefanrousseau 11:e6602513730f 371 //Try to normalize (/2048) the values so they will match the eCompass output:
stefanrousseau 11:e6602513730f 372 float fAccelScaled_x, fAccelScaled_y, fAccelScaled_z;
stefanrousseau 11:e6602513730f 373 fAccelScaled_x = (accel_data.x/2048.0);
stefanrousseau 11:e6602513730f 374 fAccelScaled_y = (accel_data.y/2048.0);
stefanrousseau 11:e6602513730f 375 fAccelScaled_z = (accel_data.z/2048.0);
stefanrousseau 64:09004cd610df 376 //PRINTF("Acc: X=%2.3f Y=%2.3f Z=%2.3f;\r\n", fAccelScaled_x, fAccelScaled_y, fAccelScaled_z);
stefanrousseau 11:e6602513730f 377 sprintf(SENSOR_DATA.AccelX, "%2.3f", fAccelScaled_x);
stefanrousseau 11:e6602513730f 378 sprintf(SENSOR_DATA.AccelY, "%2.3f", fAccelScaled_y);
stefanrousseau 11:e6602513730f 379 sprintf(SENSOR_DATA.AccelZ, "%2.3f", fAccelScaled_z);
stefanrousseau 11:e6602513730f 380 } //bMotionSensor_present
stefanrousseau 61:f6b93129f954 381 } //Read_motion_sensor()
stefanrousseau 61:f6b93129f954 382
stefanrousseau 61:f6b93129f954 383
stefanrousseau 61:f6b93129f954 384 //********************************************************************************************************************************************
stefanrousseau 61:f6b93129f954 385 //* Read the HTS221 temperature & humidity sensor on the Cellular Shield
stefanrousseau 61:f6b93129f954 386 //********************************************************************************************************************************************
stefanrousseau 61:f6b93129f954 387 // These are to be built on the fly
stefanrousseau 61:f6b93129f954 388 string my_temp;
stefanrousseau 61:f6b93129f954 389 string my_humidity;
stefanrousseau 61:f6b93129f954 390 HTS221 hts221;
stefanrousseau 11:e6602513730f 391
stefanrousseau 61:f6b93129f954 392 #define CTOF(x) ((x)*1.8+32)
stefanrousseau 61:f6b93129f954 393 bool bHTS221_present = false;
stefanrousseau 61:f6b93129f954 394 void Init_HTS221()
stefanrousseau 61:f6b93129f954 395 {
stefanrousseau 61:f6b93129f954 396 int i;
stefanrousseau 61:f6b93129f954 397 void hts221_init(void);
stefanrousseau 61:f6b93129f954 398 i = hts221.begin();
stefanrousseau 61:f6b93129f954 399 if (i)
stefanrousseau 61:f6b93129f954 400 {
stefanrousseau 61:f6b93129f954 401 bHTS221_present = true;
stefanrousseau 64:09004cd610df 402 PRINTF(BLU "HTS221 Detected (0x%02X)\n\r",i);
stefanrousseau 64:09004cd610df 403 PRINTF(" Temp is: %0.2f F \n\r",CTOF(hts221.readTemperature()));
stefanrousseau 64:09004cd610df 404 PRINTF(" Humid is: %02d %%\n\r",hts221.readHumidity());
stefanrousseau 61:f6b93129f954 405 }
stefanrousseau 61:f6b93129f954 406 else
stefanrousseau 61:f6b93129f954 407 {
stefanrousseau 61:f6b93129f954 408 bHTS221_present = false;
stefanrousseau 64:09004cd610df 409 PRINTF(RED "HTS221 NOT DETECTED!\n\r");
stefanrousseau 61:f6b93129f954 410 }
stefanrousseau 61:f6b93129f954 411 } //Init_HTS221()
stefanrousseau 61:f6b93129f954 412
stefanrousseau 61:f6b93129f954 413 void Read_HTS221()
stefanrousseau 61:f6b93129f954 414 {
stefanrousseau 61:f6b93129f954 415 if (bHTS221_present)
stefanrousseau 61:f6b93129f954 416 {
stefanrousseau 61:f6b93129f954 417 sprintf(SENSOR_DATA.Temperature, "%0.2f", CTOF(hts221.readTemperature()));
stefanrousseau 61:f6b93129f954 418 sprintf(SENSOR_DATA.Humidity, "%02d", hts221.readHumidity());
stefanrousseau 61:f6b93129f954 419 } //bHTS221_present
stefanrousseau 61:f6b93129f954 420 } //Read_HTS221()
stefanrousseau 55:3abf9e3f42e6 421
stefanrousseau 55:3abf9e3f42e6 422 #ifdef USE_VIRTUAL_SENSORS
stefanrousseau 55:3abf9e3f42e6 423 bool bUsbConnected = false;
stefanrousseau 55:3abf9e3f42e6 424 volatile uint8_t usb_uart_rx_buff[256];
stefanrousseau 55:3abf9e3f42e6 425 //volatile uint8_t usb_uart_tx_buff[256];
stefanrousseau 55:3abf9e3f42e6 426 volatile unsigned char usb_uart_rx_buff_putptr = 0;
stefanrousseau 55:3abf9e3f42e6 427 volatile unsigned char usb_uart_rx_buff_getptr = 0;
stefanrousseau 55:3abf9e3f42e6 428 //volatile unsigned char usb_uart_tx_buff_putptr = 0;
stefanrousseau 55:3abf9e3f42e6 429 //volatile unsigned char usb_uart_tx_buff_getptr = 0;
stefanrousseau 55:3abf9e3f42e6 430 char usbhost_rx_string[256];
stefanrousseau 55:3abf9e3f42e6 431 unsigned char usbhost_rxstring_index;
stefanrousseau 55:3abf9e3f42e6 432 char usbhost_tx_string[256];
stefanrousseau 55:3abf9e3f42e6 433
stefanrousseau 55:3abf9e3f42e6 434
stefanrousseau 55:3abf9e3f42e6 435 float f_sensor1_value = 12.3;
stefanrousseau 55:3abf9e3f42e6 436 float f_sensor2_value = 45.6;
stefanrousseau 55:3abf9e3f42e6 437 float f_sensor3_value = 78.9;
stefanrousseau 55:3abf9e3f42e6 438 float f_sensor4_value = 78.9;
stefanrousseau 55:3abf9e3f42e6 439 float f_sensor5_value = 78.9;
stefanrousseau 55:3abf9e3f42e6 440 float f_sensor6_value = 78.9;
stefanrousseau 55:3abf9e3f42e6 441 float f_sensor7_value = 78.9;
stefanrousseau 55:3abf9e3f42e6 442 float f_sensor8_value = 78.9;
stefanrousseau 55:3abf9e3f42e6 443 char usb_sensor_string[110];
stefanrousseau 55:3abf9e3f42e6 444
stefanrousseau 55:3abf9e3f42e6 445
stefanrousseau 55:3abf9e3f42e6 446 //********************************************************************************************************************************************
stefanrousseau 55:3abf9e3f42e6 447 //* Parse the input sensor data from the USB host
stefanrousseau 55:3abf9e3f42e6 448 //********************************************************************************************************************************************
stefanrousseau 55:3abf9e3f42e6 449 int parse_usbhost_message()
stefanrousseau 55:3abf9e3f42e6 450 {
stefanrousseau 64:09004cd610df 451 //PRINTF("String = %s\n", usbhost_rx_string); //test
stefanrousseau 55:3abf9e3f42e6 452 uint8_t length;
stefanrousseau 55:3abf9e3f42e6 453 uint8_t x ;
stefanrousseau 55:3abf9e3f42e6 454 //It seems that sscanf needs 11 characters to store a 7-character number. There must be some formatting and termination values...
stefanrousseau 55:3abf9e3f42e6 455 char Record[8][11]; //There are 8 sensors with up to 7 characters each
stefanrousseau 55:3abf9e3f42e6 456 char StringRecord[110]; //There are is a sensor "string" with up to 100 characters in it
stefanrousseau 55:3abf9e3f42e6 457
stefanrousseau 55:3abf9e3f42e6 458 // Data format is: "S1:1234,S2:5678,S3:1234,S4:5678,S5:1234,S6:5678,S7:5678,S8:5678,S9:abcde...\n"
stefanrousseau 55:3abf9e3f42e6 459 int args_assigned = sscanf(usbhost_rx_string, "%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%[^\n]", Record[0], Record[1], Record[2], Record[3], Record[4], Record[5], Record[6], Record[7], StringRecord);
stefanrousseau 55:3abf9e3f42e6 460
stefanrousseau 55:3abf9e3f42e6 461 //StringRecord[109] = '\0';
stefanrousseau 64:09004cd610df 462 //PRINTF("Last = %s\n", StringRecord); //test
stefanrousseau 55:3abf9e3f42e6 463
stefanrousseau 55:3abf9e3f42e6 464 if (args_assigned == 9)
stefanrousseau 55:3abf9e3f42e6 465 { //sscanf was able to assign all 9 values
stefanrousseau 55:3abf9e3f42e6 466 for (x=0; x < 8; x++) // loop through the 8 sensors
stefanrousseau 55:3abf9e3f42e6 467 {
stefanrousseau 55:3abf9e3f42e6 468 // Strip the "Sx:" label characters from the field value
stefanrousseau 55:3abf9e3f42e6 469 length = strlen(Record[x]); // max of 7 characters but could be less
stefanrousseau 55:3abf9e3f42e6 470 strncpy(Record[x], Record[x] + 3, length);
stefanrousseau 55:3abf9e3f42e6 471 Record[x][length] = '\0'; // null termination character manually added
stefanrousseau 55:3abf9e3f42e6 472 }
stefanrousseau 55:3abf9e3f42e6 473 length = strlen(StringRecord);
stefanrousseau 55:3abf9e3f42e6 474 strncpy(StringRecord, StringRecord + 3, length);
stefanrousseau 55:3abf9e3f42e6 475 StringRecord[length] = '\0'; // null termination character manually added
stefanrousseau 55:3abf9e3f42e6 476
stefanrousseau 55:3abf9e3f42e6 477 if ((usbhost_rx_string[0] == 'S') && (usbhost_rx_string[1] == '1')) //The message starts with "S1"
stefanrousseau 55:3abf9e3f42e6 478 {
stefanrousseau 55:3abf9e3f42e6 479 f_sensor1_value = atof(Record[0]);
stefanrousseau 55:3abf9e3f42e6 480 f_sensor2_value = atof(Record[1]);
stefanrousseau 55:3abf9e3f42e6 481 f_sensor3_value = atof(Record[2]);
stefanrousseau 55:3abf9e3f42e6 482 f_sensor4_value = atof(Record[3]);
stefanrousseau 55:3abf9e3f42e6 483 f_sensor5_value = atof(Record[4]);
stefanrousseau 55:3abf9e3f42e6 484 f_sensor6_value = atof(Record[5]);
stefanrousseau 55:3abf9e3f42e6 485 f_sensor7_value = atof(Record[6]);
stefanrousseau 55:3abf9e3f42e6 486 f_sensor8_value = atof(Record[7]);
stefanrousseau 55:3abf9e3f42e6 487 sprintf(usb_sensor_string,StringRecord);
stefanrousseau 64:09004cd610df 488 //PRINTF("Received = %s, %s, %s, %s, %s, %s, %s, %s, %s\n", Record[0], Record[1], Record[2], Record[3], Record[4], Record[5], Record[6], Record[7], usb_sensor_string); //test
stefanrousseau 55:3abf9e3f42e6 489 sprintf(SENSOR_DATA.Virtual_Sensor1, "%s", Record[0]);
stefanrousseau 55:3abf9e3f42e6 490 sprintf(SENSOR_DATA.Virtual_Sensor2, "%s", Record[1]);
stefanrousseau 55:3abf9e3f42e6 491 sprintf(SENSOR_DATA.Virtual_Sensor3, "%s", Record[2]);
stefanrousseau 55:3abf9e3f42e6 492 sprintf(SENSOR_DATA.Virtual_Sensor4, "%s", Record[3]);
stefanrousseau 55:3abf9e3f42e6 493 sprintf(SENSOR_DATA.Virtual_Sensor5, "%s", Record[4]);
stefanrousseau 55:3abf9e3f42e6 494 sprintf(SENSOR_DATA.Virtual_Sensor6, "%s", Record[5]);
stefanrousseau 55:3abf9e3f42e6 495 sprintf(SENSOR_DATA.Virtual_Sensor7, "%s", Record[6]);
stefanrousseau 55:3abf9e3f42e6 496 sprintf(SENSOR_DATA.Virtual_Sensor8, "%s", Record[7]);
stefanrousseau 55:3abf9e3f42e6 497 }
stefanrousseau 55:3abf9e3f42e6 498 } //sscanf was able to assign all values
stefanrousseau 55:3abf9e3f42e6 499 return args_assigned;
stefanrousseau 55:3abf9e3f42e6 500 } //parse_usbhost_message()
stefanrousseau 55:3abf9e3f42e6 501
stefanrousseau 55:3abf9e3f42e6 502 //********************************************************************************************************************************************
stefanrousseau 55:3abf9e3f42e6 503 //* Process any received message from the USB host
stefanrousseau 55:3abf9e3f42e6 504 //********************************************************************************************************************************************
stefanrousseau 55:3abf9e3f42e6 505 void process_usb_rx(unsigned char ucNewRxByte)
stefanrousseau 55:3abf9e3f42e6 506 {
stefanrousseau 55:3abf9e3f42e6 507 if (ucNewRxByte == '?')
stefanrousseau 55:3abf9e3f42e6 508 { //just pinging
stefanrousseau 55:3abf9e3f42e6 509 usbhost_rxstring_index = 0;
stefanrousseau 55:3abf9e3f42e6 510 return;
stefanrousseau 55:3abf9e3f42e6 511 } //just pinging
stefanrousseau 55:3abf9e3f42e6 512 usbhost_rx_string[usbhost_rxstring_index++] = ucNewRxByte;
stefanrousseau 55:3abf9e3f42e6 513 if (ucNewRxByte == '\n')
stefanrousseau 55:3abf9e3f42e6 514 { //end of message
stefanrousseau 55:3abf9e3f42e6 515 usbhost_rx_string[usbhost_rxstring_index] = 0; //null terminate string
stefanrousseau 55:3abf9e3f42e6 516 usbhost_rxstring_index = 0;
stefanrousseau 55:3abf9e3f42e6 517 parse_usbhost_message();
stefanrousseau 55:3abf9e3f42e6 518 } //end of message
stefanrousseau 55:3abf9e3f42e6 519 } //process_usb_rx()
stefanrousseau 55:3abf9e3f42e6 520
stefanrousseau 55:3abf9e3f42e6 521 void ProcessUsbInterface(void)
stefanrousseau 55:3abf9e3f42e6 522 {
stefanrousseau 55:3abf9e3f42e6 523 //Process the USB host UART receive commands:
stefanrousseau 55:3abf9e3f42e6 524 if (usb_uart_rx_buff_getptr != usb_uart_rx_buff_putptr)
stefanrousseau 55:3abf9e3f42e6 525 {
stefanrousseau 55:3abf9e3f42e6 526 bUsbConnected = true;
stefanrousseau 55:3abf9e3f42e6 527 while (usb_uart_rx_buff_getptr != usb_uart_rx_buff_putptr)
stefanrousseau 55:3abf9e3f42e6 528 {
stefanrousseau 55:3abf9e3f42e6 529 unsigned char ucByteFromHost = usb_uart_rx_buff[usb_uart_rx_buff_getptr++]; //Copy latest received byte
stefanrousseau 55:3abf9e3f42e6 530 process_usb_rx(ucByteFromHost);
stefanrousseau 55:3abf9e3f42e6 531 } //while (usb_uart_rx_buff_getptr != usb_uart_rx_buff_putptr)
stefanrousseau 55:3abf9e3f42e6 532 } // if there are USB UART bytes to receive
stefanrousseau 55:3abf9e3f42e6 533 //USB host UART transmit:
stefanrousseau 55:3abf9e3f42e6 534 //while (usb_uart_tx_buff_getptr != usb_uart_tx_buff_putptr)
stefanrousseau 55:3abf9e3f42e6 535 //{
stefanrousseau 55:3abf9e3f42e6 536 //pc.putc(usb_uart_tx_buff[usb_uart_tx_buff_getptr++]);
stefanrousseau 55:3abf9e3f42e6 537 //}
stefanrousseau 55:3abf9e3f42e6 538 } //ProcessUsbInterface()
stefanrousseau 55:3abf9e3f42e6 539
stefanrousseau 56:cb42ff383dab 540 // This function is called when a character goes into the RX buffer.
stefanrousseau 56:cb42ff383dab 541 void UsbUartRxCallback(MODSERIAL_IRQ_INFO *info)
stefanrousseau 55:3abf9e3f42e6 542 {
stefanrousseau 56:cb42ff383dab 543 // Get the pointer to our MODSERIAL object that invoked this callback.
stefanrousseau 56:cb42ff383dab 544 MODSERIAL *pc = info->serial;
stefanrousseau 56:cb42ff383dab 545 while (pc->readable())
stefanrousseau 56:cb42ff383dab 546 {
stefanrousseau 56:cb42ff383dab 547 usb_uart_rx_buff[usb_uart_rx_buff_putptr++] = pc->getcNb();
stefanrousseau 56:cb42ff383dab 548 }
stefanrousseau 55:3abf9e3f42e6 549 }
stefanrousseau 55:3abf9e3f42e6 550 #endif
stefanrousseau 55:3abf9e3f42e6 551
stefanrousseau 4:f83bedd9cab4 552 void sensors_init(void)
stefanrousseau 4:f83bedd9cab4 553 {
stefanrousseau 55:3abf9e3f42e6 554 #ifdef USE_VIRTUAL_SENSORS
stefanrousseau 56:cb42ff383dab 555 pc.attach(&UsbUartRxCallback, MODSERIAL::RxIrq);
stefanrousseau 55:3abf9e3f42e6 556 #endif
stefanrousseau 61:f6b93129f954 557 Init_HTS221();
stefanrousseau 4:f83bedd9cab4 558 Init_Si7020();
stefanrousseau 4:f83bedd9cab4 559 Init_Si1145();
stefanrousseau 61:f6b93129f954 560 Init_motion_sensor();
stefanrousseau 4:f83bedd9cab4 561 } //sensors_init
stefanrousseau 4:f83bedd9cab4 562
stefanrousseau 4:f83bedd9cab4 563 void read_sensors(void)
stefanrousseau 4:f83bedd9cab4 564 {
stefanrousseau 61:f6b93129f954 565 Read_HTS221();
stefanrousseau 4:f83bedd9cab4 566 Read_Si7020();
stefanrousseau 4:f83bedd9cab4 567 Read_Si1145();
stefanrousseau 61:f6b93129f954 568 Read_motion_sensor();
stefanrousseau 4:f83bedd9cab4 569 } //read_sensors