Adds code for reading the phototransistor values
This commit is contained in:
parent
d3ed9a3311
commit
bebf8c0a13
4 changed files with 84 additions and 11 deletions
|
|
@ -7,13 +7,15 @@
|
|||
// the the version you're programming. The version can be found on the
|
||||
// b-parasite board.
|
||||
// #define PRST_VERSION_1_0_X
|
||||
#define PRST_VERSION_1_1_X
|
||||
// #define PRST_VERSION_1_1_X
|
||||
#define PRST_VERSION_1_2_X
|
||||
|
||||
// Built-in LED.
|
||||
#define PRST_LED_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
|
||||
// Deep sleep.
|
||||
#define PRST_DEEP_SLEEP_IN_SECONDS 300
|
||||
// #define PRST_DEEP_SLEEP_IN_SECONDS 2
|
||||
#define PRST_DEEP_SLEEP_IN_SECONDS 2 * 3600
|
||||
|
||||
// Analog to digital converter (ADC).
|
||||
// Prints out ADC debug info, such as the values read for battery and soil
|
||||
|
|
@ -29,7 +31,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:01:01"
|
||||
#define PRST_BLE_MAC_ADDR "f0:ca:f0:ca:00:10"
|
||||
#define PRST_BLE_ADV_NAME "prst"
|
||||
// Total time spend advertising.
|
||||
#define PRST_BLE_ADV_TIME_IN_MS 1000
|
||||
|
|
@ -65,6 +67,16 @@
|
|||
// Whether to produce debug messages for the LDR
|
||||
#define PRST_ADC_PHOTO_DEBUG 0
|
||||
|
||||
// #endif // End of version-specific configuration.
|
||||
#elif defined(PRST_VERSION_1_2_X)
|
||||
|
||||
#define PRST_HAS_PHOTOTRANSISTOR 1
|
||||
|
||||
#define PRST_PHOTO_V_PIN NRF_GPIO_PIN_MAP(0, 29)
|
||||
#define PRST_PHOTO_OUT_PIN NRF_GPIO_PIN_MAP(0, 2)
|
||||
|
||||
#define PRST_ADC_PHOTO_DEBUG 1
|
||||
|
||||
#endif // End of version-specific configuration.
|
||||
|
||||
#endif // _PRST_CONFIG_H_
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ static void log_init(void) {
|
|||
static void gpio_init(void) {
|
||||
nrf_gpio_cfg_output(PRST_LED_PIN);
|
||||
nrf_gpio_cfg_output(PRST_FAST_DISCH_PIN);
|
||||
#if PRST_HAS_LDR
|
||||
#if PRST_HAS_LDR || PRST_HAS_PHOTOTRANSISTOR
|
||||
nrf_gpio_cfg_output(PRST_PHOTO_V_PIN);
|
||||
#endif
|
||||
NRF_LOG_INFO("GPIO pins inited.");
|
||||
|
|
@ -67,11 +67,16 @@ static void rtc_callback() {
|
|||
nrf_gpio_pin_clear(PRST_FAST_DISCH_PIN);
|
||||
|
||||
uint16_t lux = 0;
|
||||
#if PRST_HAS_LDR
|
||||
#if PRST_HAS_LDR || PRST_HAS_PHOTOTRANSISTOR
|
||||
nrf_gpio_pin_set(PRST_PHOTO_V_PIN);
|
||||
prst_adc_photo_sensor_t photo_read = prst_adc_photo_read(batt_read.voltage);
|
||||
|
||||
// Just while debugging.
|
||||
while (1) {
|
||||
nrf_delay_ms(1000);
|
||||
prst_adc_photo_sensor_t photo_read = prst_adc_photo_read(batt_read.voltage);
|
||||
lux = photo_read.brightness;
|
||||
}
|
||||
nrf_gpio_pin_clear(PRST_PHOTO_V_PIN);
|
||||
lux = photo_read.brightness;
|
||||
#endif
|
||||
|
||||
prst_ble_update_adv_data(batt_read.millivolts, temp_humi.temp_millicelcius,
|
||||
|
|
|
|||
|
|
@ -8,9 +8,16 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "prst_config.h"
|
||||
#include "sdk_config.h"
|
||||
|
||||
// 10 bits resoltuion.
|
||||
#if NRFX_SAADC_CONFIG_RESOLUTION == 1
|
||||
#define PRST_ADC_RESOLUTION 10
|
||||
#elif NRFX_SAADC_CONFIG_RESOLUTION == 2
|
||||
#define PRST_ADC_RESOLUTION 12
|
||||
#else
|
||||
#error "NRFX_SAADC_CONFIG_RESOLUTION does not have a valid value"
|
||||
#endif // NRFX_SAADC_CONFIG_RESOLUTION
|
||||
|
||||
#define PRST_ADC_BATT_INPUT NRF_SAADC_INPUT_VDD
|
||||
#define PRST_ADC_BATT_CHANNEL 0
|
||||
|
|
@ -71,6 +78,7 @@ void prst_adc_init() {
|
|||
|
||||
nrf_saadc_channel_config_t photo_channel_config =
|
||||
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PRST_ADC_PHOTO_INPUT);
|
||||
// photo_channel_config.gain = NRF_SAADC_GAIN1_4;
|
||||
|
||||
APP_ERROR_CHECK(nrf_drv_saadc_channel_init(PRST_ADC_PHOTO_CHANNEL,
|
||||
&photo_channel_config));
|
||||
|
|
@ -142,7 +150,9 @@ prst_adc_photo_sensor_t prst_adc_photo_read(double battery_voltage) {
|
|||
prst_adc_photo_sensor_t ret;
|
||||
ret.raw = raw_photo_output;
|
||||
ret.voltage = (3.6 * raw_photo_output) / (1 << PRST_ADC_RESOLUTION);
|
||||
// ret.voltage = (2.4 * raw_photo_output) / (1 << PRST_ADC_RESOLUTION);
|
||||
|
||||
#if PRST_HAS_LDR
|
||||
// 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
|
||||
|
|
@ -161,9 +171,55 @@ prst_adc_photo_sensor_t prst_adc_photo_read(double battery_voltage) {
|
|||
ret.brightness =
|
||||
MAX(0, MIN(mult_value / powf(photo_resistance, pow_value), UINT16_MAX));
|
||||
|
||||
#elif PRST_HAS_PHOTOTRANSISTOR
|
||||
// The ALS-PT19 phototransistor is a device in which the current flow between
|
||||
// its two terminals is controlled by how much light there is in the ambient.
|
||||
// We measure that current by calculating the voltage across a resistor that
|
||||
// is connected in series with the phototransistor.
|
||||
// Some infor:
|
||||
// - Not all lights are the same. The ALS-PT19 has different current
|
||||
// responses for incandescent and fluorescent lights and it shows no values
|
||||
// for sunlight. We have to make some compromises here, aiming for a
|
||||
// "reasonable" middle ground through calibration.
|
||||
// - ALS-PT19' minimum voltage is 2.5 V. Our CR2032 battery has a theoretical
|
||||
// range of 2.0 V to 3.0 V, but in our usage pattern it seems to spend most of
|
||||
// its life around 2.6 V (https://github.com/rbaron/b-parasite/issues/1). In
|
||||
// my manual tests it seems we can usually go lower than that. So while we're
|
||||
// pushing it a bit, we should be okay most of the time.
|
||||
//
|
||||
// In order to design the value of the series resistor, we assume Vcc = 2.5V,
|
||||
// and we want the upper limit of light intensity to correspond to a value of
|
||||
// Vout < 2.5 V - 0.4 V (saturation) = 2.1 V. Let's call this the "direct
|
||||
// sunlight" voltage across our resistor. This direct sunlight voltage will
|
||||
// appear when the phototransistor outputs the direct sunlight current.
|
||||
//
|
||||
// In short, what we want:
|
||||
// A value of R_L such that Vout is < 2.1 V (but close) when the sensor is in
|
||||
// direct sunlight. While Vcc is 2.5 V, R_L = 470 Ohm outputs Vout ~ 1.7V, so
|
||||
// there's still some wiggle room for even more sunnier days.
|
||||
//
|
||||
// Another caveat: the datasheet shows that the current in the transistor is
|
||||
// relatively constant when we vary Vcc (Fig.4). This seems to be true for low
|
||||
// currents (the datsheet uses 100 lx in Fig.4), but not for larger currents.
|
||||
const float phototransistor_resistor = 470.0f;
|
||||
const float current_sun = 3.59e-3f;
|
||||
// Assuming 10000 lux for the saturation test. Calibration with a proper light
|
||||
// meter would be better.
|
||||
const float lux_sun = 10000.0f;
|
||||
|
||||
const float current = ret.voltage / phototransistor_resistor;
|
||||
ret.brightness = MAX(0, MIN(lux_sun * current / current_sun, UINT16_MAX));
|
||||
|
||||
#if PRST_ADC_PHOTO_DEBUG
|
||||
NRF_LOG_INFO("[adc] Read brightness level: %d (raw); %d (lux)", ret.raw,
|
||||
ret.brightness);
|
||||
NRF_LOG_INFO("[adc] Phototransistor current: " NRF_LOG_FLOAT_MARKER " uA",
|
||||
NRF_LOG_FLOAT(1000000 * current));
|
||||
#endif // PRST_ADC_PHOTO_DEBUG
|
||||
#endif // PRST_HAS_PHOTOTRANSISTOR
|
||||
|
||||
#if PRST_ADC_PHOTO_DEBUG
|
||||
NRF_LOG_INFO("[adc] Read brightness level: " NRF_LOG_FLOAT_MARKER
|
||||
" mV %d (raw); %d (lux)",
|
||||
NRF_LOG_FLOAT(1000 * ret.voltage), ret.raw, ret.brightness);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ static void init_advertisement_data() {
|
|||
|
||||
// Bit 0 of byte 0 specifies whether or not ambient light data exists in the
|
||||
// payload.
|
||||
#if PRST_HAS_LDR
|
||||
#if PRST_HAS_LDR || PRST_HAS_PHOTOTRANSISTOR
|
||||
service_data[0] |= 1;
|
||||
#endif
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ void prst_ble_update_adv_data(uint16_t batt_millivolts,
|
|||
service_data[8] = soil_moisture >> 8;
|
||||
service_data[9] = soil_moisture & 0xff;
|
||||
|
||||
#if PRST_HAS_LDR
|
||||
#if PRST_HAS_LDR || PRST_HAS_PHOTOTRANSISTOR
|
||||
service_data[16] = brightness >> 8;
|
||||
service_data[17] = brightness & 0xff;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue