Uses better LDR x lux model

This commit is contained in:
rbaron 2021-09-22 20:40:31 +02:00
parent ba361e099c
commit a00559a98b
2 changed files with 16 additions and 18 deletions

View file

@ -6,7 +6,7 @@
// Built-in LED. // Built-in LED.
#define PRST_LED_PIN NRF_GPIO_PIN_MAP(0, 28) #define PRST_LED_PIN NRF_GPIO_PIN_MAP(0, 28)
// Photo Sensor // Photoresistor pins.
#define PRST_PHOTO_V NRF_GPIO_PIN_MAP(0, 29) #define PRST_PHOTO_V NRF_GPIO_PIN_MAP(0, 29)
#define PRST_PHOTO_OUT NRF_GPIO_PIN_MAP(0, 2) #define PRST_PHOTO_OUT NRF_GPIO_PIN_MAP(0, 2)

View file

@ -1,6 +1,7 @@
#include "prst/adc.h" #include "prst/adc.h"
#include <app_error.h> #include <app_error.h>
#include <math.h>
#include <nrf_drv_saadc.h> #include <nrf_drv_saadc.h>
#include <nrf_log.h> #include <nrf_log.h>
#include <nrf_saadc.h> #include <nrf_saadc.h>
@ -136,31 +137,28 @@ prst_adc_photo_sensor_t prst_adc_photo_read(double battery_voltage) {
prst_adc_photo_sensor_t ret; prst_adc_photo_sensor_t ret;
ret.raw = raw_photo_output; ret.raw = raw_photo_output;
ret.voltage = (3.6 * raw_photo_output) / (1 << PRST_ADC_RESOLUTION); ret.voltage = (3.6 * raw_photo_output) / (1 << PRST_ADC_RESOLUTION);
// This value needs to be calibrated.
// The photo resistor forms a voltage divider with a 10 kOhm resistor. // The photo resistor forms a voltage divider with a 10 kOhm resistor.
// The voltage here is measured in the middle of the voltage divider. // The voltage here is measured in the middle of the voltage divider.
// Vcc ---- (R_photo) ---|--- (10k) ---- GND // Vcc ---- (R_photo) ---|--- (10k) ---- GND
// Vout // Vout
// So we can estimate R_photo = R * (Vcc - Vout) / Vout // So we can estimate R_photo = R * (Vcc - Vout) / Vout
const double photo_resistance = const float photo_resistance =
1e4 * (battery_voltage - ret.voltage) / ret.voltage; 1e4f * (battery_voltage - ret.voltage) / ret.voltage;
// TODO: Now that we have the resistor value of the photo resistor, we need to // The relationship between the LDR resistance and the lux level is
// estimate the brightness level. This needs to be calibrated with a real // logarithmic. We need to solve a logarithmic equation to find the lux
// board in complete dark and in a super bright environment. This current // level, given the LDR resistance we just measured.
// value is just a placeholder. // These values work for the GL5528 LDR and were borrowed from
// Dark resistance: 1 MOhm. // https://github.com/QuentinCG/Arduino-Light-Dependent-Resistor-Library.
const double kDarkResistance = 1e6; const float mult_value = 32017200.0f;
// Light resistance: 10 kOhm. const float pow_value = 1.5832f;
const double kLightResistance = 1e4; ret.brightness =
// A value in 0x0 (dark) - 0xffff (light). MAX(0, MIN(mult_value / powf(photo_resistance, pow_value), UINT16_MAX));
// A little better, but still not great.
ret.brightness = (uint16_t)UINT16_MAX * (kDarkResistance - photo_resistance) /
(kDarkResistance - kLightResistance);
#if PRST_ADC_PHOTO_DEBUG #if PRST_ADC_PHOTO_DEBUG
NRF_LOG_INFO("[adc] Read brightness level: %d (raw); %d (brightness)", NRF_LOG_INFO("[adc] Read brightness level: %d (raw); %d (lux)", ret.raw,
ret.raw, ret.brightness); ret.brightness);
#endif #endif
return ret; return ret;
} }