Compare commits
10 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
cee3752349 | |
|
|
c3aa3b7845 | |
|
|
3bb6edd1e8 | |
|
|
0aa2c11402 | |
|
|
7ef7d25693 | |
|
|
1f0072797f | |
|
|
cfaccfb14a | |
|
|
90782229d5 | |
|
|
363e8ecc23 | |
|
|
924ec0719f |
|
|
@ -20,9 +20,9 @@ Das sind die verwendeten Libraries [1]:
|
||||||
| --- | ----- | ----------- |
|
| --- | ----- | ----------- |
|
||||||
| https://github.com/mcci-catena/Adafruit_BME280_Library.git | 3dafbe1 | Wed, 13 Dec 2017 13:56:30 -0500 |
|
| https://github.com/mcci-catena/Adafruit_BME280_Library.git | 3dafbe1 | Wed, 13 Dec 2017 13:56:30 -0500 |
|
||||||
| https://github.com/mcci-catena/Adafruit_Sensor.git | f2af6f4 | Tue, 1 Sep 2015 15:57:59 +0200 |
|
| https://github.com/mcci-catena/Adafruit_Sensor.git | f2af6f4 | Tue, 1 Sep 2015 15:57:59 +0200 |
|
||||||
| https://github.com/mcci-catena/arduino-lmic.git | 1964dcf | Mon, 22 Jun 2020 10:54:56 -0400 |
|
| https://github.com/mcci-catena/arduino-lmic.git | 9191f0c | Tue, 30 Jun 2020 09:56:19 -0400 |
|
||||||
| https://github.com/mcci-catena/arduino-lorawan.git | 4bc0d48 | Sat, 9 May 2020 12:38:28 -0400 |
|
| https://github.com/mcci-catena/arduino-lorawan.git | 4bc0d48 | Sat, 9 May 2020 12:38:28 -0400 |
|
||||||
| https://github.com/mcci-catena/Catena-Arduino-Platform.git | 478ad23 | Fri, 26 Jun 2020 18:39:01 -0400 |
|
| https://github.com/mcci-catena/Catena-Arduino-Platform.git | 7620a89 | Fri, 31 Jul 2020 14:14:30 -0400 |
|
||||||
| https://github.com/mcci-catena/Catena-mcciadk.git | a428006 | Sat, 21 Dec 2019 20:45:26 -0500 |
|
| https://github.com/mcci-catena/Catena-mcciadk.git | a428006 | Sat, 21 Dec 2019 20:45:26 -0500 |
|
||||||
| https://github.com/mcci-catena/MCCI_FRAM_I2C.git | f0a5ea5 | Sat, 21 Dec 2019 16:17:01 -0500 |
|
| https://github.com/mcci-catena/MCCI_FRAM_I2C.git | f0a5ea5 | Sat, 21 Dec 2019 16:17:01 -0500 |
|
||||||
| https://github.com/tatobari/Q2-HX711-Arduino-Library.git | ccda8d8 | Wed, 13 Mar 2019 12:41:44 -0300 |
|
| https://github.com/tatobari/Q2-HX711-Arduino-Library.git | ccda8d8 | Wed, 13 Mar 2019 12:41:44 -0300 |
|
||||||
|
|
@ -31,6 +31,7 @@ Das sind die verwendeten Libraries [1]:
|
||||||
| https://github.com/mcci-catena/SHT1x.git | be7042c | Tue, 20 Sep 2011 13:56:23 +1000 |
|
| https://github.com/mcci-catena/SHT1x.git | be7042c | Tue, 20 Sep 2011 13:56:23 +1000 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Patch arduino-lmic, so initial SF12 is used initially:
|
Patch arduino-lmic, so initial SF12 is used initially:
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ sMyExtraCommands_top(
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
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;
|
unsigned long timer_pos0;
|
||||||
|
|
||||||
// Global Variables
|
// Global Variables
|
||||||
LORA_data lora_data;
|
LORA_data lora_data;
|
||||||
|
|
@ -527,9 +527,15 @@ void DoDeepSleep(uint32_t sleep_time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadSensors(SENSOR_data &sensor_data) {
|
// Returns true if measurements are plausible, otherwise false
|
||||||
|
bool ReadSensors(SENSOR_data &sensor_data) {
|
||||||
|
bool plausible;
|
||||||
|
bool plausible_a;
|
||||||
|
bool plausible_b;
|
||||||
SENSOR_data res;
|
SENSOR_data res;
|
||||||
int32_t weight_current32;
|
int32_t weight_current32;
|
||||||
|
int32_t weight_current32_a;
|
||||||
|
int32_t weight_current32_b;
|
||||||
long w1_0_real;
|
long w1_0_real;
|
||||||
long w2_0_real;
|
long w2_0_real;
|
||||||
|
|
||||||
|
|
@ -547,30 +553,14 @@ void ReadSensors(SENSOR_data &sensor_data) {
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("LoadCell is ready.\n");
|
gCatena.SafePrintf("LoadCell is ready.\n");
|
||||||
}
|
}
|
||||||
if (config_data.cal_w1_0 != NOT_ATTACHED) {
|
|
||||||
res.weight1 = (int32_t)ReadScale('A');
|
res.weight1 = (int32_t)ReadScale('A');
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("Load_cell 1 weight1_current: %ld\n", res.weight1);
|
gCatena.SafePrintf("Load_cell 1 weight1_current: %ld\n", res.weight1);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
res.weight1 = 0;
|
|
||||||
w1_0_real = 0;
|
|
||||||
if (config_data.debug_level > 0) {
|
|
||||||
gCatena.SafePrintf("Load_cell 1 is disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config_data.cal_w2_0 != NOT_ATTACHED) {
|
|
||||||
res.weight2 = (int32_t)ReadScale('B');
|
res.weight2 = (int32_t)ReadScale('B');
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("Load_cell 2 weight2_current: %ld\n", res.weight2);
|
gCatena.SafePrintf("Load_cell 2 weight2_current: %ld\n", res.weight2);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
res.weight2 = 0;
|
|
||||||
w2_0_real = 0;
|
|
||||||
if (config_data.debug_level > 0) {
|
|
||||||
gCatena.SafePrintf("Load_cell 2 is disabled\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
|
|
@ -582,18 +572,32 @@ void ReadSensors(SENSOR_data &sensor_data) {
|
||||||
PowerdownScale();
|
PowerdownScale();
|
||||||
|
|
||||||
// Gewicht berechnen
|
// Gewicht berechnen
|
||||||
weight_current32 = (int32_t)((((res.weight1 - w1_0_real) / config_data.cal_w1_factor) + ((res.weight2 - w2_0_real) / config_data.cal_w2_factor)) / 5.0);
|
weight_current32_a = (int32_t)((res.weight1 - w1_0_real) / config_data.cal_w1_factor);
|
||||||
|
weight_current32_b = (int32_t)((res.weight2 - w2_0_real) / config_data.cal_w2_factor);
|
||||||
|
weight_current32 = (int32_t)((weight_current32_a + weight_current32_b) / 5.0);
|
||||||
|
|
||||||
|
// we check if weights are plausible
|
||||||
|
plausible_a = (weight_current32_a > -10000) && (weight_current32_a < 150000);
|
||||||
|
plausible_b = (weight_current32_b > -10000) && (weight_current32_b < 150000);
|
||||||
|
plausible = (plausible_a && plausible_b);
|
||||||
|
|
||||||
if (weight_current32 < 0) {
|
if (weight_current32 < 0) {
|
||||||
|
if (plausible) {
|
||||||
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;
|
||||||
// we set the weight to 0, as such high values are not realistic and probably a sign for bad calibration...
|
// we set the weight to 0, as such high values are not realistic and probably a sign for bad calibration...
|
||||||
weight_current32 = 0;
|
weight_current32 = 0;
|
||||||
}
|
}
|
||||||
if (config_data.cal_w1_0 == NOT_ATTACHED || config_data.cal_w2_0 == NOT_ATTACHED) {
|
if (!plausible) {
|
||||||
// when at least one load cell is disabled, we multiply the measured weight by 2
|
weight_current32 = NOT_PLAUSIBLE_16;
|
||||||
weight_current32 = weight_current32 * 2;
|
if (!plausible_a) {
|
||||||
|
res.weight1 = NOT_PLAUSIBLE_32;
|
||||||
|
}
|
||||||
|
if (!plausible_b) {
|
||||||
|
res.weight2 = NOT_PLAUSIBLE_32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res.weight = (uint16_t)weight_current32;
|
res.weight = (uint16_t)weight_current32;
|
||||||
|
|
||||||
|
|
@ -621,6 +625,7 @@ void ReadSensors(SENSOR_data &sensor_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sensor_data = res;
|
sensor_data = res;
|
||||||
|
return plausible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartNewIteration() {
|
void StartNewIteration() {
|
||||||
|
|
@ -632,7 +637,18 @@ void StartNewIteration() {
|
||||||
iteration++;
|
iteration++;
|
||||||
|
|
||||||
SENSOR_data current_sensor_reading;
|
SENSOR_data current_sensor_reading;
|
||||||
ReadSensors(current_sensor_reading);
|
if (!ReadSensors(current_sensor_reading)) {
|
||||||
|
// we try a second time if Readings do not seem plausible
|
||||||
|
if (config_data.debug_level > 0) {
|
||||||
|
gCatena.SafePrintf("Readings do not seem plausible, try a second time\n");
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
if (!ReadSensors(current_sensor_reading)) {
|
||||||
|
if (config_data.debug_level > 0) {
|
||||||
|
gCatena.SafePrintf("Readings do not seem plausible for a second time, we give up!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
int16_t temp_change;
|
int16_t temp_change;
|
||||||
|
|
||||||
// vBus
|
// vBus
|
||||||
|
|
@ -697,7 +713,7 @@ void StartNewIteration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop sending is in progress, timeout just in case after 600 seconds
|
// Loop sending is in progress, timeout just in case after 600 seconds
|
||||||
long start_time = millis();
|
unsigned long start_time = millis();
|
||||||
if (config_data.debug_level > 0) {
|
if (config_data.debug_level > 0) {
|
||||||
gCatena.SafePrintf("waiting while send is in progress\n");
|
gCatena.SafePrintf("waiting while send is in progress\n");
|
||||||
}
|
}
|
||||||
|
|
@ -927,7 +943,7 @@ void doSleepAlert(const bool fDeepSleep)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i <= 15; i++) {
|
for (int i = 0; i <= 15; i++) {
|
||||||
long prevPrint = millis();
|
unsigned long prevPrint = millis();
|
||||||
while (os_queryTimeCriticalJobs(ms2osticks(2000)) != 0)
|
while (os_queryTimeCriticalJobs(ms2osticks(2000)) != 0)
|
||||||
{
|
{
|
||||||
gCatena.poll();
|
gCatena.poll();
|
||||||
|
|
@ -1215,15 +1231,9 @@ cCommandStream::CommandStatus cmdCalibrateScaleA(cCommandStream * pThis, void *p
|
||||||
String w1_gramm(argv[1]);
|
String w1_gramm(argv[1]);
|
||||||
long weight1;
|
long weight1;
|
||||||
|
|
||||||
if (w1_gramm == "NA") {
|
|
||||||
// scale a is not connected
|
|
||||||
config_data.cal_w1_factor = 1.0;
|
|
||||||
config_data.cal_w1_0 = NOT_ATTACHED;
|
|
||||||
} else {
|
|
||||||
setup_scales();
|
setup_scales();
|
||||||
weight1 = ReadScale('A');
|
weight1 = ReadScale('A');
|
||||||
config_data.cal_w1_factor = (float)((weight1 - config_data.cal_w1_0) / w1_gramm.toFloat());
|
config_data.cal_w1_factor = (float)((weight1 - config_data.cal_w1_0) / w1_gramm.toFloat());
|
||||||
}
|
|
||||||
|
|
||||||
gCatena.getFram()->saveField(cFramStorage::kAppConf, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kAppConf, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
|
|
||||||
|
|
@ -1237,15 +1247,9 @@ cCommandStream::CommandStatus cmdCalibrateScaleB(cCommandStream * pThis, void *p
|
||||||
String w2_gramm(argv[1]);
|
String w2_gramm(argv[1]);
|
||||||
long weight2;
|
long weight2;
|
||||||
|
|
||||||
if (w2_gramm == "NA") {
|
|
||||||
// scale b is not connected
|
|
||||||
config_data.cal_w2_factor = 1.0;
|
|
||||||
config_data.cal_w2_0 = NOT_ATTACHED;
|
|
||||||
} else {
|
|
||||||
setup_scales();
|
setup_scales();
|
||||||
weight2 = ReadScale('B');
|
weight2 = ReadScale('B');
|
||||||
config_data.cal_w2_factor = (float)((weight2 - config_data.cal_w2_0) / w2_gramm.toFloat());
|
config_data.cal_w2_factor = (float)((weight2 - config_data.cal_w2_0) / w2_gramm.toFloat());
|
||||||
}
|
|
||||||
|
|
||||||
gCatena.getFram()->saveField(cFramStorage::kAppConf, (const uint8_t *)&config_data, sizeof(config_data));
|
gCatena.getFram()->saveField(cFramStorage::kAppConf, (const uint8_t *)&config_data, sizeof(config_data));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ enum {
|
||||||
|
|
|
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
static const int32_t fwVersion = 20200629;
|
static const int32_t fwVersion = 20200804;
|
||||||
|
|
||||||
static const byte INIT_PACKAGE_INTERVAL = 100; // send an init package every 100 packages;
|
static const byte INIT_PACKAGE_INTERVAL = 100; // send an init package every 100 packages;
|
||||||
static const byte MAX_VALUES_TO_SEND = 8;
|
static const byte MAX_VALUES_TO_SEND = 8;
|
||||||
|
|
@ -65,7 +65,8 @@ static const uint8_t LORA_DATA_VERSION = 1;
|
||||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||||
static const uint32_t PRESSURE_OFFSET = 825;
|
static const uint32_t PRESSURE_OFFSET = 825;
|
||||||
static const uint16_t SEND_DIFF_THRESHOLD_5GRAMS = 20; // when weight changes by 100g, then send data
|
static const uint16_t SEND_DIFF_THRESHOLD_5GRAMS = 20; // when weight changes by 100g, then send data
|
||||||
static const long NOT_ATTACHED = -2147483648;
|
static const long NOT_PLAUSIBLE_16 = 65535;
|
||||||
|
static const long NOT_PLAUSIBLE_32 = 2147483647;
|
||||||
static const byte INIT_PACKETS = 5;
|
static const byte INIT_PACKETS = 5;
|
||||||
|
|
||||||
// must be 64 bytes long (size of kAppConf)
|
// must be 64 bytes long (size of kAppConf)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
#define SAMPLES 5
|
#define SAMPLES 5
|
||||||
|
|
||||||
NAU7802 myScale; //Create instance of the NAU7802 class
|
|
||||||
|
|
||||||
byte debug_level;
|
byte debug_level;
|
||||||
|
|
||||||
|
|
@ -27,14 +26,10 @@ bool InitializeScales()
|
||||||
result = myScale.reset(); //Reset all registers
|
result = myScale.reset(); //Reset all registers
|
||||||
result &= myScale.powerUp(); //Power on analog and digital sections of the scale
|
result &= myScale.powerUp(); //Power on analog and digital sections of the scale
|
||||||
|
|
||||||
result &= myScale.setIntPolarityHigh();
|
|
||||||
result &= myScale.setLDO(NAU7802_LDO_3V3); //Set LDO to 3.3V
|
result &= myScale.setLDO(NAU7802_LDO_3V3); //Set LDO to 3.3V
|
||||||
result &= myScale.setGain(NAU7802_GAIN_128); //Set gain to 128
|
result &= myScale.setGain(NAU7802_GAIN_128); //Set gain to 128
|
||||||
result &= myScale.setSampleRate(NAU7802_SPS_40); //Set samples per second to 40
|
result &= myScale.setSampleRate(NAU7802_SPS_40); //Set samples per second to 40
|
||||||
result &= myScale.setRegister(NAU7802_ADC, 0x30); //Turn off CLK_CHP. From 9.1 power on sequencing.
|
result &= myScale.setRegister(NAU7802_ADC, 0x30); //Turn off CLK_CHP. From 9.1 power on sequencing.
|
||||||
result &= myScale.clearBit(NAU7802_PGA_PWR_PGA_CAP_EN, NAU7802_PGA_PWR);
|
|
||||||
//result &= myScale.setRegister(NAU7802_OTP_B1, 0x30);
|
|
||||||
//result &= myScale.setRegister(NAU7802_PGA, NAU7802_PGA_OUT_EN | NAU7802_PGA_CHP_DIS);
|
|
||||||
|
|
||||||
result &= myScale.calibrateAFE(); //Re-cal analog front end when we change gain, sample rate, or channel
|
result &= myScale.calibrateAFE(); //Re-cal analog front end when we change gain, sample rate, or channel
|
||||||
|
|
||||||
|
|
@ -78,7 +73,7 @@ long ReadScale(char channel)
|
||||||
} else {
|
} else {
|
||||||
channelNumber = NAU7802_CHANNEL_2;
|
channelNumber = NAU7802_CHANNEL_2;
|
||||||
}
|
}
|
||||||
long startTime = millis();
|
unsigned long startTime = millis();
|
||||||
myScale.setChannel(channelNumber);
|
myScale.setChannel(channelNumber);
|
||||||
bool calibrate_success = myScale.calibrateAFE();
|
bool calibrate_success = myScale.calibrateAFE();
|
||||||
if (! calibrate_success) {
|
if (! calibrate_success) {
|
||||||
|
|
@ -93,13 +88,15 @@ long ReadScale(char channel)
|
||||||
int const num_scale_readings = SAMPLES; // number of instantaneous scale readings to calculate the median
|
int const num_scale_readings = SAMPLES; // number of instantaneous scale readings to calculate the median
|
||||||
|
|
||||||
// we use the median, not the average, see https://community.particle.io/t/boron-gpio-provides-less-current-than-electrons-gpio/46647/13
|
// we use the median, not the average, see https://community.particle.io/t/boron-gpio-provides-less-current-than-electrons-gpio/46647/13
|
||||||
long readings[num_scale_readings]; // create arry to hold readings
|
long readings[num_scale_readings]; // create array to hold readings
|
||||||
for (int i = 0; i < num_scale_readings; i++) {
|
for (int i = 0; i < num_scale_readings; i++) {
|
||||||
//while (digitalRead(interruptPin) == LOW) {
|
//while (digitalRead(interruptPin) == LOW) {
|
||||||
long mytimer = millis();
|
unsigned long mytimer = millis();
|
||||||
while (! myScale.available()) {
|
int timeouts = 0;
|
||||||
|
while (! myScale.available() && (timeouts < 3)) {
|
||||||
// we set a timeout of 10 seconds for the measurement...
|
// we set a timeout of 10 seconds for the measurement...
|
||||||
if ((millis() - mytimer) > 10000) {
|
if ((millis() - mytimer) > 10000) {
|
||||||
|
timeouts = timeouts + 1;
|
||||||
// Timeout reading scale...
|
// Timeout reading scale...
|
||||||
Wire.endTransmission(true);
|
Wire.endTransmission(true);
|
||||||
delay(50);
|
delay(50);
|
||||||
|
|
@ -107,7 +104,6 @@ long ReadScale(char channel)
|
||||||
if (debug_level > 0) {
|
if (debug_level > 0) {
|
||||||
gCatena.SafePrintf("Timeout while reading scale...\n");
|
gCatena.SafePrintf("Timeout while reading scale...\n");
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
delay(50);
|
delay(50);
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +118,7 @@ long ReadScale(char channel)
|
||||||
delay(50);
|
delay(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
long duration = millis() - startTime;
|
unsigned long duration = millis() - startTime;
|
||||||
res = median(readings, num_scale_readings); // calculate median
|
res = median(readings, num_scale_readings); // calculate median
|
||||||
|
|
||||||
if (debug_level > 0) {
|
if (debug_level > 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue