From cc9b3e65ca93b8a761b056123b0a21b6faf82a61 Mon Sep 17 00:00:00 2001 From: Jeonghoon Park Date: Thu, 9 Aug 2018 19:02:16 +0900 Subject: [PATCH 1/1] implement voltage to ppm for example --- inc/co2-sensor.h | 6 +++-- src/co2-sensor.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/inc/co2-sensor.h b/inc/co2-sensor.h index d9ee219..d3b2b39 100644 --- a/inc/co2-sensor.h +++ b/inc/co2-sensor.h @@ -34,9 +34,11 @@ void co2_sensor_close(void); /* utility functions */ double co2_sensor_value_to_voltage(unsigned int value); -/* Not implemented, please see comment in c source code */ + +/* Fallowing functions art Not implemented, please see comments in c source code */ +int co2_sensor_set_calibration_values(unsigned int zero_point_v, + unsigned int second_point_ppm, unsigned int second_point_v); unsigned int co2_sensor_voltage_to_ppm(double voltage); unsigned int co2_sensor_value_to_ppm(unsigned int value); #endif /* __CO2_SENSOR_H__ */ - diff --git a/src/co2-sensor.c b/src/co2-sensor.c index 363f2c6..ce85c21 100644 --- a/src/co2-sensor.c +++ b/src/co2-sensor.c @@ -17,13 +17,26 @@ ******************************************************************/ #include +#include #include "adc-mcp3008.h" #include "log.h" +#define CO2_SENSOR_VOLTAGE_GAIN (8.5) + #define CO2_SENSOR_REF_VOLTAGE (5) #define CO2_SENSOR_VALUE_MAX (1024) +/* CAUTION !! These data are EXAMPLE Data, NOT REAL data */ +#define CO2_SENSOR_DEFAULT_VALUE_ZP (690) // 400ppm +#define CO2_SENSOR_DEFAULT_VALUE_1000 (644) + +#define USE_EXAMPLE_CODE + +static const double log400 = 2.602; + static bool initialized = false; +static double co2_zp_volt = -1; +static double slope_value = -1; void co2_sensor_close(void) { @@ -41,6 +54,7 @@ int co2_sensor_read(int ch_num, unsigned int *out_value) retv_if(ret != 0, -1); initialized = true; } + ret = adc_mcp3008_read(ch_num, &read_value); retv_if(ret != 0, -1); @@ -49,24 +63,64 @@ int co2_sensor_read(int ch_num, unsigned int *out_value) return 0; } -double co2_sensor_value_to_voltage(unsigned int value) +static inline double __value_to_volt(unsigned int value) +{ + return (double)value + * (double)(CO2_SENSOR_REF_VOLTAGE / CO2_SENSOR_VALUE_MAX) + / CO2_SENSOR_VOLTAGE_GAIN; +} + +static double __calc_slope(double zp_volt, double sec_volt, double x_axis_diff) +{ + return (zp_volt - sec_volt) / (x_axis_diff); +} + +/* To use to calibrate ppm value*/ +int co2_sensor_set_calibration_values(unsigned int zero_point_v, + unsigned int second_point_ppm, unsigned int second_point_v) { - double v = 0; + double sec_volt = -1; + double x_axis_diff = -1; - v = (double)value * CO2_SENSOR_REF_VOLTAGE / CO2_SENSOR_VALUE_MAX; + retv_if(zero_point_v <= second_point_v, -1); + retv_if(second_point_ppm <= 400, -1); - return v; + co2_zp_volt = __value_to_volt(zero_point_v); + sec_volt = __value_to_volt(second_point_v); + x_axis_diff = log400 - log(second_point_ppm); + + slope_value = __calc_slope(co2_zp_volt, sec_volt, x_axis_diff); + + return 0; } -/* Not implemented, please see c source code */ -unsigned int co2_sensor_voltage_to_ppm(double voltage) +double co2_sensor_value_to_voltage(unsigned int value) { - int ppm = 0; + retv_if(value > 1023, -100000000.0); // out of value range + + return __value_to_volt(value); +} +/* Not implemented !!! */ +unsigned int co2_sensor_voltage_to_ppm(double voltage) +{ + double ppm = 0; /* Make this function yourself */ /* Please ref. 'Theory' section in https://sandboxelectronics.com/?p=147#Theory */ - return ppm; + /* Example */ +#ifdef USE_EXAMPLE_CODE + if (slope_value < 0) + co2_sensor_set_calibration_values(CO2_SENSOR_DEFAULT_VALUE_ZP, + CO2_SENSOR_DEFAULT_VALUE_1000, 1000); + + if (voltage >= co2_zp_volt) + return 400; + + ppm = pow(10, (voltage - co2_zp_volt)/slope_value + log400); +#endif + + return (unsigned int)ppm; } unsigned int co2_sensor_value_to_ppm(unsigned int value) -- 2.7.4