diff --git a/aftb_adcparms.h b/aftb_adcparms.h new file mode 100644 index 0000000..4786152 --- /dev/null +++ b/aftb_adcparms.h @@ -0,0 +1,45 @@ +/* + * Parameters for new varVppMeasureVpp() + * Select the data set that matches your hardware variant or add a suitable data set. + * 2024-02-14 Initial release + */ +#ifndef __AFTB_ADCPARMS_H__ +#define __AFTB_ADCPARMS_H__ + +// Select your hardware version (AREF source) +#define AREF_1V1 // Defined data sets AREF_3V3, AREF_1V1, AREF_3V3_R4 +// For best results, measure the voltage on AREF pin with a good multimeter and use this value for VREF + +#if defined(AREF_3V3) +// Values for ATmega328P (NANO V3, UNO R3) AREF = EXTERNAL R7 = 3k3, Ri = 32k (original Afterburner) +#define ADC_R5 (100.0) // R5 in kOhm as float +#define ADC_R6 (20.0) // R6 in kOhm as float +#define VREF (3.0) // Vref in Volts as float; Vref = 3.3V * 32k / (32k + 3k3) => 2.991V +#define AREF_SOURCE EXTERNAL + +#elif defined(AREF_1V1) +// Values for ATmega328P (NANO V3, UNO R3) AREF = INTERNAL 1.1V, R5 = 20k, R6 = 1k3, R7 not populated +#define ADC_R5 (20.0) // R5 in kOhm as float +#define ADC_R6 (1.3) // R6 in kOhm as float +#define VREF (1.1) // Vref in Volts as float; Vref = 1.1V +#define AREF_SOURCE INTERNAL + +#elif defined(AREF_3V3_R4) +// Values for Renesas RA4M1 (UNO R4 Minima/WiFi) AREF = EXTERNAL R7 = 3k3, Ri = 130k (original Afterburner) +#define ADC_R5 (100.0) // R5 in kOhm as float +#define ADC_R6 (20.0) // R6 in kOhm as float +#define VREF (3.2) // Vref in Volts as float; Vref = 3.3V * 130k / (130k + 3k3) => 3.218V +#define AREF_SOURCE AR_EXTERNAL + +// You can add additional variants here + +#else +// Invalid or missing AREF variant +#undef ADC_R5 +#undef ADC_R6 +#undef VREF +#undef AREF_SOURCE +#error "Invalid or missing AREF variant\n" +#endif + +#endif diff --git a/aftb_vpp.h b/aftb_vpp.h index 519f4f6..b3f454c 100644 --- a/aftb_vpp.h +++ b/aftb_vpp.h @@ -2,6 +2,7 @@ * Variable voltage functions for Afterburner GAL project. * * 2024-02-02 Minor changes in varVppInit() + * 2024-02-14 Redesign of VPP measurement (function varVppMeasureVpp()) */ #ifndef __AFTB_VPP_H__ #define __AFTB_VPP_H__ @@ -15,6 +16,7 @@ #define VPP A0 #include "aftb_mcp4131.h" +#include "aftb_adcparms.h" #ifndef FAIL #define FAIL 0 #define OK 1 @@ -43,17 +45,6 @@ #define VPP_VERBOSE 0 -#ifdef EXTERNAL -#define ANALOG_REF_EXTERNAL EXTERNAL -#else -#define ANALOG_REF_EXTERNAL AR_EXTERNAL -#endif - -//UNO R4 Minima or Wifi (Aref internally pulled down by 130kOhm, AVR Uno R3 pulled down by 32kOhm) -#ifdef _RENESAS_RA_ -#define AREF_IS_3V2 -#endif - //pot wiper indices for the voltages uint8_t vppWiper[MAX_WIPER] = {0}; @@ -149,57 +140,29 @@ static void varVppSet(uint8_t value) { varVppSetVppIndex(vppWiper[value]); } -// UNO R4/Minima - Renesas IC (significant ADC gain errors measured) -#ifdef AREF_IS_3V2 -#define SAMPLE_CNT 16 -#define SAMPLE_DIVIDER 8 -#define SAMPLE_MULTIPLIER 25 -// SAMPLE_SHIFT moves the ADC gain error up/down -#define SAMPLE_SHIFT -45; - -//AVR based Arduinos (no ADC gain errors measured) -#else -#define SAMPLE_CNT 14 -#define SAMPLE_DIVIDER 8 -#define SAMPLE_MULTIPLIER 1 -#define SAMPLE_OFFSET 5 -#endif +// New VPP measurement algorithm +#define MCOUNT (14) // Number of added measurements as integer +#define ADCRES (10) // Analog Read Resolution in bits as integer static int16_t varVppMeasureVpp(int8_t printValue) { - int8_t i = 0; - uint16_t r1 = 0; - int16_t r2; //correction for ADC gain error + int adcsum = 0; // Sum MCOUNT measurements here + int loops = 0; // Counter for measure loop + float vpp; // Vpp result as float + // Precalculate constant parts of the formula + float divisor = ADC_R6 * float(1 << ADCRES); + float dividend = VREF * (ADC_R5 + ADC_R6); - while (i++ < SAMPLE_CNT) { - r1 += analogRead(VPP); - } - r2 = (r1 / (SAMPLE_DIVIDER * SAMPLE_MULTIPLIER)); -#ifdef SAMPLE_OFFSET - r1+= SAMPLE_OFFSET; -#endif - r1 /= SAMPLE_DIVIDER; -#ifdef SAMPLE_SHIFT - r2 += SAMPLE_SHIFT; - r1 += r2; -#endif - r1 += calOffset; + // Measure MCOUNT times and add results + do { + adcsum += analogRead(VPP); // Sum MCOUNT measurements here + } while (++loops < MCOUNT); + // Now calculate the VPP + vpp = (float(adcsum) * dividend) / divisor / float(MCOUNT); + vpp += float(calOffset) / 100.0; if (printValue) { - uint8_t a = r1%100; - Serial.print(r1/100); - Serial.print(F(".")); - if (a < 10) { - Serial.print(F("0")); - } -#if 1 - Serial.println(a); -#else - //debug - display the voltage skew value in r2 - Serial.print(a); - Serial.println(F(", ")); - Serial.println(r2); -#endif + Serial.println(vpp); } - return r1; + return int16_t(vpp * 100.0); } // Returns 1 on Success, 0 on Failure @@ -305,7 +268,7 @@ static void varVppStoreWiperCalib() { //return 1 on success (variable VPP functionality present), 0 on failure (VPP not detected on board) static int8_t varVppInit(void) { - analogReference(ANALOG_REF_EXTERNAL); //use 3V3 external reference + analogReference(AREF_SOURCE); //use analog reference depending on settings in aftp_adcparms.h analogRead(VPP); // Perform a dummy conversion referring to the datasheet wiperStat = 0; //wiper disabled diff --git a/afterburner.ino b/afterburner.ino index 308386a..be8607f 100644 --- a/afterburner.ino +++ b/afterburner.ino @@ -37,7 +37,7 @@ */ -#define VERSION "0.5.6" +#define VERSION "0.5.6hh" //#define DEBUG_PES //#define DEBUG_VERIFY @@ -832,7 +832,7 @@ static void setVCC(char on) { static void setVPP(char on) { // new board desgin if (varVppExists) { - uint8_t v = VPP_11V0; + uint8_t v; // v is recalculated in each case; initialization of the variable is unnecessary // when PES is read the VPP is not determined via PES if (on == READPES) { @@ -843,12 +843,13 @@ static void setVPP(char on) { } } else { //safety check - if (vpp < 36) { - vpp = 36; //9V + if (vpp < 36) { // set minimum to 9V0 + vpp = 36; //9V // ==> v = (36 / 2) - 18 = 0 ==> VPP_9V0 } else - if (vpp > 66) { - vpp = 40; //12V + if (vpp > 66) { // set maximum to 10V0 + vpp = 40; //12V // ==> v = (40 / 2) - 18 = 2 ==> VPP_10V0 } + // 36 <= vpp <=66 ==> v = 0 ... 15 ==> VPP_9V0 ... VPP_16V5 v = (vpp >> 1) - 18; // 18: 2 * 9V, resolution 0.5V (not 0.25V) hence 'vpp >> 1' #if 0 Serial.print(F("setVPP "));