There are days when you would like to have the window open but the weather shows a chance of rain. What if the window had enough intelligence to close automatically before the rain starts? This is the window system being built with the help of the DPS310 barometric pressure sensor.
The window system will have safety mechanisms like those used on garage doors so that the window is closed slowly and safely.
Additional backup sensors are used to close the window if the barometric pressure sensor is not sufficient to predict rain.
Hacking the Sensor Hub Nano
The project for the window is first an embedded project. Later on in the development the BLE features of the Sensor Hub Nano will be useful. But now the data from the barometric pressure sensor is the primary interest.
So how can we get the data without using the BLE functions? Attach wires to the sensor and listen to the data that is being read out by the micro-controller on the Sensor Hub Nano.
I may get instructions on how to create custom firmware for the Sensor Hub Nano. I will keep the project updated when I get instructions on how to write custom firmware. Until I get those instructions we will have to make do with listening to the sensor data as it is read out by the micro-controller of the Sensor Hub Nano.
Sensor Hub Nano under the magnifying glass
The Sensor Hub Nano has solder connections on the board edge. I haven't clipped the plastic that holds the lithium polymer battery yet, although that may happen soon. ( I am still hoping for a schematic diagram soon . )
The SI and SCK lines are bussed to an empty set of pads with the same footprint as the DPS310, but I don't think the empty location is for another DPS310 but for a different sensor .
I am hoping that an I2C interface was chosen for the data connections. I am also hopeful that SI, SCK and Signal Ground lines are all bussed to the solder connections on the side of Sensor Hub Nano. There are surface mount components on the board side under the lithium polymer battery, so the board designer must have intended for the board to be "cradled" in a board cut-out.
Snipping the plastic band that holds the battery in place
The battery wire is very fine gauge wire and broke off almost immediately , so note how to solder it back :)
There is only so much to be figured out by visually inspecting the board. The BLE module on the other side of the board obscures the board circuit routing. I hope to get the schematic I have requested.
Soon I will have fun powering it up and probing the signals on the edge connections of the Sensor Hub Nano.
Soldering to Sensor Hub Nano
The connections on the side of Sensor Hub Nano are separated by 0.1 inch . I used 0.1 inch wire wrap header and a circuit board and a breadboard to hold all of this together firmly while soldering. I am leaving the Sensor Hub Nano in the circuit board to act as a mechanical reinforcement to help prevent the wire wrap header from getting torn off the board by any mechanical side loads on the pins while I do assembly and wire wrapping.
XMC 2 Go Kit
An XMC 2 Go Kit is used as the brains for this project. Since I am using the Infineon Dave Software Development IDE in another project I thought I would keep my life simple and us the Infineon Dave Software IDE here too.
The Dave Software IDE is similar to the MBED.org IDE it provides library code for using microcontroller peripherals and help specifying the pin connections on the microcontroller. The goal for this project is to intercept the I2C barometric data on the Sensor Hub Nano and use the data to shut the window just before rain starts falling.
I created a Dave App based starter project that has a precise 1 millesecond tick, that is used to precisely blink an LED. I plan on using this for many different tasks in my embedded software project. I am including the zipped up archive as ' hello world ' type of demonstration project.
From the Dave IDE you can do File->Import which brings up a pop-up window from which you select Infineon and then Dave Project as an Import source. The next popup window helps select the file, a zipped archive file in this case.
There may be a really convenient way of creating a GitHub repository from the Dave IDE, I have not found it yet.
This project will be built on with additional Dave Apps, think of them as software components.
/*
* main.c
*
* Created on: 2017 Aug 24 08:35:14
* Author: tminnich
*/
#include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration)
uint32_t event_count;
uint8_t data[] = "Infineon Technologies";
uint8_t rec_data[10];
/**
* @brief main() - Application entry point
*
* <b>Details of function</b><br>
* This routine is the application entry point. It is invoked by the device startup code. It is responsible for
* invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application
* code.
*/
int main(void)
{
DAVE_STATUS_t status;
#define TOM_TIMER_LIMIT 1000000
int tom_timer;
status = DAVE_Init(); /* Initialization of DAVE APPs */
if(status != DAVE_STATUS_SUCCESS)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */
XMC_DEBUG("DAVE APPs initialization failed\n");
while(1U)
{
}
}
/* Placeholder for user application code. The while loop below can be replaced with user application code. */
UART_Transmit(&UART_0,data,sizeof(data) - 1);
while(1U)
{
for(tom_timer=0;tom_timer<TOM_TIMER_LIMIT;tom_timer++){
}
}
}
void Timer_Interval_Event(void)
{
event_count++;
if (event_count >= 500U)
{
event_count = 0;
DIGITAL_IO_ToggleOutput(&DIGITAL_IO_0);
}
}
void EndofTransmit()//
{
UART_Receive(&UART_0, rec_data, sizeof(rec_data));
}
void EndofReceive()//
{
UART_Transmit(&UART_0, rec_data, sizeof(rec_data));
}
Short Term Goals
Copy the barometric data from the Sensor Hub Nano. This is the really tricky part of the project where I have to monitor the I2C data coming out of the barometric pressure sensor on the Sensor Hub Nano. I doubt that the Dave App component for I2C can help me monitor the I2C data, so I will have to do something similar to a "bit banging" technique to capture the I2C data.
Now it is time to start messing with the I2C signals coming out of the pressure sensor. I suppose that I am not allowed to disclose the schematic of the Sensor Hub Nano. But the I2C signals are as follows:
SDA <------------------> X3 connector pin 6
SDC <------------------- X3 connector pin 7
GND <------------------> X2 connector pin 7
The X3 connector is further away and has pin 1 closest to the USB connector. Also note it has two wires attached to it the I2C data line SDA and the I2C clock line SDC.
The X2 connector is closer to us in the picture and has pin 1 closest to the USB connector. It has one wire attached to it , the signal ground connection,
The pressure sensor data register reads hexadecimal FA762B.
This corresponds to a decimal reading of 16414251.
An alternative to listening to I2C bus data to capture pressure data
if there is no BLE device connected to the Sensor Hub Nano there is no activity on the I2C bus, after a power on initialization by Sensor Hub Nano, An external board could drive the I2C bus and re-initialize the pressure sensor and use the pressure sensor via I2C bus commands in any desired manner. This seems a more powerful and direct approach.
Long Term Goals
Many sensor systems use additional sensors to improve the reliability of operation, An Adafruit 2857 using a SHT31-D humidity sensor provides a nice backup for the barometric pressure sensor.
Here is what the combined system looks like. There is the XMC 2Go board for developing firmware, the Sensor Hub Nano with its Lithium ion battery and the Adafruit SHT31-D humidity sensor.
Link to Dropbox Humidity Sensor Project
Here is the code for reading the humidity sensor. Work was done for the humidity sensor first so I could gain familiarity with the I2C Dave APP and be able to use the I2C software/hardware before attempting to use it with the DPS 610 pressure sensor.
/*
* main.c
*
* Created on: 2017 Aug 24 08:35:14
* Author: tminnich
*/
#include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration)
//I2C stuff
uint8_t rx_buf[25];
uint8_t tx_buf[2];
uint32_t event_count, measurement_timer;
uint8_t data[] = "Infineon Technologies";
uint8_t rec_data[10];
// SENSIRION humidity sensor stuff
#define HUMIDITY_SENS_ADDR 0x88 //0x44 //I2C address for humidity sensor
// Single shot high repeatability measurement command
const uint8_t measure_hum[] = { 0x2c, 0x06 };
// CRC generation for SENSIRION humidity sensor
uint8_t test_crc;
#define CRC8_POLY 0x31
/* CheckSumByteCRC8: calculate the CRC8 checksum of a single additional byte */
uint8_t CheckSumByteCRC8( uint8_t crc, uint8_t val, uint8_t poly) {
unsigned char temp;
unsigned char index;
for (index= 8; index != 0; index--) {
temp = (unsigned char)((crc >> 7) ^ (val >> 7));
crc <<= 1;
val <<= 1;
if (temp) {
crc ^= poly;
}
}
return crc;
}
/**
* @brief main() - Application entry point
*
* <b>Details of function</b><br>
* This routine is the application entry point. It is invoked by the device startup code. It is responsible for
* invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application
* code.
*/
int main(void)
{
DAVE_STATUS_t status;
status = DAVE_Init(); /* Initialization of DAVE APPs */
if(status != DAVE_STATUS_SUCCESS)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */
XMC_DEBUG("DAVE APPs initialization failed\n");
while(1U)
{
}
}
/* Placeholder for user application code. The while loop below can be replaced with user application code. */
UART_Transmit(&UART_0,data,sizeof(data) - 1);
//Test the CRC generator for proper operation
//test_crc = 0xff;
//test_crc = CheckSumByteCRC8( test_crc, 0xbe, CRC8_POLY);
//test_crc = CheckSumByteCRC8( test_crc, 0xef, CRC8_POLY);
// Let the Humidity Sensor power up
//and get ready for measurements
while(event_count < 3){
// wait for event counts to accumulate
}
// DAVE APP I2C MASTER does not support clock stretching
//so any modes of the humidity sensor requiring clock stretching
//are avoided.
while(1U)
{
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR,/*(uint8_t*)*/&measure_hum[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
I2C_MASTER_Receive(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR, &rx_buf[0], 6, true, true);
measurement_timer=0;
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20)){
}
if(measurement_timer < 20){
// Now we have data to look at.
// Use the CRC checksum
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[0], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[1], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[2], CRC8_POLY);
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[3], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[4], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[5], CRC8_POLY);
}else{
I2C_MASTER_AbortReceive(&I2C_MASTER_0);
}
}
}
}
void Timer_Interval_Event(void)
{
measurement_timer++;
event_count++;
if (event_count >= 500U)
{
event_count = 0;
DIGITAL_IO_ToggleOutput(&DIGITAL_IO_0);
}
}
void EndofTransmit()//
{
UART_Receive(&UART_0, rec_data, sizeof(rec_data));
}
void EndofReceive()//
{
UART_Transmit(&UART_0, rec_data, sizeof(rec_data));
}
Adding the code to handle the DPS610 on the I2C bus
Link to DPS610 I2C code project
This is the code to read the calibration coefficients, the temperature sensor and the barometric pressure sensor. More code is require to apply the calibration coefficients and do useful things with the data. I thought this would be useful for a starting point for other people's projects using the DPS610.
/*
* main.c
*
* Created on: 2017 Aug 24 08:35:14
* Author: tminnich
*/
#include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration)
//I2C stuff
uint8_t rx_buf[25];
uint8_t tx_buf[2];
uint32_t event_count, measurement_timer;
uint8_t data[] = "Infineon Technologies";
uint8_t rec_data[10];
// DPS610 Barometric Pressure Sensor Stuff
//I2C address for barometric pressure sensor
#define BAROMETRIC_SENS_ADDR 0xEC // 0xEC is 0x76 shifted left once
const uint8_t get_coeff[] = { 0x10}; // Starting address for coefficients
const uint8_t get_temp_data[] = { 0x03}; // Starting address for temp registers
const uint8_t get_baro_data[] = { 0x00}; // Starting address for barometric registers data
uint8_t dps610_temp_data[3];
uint8_t dps610_baro_data[3];
uint8_t dps610_cal_coeff[16];
const uint8_t prs_cfg[] = { 0x06,0x01}; // Weather Station (low power) use case
const uint8_t tmp_cfg[] = { 0x07,0x80}; // see page 17 of the data sheet PDF
//const uint8_t cfg_reg[] = { 0x09,0x00}; // No need to do init if 0x00 is good
const uint8_t read_temp[] = { 0x08,0x02 }; // command a temp sensor reading
const uint8_t read_baro[] = { 0x08,0x01 }; // command a barometric pressure sensor reading
// SENSIRION humidity sensor stuff
// DAVE APP I2C MASTER does not support clock stretching
//so any modes of the humidity sensor requiring clock stretching
//are avoided.
//I2C address for humidity sensor
#define HUMIDITY_SENS_ADDR 0x88 // 0x88 is 0x44 shifted left once
// Single shot high repeatability measurement command
const uint8_t measure_hum[] = { 0x2c, 0x06 };
// CRC generation for SENSIRION humidity sensor
uint8_t test_crc;
#define CRC8_POLY 0x31
/* CheckSumByteCRC8: calculate the CRC8 checksum of a single additional byte */
uint8_t CheckSumByteCRC8( uint8_t crc, uint8_t val, uint8_t poly) {
unsigned char temp;
unsigned char index;
for (index= 8; index != 0; index--) {
temp = (unsigned char)((crc >> 7) ^ (val >> 7));
crc <<= 1;
val <<= 1;
if (temp) {
crc ^= poly;
}
}
return crc;
}
/**
* @brief main() - Application entry point
*
* <b>Details of function</b><br>
* This routine is the application entry point. It is invoked by the device startup code. It is responsible for
* invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application
* code.
*/
int main(void)
{
DAVE_STATUS_t status;
status = DAVE_Init(); /* Initialization of DAVE APPs */
if(status != DAVE_STATUS_SUCCESS)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */
XMC_DEBUG("DAVE APPs initialization failed\n");
while(1U)
{
}
}
/* Placeholder for user application code. The while loop below can be replaced with user application code. */
UART_Transmit(&UART_0,data,sizeof(data) - 1);
// Let the Barometric Pressure Sensor and Humidity Sensor power up
//and get ready for measurements
while(event_count < 50){
// wait for event counts to accumulate
}
// Read Calibration Coefficients from DPS610
for(;;){
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_coeff[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
break;
}
}
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_cal_coeff[0], 16, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
measurement_timer=0;
// Pressure config register setup
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&prs_cfg[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
// Temp config register setup
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&tmp_cfg[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(1U)
{
// Read Infineon Temperature Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&read_temp[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
// Collect temp data
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_temp_data[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_temp_data[0], 3, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
// Read Infineon Barometric Pressure Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&read_baro[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
// Collect pressure data
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_baro_data[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_baro_data[0], 3, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
// Read Sensirion Humidity and Temperature Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR,(uint8_t*)&measure_hum[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
I2C_MASTER_Receive(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR, &rx_buf[0], 6, true, true);
measurement_timer=0;
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20)){
}
if(measurement_timer < 20){
// Now we have data to look at.
// Use the CRC checksum
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[0], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[1], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[2], CRC8_POLY);
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[3], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[4], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[5], CRC8_POLY);
}else{
I2C_MASTER_AbortReceive(&I2C_MASTER_0);
}
}
}
}
void Timer_Interval_Event(void)
{
measurement_timer++;
event_count++;
if (event_count >= 500U)
{
event_count = 0;
DIGITAL_IO_ToggleOutput(&DIGITAL_IO_0);
}
}
void EndofTransmit()//
{
UART_Receive(&UART_0, rec_data, sizeof(rec_data));
}
void EndofReceive()//
{
UART_Transmit(&UART_0, rec_data, sizeof(rec_data));
}
Here is the code that uses the calibration coefficients in DPS610 to calculate calibrated barometric pressure sensor and calibrated temperature sensor measurements.
DropBox link to Dave App for calibrated DPS610 sensor readings
/*
* main.c
*
* Created on: 2017 Aug 24 08:35:14
* Author: tminnich
*/
#include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration)
//I2C stuff
uint8_t rx_buf[25];
uint8_t tx_buf[2];
uint32_t event_count, measurement_timer;
uint8_t data[] = "Infineon Technologies";
uint8_t rec_data[10];
// DPS610 Barometric Pressure Sensor Stuff
//I2C address for barometric pressure sensor
#define BAROMETRIC_SENS_ADDR 0xEC // 0xEC is 0x76 shifted left once
const uint8_t get_coeff[] = { 0x10}; // Starting address for coefficients
const uint8_t get_temp_data[] = { 0x03}; // Starting address for temp registers
const uint8_t get_baro_data[] = { 0x00}; // Starting address for barometric registers data
uint8_t dps610_temp_data[3];
uint8_t dps610_baro_data[3];
uint8_t dps610_cal_coeff[18];
float baro_sc_float,temp_sc_float,baro_comp,temp_comp;
// variables for the coefficients (unpacked from bytes)
int32_t C0,C1,C00,C10,C01,C11,C20,C21,C30,TEMP,BARO;
#define BARO_COMP_SCALE_FACTOR 1572864 // see table 9 in DSP610 data sheet
#define TEMP_COMP_SCALE_FACTOR 330721 // see table 9 in DSP610 data sheet
const uint8_t prs_cfg[] = { 0x06,0x01}; // Weather Station (low power) use case
const uint8_t tmp_cfg[] = { 0x07,0x80}; // see page 17 of the data sheet PDF
//const uint8_t cfg_reg[] = { 0x09,0x00}; // No need to do init if 0x00 is good
const uint8_t read_temp[] = { 0x08,0x02 }; // command a temp sensor reading
const uint8_t read_baro[] = { 0x08,0x01 }; // command a barometric pressure sensor reading
// SENSIRION humidity sensor stuff
// DAVE APP I2C MASTER does not support clock stretching
//so any modes of the humidity sensor requiring clock stretching
//are avoided.
//I2C address for humidity sensor
#define HUMIDITY_SENS_ADDR 0x88 // 0x88 is 0x44 shifted left once
// Single shot high repeatability measurement command
const uint8_t measure_hum[] = { 0x2c, 0x06 };
// CRC generation for SENSIRION humidity sensor
uint8_t test_crc;
float sensirion_temp, sensirion_rel_humidity;
#define CRC8_POLY 0x31
/* CheckSumByteCRC8: calculate the CRC8 checksum of a single additional byte */
uint8_t CheckSumByteCRC8( uint8_t crc, uint8_t val, uint8_t poly) {
unsigned char temp;
unsigned char index;
for (index= 8; index != 0; index--) {
temp = (unsigned char)((crc >> 7) ^ (val >> 7));
crc <<= 1;
val <<= 1;
if (temp) {
crc ^= poly;
}
}
return crc;
}
/**
* @brief main() - Application entry point
*
* <b>Details of function</b><br>
* This routine is the application entry point. It is invoked by the device startup code. It is responsible for
* invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application
* code.
*/
int main(void)
{
DAVE_STATUS_t status;
int temp_int;
status = DAVE_Init(); /* Initialization of DAVE APPs */
if(status != DAVE_STATUS_SUCCESS)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */
XMC_DEBUG("DAVE APPs initialization failed\n");
while(1U)
{
}
}
/* Placeholder for user application code. The while loop below can be replaced with user application code. */
UART_Transmit(&UART_0,data,sizeof(data) - 1);
// Let the Barometric Pressure Sensor and Humidity Sensor power up
//and get ready for measurements
while(event_count < 50){
// wait for event counts to accumulate
}
// Read Calibration Coefficients from DPS610
for(;;){
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_coeff[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
break;
}
}
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_cal_coeff[0], 18, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
/* C0 a 12 bit signed constant
* C0 := (reg0x10 * 2^ 4) + ((reg0x11 / 2^4) & 0x0F)
* if (C0 > (2^11 - 1))
* C0 := C0 - 2^12
* end if
*/
C0 = (int32_t) dps610_cal_coeff[0];
C0 <<= 4; // left shift 4 times
C0 += (int32_t)((dps610_cal_coeff[1] >> 4) & 0x0f);
if( C0 > 0x7ff){
C0 -= 0x1000; // make it a proper 2s complement negative number
}
/* C1 a 12 bit signed constant
* C1 := (reg0x11 & 0x0f) * 2^ 8) + reg0x12
* if (C1 > (2^11 - 1))
* C1 := C1 - 2^12
* end if
*/
C1 = (int32_t)( dps610_cal_coeff[1] & 0x0f);
C1 <<= 8 ; // left shift 8 times
C1 += (int32_t) dps610_cal_coeff[2];
if( C1 > 0x7ff){
C1 -= 0x1000; // make it a proper 2s complement negative number
}
/* C00 a 20 bit signed constant
* C00 := (reg0x13 * 2^ 16) + (reg0x14 * 2^ 8) + ((reg0x15 / 2^4) & 0x0F)
* if (C00 > (2^19 - 1))
* C00 := C00 - 2^20
* end if
*/
C00 = (int32_t) dps610_cal_coeff[3];
C00 <<= 8 ; // left shift 8 times
C00 += (int32_t) dps610_cal_coeff[4];
C00 <<= 4 ; // left shift 4 times
C00 += (int32_t)((dps610_cal_coeff[5] >> 4) & 0x0f);
if( C00 > 0x7ffff){
C00 -= 0x100000; // make it a proper 2s complement negative number
}
/* C10 a 20 bit signed constant
* C10 := ((reg0x15& 0x0F) * 2^ 16) + (reg0x16 * 2^ 8) + reg0x17
* if (C10 > (2^19 - 1))
* C10 := C10 - 2^20
* end if
*/
C10 = (int32_t)(dps610_cal_coeff[5] & 0x0f);
C10 <<= 8 ; // left shift 8 times
C10 += (int32_t)dps610_cal_coeff[6];
C10 <<= 8 ; // left shift 8 times
C10 += (int32_t)dps610_cal_coeff[7];
if( C10 > 0x7ffff){
C10 -= 0x100000; // make it a proper 2s complement negative number
}
/* C01 a 16 bit signed constant
* C10 := (reg0x18& * 2^ 8) + reg0x19
* if (C10 > (2^15 - 1))
* C10 := C10 - 2^16
* end if
*/
C01 = (int32_t)dps610_cal_coeff[8];
C01 <<= 8 ; // left shift 8 times
C01 += (int32_t)dps610_cal_coeff[9];
if( C01 > 0x7fff){
C01 -= 0x10000; // make it a proper 2s complement negative number
}
/* C11 a 16 bit signed constant
* C11 := (reg0x1A& * 2^ 8) + reg0x1B
* if (C11 > (2^15 - 1))
* C11 := C11 - 2^16
* end if
*/
C11 = (int32_t)dps610_cal_coeff[10];
C11 <<= 8 ; // left shift 8 times
C11 += (int32_t)dps610_cal_coeff[11];
if( C11 > 0x7fff){
C11 -= 0x10000; // make it a proper 2s complement negative number
}
/*
* C20 := (reg0x1C * 2^ 8) + reg0x1D
* if (C20 > (2^15 - 1))
* C20 := C20 - 2^16
* end if
*
*
*/
C20 = (int32_t)dps610_cal_coeff[12];
C20 <<= 8 ; // left shift 8 times
C20 += (int32_t)dps610_cal_coeff[13];
if( C20 > 0x7fff){
C20 -= 0x10000; // make it a proper 2s complement negative number
}
/*
* C21 := (reg0x1E * 2^ 8) + reg0x1F
* if (C21 > (2^15 - 1))
* C21 := C21 - 2^16
* end if
*
*
*/
C21 = (int32_t)dps610_cal_coeff[14];
C21 <<= 8 ; // left shift 8 times
C21 += (int32_t)dps610_cal_coeff[15];
if( C21 > 0x7fff){
C21 -= 0x10000; // make it a proper 2s complement negative number
}
/*
* C30 := (reg0x20 * 2^ 8) + reg0x21
* if (C30 > (2^15 - 1))
* C30 := C30 - 2^16
* end if
*
*
*/
C30 = (int32_t)dps610_cal_coeff[16];
C30 <<= 8 ; // left shift 8 times
C30 += (int32_t)dps610_cal_coeff[17];
if( C30 > 0x7fff){
C30 -= 0x10000; // make it a proper 2s complement negative number
}
measurement_timer=0;
// Pressure config register setup
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&prs_cfg[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
// Temp config register setup
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&tmp_cfg[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(1U)
{
// Read Infineon Temperature Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&read_temp[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
// Collect temp data
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_temp_data[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_temp_data[0], 3, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
TEMP = (int32_t) dps610_temp_data[0];
TEMP <<= 8;
TEMP += (int32_t) dps610_temp_data[1];
TEMP <<= 8;
TEMP += (int32_t) dps610_temp_data[2];
if(TEMP > 0x7fffff) TEMP -= 0x1000000;
temp_sc_float = ((float)( TEMP))/ ((float) TEMP_COMP_SCALE_FACTOR);
temp_comp = ((float)(C0))*0.5 + temp_sc_float * ((float)(C1));
// Read Infineon Barometric Pressure Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&read_baro[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
// Collect pressure data
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_baro_data[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_baro_data[0], 3, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
BARO = (int32_t) dps610_baro_data[0];
BARO <<= 8;
BARO += (int32_t) dps610_baro_data[1];
BARO <<= 8;
BARO += (int32_t) dps610_baro_data[2];
if(BARO > 0x7fffff) BARO -= 0x1000000;
baro_sc_float = ((float)( BARO))/ ((float) BARO_COMP_SCALE_FACTOR);
baro_comp = ((float)(C20) + baro_sc_float * (float)(C30));
baro_comp = ((float)(C10) + baro_sc_float * baro_comp);
baro_comp = ((float)(C00) + baro_sc_float * baro_comp);
baro_comp += temp_sc_float * ((float)(C01));
baro_comp += temp_sc_float * baro_sc_float * (((float)(C11)) + baro_sc_float*((float)(C21)));
// Read Sensirion Humidity and Temperature Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR,(uint8_t*)&measure_hum[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
I2C_MASTER_Receive(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR, &rx_buf[0], 6, true, true);
measurement_timer=0;
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20)){
}
if(measurement_timer < 20){
// Now we have data to look at.
// Use the CRC checksum
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[0], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[1], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[2], CRC8_POLY);
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[3], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[4], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[5], CRC8_POLY);
temp_int = (int)(rx_buf[0]);
temp_int <<= 8;
temp_int += (int)(rx_buf[1]);
sensirion_temp = -45.0 + ((175.0 * (float)(temp_int))/65535);
temp_int = (int)(rx_buf[3]);
temp_int <<= 8;
temp_int += (int)(rx_buf[4]);
sensirion_rel_humidity = (100.0 * (float)(temp_int))/65535;
}else{
I2C_MASTER_AbortReceive(&I2C_MASTER_0);
}
}
}
}
void Timer_Interval_Event(void)
{
measurement_timer++;
event_count++;
if (event_count >= 500U)
{
event_count = 0;
DIGITAL_IO_ToggleOutput(&DIGITAL_IO_0);
}
}
void EndofTransmit()//
{
UART_Receive(&UART_0, rec_data, sizeof(rec_data));
}
void EndofReceive()//
{
UART_Transmit(&UART_0, rec_data, sizeof(rec_data));
}
Setting Limits for closing the window.
Adjusting for the elevation where I live, the average air pressure is slightly lower than that at sea level, 98800 Pascal is a good number. Taking a little pressure a little lower, about 0.5 inches of mercury like the rain indication of an antique barometer brings us to 97107 Pascal.
Because I don't like humid air much either, I am going to close the window when the relative humidity rises above 45%.
DropBox link to the Sensor Code with detection limits in place
/*
* main.c
*
* Created on: 2017 Aug 24 08:35:14
* Author: tminnich
*/
#include <DAVE.h> //Declarations from DAVE Code Generation (includes SFR declaration)
//I2C stuff
uint8_t rx_buf[25];
uint8_t tx_buf[2];
uint8_t flash_led;
uint32_t event_count, measurement_timer;
uint8_t data[] = "Infineon Technologies";
uint8_t rec_data[10];
// DPS610 Barometric Pressure Sensor Stuff
//I2C address for barometric pressure sensor
#define BAROMETRIC_SENS_ADDR 0xEC // 0xEC is 0x76 shifted left once
const uint8_t get_coeff[] = { 0x10}; // Starting address for coefficients
const uint8_t get_temp_data[] = { 0x03}; // Starting address for temp registers
const uint8_t get_baro_data[] = { 0x00}; // Starting address for barometric registers data
uint8_t dps610_temp_data[3];
uint8_t dps610_baro_data[3];
uint8_t dps610_cal_coeff[18];
float baro_sc_float,temp_sc_float,baro_comp,temp_comp;
// variables for the coefficients (unpacked from bytes)
int32_t C0,C1,C00,C10,C01,C11,C20,C21,C30,TEMP,BARO;
#define BARO_COMP_SCALE_FACTOR 1572864 // see table 9 in DSP610 data sheet
#define TEMP_COMP_SCALE_FACTOR 330721 // see table 9 in DSP610 data sheet
const uint8_t prs_cfg[] = { 0x06,0x01}; // Weather Station (low power) use case
const uint8_t tmp_cfg[] = { 0x07,0x80}; // see page 17 of the data sheet PDF
//const uint8_t cfg_reg[] = { 0x09,0x00}; // No need to do init if 0x00 is good
const uint8_t read_temp[] = { 0x08,0x02 }; // command a temp sensor reading
const uint8_t read_baro[] = { 0x08,0x01 }; // command a barometric pressure sensor reading
// SENSIRION humidity sensor stuff
// DAVE APP I2C MASTER does not support clock stretching
//so any modes of the humidity sensor requiring clock stretching
//are avoided.
//I2C address for humidity sensor
#define HUMIDITY_SENS_ADDR 0x88 // 0x88 is 0x44 shifted left once
// Single shot high repeatability measurement command
const uint8_t measure_hum[] = { 0x2c, 0x06 };
// CRC generation for SENSIRION humidity sensor
uint8_t test_crc;
float sensirion_temp, sensirion_rel_humidity;
#define CRC8_POLY 0x31
/* CheckSumByteCRC8: calculate the CRC8 checksum of a single additional byte */
uint8_t CheckSumByteCRC8( uint8_t crc, uint8_t val, uint8_t poly) {
unsigned char temp;
unsigned char index;
for (index= 8; index != 0; index--) {
temp = (unsigned char)((crc >> 7) ^ (val >> 7));
crc <<= 1;
val <<= 1;
if (temp) {
crc ^= poly;
}
}
return crc;
}
/**
* @brief main() - Application entry point
*
* <b>Details of function</b><br>
* This routine is the application entry point. It is invoked by the device startup code. It is responsible for
* invoking the APP initialization dispatcher routine - DAVE_Init() and hosting the place-holder for user application
* code.
*/
int main(void)
{
DAVE_STATUS_t status;
int temp_int;
status = DAVE_Init(); /* Initialization of DAVE APPs */
if(status != DAVE_STATUS_SUCCESS)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler. */
XMC_DEBUG("DAVE APPs initialization failed\n");
while(1U)
{
}
}
/* Placeholder for user application code. The while loop below can be replaced with user application code. */
UART_Transmit(&UART_0,data,sizeof(data) - 1);
// Let the Barometric Pressure Sensor and Humidity Sensor power up
//and get ready for measurements
while(event_count < 50){
// wait for event counts to accumulate
}
// Read Calibration Coefficients from DPS610
for(;;){
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_coeff[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
break;
}
}
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_cal_coeff[0], 18, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
/* C0 a 12 bit signed constant
* C0 := (reg0x10 * 2^ 4) + ((reg0x11 / 2^4) & 0x0F)
* if (C0 > (2^11 - 1))
* C0 := C0 - 2^12
* end if
*/
C0 = (int32_t) dps610_cal_coeff[0];
C0 <<= 4; // left shift 4 times
C0 += (int32_t)((dps610_cal_coeff[1] >> 4) & 0x0f);
if( C0 > 0x7ff){
C0 -= 0x1000; // make it a proper 2s complement negative number
}
/* C1 a 12 bit signed constant
* C1 := (reg0x11 & 0x0f) * 2^ 8) + reg0x12
* if (C1 > (2^11 - 1))
* C1 := C1 - 2^12
* end if
*/
C1 = (int32_t)( dps610_cal_coeff[1] & 0x0f);
C1 <<= 8 ; // left shift 8 times
C1 += (int32_t) dps610_cal_coeff[2];
if( C1 > 0x7ff){
C1 -= 0x1000; // make it a proper 2s complement negative number
}
/* C00 a 20 bit signed constant
* C00 := (reg0x13 * 2^ 16) + (reg0x14 * 2^ 8) + ((reg0x15 / 2^4) & 0x0F)
* if (C00 > (2^19 - 1))
* C00 := C00 - 2^20
* end if
*/
C00 = (int32_t) dps610_cal_coeff[3];
C00 <<= 8 ; // left shift 8 times
C00 += (int32_t) dps610_cal_coeff[4];
C00 <<= 4 ; // left shift 4 times
C00 += (int32_t)((dps610_cal_coeff[5] >> 4) & 0x0f);
if( C00 > 0x7ffff){
C00 -= 0x100000; // make it a proper 2s complement negative number
}
/* C10 a 20 bit signed constant
* C10 := ((reg0x15& 0x0F) * 2^ 16) + (reg0x16 * 2^ 8) + reg0x17
* if (C10 > (2^19 - 1))
* C10 := C10 - 2^20
* end if
*/
C10 = (int32_t)(dps610_cal_coeff[5] & 0x0f);
C10 <<= 8 ; // left shift 8 times
C10 += (int32_t)dps610_cal_coeff[6];
C10 <<= 8 ; // left shift 8 times
C10 += (int32_t)dps610_cal_coeff[7];
if( C10 > 0x7ffff){
C10 -= 0x100000; // make it a proper 2s complement negative number
}
/* C01 a 16 bit signed constant
* C10 := (reg0x18& * 2^ 8) + reg0x19
* if (C10 > (2^15 - 1))
* C10 := C10 - 2^16
* end if
*/
C01 = (int32_t)dps610_cal_coeff[8];
C01 <<= 8 ; // left shift 8 times
C01 += (int32_t)dps610_cal_coeff[9];
if( C01 > 0x7fff){
C01 -= 0x10000; // make it a proper 2s complement negative number
}
/* C11 a 16 bit signed constant
* C11 := (reg0x1A& * 2^ 8) + reg0x1B
* if (C11 > (2^15 - 1))
* C11 := C11 - 2^16
* end if
*/
C11 = (int32_t)dps610_cal_coeff[10];
C11 <<= 8 ; // left shift 8 times
C11 += (int32_t)dps610_cal_coeff[11];
if( C11 > 0x7fff){
C11 -= 0x10000; // make it a proper 2s complement negative number
}
/*
* C20 := (reg0x1C * 2^ 8) + reg0x1D
* if (C20 > (2^15 - 1))
* C20 := C20 - 2^16
* end if
*
*
*/
C20 = (int32_t)dps610_cal_coeff[12];
C20 <<= 8 ; // left shift 8 times
C20 += (int32_t)dps610_cal_coeff[13];
if( C20 > 0x7fff){
C20 -= 0x10000; // make it a proper 2s complement negative number
}
/*
* C21 := (reg0x1E * 2^ 8) + reg0x1F
* if (C21 > (2^15 - 1))
* C21 := C21 - 2^16
* end if
*
*
*/
C21 = (int32_t)dps610_cal_coeff[14];
C21 <<= 8 ; // left shift 8 times
C21 += (int32_t)dps610_cal_coeff[15];
if( C21 > 0x7fff){
C21 -= 0x10000; // make it a proper 2s complement negative number
}
/*
* C30 := (reg0x20 * 2^ 8) + reg0x21
* if (C30 > (2^15 - 1))
* C30 := C30 - 2^16
* end if
*
*
*/
C30 = (int32_t)dps610_cal_coeff[16];
C30 <<= 8 ; // left shift 8 times
C30 += (int32_t)dps610_cal_coeff[17];
if( C30 > 0x7fff){
C30 -= 0x10000; // make it a proper 2s complement negative number
}
measurement_timer=0;
// Pressure config register setup
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&prs_cfg[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
// Temp config register setup
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&tmp_cfg[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(1U)
{
// Read Infineon Temperature Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&read_temp[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
// Collect temp data
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_temp_data[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_temp_data[0], 3, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
TEMP = (int32_t) dps610_temp_data[0];
TEMP <<= 8;
TEMP += (int32_t) dps610_temp_data[1];
TEMP <<= 8;
TEMP += (int32_t) dps610_temp_data[2];
if(TEMP > 0x7fffff) TEMP -= 0x1000000;
temp_sc_float = ((float)( TEMP))/ ((float) TEMP_COMP_SCALE_FACTOR);
temp_comp = ((float)(C0))*0.5 + temp_sc_float * ((float)(C1));
// Read Infineon Barometric Pressure Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&read_baro[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
// Collect pressure data
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR,(uint8_t*)&get_baro_data[0], 1, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
measurement_timer=0;
I2C_MASTER_Receive(&I2C_MASTER_0, true, BAROMETRIC_SENS_ADDR, &dps610_baro_data[0], 3, true, true);
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20));
BARO = (int32_t) dps610_baro_data[0];
BARO <<= 8;
BARO += (int32_t) dps610_baro_data[1];
BARO <<= 8;
BARO += (int32_t) dps610_baro_data[2];
if(BARO > 0x7fffff) BARO -= 0x1000000;
baro_sc_float = ((float)( BARO))/ ((float) BARO_COMP_SCALE_FACTOR);
baro_comp = ((float)(C20) + baro_sc_float * (float)(C30));
baro_comp = ((float)(C10) + baro_sc_float * baro_comp);
baro_comp = ((float)(C00) + baro_sc_float * baro_comp);
baro_comp += temp_sc_float * ((float)(C01));
baro_comp += temp_sc_float * baro_sc_float * (((float)(C11)) + baro_sc_float*((float)(C21)));
// Read Sensirion Humidity and Temperature Sensor
measurement_timer=0;
I2C_MASTER_Transmit(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR,(uint8_t*)&measure_hum[0], 2, true);
while((I2C_MASTER_IsTxBusy(&I2C_MASTER_0))&&(measurement_timer < 5));
if(measurement_timer>=5){
I2C_MASTER_AbortTransmit(&I2C_MASTER_0);
}else{
while(measurement_timer < 20){
// wait a while for the measurement to complete
}
I2C_MASTER_Receive(&I2C_MASTER_0, true, HUMIDITY_SENS_ADDR, &rx_buf[0], 6, true, true);
measurement_timer=0;
while((I2C_MASTER_IsRxBusy(&I2C_MASTER_0))&&(measurement_timer < 20)){
}
if(measurement_timer < 20){
// Now we have data to look at.
// Use the CRC checksum
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[0], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[1], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[2], CRC8_POLY);
if(!test_crc){
temp_int = (int)(rx_buf[0]);
temp_int <<= 8;
temp_int += (int)(rx_buf[1]);
sensirion_temp = -45.0 + ((175.0 * (float)(temp_int))/65535);
}
test_crc = 0xff; // guessing that CRC should be initialized to 0xff
test_crc = CheckSumByteCRC8( test_crc, rx_buf[3], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[4], CRC8_POLY);
test_crc = CheckSumByteCRC8( test_crc, rx_buf[5], CRC8_POLY);
if(!test_crc){
temp_int = (int)(rx_buf[3]);
temp_int <<= 8;
temp_int += (int)(rx_buf[4]);
sensirion_rel_humidity = (100.0 * (float)(temp_int))/65535;
}
}else{
I2C_MASTER_AbortReceive(&I2C_MASTER_0);
}
}
// Close the window if the LED is flashing
if(baro_comp < 97107.0){
flash_led = 1;
}else{
if(sensirion_rel_humidity > 45.0){
flash_led = 1;
}else{
flash_led = 0;
}
}
}
}
void Timer_Interval_Event(void)
{
measurement_timer++;
event_count++;
if (event_count >= 500U)
{
event_count = 0;
if(flash_led){
DIGITAL_IO_ToggleOutput(&DIGITAL_IO_0);
}else{
event_count = 0;
DIGITAL_IO_SetOutputLow(&DIGITAL_IO_0);
}
}
}
void EndofTransmit()//
{
UART_Receive(&UART_0, rec_data, sizeof(rec_data));
}
void EndofReceive()//
{
UART_Transmit(&UART_0, rec_data, sizeof(rec_data));
}
I ran out of time to get actuators and a sample window before the project deadline.
Comments