From 88bf94f756c34bdff9516ca66a7e558873ae71bd Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 15 Jan 2017 15:49:04 +0100 Subject: [PATCH] Calculate current using linear fit from measurements --- scripts/current_fit.py | 57 ++++++++++++++++++++++++++++++++++++++++++ src/main.c | 16 +++++++++--- 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100755 scripts/current_fit.py diff --git a/scripts/current_fit.py b/scripts/current_fit.py new file mode 100755 index 0000000..6542ca5 --- /dev/null +++ b/scripts/current_fit.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# coding: utf-8 + +import pylab as p + +data = [ + # SolarLader, Multimeter + [0, 0], + [0.412, 0.388], + [0.421, 0.392], + [0.64, 0.591], + [0.72, 0.655], + [0.78, 0.705], + [1, 0.903], + [1.05, 0.928], + [1.2, 1.04], + [1.36, 1.17], + [1.4, 1.205], + [1.706, 1.470], + [1.93, 1.58], + [2, 1.661], + [2.01, 1.683], + [2.08, 1.69], + [2.22, 1.78], + [2.27, 1.815], + ] + +data_array = p.transpose(p.array(data)) + +Ichg = data_array[0] +Imulti = data_array[1] + +adc = Ichg * 4096/8.6 + 89 + +fit = p.polyfit(adc, Imulti, 1) + +poly = p.poly1d(fit) + +#Ifit = adc**2 * fit[0] + adc * fit[1] + fit[2] +Ifit = poly(adc) +Ierror = Ifit - Imulti + +adc_expanded = p.arange(0, 4095, 1) +Ifit_expanded = poly(adc_expanded) + +#print("adc² • {:.3f} + adc • {:.3f} + {:.3f}".format(fit[0], fit[1], fit[2])) +print("adc • {:.3g} + {:.3g}".format(fit[0], fit[1])) + +p.figure() +p.plot(adc, Imulti, 'rx') +p.plot(adc, Ifit, 'r-') +p.figure() +p.plot(adc, Imulti, 'rx') +p.plot(adc_expanded, Ifit_expanded, 'b-') +p.figure() +p.plot(adc, Ierror) +p.show() diff --git a/src/main.c b/src/main.c index 4ae991f..235806a 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,7 @@ #define MAX_SLEEP_TIME 3600 #define MAX_SLEEP_TIME_LOW_VOLTAGE 300 -#define CURRENT_ADC_OFFSET 89 +#define ADC_VALUE_AT_ZERO_CURRENT 90 enum OperState { Bootstrap, @@ -562,12 +562,14 @@ int main(void) // Calculated values //fxp_t VIN_SCALE = fxp_from_float(3.3f * (100 + 10.0f) / 10.0f / 4095.0f); //fxp_t VOUT_SCALE = fxp_from_float(3.3f * (100 + 12.0f) / 12.0f / 4095.0f); - //fxp_t CURRENT_SCALE = fxp_from_float(9.7f / 4095.0f); // Calibrated from measurements fxp_t VIN_SCALE = fxp_from_float(36.41f / 4096.0f); fxp_t VOUT_SCALE = fxp_from_float(30.87f / 4096.0f); - fxp_t CURRENT_SCALE = fxp_from_float(8.60f / 4096.0f); + + // current = adc • 0.00166 + -0.0725 = adc • m + t + fxp_t ADC2CURRENT_M = fxp_from_float( 0.00166f); + fxp_t ADC2CURRENT_T = fxp_from_float(-0.07250f); /* if power changes by more than this factor, MPP is tested again */ MPP_MAX_POWER_CHANGE_FACTOR = fxp_from_float(0.2f); @@ -664,7 +666,13 @@ int main(void) // convert read values power_state.vin = fxp_mult(fxp_from_int(adc_values[0]), VIN_SCALE); power_state.vout = fxp_mult(fxp_from_int(adc_values[1]), VOUT_SCALE); - power_state.current = fxp_mult(fxp_from_int(adc_values[2] - CURRENT_ADC_OFFSET), CURRENT_SCALE); + + if(adc_values[2] <= ADC_VALUE_AT_ZERO_CURRENT+3) { + power_state.current = 0; + } else { + // current = adc • m + t + power_state.current = fxp_add(fxp_mult(fxp_from_int(adc_values[2]), ADC2CURRENT_M), ADC2CURRENT_T); + } power_state.vin_avg = fxp_add(fxp_mult(power_state.vin, AVG_FACT), fxp_mult(power_state.vin_avg, AVG_FACT_INV)); power_state.vout_avg = fxp_add(fxp_mult(power_state.vout, AVG_FACT), fxp_mult(power_state.vout_avg, AVG_FACT_INV));