Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesigned algorithm for VPP measurement #55

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions aftb_adcparms.h
Original file line number Diff line number Diff line change
@@ -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
81 changes: 22 additions & 59 deletions aftb_vpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand All @@ -15,6 +16,7 @@
#define VPP A0

#include "aftb_mcp4131.h"
#include "aftb_adcparms.h"
#ifndef FAIL
#define FAIL 0
#define OK 1
Expand Down Expand Up @@ -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};

Expand Down Expand Up @@ -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

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;
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);

// 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
Expand Down Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions afterburner.ino
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*/


#define VERSION "0.5.6"
#define VERSION "0.5.6hh"

//#define DEBUG_PES
//#define DEBUG_VERIFY
Expand Down Expand Up @@ -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) {
Expand All @@ -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 "));
Expand Down