refactor sending code
This commit is contained in:
parent
9be03ea5c2
commit
da5e52a033
|
|
@ -26,59 +26,14 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <HX711.h>
|
#include <HX711.h>
|
||||||
|
#include "mini_beieli_node.h"
|
||||||
|
|
||||||
using namespace McciCatena;
|
using namespace McciCatena;
|
||||||
|
|
||||||
/****************************************************************************\
|
|
||||||
|
|
|
||||||
| MANIFEST CONSTANTS & TYPEDEFS
|
|
||||||
|
|
|
||||||
\****************************************************************************/
|
|
||||||
|
|
||||||
constexpr uint8_t kUplinkPort = 2;
|
|
||||||
|
|
||||||
/* how long do we wait between transmissions? (in seconds) */
|
|
||||||
enum {
|
|
||||||
// set this to interval between transmissions, in seconds
|
|
||||||
// Actual time will be a little longer because have to
|
|
||||||
// add measurement and broadcast time, but we attempt
|
|
||||||
// to compensate for the gross effects below.
|
|
||||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
|
||||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
|
||||||
CATCFG_T_CYCLE_INITIAL = 30, // every 30 seconds initially
|
|
||||||
CATCFG_INTERVAL_COUNT_INITIAL = 30, // repeat for 15 minutes
|
|
||||||
};
|
|
||||||
|
|
||||||
/* additional timing parameters; ususually you don't change these. */
|
|
||||||
enum {
|
|
||||||
CATCFG_T_WARMUP = 1,
|
|
||||||
CATCFG_T_SETTLE = 5,
|
|
||||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
|
||||||
CATCFG_T_MIN = CATCFG_T_OVERHEAD,
|
|
||||||
CATCFG_T_MAX = CATCFG_T_CYCLE < 60 * 60 ? 60 * 60 : CATCFG_T_CYCLE, // normally one hour max.
|
|
||||||
CATCFG_INTERVAL_COUNT = 30,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
|
||||||
{
|
|
||||||
return (tCycle < CATCFG_T_OVERHEAD)
|
|
||||||
? CATCFG_T_OVERHEAD
|
|
||||||
: tCycle - CATCFG_T_OVERHEAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
|
||||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
|
||||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
|
||||||
};
|
|
||||||
|
|
||||||
// forwards
|
// forwards
|
||||||
static void settleDoneCb(osjob_t* pSendJob);
|
static void settleDoneCb(osjob_t* pSendJob);
|
||||||
static void warmupDoneCb(osjob_t* pSendJob);
|
static void warmupDoneCb(osjob_t* pSendJob);
|
||||||
|
static void startNewIterationCb(osjob_t* pJob);
|
||||||
static void txNotProvisionedCb(osjob_t *pSendJob);
|
static void txNotProvisionedCb(osjob_t *pSendJob);
|
||||||
static void sleepDoneCb(osjob_t* pSendJob);
|
static void sleepDoneCb(osjob_t* pSendJob);
|
||||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||||
|
|
@ -123,69 +78,12 @@ sMyExtraCommands_top(
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************\
|
|
||||||
|
|
|
||||||
| READ-ONLY DATA
|
|
||||||
|
|
|
||||||
\****************************************************************************/
|
|
||||||
|
|
||||||
static const int32_t fwVersion = 20191004;
|
|
||||||
static const byte MAX_VALUES_TO_SEND = 8;
|
|
||||||
static const uint8_t LORA_DATA_VERSION = 1;
|
|
||||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 129;
|
|
||||||
static const uint32_t PRESSURE_OFFSET = 825;
|
|
||||||
static const uint16_t SEND_DIFF_THRESHOLD_5GRAMS = 10; // when weight value drops by 50g, then send data
|
|
||||||
|
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
|
|
|
|
||||||
| VARIABLES
|
| VARIABLES
|
||||||
|
|
|
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
// must be 139 bytes long (size of kBme680Cal)
|
|
||||||
typedef struct {
|
|
||||||
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
|
||||||
long cal_w2_0; // 4 Bytes, Wert Waegezelle 2 ohne Gewicht
|
|
||||||
float cal_w1_factor; // 4 Bytes, Kalibrationsfaktor Waegezelle 1
|
|
||||||
float cal_w2_factor; // 4 Bytes, Kalibrationsfaktor Waegezelle 2
|
|
||||||
byte debug_level; // 0 => no debugging, 1 => infos, 2 => error, 3 => highest level
|
|
||||||
byte fill[122];
|
|
||||||
} __attribute__((packed)) CONFIG_data;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t version; // Version of Packet Format (must be increased every time format changes...)
|
|
||||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
|
||||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
|
||||||
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
|
||||||
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
|
||||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
|
||||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
|
||||||
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
|
||||||
} __attribute__((packed)) LORA_data;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t version; // Version of Packet Format (must be increased every time format changes...)
|
|
||||||
int32_t fw_version; // Version of Firmware, Nummer entspricht YYYYMMDD
|
|
||||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
|
||||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
|
||||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
|
||||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
|
||||||
int32_t weight1; // Waegezelle 1, Raw Value
|
|
||||||
int32_t weight2; // Waegezelle 2, Raw Value
|
|
||||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
|
||||||
} __attribute__((packed)) LORA_data_first;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
|
||||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
|
||||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
|
||||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
|
||||||
int32_t weight1; // Waegezelle 1, Raw Value
|
|
||||||
int32_t weight2; // Waegezelle 2, Raw Value
|
|
||||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
|
||||||
} SENSOR_data;
|
|
||||||
|
|
||||||
|
|
||||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||||
long timer_pos0;
|
long timer_pos0;
|
||||||
|
|
||||||
|
|
@ -194,6 +92,7 @@ LORA_data lora_data;
|
||||||
LORA_data_first lora_data_first;
|
LORA_data_first lora_data_first;
|
||||||
CONFIG_data config_data;
|
CONFIG_data config_data;
|
||||||
SENSOR_data last_sensor_reading;
|
SENSOR_data last_sensor_reading;
|
||||||
|
long iteration = 0; // what iteration number do we have, starts with 0
|
||||||
|
|
||||||
// generic timer
|
// generic timer
|
||||||
long t_cur;
|
long t_cur;
|
||||||
|
|
@ -234,9 +133,9 @@ bool fUsbPower;
|
||||||
// have we printed the sleep info?
|
// have we printed the sleep info?
|
||||||
bool g_fPrintedSleeping = false;
|
bool g_fPrintedSleeping = false;
|
||||||
|
|
||||||
// tFhe job that's used to synchronize us with the LMIC code
|
// the job that's used to synchronize us with the LMIC code
|
||||||
static osjob_t sensorJob;
|
static osjob_t sensorJob;
|
||||||
void sensorJob_cb(osjob_t* pJob);
|
static osjob_t iterationJob;
|
||||||
|
|
||||||
void setup(void)
|
void setup(void)
|
||||||
{
|
{
|
||||||
|
|
@ -276,6 +175,8 @@ void setup_platform(void)
|
||||||
gCatena.SafePrintf("cal_w2_factor: %d.%03d\n", (int)config_data.cal_w2_factor, (int)(config_data.cal_w2_factor * 1000) % 1000);
|
gCatena.SafePrintf("cal_w2_factor: %d.%03d\n", (int)config_data.cal_w2_factor, (int)(config_data.cal_w2_factor * 1000) % 1000);
|
||||||
gCatena.SafePrintf("debug_level: %d\n", (int)config_data.debug_level);
|
gCatena.SafePrintf("debug_level: %d\n", (int)config_data.debug_level);
|
||||||
gCatena.SafePrintf("Size of config_data: %d\n", sizeof(config_data));
|
gCatena.SafePrintf("Size of config_data: %d\n", sizeof(config_data));
|
||||||
|
gCatena.SafePrintf("Size of lora_data_first: %d\n", sizeof(lora_data_first));
|
||||||
|
gCatena.SafePrintf("Size of lora_data: %d\n", sizeof(lora_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -441,7 +342,7 @@ void setup_uplink(void)
|
||||||
gLed.Set(LedPattern::Joining);
|
gLed.Set(LedPattern::Joining);
|
||||||
|
|
||||||
/* trigger a join by sending the first packet */
|
/* trigger a join by sending the first packet */
|
||||||
ReadSensors(true, false);
|
StartNewIteration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +466,6 @@ uint8_t GetVBatValue(int millivolts)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DoDeepSleep()
|
void DoDeepSleep()
|
||||||
{
|
{
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
|
|
@ -595,51 +495,30 @@ void DoDeepSleep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReadSensors(SENSOR_data &sensor_data) {
|
||||||
void ReadSensors(bool firstTime, bool readOnly)
|
SENSOR_data res;
|
||||||
{
|
|
||||||
int16_t temp_current;
|
|
||||||
uint8_t humidity_current;
|
|
||||||
uint8_t pressure_current;
|
|
||||||
int32_t weight1_current;
|
|
||||||
int32_t weight2_current;
|
|
||||||
int16_t temp_change;
|
|
||||||
int32_t weight_current32;
|
int32_t weight_current32;
|
||||||
uint16_t weight_current;
|
|
||||||
|
|
||||||
// vBat
|
// vBat
|
||||||
float vBat = gCatena.ReadVbat();
|
res.vbat = (uint8_t)(gCatena.ReadVbat() * 1000.0f);
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
gCatena.SafePrintf("vBat: %d mV\n", res.vbat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vBus
|
|
||||||
float vBus = gCatena.ReadVbus();
|
|
||||||
if (config_data.debug_level > 0) {
|
|
||||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
|
||||||
}
|
|
||||||
fUsbPower = (vBus > 4.3) ? true : false;
|
|
||||||
|
|
||||||
// Setup Scales
|
|
||||||
|
|
||||||
// Read Scales
|
// Read Scales
|
||||||
if (setup_scales()) {
|
if (setup_scales()) {
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("HX711 LoadCell is ready.\n");
|
gCatena.SafePrintf("HX711 LoadCell is ready.\n");
|
||||||
}
|
}
|
||||||
LoadCell.set_gain(128);
|
LoadCell.set_gain(128);
|
||||||
long w1 = LoadCell.read_average(5);
|
res.weight1 = (int32_t)LoadCell.read_average(5);
|
||||||
weight1_current = (int32_t)w1;
|
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
gCatena.SafePrintf("Load_cell 1 weight1_current: %ld\n", res.weight1);
|
||||||
gCatena.SafePrintf("Load_cell 1 weight1_current: %ld\n", weight1_current);
|
|
||||||
}
|
}
|
||||||
LoadCell.set_gain(32);
|
LoadCell.set_gain(32);
|
||||||
long w2 = LoadCell.read_average(5);
|
res.weight2 = (int32_t)LoadCell.read_average(5);
|
||||||
weight2_current = (int32_t)w2;
|
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
gCatena.SafePrintf("Load_cell 2 weight2_current: %ld\n", res.weight2);
|
||||||
gCatena.SafePrintf("Load_cell 2 weight2_current: %ld\n", weight2_current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -652,13 +531,13 @@ void ReadSensors(bool firstTime, bool readOnly)
|
||||||
digitalWrite(D10, LOW);
|
digitalWrite(D10, LOW);
|
||||||
|
|
||||||
// Gewicht berechnen
|
// Gewicht berechnen
|
||||||
weight_current32 = (int32_t)((((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor)) / 5.0);
|
weight_current32 = (int32_t)((((res.weight1 - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((res.weight2 - config_data.cal_w2_0) / config_data.cal_w2_factor)) / 5.0);
|
||||||
if (weight_current32 < 0) {
|
if (weight_current32 < 0) {
|
||||||
weight_current32 = 0;
|
weight_current32 = 0;
|
||||||
} else if (weight_current32 > UINT16_MAX) {
|
} else if (weight_current32 > UINT16_MAX) {
|
||||||
weight_current32 = UINT16_MAX;
|
weight_current32 = UINT16_MAX;
|
||||||
}
|
}
|
||||||
weight_current = (uint16_t)weight_current32;
|
res.weight = (uint16_t)weight_current32;
|
||||||
|
|
||||||
if (fBme) {
|
if (fBme) {
|
||||||
/* warm up the BME280 by discarding a measurement */
|
/* warm up the BME280 by discarding a measurement */
|
||||||
|
|
@ -675,42 +554,57 @@ void ReadSensors(bool firstTime, bool readOnly)
|
||||||
(int)m.Pressure,
|
(int)m.Pressure,
|
||||||
(int)m.Humidity);
|
(int)m.Humidity);
|
||||||
}
|
}
|
||||||
temp_current = (int16_t)((m.Temperature) * 10);
|
res.temperature = (int16_t)((m.Temperature) * 10);
|
||||||
humidity_current = (uint8_t)m.Humidity;
|
res.humidity = (uint8_t)m.Humidity;
|
||||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
res.pressure = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("pressure_current: %d\n", pressure_current);
|
gCatena.SafePrintf("pressure_current: %d\n", res.pressure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not(readOnly)) {
|
sensor_data = res;
|
||||||
|
}
|
||||||
|
|
||||||
if (firstTime) {
|
void StartNewIteration() {
|
||||||
lora_data_first.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
// we increment the iteration counter
|
||||||
lora_data_first.weight1 = weight1_current;
|
iteration++;
|
||||||
lora_data_first.weight2 = weight2_current;
|
|
||||||
lora_data_first.weight = weight_current;
|
SENSOR_data current_sensor_reading;
|
||||||
lora_data_first.temperature = temp_current;
|
ReadSensors(current_sensor_reading);
|
||||||
lora_data_first.humidity = humidity_current;
|
int16_t temp_change;
|
||||||
lora_data_first.pressure = pressure_current;
|
|
||||||
|
// vBus
|
||||||
|
float vBus = gCatena.ReadVbus();
|
||||||
|
if (config_data.debug_level > 0) {
|
||||||
|
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||||
|
}
|
||||||
|
fUsbPower = (vBus > 4.3) ? true : false;
|
||||||
|
|
||||||
|
if (iteration == 1) {
|
||||||
|
lora_data_first.vbat = current_sensor_reading.vbat;
|
||||||
|
lora_data_first.weight1 = current_sensor_reading.weight1;
|
||||||
|
lora_data_first.weight2 = current_sensor_reading.weight2;
|
||||||
|
lora_data_first.weight = current_sensor_reading.weight;
|
||||||
|
lora_data_first.temperature = current_sensor_reading.temperature;
|
||||||
|
lora_data_first.humidity = current_sensor_reading.humidity;
|
||||||
|
lora_data_first.pressure = current_sensor_reading.pressure;
|
||||||
} else {
|
} else {
|
||||||
lora_data.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
lora_data.vbat = current_sensor_reading.vbat;
|
||||||
lora_data.weight[my_position] = weight_current;
|
lora_data.weight[my_position] = current_sensor_reading.weight;
|
||||||
if (my_position == 0) {
|
if (my_position == 0) {
|
||||||
lora_data.temperature = temp_current;
|
lora_data.temperature = current_sensor_reading.temperature;
|
||||||
} else {
|
} else {
|
||||||
temp_change = temp_current - last_sensor_reading.temperature;
|
temp_change = current_sensor_reading.temperature - last_sensor_reading.temperature;
|
||||||
if (temp_change > 127) {
|
if (temp_change > 127) {
|
||||||
temp_change = 127;
|
temp_change = 127;
|
||||||
}
|
}
|
||||||
if (temp_change < -128) {
|
if (temp_change < -128) {
|
||||||
temp_change = -128;
|
temp_change = -128;
|
||||||
}
|
}
|
||||||
|
|
||||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||||
}
|
}
|
||||||
lora_data.humidity[my_position] = humidity_current;
|
lora_data.humidity[my_position] = current_sensor_reading.humidity;
|
||||||
lora_data.pressure[my_position] = pressure_current;
|
lora_data.pressure[my_position] = current_sensor_reading.pressure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (my_position == 0) {
|
if (my_position == 0) {
|
||||||
|
|
@ -718,7 +612,7 @@ void ReadSensors(bool firstTime, bool readOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
ShowLORAData(firstTime);
|
ShowLORAData(iteration == 1);
|
||||||
}
|
}
|
||||||
my_position++;
|
my_position++;
|
||||||
|
|
||||||
|
|
@ -726,14 +620,15 @@ void ReadSensors(bool firstTime, bool readOnly)
|
||||||
// we send data the first time the system is started, when the array is full
|
// we send data the first time the system is started, when the array is full
|
||||||
// or when the weight has fallen more than threshold or the first measurement is
|
// or when the weight has fallen more than threshold or the first measurement is
|
||||||
// more than one hour old (which should not happen :-) )
|
// more than one hour old (which should not happen :-) )
|
||||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((last_sensor_reading.weight - weight_current) > SEND_DIFF_THRESHOLD_5GRAMS) || ((millis() - timer_pos0) > 3600000)) {
|
if ( (iteration == 1) || (my_position >= MAX_VALUES_TO_SEND) || ((last_sensor_reading.weight - current_sensor_reading.weight) > SEND_DIFF_THRESHOLD_5GRAMS) || ((millis() - timer_pos0) > 3600000)) {
|
||||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("startSendingUplink()\n");
|
gCatena.SafePrintf("startSendingUplink(), my_position: %d\n",my_position);
|
||||||
}
|
}
|
||||||
startSendingUplink(firstTime);
|
startSendingUplink(iteration == 1);
|
||||||
gLed.Set(LedPattern::TwoShort);
|
gLed.Set(LedPattern::TwoShort);
|
||||||
|
|
||||||
|
// we allow 10 seconds for RX1 and RX2 to complete...
|
||||||
uint32_t deepSleepDelay = 10;
|
uint32_t deepSleepDelay = 10;
|
||||||
for (auto n = deepSleepDelay; n > 0; --n)
|
for (auto n = deepSleepDelay; n > 0; --n)
|
||||||
{
|
{
|
||||||
|
|
@ -745,9 +640,15 @@ void ReadSensors(bool firstTime, bool readOnly)
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (iteration > 1) {
|
||||||
|
// we make the current sensor reading to the last one...
|
||||||
|
last_sensor_reading = current_sensor_reading;
|
||||||
|
}
|
||||||
|
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("now going to sleep for 6 minutes...\n");
|
gCatena.SafePrintf("now going to sleep for %d seconds...\n",CATCFG_T_INTERVAL);
|
||||||
if (fUsbPower) {
|
if (fUsbPower) {
|
||||||
gCatena.SafePrintf("USB Power is on\n");
|
gCatena.SafePrintf("USB Power is on\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -758,25 +659,14 @@ void ReadSensors(bool firstTime, bool readOnly)
|
||||||
gLed.Set(LedPattern::Sleeping);
|
gLed.Set(LedPattern::Sleeping);
|
||||||
if (!fUsbPower) {
|
if (!fUsbPower) {
|
||||||
DoDeepSleep();
|
DoDeepSleep();
|
||||||
sleepDoneCb(&sensorJob);
|
startNewIterationCb(&iterationJob);
|
||||||
} else {
|
} else {
|
||||||
|
gCatena.SafePrintf("os_setTimedCallback for startNewIterationCb in %d...\n",CATCFG_T_INTERVAL);
|
||||||
os_setTimedCallback(
|
os_setTimedCallback(
|
||||||
&sensorJob,
|
&iterationJob,
|
||||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||||
sleepDoneCb);
|
startNewIterationCb);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_sensor_reading.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
|
||||||
|
|
||||||
last_sensor_reading.weight1 = weight1_current;
|
|
||||||
last_sensor_reading.weight2 = weight2_current;
|
|
||||||
last_sensor_reading.weight = weight_current;
|
|
||||||
last_sensor_reading.temperature = temp_current;
|
|
||||||
last_sensor_reading.humidity = humidity_current;
|
|
||||||
last_sensor_reading.pressure = pressure_current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void startSendingUplink(bool firstTime)
|
void startSendingUplink(bool firstTime)
|
||||||
|
|
@ -884,13 +774,20 @@ static void sleepDoneCb(osjob_t* pJob)
|
||||||
|
|
||||||
static void warmupDoneCb(osjob_t* pJob)
|
static void warmupDoneCb(osjob_t* pJob)
|
||||||
{
|
{
|
||||||
ReadSensors(false, false);
|
gCatena.SafePrintf("warmupDoneCb\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void startNewIterationCb(osjob_t* pJob)
|
||||||
|
{
|
||||||
|
gCatena.SafePrintf("startNewIterationCb\n");
|
||||||
|
StartNewIteration();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage, size_t nMessage)
|
static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage, size_t nMessage)
|
||||||
{
|
{
|
||||||
uint32_t gram_A;
|
uint32_t gram_A;
|
||||||
uint32_t gram_B;
|
uint32_t gram_B;
|
||||||
|
SENSOR_data temp_sensor_data;
|
||||||
|
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("receiveMessage was called!!!\n");
|
gCatena.SafePrintf("receiveMessage was called!!!\n");
|
||||||
|
|
@ -921,7 +818,7 @@ static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage
|
||||||
port, nMessage
|
port, nMessage
|
||||||
);
|
);
|
||||||
// we print out the received message...
|
// we print out the received message...
|
||||||
gCatena.SafePrintf("Current LMIC.seqnoUp: %d\n",LMIC.seqnoUp);
|
gCatena.SafePrintf("Current LMIC.seqnoUp: %d\n", LMIC.seqnoUp);
|
||||||
gCatena.SafePrintf("Received Data (Payload): \n");
|
gCatena.SafePrintf("Received Data (Payload): \n");
|
||||||
for (byte i = 0; i < nMessage; i++) {
|
for (byte i = 0; i < nMessage; i++) {
|
||||||
gCatena.SafePrintf("%02x", pMessage[i]);
|
gCatena.SafePrintf("%02x", pMessage[i]);
|
||||||
|
|
@ -942,9 +839,9 @@ static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("reset both scales to zero\n");
|
gCatena.SafePrintf("reset both scales to zero\n");
|
||||||
}
|
}
|
||||||
ReadSensors(false, true);
|
ReadSensors(temp_sensor_data);
|
||||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
config_data.cal_w1_0 = temp_sensor_data.weight1;
|
||||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
config_data.cal_w2_0 = temp_sensor_data.weight2;
|
||||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -966,9 +863,9 @@ static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("tare scales, A: %d, B: %d\n", gram_A, gram_B);
|
gCatena.SafePrintf("tare scales, A: %d, B: %d\n", gram_A, gram_B);
|
||||||
}
|
}
|
||||||
ReadSensors(false, true);
|
ReadSensors(temp_sensor_data);
|
||||||
config_data.cal_w1_factor = (((float)last_sensor_reading.weight1 - config_data.cal_w1_0) / gram_A);
|
config_data.cal_w1_factor = (((float)temp_sensor_data.weight1 - config_data.cal_w1_0) / gram_A);
|
||||||
config_data.cal_w2_factor = (((float)last_sensor_reading.weight2 - config_data.cal_w2_0) / gram_B);
|
config_data.cal_w2_factor = (((float)temp_sensor_data.weight2 - config_data.cal_w2_0) / gram_B);
|
||||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1000,15 +897,17 @@ cCommandStream::CommandStatus cmdGetCalibrationSettings(cCommandStream *pThis, v
|
||||||
|
|
||||||
cCommandStream::CommandStatus cmdGetSensorReadings(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
cCommandStream::CommandStatus cmdGetSensorReadings(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||||
{
|
{
|
||||||
ReadSensors(false, true);
|
SENSOR_data temp_sensor_data;
|
||||||
|
|
||||||
|
ReadSensors(temp_sensor_data);
|
||||||
pThis->printf("{\n");
|
pThis->printf("{\n");
|
||||||
pThis->printf(" \"weight\": \"%d\",\n", last_sensor_reading.weight);
|
pThis->printf(" \"weight\": \"%d\",\n", temp_sensor_data.weight);
|
||||||
pThis->printf(" \"weight1_raw\": \"%d\",\n", last_sensor_reading.weight1);
|
pThis->printf(" \"weight1_raw\": \"%d\",\n", temp_sensor_data.weight1);
|
||||||
pThis->printf(" \"weight2_raw\": \"%d\",\n", last_sensor_reading.weight2);
|
pThis->printf(" \"weight2_raw\": \"%d\",\n", temp_sensor_data.weight2);
|
||||||
pThis->printf(" \"temperature\": \"%d\",\n", last_sensor_reading.temperature);
|
pThis->printf(" \"temperature\": \"%d\",\n", temp_sensor_data.temperature);
|
||||||
pThis->printf(" \"humidity\": \"%d\",\n", last_sensor_reading.humidity);
|
pThis->printf(" \"humidity\": \"%d\",\n", temp_sensor_data.humidity);
|
||||||
pThis->printf(" \"pressure\": \"%d\",\n", last_sensor_reading.pressure);
|
pThis->printf(" \"pressure\": \"%d\",\n", temp_sensor_data.pressure);
|
||||||
pThis->printf(" \"batt\": \"%d\",\n", last_sensor_reading.vbat);
|
pThis->printf(" \"batt\": \"%d\",\n", temp_sensor_data.vbat);
|
||||||
pThis->printf("}\n");
|
pThis->printf("}\n");
|
||||||
|
|
||||||
return cCommandStream::CommandStatus::kSuccess;
|
return cCommandStream::CommandStatus::kSuccess;
|
||||||
|
|
@ -1030,8 +929,10 @@ cCommandStream::CommandStatus cmdGetScale2(cCommandStream *pThis, void *pContext
|
||||||
|
|
||||||
cCommandStream::CommandStatus cmdCalibrateZeroScaleA(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
cCommandStream::CommandStatus cmdCalibrateZeroScaleA(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||||
{
|
{
|
||||||
ReadSensors(false, true);
|
SENSOR_data temp_sensor_data;
|
||||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
|
||||||
|
ReadSensors(temp_sensor_data);
|
||||||
|
config_data.cal_w1_0 = temp_sensor_data.weight1;
|
||||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
|
|
||||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale_a was successful\" }\n");
|
pThis->printf("{ \"msg\": \"calibrate_zero_scale_a was successful\" }\n");
|
||||||
|
|
@ -1041,8 +942,10 @@ cCommandStream::CommandStatus cmdCalibrateZeroScaleA(cCommandStream *pThis, void
|
||||||
|
|
||||||
cCommandStream::CommandStatus cmdCalibrateZeroScaleB(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
cCommandStream::CommandStatus cmdCalibrateZeroScaleB(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||||
{
|
{
|
||||||
ReadSensors(false, true);
|
SENSOR_data temp_sensor_data;
|
||||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
|
||||||
|
ReadSensors(temp_sensor_data);
|
||||||
|
config_data.cal_w2_0 = temp_sensor_data.weight2;
|
||||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
|
|
||||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale_b was successful\" }\n");
|
pThis->printf("{ \"msg\": \"calibrate_zero_scale_b was successful\" }\n");
|
||||||
|
|
@ -1052,14 +955,15 @@ cCommandStream::CommandStatus cmdCalibrateZeroScaleB(cCommandStream *pThis, void
|
||||||
|
|
||||||
cCommandStream::CommandStatus cmdCalibrateScaleA(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
cCommandStream::CommandStatus cmdCalibrateScaleA(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||||
{
|
{
|
||||||
ReadSensors(false, true);
|
SENSOR_data temp_sensor_data;
|
||||||
|
|
||||||
|
ReadSensors(temp_sensor_data);
|
||||||
String w1_gramm(argv[1]);
|
String w1_gramm(argv[1]);
|
||||||
config_data.cal_w1_factor = (((float)last_sensor_reading.weight1 - config_data.cal_w1_0) / w1_gramm.toFloat());
|
config_data.cal_w1_factor = (((float)temp_sensor_data.weight1 - config_data.cal_w1_0) / w1_gramm.toFloat());
|
||||||
|
|
||||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
|
|
||||||
gCatena.SafePrintf("last_sensor_reading.weight1: %ld\n", last_sensor_reading.weight1);
|
gCatena.SafePrintf("temp_sensor_data.weight1: %ld\n", temp_sensor_data.weight1);
|
||||||
gCatena.SafePrintf("config_data.cal_w1_0: %ld\n", config_data.cal_w1_0);
|
gCatena.SafePrintf("config_data.cal_w1_0: %ld\n", config_data.cal_w1_0);
|
||||||
gCatena.SafePrintf("w1_gramm: %s\n", w1_gramm);
|
gCatena.SafePrintf("w1_gramm: %s\n", w1_gramm);
|
||||||
gCatena.SafePrintf("w1_gramm (float): %d\n", (int)w1_gramm.toFloat());
|
gCatena.SafePrintf("w1_gramm (float): %d\n", (int)w1_gramm.toFloat());
|
||||||
|
|
@ -1072,10 +976,11 @@ cCommandStream::CommandStatus cmdCalibrateScaleA(cCommandStream *pThis, void *pC
|
||||||
|
|
||||||
cCommandStream::CommandStatus cmdCalibrateScaleB(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
cCommandStream::CommandStatus cmdCalibrateScaleB(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||||
{
|
{
|
||||||
ReadSensors(false, true);
|
SENSOR_data temp_sensor_data;
|
||||||
|
|
||||||
|
ReadSensors(temp_sensor_data);
|
||||||
String w2_gramm(argv[1]);
|
String w2_gramm(argv[1]);
|
||||||
config_data.cal_w2_factor = (((float)last_sensor_reading.weight2 - config_data.cal_w2_0) / w2_gramm.toFloat());
|
config_data.cal_w2_factor = (((float)temp_sensor_data.weight2 - config_data.cal_w2_0) / w2_gramm.toFloat());
|
||||||
|
|
||||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
// mini_beieli_node.h
|
||||||
|
|
||||||
|
/****************************************************************************\
|
||||||
|
|
|
||||||
|
| MANIFEST CONSTANTS & TYPEDEFS
|
||||||
|
|
|
||||||
|
\****************************************************************************/
|
||||||
|
|
||||||
|
constexpr uint8_t kUplinkPort = 2;
|
||||||
|
|
||||||
|
/* how long do we wait between transmissions? (in seconds) */
|
||||||
|
enum {
|
||||||
|
// set this to interval between transmissions, in seconds
|
||||||
|
// Actual time will be a little longer because have to
|
||||||
|
// add measurement and broadcast time, but we attempt
|
||||||
|
// to compensate for the gross effects below.
|
||||||
|
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||||
|
//CATCFG_T_CYCLE = 60, // for Testing
|
||||||
|
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||||
|
CATCFG_T_CYCLE_INITIAL = 30, // every 30 seconds initially
|
||||||
|
CATCFG_INTERVAL_COUNT_INITIAL = 30, // repeat for 15 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
/* additional timing parameters; ususually you don't change these. */
|
||||||
|
enum {
|
||||||
|
CATCFG_T_WARMUP = 1,
|
||||||
|
CATCFG_T_SETTLE = 5,
|
||||||
|
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||||
|
CATCFG_T_MIN = CATCFG_T_OVERHEAD,
|
||||||
|
CATCFG_T_MAX = CATCFG_T_CYCLE < 60 * 60 ? 60 * 60 : CATCFG_T_CYCLE, // normally one hour max.
|
||||||
|
CATCFG_INTERVAL_COUNT = 30,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||||
|
{
|
||||||
|
return (tCycle < CATCFG_T_OVERHEAD)
|
||||||
|
? CATCFG_T_OVERHEAD
|
||||||
|
: tCycle - CATCFG_T_OVERHEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||||
|
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||||
|
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************\
|
||||||
|
|
|
||||||
|
| READ-ONLY DATA
|
||||||
|
|
|
||||||
|
\****************************************************************************/
|
||||||
|
|
||||||
|
static const int32_t fwVersion = 20191115;
|
||||||
|
static const byte MAX_VALUES_TO_SEND = 8;
|
||||||
|
//static const byte MAX_VALUES_TO_SEND = 1; // Testing
|
||||||
|
static const uint8_t LORA_DATA_VERSION = 1;
|
||||||
|
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 129;
|
||||||
|
static const uint32_t PRESSURE_OFFSET = 825;
|
||||||
|
static const uint16_t SEND_DIFF_THRESHOLD_5GRAMS = 10; // when weight value drops by 50g, then send data
|
||||||
|
|
||||||
|
// must be 139 bytes long (size of kBme680Cal)
|
||||||
|
typedef struct {
|
||||||
|
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||||
|
long cal_w2_0; // 4 Bytes, Wert Waegezelle 2 ohne Gewicht
|
||||||
|
float cal_w1_factor; // 4 Bytes, Kalibrationsfaktor Waegezelle 1
|
||||||
|
float cal_w2_factor; // 4 Bytes, Kalibrationsfaktor Waegezelle 2
|
||||||
|
byte debug_level; // 0 => no debugging, 1 => infos, 2 => error, 3 => highest level
|
||||||
|
byte fill[122];
|
||||||
|
} __attribute__((packed)) CONFIG_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t version; // Version of Packet Format (must be increased every time format changes...)
|
||||||
|
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||||
|
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||||
|
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
||||||
|
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
||||||
|
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||||
|
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||||
|
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
||||||
|
} __attribute__((packed)) LORA_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t version; // Version of Packet Format (must be increased every time format changes...)
|
||||||
|
int32_t fw_version; // Version of Firmware, Nummer entspricht YYYYMMDD
|
||||||
|
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||||
|
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||||
|
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||||
|
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||||
|
int32_t weight1; // Waegezelle 1, Raw Value
|
||||||
|
int32_t weight2; // Waegezelle 2, Raw Value
|
||||||
|
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||||
|
} __attribute__((packed)) LORA_data_first;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||||
|
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||||
|
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||||
|
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||||
|
int32_t weight1; // Waegezelle 1, Raw Value
|
||||||
|
int32_t weight2; // Waegezelle 2, Raw Value
|
||||||
|
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||||
|
} SENSOR_data;
|
||||||
Loading…
Reference in New Issue