@ -19,6 +19,21 @@ RAK4631SensorManager sensors = RAK4631SensorManager(nmea);
RAK4631SensorManager sensors ;
# endif
# if ENV_INCLUDE_BME680
# ifndef TELEM_BME680_ADDRESS
# define TELEM_BME680_ADDRESS 0x76 // BME680 environmental sensor I2C address
# endif
# include <bsec2.h>
static Bsec2 BME680 ;
float rawPressure = 0 ;
float rawTemperature = 0 ;
float compTemperature = 0 ;
float rawHumidity = 0 ;
float compHumidity = 0 ;
float readIAQ = 0 ;
float readCO2 = 0 ;
# endif
# ifdef DISPLAY_CLASS
DISPLAY_CLASS display ;
# endif
@ -43,6 +58,10 @@ void scanDevices(TwoWire *w)
Serial . println ( " \t Found RAK12500 GPS Sensor " ) ;
deviceOnline | = RAK12500_ONLINE ;
break ;
case 0x76 :
Serial . println ( " \t Found RAK1906 Environment Sensor " ) ;
deviceOnline | = BME680_ONLINE ;
break ;
default :
Serial . print ( " \t I2C device found at address 0x " ) ;
if ( addr < 16 ) {
@ -137,7 +156,7 @@ bool RAK4631SensorManager::gpsIsAwake(uint32_t ioPin){
ublox_GNSS . saveConfigSelective ( VAL_CFG_SUBSEC_IOPORT ) ;
disStandbyPin = ioPin ;
gps_active = true ;
gps_present = true ;
gps_detected = true ;
return true ;
}
else
@ -147,73 +166,256 @@ bool RAK4631SensorManager::gpsIsAwake(uint32_t ioPin){
}
# endif
# if ENV_INCLUDE_BME680
void checkBMEStatus ( Bsec2 bsec )
{
if ( bsec . status < BSEC_OK )
{
MESH_DEBUG_PRINTLN ( " BSEC error code : %f " , String ( bsec . status ) ) ;
}
else if ( bsec . status > BSEC_OK )
{
MESH_DEBUG_PRINTLN ( " BSEC warning code : %f " , String ( bsec . status ) ) ;
}
if ( bsec . sensor . status < BME68X_OK )
{
MESH_DEBUG_PRINTLN ( " BME68X error code : %f " , String ( bsec . sensor . status ) ) ;
}
else if ( bsec . sensor . status > BME68X_OK )
{
MESH_DEBUG_PRINTLN ( " BME68X warning code : %f " , String ( bsec . sensor . status ) ) ;
}
}
void newDataCallback ( const bme68xData data , const bsecOutputs outputs , Bsec2 bsec )
{
if ( ! outputs . nOutputs )
{
MESH_DEBUG_PRINTLN ( " No new data to report out " ) ;
return ;
}
MESH_DEBUG_PRINTLN ( " BSEC outputs: \n \t Time stamp = %f " , String ( ( int ) ( outputs . output [ 0 ] . time_stamp / INT64_C ( 1000000 ) ) ) ) ;
for ( uint8_t i = 0 ; i < outputs . nOutputs ; i + + )
{
const bsecData output = outputs . output [ i ] ;
switch ( output . sensor_id )
{
case BSEC_OUTPUT_IAQ :
MESH_DEBUG_PRINTLN ( " \t IAQ = %f " , String ( output . signal ) ) ;
MESH_DEBUG_PRINTLN ( " \t IAQ accuracy = %f " , String ( ( int ) output . accuracy ) ) ;
break ;
case BSEC_OUTPUT_RAW_TEMPERATURE :
rawTemperature = output . signal ;
MESH_DEBUG_PRINTLN ( " \t Temperature = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_RAW_PRESSURE :
rawPressure = output . signal ;
MESH_DEBUG_PRINTLN ( " \t Pressure = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_RAW_HUMIDITY :
rawHumidity = output . signal ;
MESH_DEBUG_PRINTLN ( " \t Humidity = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_RAW_GAS :
MESH_DEBUG_PRINTLN ( " \t Gas resistance = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_STABILIZATION_STATUS :
MESH_DEBUG_PRINTLN ( " \t Stabilization status = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_RUN_IN_STATUS :
MESH_DEBUG_PRINTLN ( " \t Run in status = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE :
compTemperature = output . signal ;
MESH_DEBUG_PRINTLN ( " \t Compensated temperature = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY :
compHumidity = output . signal ;
MESH_DEBUG_PRINTLN ( " \t Compensated humidity = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_STATIC_IAQ :
readIAQ = output . signal ;
MESH_DEBUG_PRINTLN ( " \t Static IAQ = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_CO2_EQUIVALENT :
readCO2 = output . signal ;
MESH_DEBUG_PRINTLN ( " \t CO2 Equivalent = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_BREATH_VOC_EQUIVALENT :
MESH_DEBUG_PRINTLN ( " \t bVOC equivalent = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_GAS_PERCENTAGE :
MESH_DEBUG_PRINTLN ( " \t Gas percentage = %f " , String ( output . signal ) ) ;
break ;
case BSEC_OUTPUT_COMPENSATED_GAS :
MESH_DEBUG_PRINTLN ( " \t Compensated gas = %f " , String ( output . signal ) ) ;
break ;
default :
break ;
}
}
}
# endif
bool RAK4631SensorManager : : begin ( ) {
# ifdef MESH_DEBUG
scanDevices ( & Wire ) ;
# endif
# if ENV_INCLUDE_GPS
//search for the correct IO standby pin depending on socket used
if ( gpsIsAwake ( P_GPS_STANDBY_A ) ) {
MESH_DEBUG_PRINTLN ( " GPS is on socket A " ) ;
}
else if ( gpsIsAwake ( P_GPS_STANDBY_C ) ) {
MESH_DEBUG_PRINTLN ( " GPS is on socket C " ) ;
}
else if ( gpsIsAwake ( P_GPS_STANDBY_F ) ) {
MESH_DEBUG_PRINTLN ( " GPS is on socket F " ) ;
}
else {
MESH_DEBUG_PRINTLN ( " Error: No GPS found on sockets A, C or F " ) ;
gps_active = false ;
gps_present = false ;
return false ;
}
# if ENV_INCLUDE_GPS
//search for the correct IO standby pin depending on socket used
if ( gpsIsAwake ( P_GPS_STANDBY_A ) ) {
MESH_DEBUG_PRINTLN ( " GPS is on socket A " ) ;
}
else if ( gpsIsAwake ( P_GPS_STANDBY_C ) ) {
MESH_DEBUG_PRINTLN ( " GPS is on socket C " ) ;
}
else if ( gpsIsAwake ( P_GPS_STANDBY_F ) ) {
MESH_DEBUG_PRINTLN ( " GPS is on socket F " ) ;
}
else {
MESH_DEBUG_PRINTLN ( " Error: No GPS found on sockets A, C or F " ) ;
gps_active = false ;
gps_detected = false ;
return false ;
}
//Now that GPS is found and set up, set to sleep for initial state
stop_gps ( ) ;
# endif
# ifndef FORCE_GPS_ALIVE
//Now that GPS is found and set up, set to sleep for initial state
stop_gps ( ) ;
# endif
# endif
# if ENV_INCLUDE_BME680
bsecSensor sensorList [ 4 ] = {
BSEC_OUTPUT_IAQ ,
// BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE ,
// BSEC_OUTPUT_RAW_HUMIDITY,
// BSEC_OUTPUT_RAW_GAS,
// BSEC_OUTPUT_STABILIZATION_STATUS,
// BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE ,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY ,
// BSEC_OUTPUT_STATIC_IAQ,
// BSEC_OUTPUT_CO2_EQUIVALENT,
// BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
// BSEC_OUTPUT_GAS_PERCENTAGE,
// BSEC_OUTPUT_COMPENSATED_GAS
} ;
if ( ! BME680 . begin ( TELEM_BME680_ADDRESS , Wire ) ) {
checkBMEStatus ( BME680 ) ;
bme680_present = false ;
bme680_active = false ;
return false ;
}
MESH_DEBUG_PRINTLN ( " Found BME680 at address: %02X " , TELEM_BME680_ADDRESS ) ;
bme680_present = true ;
bme680_active = true ;
if ( SAMPLING_RATE = = BSEC_SAMPLE_RATE_ULP )
{
BME680 . setTemperatureOffset ( BSEC_SAMPLE_RATE_ULP ) ;
}
else if ( SAMPLING_RATE = = BSEC_SAMPLE_RATE_LP )
{
BME680 . setTemperatureOffset ( TEMP_OFFSET_LP ) ;
}
if ( ! BME680 . updateSubscription ( sensorList , ARRAY_LEN ( sensorList ) , SAMPLING_RATE ) )
{
checkBMEStatus ( BME680 ) ;
}
BME680 . attachCallback ( newDataCallback ) ;
# endif
}
# if ENV_INCLUDE_GPS
bool RAK4631SensorManager : : querySensors ( uint8_t requester_permissions , CayenneLPP & telemetry ) {
# ifdef ENV_INCLUDE_GPS
if ( requester_permissions & TELEM_PERM_LOCATION & & gps_active ) { // does requester have permission?
telemetry . addGPS ( TELEM_CHANNEL_SELF , node_lat , node_lon , node_altitude ) ;
}
# endif
if ( requester_permissions & TELEM_PERM_ENVIRONMENT ) {
# if ENV_INCLUDE_BME680
if ( bme680_active ) {
telemetry . addTemperature ( TELEM_CHANNEL_SELF , compTemperature ) ;
telemetry . addRelativeHumidity ( TELEM_CHANNEL_SELF , compHumidity ) ;
telemetry . addBarometricPressure ( TELEM_CHANNEL_SELF , rawPressure ) ;
telemetry . addRelativeHumidity ( TELEM_CHANNEL_SELF + 1 , readIAQ ) ;
}
# endif
}
return true ;
}
void RAK4631SensorManager : : loop ( ) {
static long next_update = 0 ;
# ifdef ENV_INCLUDE_GPS
_nmea - > loop ( ) ;
# endif
if ( millis ( ) > next_update & & gps_active ) {
node_lat = ( double ) ublox_GNSS . getLatitude ( ) / 10000000. ;
node_lon = ( double ) ublox_GNSS . getLongitude ( ) / 10000000. ;
node_altitude = ( double ) ublox_GNSS . getAltitude ( ) / 1000. ;
MESH_DEBUG_PRINT ( " lat %f lon %f alt %f \r \n " , node_lat , node_lon , node_altitude ) ;
if ( millis ( ) > next_update ) {
# ifdef ENV_INCLUDE_GPS
if ( gps_active ) {
node_lat = ( double ) ublox_GNSS . getLatitude ( ) / 10000000. ;
node_lon = ( double ) ublox_GNSS . getLongitude ( ) / 10000000. ;
node_altitude = ( double ) ublox_GNSS . getAltitude ( ) / 1000. ;
MESH_DEBUG_PRINT ( " lat %f lon %f alt %f \r \n " , node_lat , node_lon , node_altitude ) ;
}
# endif
# ifdef ENV_INCLUDE_BME680
if ( bme680_active ) {
if ( ! BME680 . run ( ) ) {
checkBMEStatus ( BME680 ) ;
}
}
# endif
next_update = millis ( ) + 1000 ;
}
}
int RAK4631SensorManager : : getNumSettings ( ) const { return 1 ; } // just one supported: "gps" (power switch)
int RAK4631SensorManager : : getNumSettings ( ) const {
# if ENV_INCLUDE_GPS
return gps_detected ? 1 : 0 ; // only show GPS setting if GPS is detected
# else
return 0 ;
# endif
}
const char * RAK4631SensorManager : : getSettingName ( int i ) const {
return i = = 0 ? " gps " : NULL ;
# if ENV_INCLUDE_GPS
return ( gps_detected & & i = = 0 ) ? " gps " : NULL ;
# else
return NULL ;
# endif
}
const char * RAK4631SensorManager : : getSettingValue ( int i ) const {
if ( i = = 0 ) {
# if ENV_INCLUDE_GPS
if ( gps_detected & & i = = 0 ) {
return gps_active ? " 1 " : " 0 " ;
}
# endif
return NULL ;
}
bool RAK4631SensorManager : : setSettingValue ( const char * name , const char * value ) {
if ( strcmp ( name , " gps " ) = = 0 ) {
# if ENV_INCLUDE_GPS
if ( gps_detected & & strcmp ( name , " gps " ) = = 0 ) {
if ( strcmp ( value , " 0 " ) = = 0 ) {
stop_gps ( ) ;
} else {
@ -221,9 +423,9 @@ bool RAK4631SensorManager::setSettingValue(const char* name, const char* value)
}
return true ;
}
# endif
return false ; // not supported
}
# endif
mesh : : LocalIdentity radio_new_identity ( ) {
RadioNoiseListener rng ( radio ) ;