diff --git a/code/b-parasite/config/prst_config.h b/code/b-parasite/config/prst_config.h index 8285f1b..036f684 100644 --- a/code/b-parasite/config/prst_config.h +++ b/code/b-parasite/config/prst_config.h @@ -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_ \ No newline at end of file diff --git a/code/b-parasite/config/sdk_config.h b/code/b-parasite/config/sdk_config.h index 73eb48c..01dd3cc 100644 --- a/code/b-parasite/config/sdk_config.h +++ b/code/b-parasite/config/sdk_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 // diff --git a/code/b-parasite/src/main.c b/code/b-parasite/src/main.c index 3b6e910..f916d94 100644 --- a/code/b-parasite/src/main.c +++ b/code/b-parasite/src/main.c @@ -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(); } diff --git a/code/b-parasite/src/prst/adc.c b/code/b-parasite/src/prst/adc.c index ec3d2b0..907cee6 100644 --- a/code/b-parasite/src/prst/adc.c +++ b/code/b-parasite/src/prst/adc.c @@ -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; } \ No newline at end of file diff --git a/code/b-parasite/src/prst/adc.h b/code/b-parasite/src/prst/adc.h index 6f1a459..4cd0112 100644 --- a/code/b-parasite/src/prst/adc.h +++ b/code/b-parasite/src/prst/adc.h @@ -3,16 +3,29 @@ #include +// 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_ \ No newline at end of file diff --git a/code/b-parasite/src/prst/shtc3.c b/code/b-parasite/src/prst/shtc3.c index 9cc4eda..4d81f36 100644 --- a/code/b-parasite/src/prst/shtc3.c +++ b/code/b-parasite/src/prst/shtc3.c @@ -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; } \ No newline at end of file