refactor sending code
This commit is contained in:
parent
9be03ea5c2
commit
da5e52a033
|
|
@ -26,59 +26,14 @@
|
|||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
#include "mini_beieli_node.h"
|
||||
|
||||
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
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void startNewIterationCb(osjob_t* pJob);
|
||||
static void txNotProvisionedCb(osjob_t *pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
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
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// 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
|
||||
long timer_pos0;
|
||||
|
||||
|
|
@ -194,6 +92,7 @@ LORA_data lora_data;
|
|||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
SENSOR_data last_sensor_reading;
|
||||
long iteration = 0; // what iteration number do we have, starts with 0
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
|
@ -234,9 +133,9 @@ bool fUsbPower;
|
|||
// have we printed the sleep info?
|
||||
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;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
static osjob_t iterationJob;
|
||||
|
||||
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("debug_level: %d\n", (int)config_data.debug_level);
|
||||
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);
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true, false);
|
||||
StartNewIteration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -565,7 +466,6 @@ uint8_t GetVBatValue(int millivolts)
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
void DoDeepSleep()
|
||||
{
|
||||
if (config_data.debug_level > 0) {
|
||||
|
|
@ -595,51 +495,30 @@ void DoDeepSleep()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void ReadSensors(bool firstTime, bool readOnly)
|
||||
{
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int16_t temp_change;
|
||||
void ReadSensors(SENSOR_data &sensor_data) {
|
||||
SENSOR_data res;
|
||||
int32_t weight_current32;
|
||||
uint16_t weight_current;
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
res.vbat = (uint8_t)(gCatena.ReadVbat() * 1000.0f);
|
||||
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
|
||||
if (setup_scales()) {
|
||||
if (config_data.debug_level > 0) {
|
||||
gCatena.SafePrintf("HX711 LoadCell is ready.\n");
|
||||
}
|
||||
LoadCell.set_gain(128);
|
||||
long w1 = LoadCell.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
res.weight1 = (int32_t)LoadCell.read_average(5);
|
||||
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", weight1_current);
|
||||
gCatena.SafePrintf("Load_cell 1 weight1_current: %ld\n", res.weight1);
|
||||
}
|
||||
LoadCell.set_gain(32);
|
||||
long w2 = LoadCell.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
res.weight2 = (int32_t)LoadCell.read_average(5);
|
||||
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", weight2_current);
|
||||
gCatena.SafePrintf("Load_cell 2 weight2_current: %ld\n", res.weight2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -652,13 +531,13 @@ void ReadSensors(bool firstTime, bool readOnly)
|
|||
digitalWrite(D10, LOW);
|
||||
|
||||
// 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) {
|
||||
weight_current32 = 0;
|
||||
} else if (weight_current32 > UINT16_MAX) {
|
||||
weight_current32 = UINT16_MAX;
|
||||
}
|
||||
weight_current = (uint16_t)weight_current32;
|
||||
res.weight = (uint16_t)weight_current32;
|
||||
|
||||
if (fBme) {
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
|
|
@ -675,108 +554,119 @@ void ReadSensors(bool firstTime, bool readOnly)
|
|||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
}
|
||||
temp_current = (int16_t)((m.Temperature) * 10);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
res.temperature = (int16_t)((m.Temperature) * 10);
|
||||
res.humidity = (uint8_t)m.Humidity;
|
||||
res.pressure = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
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) {
|
||||
lora_data_first.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
if (my_position == 0) {
|
||||
lora_data.temperature = temp_current;
|
||||
} else {
|
||||
temp_change = temp_current - last_sensor_reading.temperature;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
void StartNewIteration() {
|
||||
// we increment the iteration counter
|
||||
iteration++;
|
||||
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
SENSOR_data current_sensor_reading;
|
||||
ReadSensors(current_sensor_reading);
|
||||
int16_t temp_change;
|
||||
|
||||
// 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 {
|
||||
lora_data.vbat = current_sensor_reading.vbat;
|
||||
lora_data.weight[my_position] = current_sensor_reading.weight;
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
if (config_data.debug_level > 0) {
|
||||
ShowLORAData(firstTime);
|
||||
}
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// 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
|
||||
// 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)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
if (config_data.debug_level > 0) {
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
}
|
||||
startSendingUplink(firstTime);
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
uint32_t deepSleepDelay = 10;
|
||||
for (auto n = deepSleepDelay; n > 0; --n)
|
||||
{
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000)
|
||||
{
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
lora_data.temperature = current_sensor_reading.temperature;
|
||||
} else {
|
||||
if (config_data.debug_level > 0) {
|
||||
gCatena.SafePrintf("now going to sleep for 6 minutes...\n");
|
||||
if (fUsbPower) {
|
||||
gCatena.SafePrintf("USB Power is on\n");
|
||||
} else {
|
||||
gCatena.SafePrintf("USB Power is off\n");
|
||||
}
|
||||
//Serial.flush();
|
||||
temp_change = current_sensor_reading.temperature - last_sensor_reading.temperature;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
if (!fUsbPower) {
|
||||
DoDeepSleep();
|
||||
sleepDoneCb(&sensorJob);
|
||||
} else {
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = current_sensor_reading.humidity;
|
||||
lora_data.pressure[my_position] = current_sensor_reading.pressure;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
if (config_data.debug_level > 0) {
|
||||
ShowLORAData(iteration == 1);
|
||||
}
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// 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
|
||||
// more than one hour old (which should not happen :-) )
|
||||
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);
|
||||
if (config_data.debug_level > 0) {
|
||||
gCatena.SafePrintf("startSendingUplink(), my_position: %d\n",my_position);
|
||||
}
|
||||
startSendingUplink(iteration == 1);
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
// we allow 10 seconds for RX1 and RX2 to complete...
|
||||
uint32_t deepSleepDelay = 10;
|
||||
for (auto n = deepSleepDelay; n > 0; --n)
|
||||
{
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000)
|
||||
{
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_sensor_reading.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
if (iteration > 1) {
|
||||
// we make the current sensor reading to the last one...
|
||||
last_sensor_reading = current_sensor_reading;
|
||||
}
|
||||
|
||||
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;
|
||||
if (config_data.debug_level > 0) {
|
||||
gCatena.SafePrintf("now going to sleep for %d seconds...\n",CATCFG_T_INTERVAL);
|
||||
if (fUsbPower) {
|
||||
gCatena.SafePrintf("USB Power is on\n");
|
||||
} else {
|
||||
gCatena.SafePrintf("USB Power is off\n");
|
||||
}
|
||||
//Serial.flush();
|
||||
}
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
if (!fUsbPower) {
|
||||
DoDeepSleep();
|
||||
startNewIterationCb(&iterationJob);
|
||||
} else {
|
||||
gCatena.SafePrintf("os_setTimedCallback for startNewIterationCb in %d...\n",CATCFG_T_INTERVAL);
|
||||
os_setTimedCallback(
|
||||
&iterationJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
startNewIterationCb);
|
||||
}
|
||||
}
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
|
|
@ -884,13 +774,20 @@ static void sleepDoneCb(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)
|
||||
{
|
||||
uint32_t gram_A;
|
||||
uint32_t gram_B;
|
||||
SENSOR_data temp_sensor_data;
|
||||
|
||||
if (config_data.debug_level > 0) {
|
||||
gCatena.SafePrintf("receiveMessage was called!!!\n");
|
||||
|
|
@ -921,7 +818,7 @@ static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage
|
|||
port, nMessage
|
||||
);
|
||||
// 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");
|
||||
for (byte i = 0; i < nMessage; 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) {
|
||||
gCatena.SafePrintf("reset both scales to zero\n");
|
||||
}
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
||||
ReadSensors(temp_sensor_data);
|
||||
config_data.cal_w1_0 = temp_sensor_data.weight1;
|
||||
config_data.cal_w2_0 = temp_sensor_data.weight2;
|
||||
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) {
|
||||
gCatena.SafePrintf("tare scales, A: %d, B: %d\n", gram_A, gram_B);
|
||||
}
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w1_factor = (((float)last_sensor_reading.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);
|
||||
ReadSensors(temp_sensor_data);
|
||||
config_data.cal_w1_factor = (((float)temp_sensor_data.weight1 - config_data.cal_w1_0) / gram_A);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1000,15 +897,17 @@ cCommandStream::CommandStatus cmdGetCalibrationSettings(cCommandStream *pThis, v
|
|||
|
||||
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(" \"weight\": \"%d\",\n", last_sensor_reading.weight);
|
||||
pThis->printf(" \"weight1_raw\": \"%d\",\n", last_sensor_reading.weight1);
|
||||
pThis->printf(" \"weight2_raw\": \"%d\",\n", last_sensor_reading.weight2);
|
||||
pThis->printf(" \"temperature\": \"%d\",\n", last_sensor_reading.temperature);
|
||||
pThis->printf(" \"humidity\": \"%d\",\n", last_sensor_reading.humidity);
|
||||
pThis->printf(" \"pressure\": \"%d\",\n", last_sensor_reading.pressure);
|
||||
pThis->printf(" \"batt\": \"%d\",\n", last_sensor_reading.vbat);
|
||||
pThis->printf(" \"weight\": \"%d\",\n", temp_sensor_data.weight);
|
||||
pThis->printf(" \"weight1_raw\": \"%d\",\n", temp_sensor_data.weight1);
|
||||
pThis->printf(" \"weight2_raw\": \"%d\",\n", temp_sensor_data.weight2);
|
||||
pThis->printf(" \"temperature\": \"%d\",\n", temp_sensor_data.temperature);
|
||||
pThis->printf(" \"humidity\": \"%d\",\n", temp_sensor_data.humidity);
|
||||
pThis->printf(" \"pressure\": \"%d\",\n", temp_sensor_data.pressure);
|
||||
pThis->printf(" \"batt\": \"%d\",\n", temp_sensor_data.vbat);
|
||||
pThis->printf("}\n");
|
||||
|
||||
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)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
||||
SENSOR_data temp_sensor_data;
|
||||
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
||||
SENSOR_data temp_sensor_data;
|
||||
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
SENSOR_data temp_sensor_data;
|
||||
|
||||
ReadSensors(temp_sensor_data);
|
||||
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.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("w1_gramm: %s\n", w1_gramm);
|
||||
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)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
SENSOR_data temp_sensor_data;
|
||||
|
||||
ReadSensors(temp_sensor_data);
|
||||
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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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