Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

BME280 #76

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
bin_PROGRAMS = openstratos
openstratos_SOURCES = openstratos.cc utils.cc threads.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc gsm/GSM.cc
openstratos_SOURCES = openstratos.cc utils.cc threads.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc gsm/GSM.cc bme280/BME280.cc
openstratos_CPPFLAGS = -std=c++14

EXTRA_PROGRAMS = utesting
Expand Down
148 changes: 148 additions & 0 deletions bme280/BME280.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#include "bme280/BME280.h"

#include <cstdint>

#include <wiringPiI2C.h>

#include "constants.h"

using namespace os;

BME280::BME280()
{
this->filehandle = wiringPiI2CSetup(BME280_DEVICE);

if (wiringPiI2CReadReg8(this->filehandle, BME280_REGISTER_CHIPID) != 0x60)
return;

this->bme280_calib.dig_T1 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_T1));
this->bme280_calib.dig_T2 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_T2));
this->bme280_calib.dig_T3 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_T3));

this->bme280_calib.dig_P1 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P1));
this->bme280_calib.dig_P2 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P2));
this->bme280_calib.dig_P3 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P3));
this->bme280_calib.dig_P4 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P4));
this->bme280_calib.dig_P5 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P5));
this->bme280_calib.dig_P6 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P6));
this->bme280_calib.dig_P7 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P7));
this->bme280_calib.dig_P8 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P8));
this->bme280_calib.dig_P9 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_P9));

this->bme280_calib.dig_H1 = wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H1);
this->bme280_calib.dig_H2 = this->to_LE(wiringPiI2CReadReg16(
this->filehandle, BME280_REGISTER_DIG_H2));
this->bme280_calib.dig_H3 = wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H3);
this->bme280_calib.dig_H4 = (wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H4) << 4) |
(wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H4+1) & 0xF);
this->bme280_calib.dig_H5 = (wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H5+1) << 4) |
(wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H5) >> 4);
this->bme280_calib.dig_H6 = (int8_t) wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_DIG_H6);

// Set before CONTROL (DS 5.4.3)
wiringPiI2CWriteReg8(this->filehandle, BME280_REGISTER_CONTROLHUMID, 0x03);
wiringPiI2CWriteReg8(this->filehandle, BME280_REGISTER_CONTROL, 0x3F);
}

double BME280::get_temperature()
{
int32_t var1, var2;

int32_t adc_T = wiringPiI2CReadReg16(this->filehandle,
BME280_REGISTER_TEMPDATA);
adc_T <<= 8;
adc_T |= wiringPiI2CReadReg8(this->filehandle, BME280_REGISTER_TEMPDATA+2);
adc_T >>= 4;

var1 = ((((adc_T>>3) - ((int32_t) this->bme280_calib.dig_T1 <<1))) *
((int32_t) this->bme280_calib.dig_T2)) >> 11;

var2 = (((((adc_T>>4) - ((int32_t) this->bme280_calib.dig_T1)) *
((adc_T>>4) - ((int32_t) this->bme280_calib.dig_T1))) >> 12) *
((int32_t) this->bme280_calib.dig_T3)) >> 14;

this->t_fine = var1 + var2;

double T = (t_fine * 5 + 128) >> 8;
return T/100;
}

double BME280::get_pressure() const
{
int64_t var1, var2, p;

int32_t adc_P = wiringPiI2CReadReg16(this->filehandle,
BME280_REGISTER_PRESSUREDATA);
adc_P <<= 8;
adc_P |= wiringPiI2CReadReg8(this->filehandle,
BME280_REGISTER_PRESSUREDATA+2);
adc_P >>= 4;

var1 = ((int64_t) t_fine) - 128000;
var2 = var1 * var1 * (int64_t) this->bme280_calib.dig_P6;
var2 = var2 + ((var1*(int64_t) this->bme280_calib.dig_P5)<<17);
var2 = var2 + (((int64_t) this->bme280_calib.dig_P4)<<35);
var1 = ((var1 * var1 * (int64_t) this->bme280_calib.dig_P3)>>8) +
((var1 * (int64_t) this->bme280_calib.dig_P2)<<12);
var1 = (((((int64_t)1)<<47)+var1))*(
(int64_t) this->bme280_calib.dig_P1)>>33;

if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - adc_P;
p = (((p<<31) - var2)*3125) / var1;
var1 = (((int64_t) this->bme280_calib.dig_P9) * (p>>13) * (p>>13)) >> 25;
var2 = (((int64_t) this->bme280_calib.dig_P8) * p) >> 19;

p = ((p + var1 + var2) >> 8) + (((int64_t) this->bme280_calib.dig_P7)<<4);
return (double) p/256;
}

double BME280::get_humidity() const
{
int32_t adc_H = wiringPiI2CReadReg16(this->filehandle,
BME280_REGISTER_HUMIDDATA);

int32_t v_x1_u32r;

v_x1_u32r = (t_fine - ((int32_t)76800));

v_x1_u32r = (((((adc_H << 14) - (((int32_t) this->bme280_calib.dig_H4) <<
20) -
(((int32_t) this->bme280_calib.dig_H5) * v_x1_u32r)) +
((int32_t)16384)) >> 15) *
(((((((v_x1_u32r * ((int32_t)
this->bme280_calib.dig_H6)) >> 10) *
(((v_x1_u32r * ((int32_t) this->bme280_calib.dig_H3)) >> 11)
+ ((int32_t)32768))) >> 10) +
((int32_t)2097152)) * ((int32_t)
this->bme280_calib.dig_H2) + 8192) >> 14));

v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
((int32_t) this->bme280_calib.dig_H1)) >> 4));

v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
double h = (v_x1_u32r>>12);
return h / 1024;
}
98 changes: 98 additions & 0 deletions bme280/BME280.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#ifndef BME280_BME280_H_
#define BME280_BME280_H_

#include <cstdint>

namespace os {
/*=========================================================================
REGISTERS
-----------------------------------------------------------------------*/
enum
{
BME280_REGISTER_DIG_T1 = 0x88,
BME280_REGISTER_DIG_T2 = 0x8A,
BME280_REGISTER_DIG_T3 = 0x8C,

BME280_REGISTER_DIG_P1 = 0x8E,
BME280_REGISTER_DIG_P2 = 0x90,
BME280_REGISTER_DIG_P3 = 0x92,
BME280_REGISTER_DIG_P4 = 0x94,
BME280_REGISTER_DIG_P5 = 0x96,
BME280_REGISTER_DIG_P6 = 0x98,
BME280_REGISTER_DIG_P7 = 0x9A,
BME280_REGISTER_DIG_P8 = 0x9C,
BME280_REGISTER_DIG_P9 = 0x9E,

BME280_REGISTER_DIG_H1 = 0xA1,
BME280_REGISTER_DIG_H2 = 0xE1,
BME280_REGISTER_DIG_H3 = 0xE3,
BME280_REGISTER_DIG_H4 = 0xE4,
BME280_REGISTER_DIG_H5 = 0xE5,
BME280_REGISTER_DIG_H6 = 0xE7,

BME280_REGISTER_CHIPID = 0xD0,
BME280_REGISTER_VERSION = 0xD1,
BME280_REGISTER_SOFTRESET = 0xE0,

// R calibration stored in 0xE1-0xF0
BME280_REGISTER_CAL26 = 0xE1,

BME280_REGISTER_CONTROLHUMID = 0xF2,
BME280_REGISTER_CONTROL = 0xF4,
BME280_REGISTER_CONFIG = 0xF5,
BME280_REGISTER_PRESSUREDATA = 0xF7,
BME280_REGISTER_TEMPDATA = 0xFA,
BME280_REGISTER_HUMIDDATA = 0xFD,
};
/*========================================================================*/

/*=========================================================================
CALIBRATION DATA
-----------------------------------------------------------------------*/
typedef struct
{
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;

uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;

uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
} bme280_calib_data;
/*========================================================================*/

class BME280
{
private:
int filehandle;
bme280_calib_data bme280_calib;

int32_t t_fine;

uint16_t to_LE(uint16_t be) { return (be >> 8) | (be << 8); }

public:
BME280(BME280& copy) = delete;
BME280();
~BME280() = default;

double get_temperature();
double get_pressure() const;
double get_humidity() const;
};
}

#endif // BME280_BME280_H_
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.68])
AC_INIT(OpenStratos, 1.0, https://github.com/OpenStratos/server/issues)
AC_INIT(OpenStratos, 1.1-dev, https://github.com/OpenStratos/server/issues)
AC_CONFIG_SRCDIR([openstratos.cc])
AM_INIT_AUTOMAKE([subdir-objects])
AC_CONFIG_HEADERS([config.h])
Expand Down
3 changes: 3 additions & 0 deletions constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@
#define SMS_PHONE ""

#define STATE_FILE "data/last_state.txt"

// TODO get the real one
#define BME280_DEVICE (0x77)
#endif // CONSTANTS_H_
3 changes: 1 addition & 2 deletions gps/GPS.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "gps/GPS.h"
#include "constants.h"

#include <functional>
#include <vector>
Expand All @@ -11,8 +10,8 @@
#include <sys/time.h>

#include <wiringPi.h>

#include "constants.h"

#include "serial/Serial.h"
#include "logger/Logger.h"

Expand Down
27 changes: 19 additions & 8 deletions openstratos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ int main(void)
cout << "[OpenStratos] Realistic simulation." << endl;
#endif

cout << "[OpenStratos] Starting..." << endl;
cout << "[OpenStratos] Starting " << PACKAGE_STRING << "..." << endl;
#endif

if ( ! file_exists(STATE_FILE))
Expand Down Expand Up @@ -45,8 +45,8 @@ void os::main_logic()

#ifdef DEBUG
cout << "[OpenStratos] Current time: " << setfill('0') << setw(2) << now->tm_hour << ":" <<
setfill('0') << setw(2) << now->tm_min << ":" << setfill('0') << setw(2) << now->tm_sec <<
" UTC of " << setfill('0') << setw(2) << now->tm_mon << "/" <<
setfill('0') << setw(2) << now->tm_min << ":" << setfill('0') << setw(2) << now->tm_sec
<< " UTC of " << setfill('0') << setw(2) << now->tm_mon << "/" <<
setfill('0') << setw(2) << now->tm_mday << "/" << (now->tm_year+1900) << endl;
#endif

Expand All @@ -72,6 +72,8 @@ void os::main_logic()
cout << "[OpenStratos] Logger started." << endl;
#endif

logger.log(PACKAGE_STRING);

logger.log("Starting system thread...");
thread system_thread(&system_thread_fn, ref(state));
logger.log("System thread started.");
Expand Down Expand Up @@ -122,8 +124,10 @@ void os::safe_mode()
struct tm* now = gmtime(&timer.tv_sec);

logger = new Logger("data/logs/main/OpenStratos."+ to_string(now->tm_year+1900) +"-"+
to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+
to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "OpenStratos");
to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour)
+"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "OpenStratos");

logger->log(PACKAGE_STRING);
}

switch (last_state)
Expand Down Expand Up @@ -232,9 +236,9 @@ void os::safe_mode()
logger->log("GSM connected.");

logger->log("Sending mayday messages...");
for (count = 0; count < 10;)
for (count = 0; count < 2;)
{
this_thread::sleep_for(20s);
this_thread::sleep_for(1min);

GSM::get_instance().get_location(latitude, longitude);
GSM::get_instance().send_SMS("MAYDAY\r\nLat: "+ to_string(latitude) +"\r\n"+
Expand Down Expand Up @@ -262,7 +266,14 @@ void os::safe_mode()
}

logger->log("GPS fix acquired.");
this_thread::sleep_for(1min);
this_thread::sleep_for(10s);
GSM::get_instance().send_SMS("MAYDAY\r\nLat: " +
to_string(GPS::get_instance().get_latitude()) +
"\r\nLon: "+ to_string(GPS::get_instance().get_longitude()) +
"\r\nAlt: "+ to_string(GPS::get_instance().get_altitude()) +
"\r\nFix: OK", SMS_PHONE) && ++count;

this_thread::sleep_for(30s);
state = (state == LANDED) ? LANDED : get_real_state();

main_while(logger, &state);
Expand Down