Puts soil moisture reading into the BLE advertisement packet
This commit is contained in:
parent
30162f4628
commit
6ec48b7188
6 changed files with 56 additions and 25 deletions
|
|
@ -7,11 +7,12 @@
|
|||
#define PRST_LED_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
|
||||
// Deep sleep.
|
||||
#define PRST_DEEP_SLEEP_IN_SECONDS 2
|
||||
#define PRST_DEEP_SLEEP_IN_SECONDS 3
|
||||
|
||||
// Analog to digital converter (ADC).
|
||||
// Prints out ADC debug info, such as the values read for battery and soil moisture.
|
||||
#define PRST_ADC_DEBUG 1
|
||||
// Prints out ADC debug info, such as the values read for battery and soil
|
||||
// moisture.
|
||||
#define PRST_ADC_DEBUG 0
|
||||
|
||||
// BLE.
|
||||
#define PRST_BLE_ADV_NAME "prst"
|
||||
|
|
@ -22,4 +23,7 @@
|
|||
#define PRST_PWM_PIN NRF_GPIO_PIN_MAP(0, 5)
|
||||
#define PRST_FAST_DISCH_PIN NRF_GPIO_PIN_MAP(1, 10)
|
||||
|
||||
// SHT3C temp/humidity sensor.
|
||||
#define PRST_SHT3C_DEBUG 1
|
||||
|
||||
#endif // _PRST_CONFIG_H_
|
||||
|
|
@ -11343,7 +11343,7 @@
|
|||
// <2=> BLOCK_IF_FIFO_FULL
|
||||
|
||||
#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
|
||||
#define SEGGER_RTT_CONFIG_DEFAULT_MODE 2
|
||||
#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
|
|
|
|||
|
|
@ -58,31 +58,22 @@ static void power_manage(void) {
|
|||
// Here we need to be extra careful with what operations we do. This callback
|
||||
// has to return fast-ish, otherwise we hit some hard exceptions.
|
||||
static void rtc_callback() {
|
||||
NRF_LOG_INFO("Batt raw ");
|
||||
NRF_LOG_FLUSH();
|
||||
nrf_gpio_pin_set(PRST_LED_PIN);
|
||||
prst_shtc3_read_t temp_humi = prst_shtc3_read();
|
||||
nrf_gpio_pin_set(PRST_FAST_DISCH_PIN);
|
||||
prst_pwm_init();
|
||||
prst_pwm_start();
|
||||
prst_adc_batt_read_t batt_read = prst_adc_batt_read();
|
||||
int16_t soil_read = prst_adc_soil_read();
|
||||
prst_adc_soil_moisture_t soil_read = prst_adc_soil_read();
|
||||
prst_pwm_stop();
|
||||
nrf_gpio_pin_clear(PRST_FAST_DISCH_PIN);
|
||||
NRF_LOG_INFO("Read soil: %d", soil_read);
|
||||
prst_ble_update_adv_data(batt_read.millivolts, temp_humi.temp_millicelcius, temp_humi.humidity, 0);
|
||||
prst_ble_update_adv_data(batt_read.millivolts, temp_humi.temp_millicelcius,
|
||||
temp_humi.humidity, soil_read.relative);
|
||||
NRF_LOG_FLUSH();
|
||||
prst_adv_start();
|
||||
nrf_delay_ms(200);
|
||||
prst_adv_stop();
|
||||
nrf_gpio_pin_clear(PRST_LED_PIN);
|
||||
UNUSED_VARIABLE(batt_read);
|
||||
// NRF_LOG_INFO("Read batt: " NRF_LOG_FLOAT_MARKER " V (%d), %u mV",
|
||||
// NRF_LOG_FLOAT(batt_read.voltage), batt_read.raw, batt_read.millivolts);
|
||||
// NRF_LOG_INFO("Read temp: " NRF_LOG_FLOAT_MARKER " oC",
|
||||
// NRF_LOG_FLOAT((float) temp_humi.temp_millicelcius / 1000.0));
|
||||
// NRF_LOG_INFO("Read humi: " NRF_LOG_FLOAT_MARKER " %%",
|
||||
// NRF_LOG_FLOAT(100.0 * temp_humi.humidity / (1 << 16)));
|
||||
NRF_LOG_FLUSH();
|
||||
}
|
||||
|
||||
|
|
@ -94,11 +85,18 @@ int main(void) {
|
|||
prst_ble_init();
|
||||
prst_adc_init();
|
||||
prst_shtc3_init();
|
||||
|
||||
// Set up RTC. It will call our custom callback at a regular interval, defined
|
||||
// by PRST_DEEP_SLEEP_IN_SECONDS.
|
||||
prst_rtc_set_callback(rtc_callback);
|
||||
prst_rtc_init();
|
||||
|
||||
nrf_delay_ms(100);
|
||||
// In addition to scheduling it, let's immediatelly call it - it makes
|
||||
// debugging less tedious.
|
||||
rtc_callback();
|
||||
|
||||
// Here we go into a low energy mode. The datasheet calls this mode "System
|
||||
// ON", and in my tests it consumes around 2.7uA.
|
||||
for (;;) {
|
||||
power_manage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ static nrf_saadc_value_t sample_adc_channel(uint8_t channel) {
|
|||
return result;
|
||||
}
|
||||
|
||||
// Caps the argument to the [0, 1] range.
|
||||
static inline double cap_value(double value) {
|
||||
return value > 1.0 ? 1.0 : (value < 0.0 ? 0.0 : value);
|
||||
}
|
||||
|
||||
// Unused, since we'll call the SAADC synchronously for now.
|
||||
void saadc_callback(nrf_drv_saadc_evt_t const* p_event) {
|
||||
if (p_event->type == NRF_DRV_SAADC_EVT_DONE) {
|
||||
|
|
@ -69,16 +74,23 @@ prst_adc_batt_read_t prst_adc_batt_read() {
|
|||
ret.voltage = (3.6 * result) / (1 << PRST_ADC_RESOLUTION);
|
||||
ret.millivolts = ret.voltage * 1000;
|
||||
#if PRST_ADC_DEBUG
|
||||
NRF_LOG_INFO("[adc] Read battery voltage: %d (raw); %d mV; ", ret.raw, ret.millivolts,
|
||||
ret.voltage);
|
||||
NRF_LOG_INFO("[adc] Read battery voltage: %d (raw); %d mV; ", ret.raw,
|
||||
ret.millivolts, ret.voltage);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16_t prst_adc_soil_read() {
|
||||
prst_adc_soil_moisture_t prst_adc_soil_read() {
|
||||
nrf_saadc_value_t result = sample_adc_channel(PRST_ADC_SOIL_CHANNEL);
|
||||
double percentage = cap_value(((double)result - PRST_SOIL_DRY) /
|
||||
(PRST_SOIL_WET - PRST_SOIL_DRY));
|
||||
prst_adc_soil_moisture_t ret;
|
||||
ret.raw = result;
|
||||
ret.relative = percentage * (1 << 16);
|
||||
#if PRST_ADC_DEBUG
|
||||
NRF_LOG_INFO("[adc] Read soil moisture: %d", result);
|
||||
NRF_LOG_INFO("[adc] Read soil moisture: %d (raw); " NRF_LOG_FLOAT_MARKER
|
||||
" %% (percentage); %u (relative)",
|
||||
ret.raw, NRF_LOG_FLOAT(percentage * 100), ret.relative);
|
||||
#endif
|
||||
return result;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -3,16 +3,29 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
// ADC values. Assumes 10 bits resolution.
|
||||
// TODO(rbaron) this values drift a little bit as the battery discharges.
|
||||
// I previously did a hacky linear regression to estimate them, but I'm
|
||||
// not super sure how useful that is.
|
||||
#define PRST_SOIL_WET 200
|
||||
#define PRST_SOIL_DRY 500
|
||||
|
||||
typedef struct prst_adc_batt_val {
|
||||
int16_t raw;
|
||||
uint16_t millivolts;
|
||||
double voltage;
|
||||
} prst_adc_batt_read_t;
|
||||
|
||||
typedef struct prst_adc_soil_moisture {
|
||||
int16_t raw;
|
||||
// A value from 0 (cmopletely dry) to 2^10 (completely wet).
|
||||
uint16_t relative;
|
||||
} prst_adc_soil_moisture_t;
|
||||
|
||||
void prst_adc_init();
|
||||
|
||||
prst_adc_batt_read_t prst_adc_batt_read();
|
||||
|
||||
int16_t prst_adc_soil_read();
|
||||
prst_adc_soil_moisture_t prst_adc_soil_read();
|
||||
|
||||
#endif // _PRST_ADC_H_
|
||||
|
|
@ -47,12 +47,16 @@ prst_shtc3_read_t prst_shtc3_read() {
|
|||
// TODO(rbaron): verify the CRC of the measurements. The function is described
|
||||
// in the datasheet.
|
||||
|
||||
NRF_LOG_INFO("Computing...");
|
||||
double temp_c = -45 + 175 * ((double)((buff[0] << 8) | buff[1])) / (1 << 16);
|
||||
// double humi = ((double)((buff[3] << 8) | buff[4])) / ((1 << 16) - 1);
|
||||
uint16_t humi = (buff[3] << 8) | buff[4];
|
||||
|
||||
prst_shtc3_read_t ret = {.temp_millicelcius = temp_c * 1000,
|
||||
.humidity = humi};
|
||||
#if PRST_SHT3C_DEBUG
|
||||
NRF_LOG_INFO("[sht3c] Read temp: " NRF_LOG_FLOAT_MARKER " oC",
|
||||
NRF_LOG_FLOAT((float)temp_humi.temp_millicelcius / 1000.0));
|
||||
NRF_LOG_INFO("[sht3c] Read humi: " NRF_LOG_FLOAT_MARKER " %%",
|
||||
NRF_LOG_FLOAT(100.0 * temp_humi.humidity / (1 << 16)));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue