From e32803d44d60f12991f3095269b76bcc249b2dbf Mon Sep 17 00:00:00 2001 From: rbaron Date: Thu, 2 Sep 2021 21:29:11 +0200 Subject: [PATCH] Improvements to photo resistor-based lux estimation - Code now compiles - Estimation of the photo resistor resistance works - Lux estimation from the photo resistor resistance needs more work and calibration - Lux is now encoded in the BLE advertisement payload --- code/b-parasite/config/prst_config.h | 5 +++-- code/b-parasite/src/main.c | 9 +++++---- code/b-parasite/src/prst/adc.c | 28 +++++++++++++++++++++------- code/b-parasite/src/prst/ble.c | 9 +++++++-- code/b-parasite/src/prst/ble.h | 3 ++- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/code/b-parasite/config/prst_config.h b/code/b-parasite/config/prst_config.h index 3c52b5f..8aef6d3 100644 --- a/code/b-parasite/config/prst_config.h +++ b/code/b-parasite/config/prst_config.h @@ -11,13 +11,14 @@ #define PRST_PHOTO_OUT NRF_GPIO_PIN_MAP(0, 2) // Deep sleep. -#define PRST_DEEP_SLEEP_IN_SECONDS 300 +#define PRST_DEEP_SLEEP_IN_SECONDS 2 // Analog to digital converter (ADC). // Prints out ADC debug info, such as the values read for battery and soil // moisture. #define PRST_ADC_BATT_DEBUG 0 #define PRST_ADC_SOIL_DEBUG 0 +#define PRST_ADC_PHOTO_DEBUG 1 // BLE. // Prints out BLE debug info, such as the final encoded advertisement packet. @@ -27,7 +28,7 @@ // 1. Two most significant bits are set to 1; // 2. The remaining bits should not _all_ be set to 0; // 2. The remaining bits should not _all_ be set to 1; -#define PRST_BLE_MAC_ADDR "f0:ca:f0:ca:00:01" +#define PRST_BLE_MAC_ADDR "f0:ca:f0:ca:01:01" #define PRST_BLE_ADV_NAME "prst" // Total time spend advertising. #define PRST_BLE_ADV_TIME_IN_MS 1000 diff --git a/code/b-parasite/src/main.c b/code/b-parasite/src/main.c index c099fec..68211f1 100644 --- a/code/b-parasite/src/main.c +++ b/code/b-parasite/src/main.c @@ -63,12 +63,13 @@ static void rtc_callback() { prst_pwm_stop(); nrf_gpio_pin_clear(PRST_FAST_DISCH_PIN); - nrf_gpio_pin_set(PRST_PHOTO_V); // set GPIO for photoresistor HIGH - prst_adc_photo_sensor_t photo_read = prst_adc_photo_read(batt_read.voltage); // read PHOTO SENSOR value - nrf_gpio_pin_clear(PRST_PHOTO_V); // clear GPIO for photoresistor + nrf_gpio_pin_set(PRST_PHOTO_V); + prst_adc_photo_sensor_t photo_read = prst_adc_photo_read(batt_read.voltage); + nrf_gpio_pin_clear(PRST_PHOTO_V); prst_ble_update_adv_data(batt_read.millivolts, temp_humi.temp_millicelcius, - temp_humi.humidity, soil_read.relative, photo_read.lux, run_counter); + temp_humi.humidity, soil_read.relative, + photo_read.lux, run_counter); prst_adv_start(); nrf_delay_ms(PRST_BLE_ADV_TIME_IN_MS); prst_adv_stop(); diff --git a/code/b-parasite/src/prst/adc.c b/code/b-parasite/src/prst/adc.c index a352abb..dc056c9 100644 --- a/code/b-parasite/src/prst/adc.c +++ b/code/b-parasite/src/prst/adc.c @@ -71,8 +71,8 @@ void prst_adc_init() { nrf_saadc_channel_config_t photo_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PRST_ADC_PHOTO_INPUT); - APP_ERROR_CHECK( - nrf_drv_saadc_channel_init(PRST_ADC_PHOTO_CHANNEL, &photo_channel_config)); + APP_ERROR_CHECK(nrf_drv_saadc_channel_init(PRST_ADC_PHOTO_CHANNEL, + &photo_channel_config)); } prst_adc_batt_read_t prst_adc_batt_read() { @@ -131,14 +131,28 @@ prst_adc_soil_moisture_t prst_adc_soil_read(double battery_voltage) { } prst_adc_photo_sensor_t prst_adc_photo_read(double battery_voltage) { - nrf_saadc_value_t raw_photo_output = sample_adc_channel(PRST_ADC_PHOTO_CHANNEL); + nrf_saadc_value_t raw_photo_output = + sample_adc_channel(PRST_ADC_PHOTO_CHANNEL); prst_adc_photo_sensor_t ret; ret.raw = raw_photo_output; ret.voltage = (3.6 * raw_photo_output) / (1 << PRST_ADC_RESOLUTION); - ret.lux = (uint16_t)ret.voltage*100000/(battery_voltage-ret.voltage); -#if PRST_ADC_SOIL_DEBUG - NRF_LOG_INFO("[adc] Read lux level: %d (raw); %d (lux)", - ret.raw, ret.lux); + // This value needs to be calibrated. + // The photo resistor forms a voltage divider with a 10 kOhm resistor. + // The voltage here is measured in the middle of the voltage divider. + // Vcc ---- (R_photo) ---|--- (10k) ---- GND + // Vout + // So we can estimate R_photo = R * (Vcc - Vout) / Vout + const double photo_resistance = + 1e4 * (battery_voltage - ret.voltage) / ret.voltage; + + // TODO: Now that we have the resistor value of the photo resistor, we need to + // estimate the value in lux. This needs to be calibrated with a real board in + // complete dark and in a super bright environment. + // This current value is just a placeholder. + ret.lux = (uint16_t)UINT16_MAX * (photo_resistance / 1e4); + +#if PRST_ADC_PHOTO_DEBUG + NRF_LOG_INFO("[adc] Read lux level: %d (raw); %d (lux)", ret.raw, ret.lux); #endif return ret; } \ No newline at end of file diff --git a/code/b-parasite/src/prst/ble.c b/code/b-parasite/src/prst/ble.c index ea0e026..8dd8190 100644 --- a/code/b-parasite/src/prst/ble.c +++ b/code/b-parasite/src/prst/ble.c @@ -33,8 +33,9 @@ | 6-7 | Relative air humidity, scaled from 0 (0%) to 0xffff (100%) | | 8-9 | Soil moisture, scaled from from 0 (0%) to 0xffff (100%) | | 10-15 | b-parasite's own MAC address | +| 16-17 | Lux level from the photoresistor | */ -#define SERVICE_DATA_LEN 16 +#define SERVICE_DATA_LEN 18 static uint8_t service_data[SERVICE_DATA_LEN]; // Stores the encoded advertisement data. As per BLE spec, 31 bytes max. @@ -135,7 +136,8 @@ void prst_ble_init() { void prst_ble_update_adv_data(uint16_t batt_millivolts, uint16_t temp_millicelcius, uint16_t humidity, - uint16_t soil_moisture, uint8_t run_counter) { + uint16_t soil_moisture, uint16_t lux, + uint8_t run_counter) { // 4 bits for a small wrap-around counter for deduplicating messages on the // receiver. service_data[1] = run_counter & 0x0f; @@ -152,6 +154,9 @@ void prst_ble_update_adv_data(uint16_t batt_millivolts, service_data[8] = soil_moisture >> 8; service_data[9] = soil_moisture & 0xff; + service_data[16] = lux >> 8; + service_data[17] = lux & 0xff; + // Encodes adv_data_ into .gap_adv_data_. uint32_t err_code = ble_advdata_encode( &adv_data_, gap_adv_data_.adv_data.p_data, &gap_adv_data_.adv_data.len); diff --git a/code/b-parasite/src/prst/ble.h b/code/b-parasite/src/prst/ble.h index bfe8460..b3b7f62 100644 --- a/code/b-parasite/src/prst/ble.h +++ b/code/b-parasite/src/prst/ble.h @@ -13,6 +13,7 @@ void prst_adv_stop(); void prst_ble_update_adv_data(uint16_t batt_millivolts, uint16_t temp_millicelcius, uint16_t humidity, - uint16_t soil_moisture, uint8_t run_counter); + uint16_t soil_moisture, uint16_t lux, + uint8_t run_counter); #endif // _PRST_BLE_H_ \ No newline at end of file