sketch: improved calibration, mcp4151 uses full tap scale

This change stores the digi pot indices in the scale 1-255
(previously 1 -128) so the stored values for calibration
are no longer valid after this change is uploaded to Arduino.

Please re-run the full calibration on your Afterburner!
This commit is contained in:
ole00 2024-03-17 20:55:56 +00:00
parent 103a99ab7a
commit 3ee0147d88
2 changed files with 83 additions and 40 deletions

View File

@ -1,5 +1,6 @@
//MCP4131 digital pot (bitbanged control) for Afterburner GAL project.
// * compatible with MCP4151 (resolution of the wiper is halved to match MCP4131)
//MCP4151 digital pot (bitbanged control) for Afterburner GAL project.
// * compatible with MCP4131 (resolution of the wiper is divided by 2)
// * the storage for tap indices is 8bit wide, therefore we must not use index 256.
// 2024-02-02 Minor change
#ifndef __AFTB_MCP4131_H__
@ -40,7 +41,7 @@
#define mcp4131_read(A) mcp4131_reg((A),0,1)
#define mcp4131_write(A,V) mcp4131_reg((A),(V),0)
static uint8_t mcp4151_detected;
static uint8_t mcp4131_detected;
// read or write the mcp4131 register
static uint16_t mcp4131_reg(uint8_t address, uint16_t value, uint8_t read_reg) {
@ -49,8 +50,9 @@ static uint16_t mcp4131_reg(uint8_t address, uint16_t value, uint8_t read_reg)
r <<= 12;
if (mcp4151_detected && address == ADDR_WIPER) {
value <<= 1; //multiply the wiper value by 2
if (mcp4131_detected && address == ADDR_WIPER) {
value >>= 1; //divide the wiper value by 2
value++; // ensure we use the last tap (index 128)
}
if (address == ADDR_INCREMENT) {
@ -95,8 +97,9 @@ static uint16_t mcp4131_reg(uint8_t address, uint16_t value, uint8_t read_reg)
pinMode(POT_DAT, OUTPUT);
}
if (mcp4151_detected && address == ADDR_WIPER && read_reg) {
r >>= 1; //divide the wiper value by 2
if (mcp4131_detected && address == ADDR_WIPER && read_reg) {
r--;
r >>= 1; //multiply the wiper value by 2
}
//disable IC
@ -117,7 +120,7 @@ static void mcp4131_init(void) {
static uint8_t mcp4131_detect(void) {
uint16_t r;
mcp4151_detected = 0;
mcp4131_detected = 0;
mcp4131_disableWiper();
@ -143,16 +146,16 @@ static uint8_t mcp4131_detect(void) {
//detect MCP4151 by incrementing again - MCP4131 clamps the value to 128, MCP4151 increments to 129
mcp4131_write(ADDR_INCREMENT, 0);
r = mcp4131_read(ADDR_WIPER);
#if 0
Serial.print(F("MCP41541 detect: "));
#if 0
Serial.print(F("MCP4151 detect: "));
Serial.println(r == 129 ? 1 : 0, DEC);
#endif
if (r == 129) {
mcp4151_detected = 1;
if (r == 128) {
mcp4131_detected = 1;
} else
if (r != 128) {
return 0; //error - the value should be clamped to 128
}
if (r != 129) {
return 0; //error - the value should be either 128 (clamped by mcp4313) or 129 (mcp5151)
}
mcp4131_write(ADDR_WIPER, POT_DEFAULT_VALUE);
#if POT_WIPER_ENABLED

View File

@ -57,12 +57,15 @@
//pot wiper indices for the voltages
uint8_t vppWiper[MAX_WIPER] = {0};
// VPP must ramp-up to prevent voltage spikes and possibly resting arduino
#define varVppSetMax() varVppSetVppIndex(0x40); \
varVppSetVppIndex(0x70); \
varVppSetVppIndex(0x7c); \
varVppSetVppIndex(0x7e); \
varVppSetVppIndex(0x80);
// VPP must ramp-up to prevent voltage spikes and possibly resetting arduino
// These values are for mcp4151 (for mcp4131 they are divided by 2)
#define varVppSetMax() varVppSetVppIndex(0x80); \
varVppSetVppIndex(0xE0); \
varVppSetVppIndex(0xF4); \
varVppSetVppIndex(0xFA); \
varVppSetVppIndex(0xFF);
#define varVppSetMin() varVppSetVppIndex(0x0);
uint8_t wiperStat = 0; //enabled / disabled
@ -84,7 +87,7 @@ static void varVppReadCalib(void) {
Serial.print(i);
Serial.print(F(":"));
Serial.println(vppWiper[i]);
#endif
#endif
}
}
@ -124,7 +127,7 @@ static void varVppSet(uint8_t value) {
varVppSetVppIndex(0);
return;
}
#if VPP_VERBOSE
#if VPP_VERBOSE
Serial.print(F("varSetVpp "));
Serial.print(value);
Serial.print(F(":"));
@ -209,7 +212,7 @@ static uint8_t varVppCalibrateVpp(void) {
int16_t v = 900; //starting at 9.00 V
int16_t r1 = 0;
int16_t r2;
int16_t minDif = 5000;
int16_t minDif;
Serial.print(F("VPP calib. offset: "));
Serial.println(calOffset);
@ -218,34 +221,50 @@ static uint8_t varVppCalibrateVpp(void) {
delay(300); //settle voltage
while (1) {
while (i <= 0x80) {
// reset the 'minimal difference' variable every time we search for a new index
minDif = 9000;
//the 'vppWiper' storage for tap indices is 8bit wide, therefore we must not use tap index 256.
while (i <= 0xFF) {
int16_t d1,d2;
varVppSetVppIndex(i);
delay(50); //let the voltage settle
#if VPP_VERBOSE
Serial.print(i);
Serial.print(F(") "));
#endif
delay(100); //let the voltage settle
r2 = varVppMeasureVpp(0);
// Sanity check: the previous voltage can't be higher than the voltage just measured
// because we are ramping up the voltage. Therefore it must be an ADC measurement
// glitch. In that case use the previous value as the measured one.
// This can happen at lower tap indices where the voltage differences are very small (like 0.01V).
if (r1 > r2) {
r2 = r1;
}
d1 = r1 - v;
d2 = r2 - v;
d1 = ABS(d1);
d2 = ABS(d2);
#if VPP_VERBOSE
Serial.print(i);
Serial.print(F(") r2="));
Serial.print(r2, DEC);
Serial.print(F(" d1="));
Serial.print(d1, DEC);
Serial.print(F(" d2="));
Serial.print(d2, DEC);
Serial.print(F(" md="));
Serial.println(minDif, DEC);
#endif
if (r2 <= 100) { // less than 1V ? Failure
r1 = FAIL;
goto ret;
}
if (d2 < minDif) {
if (d2 <= minDif) {
minDif = d2;
vppWiper[vppIndex] = i;
//check last value / voltage
if (i == 0x80) {
if (i == 0xFF) {
if (v >= 1620 && v <= 1670) {
#if 1 || VPP_VERBOSE
Serial.println(F("*Index for VPP 1650 is 128"));
#endif
Serial.println(F("*Index for VPP 1650 is 255"));
r1 = OK;
goto ret;
}
@ -255,12 +274,10 @@ static uint8_t varVppCalibrateVpp(void) {
} else {
i--;
minDif = 5000;
#if 1 || VPP_VERBOSE
Serial.print(F("*Index for VPP "));
Serial.print(v);
Serial.print(F(" is "));
Serial.println(i);
#endif
break;
}
@ -276,7 +293,7 @@ static uint8_t varVppCalibrateVpp(void) {
r1 = OK;
goto ret;
}
v += 50;
v += 50; //next voltage to search for is 0.5V higher
}
ret:
@ -312,7 +329,7 @@ static int8_t varVppInit(void) {
mcp4131_init();
if (mcp4131_detect()) {
#if VPP_VERBOSE
Serial.print(mcp4151_detected ? F("MCP4151") : F("MCP4131"));
Serial.print(mcp4131_detected ? F("MCP4131") : F("MCP4151"));
Serial.println(F(" POT found"));
#endif
return OK;
@ -352,7 +369,30 @@ static int8_t varVppCheckCalibration(void) {
return OK;
}
// only for VPP testing and debugging
static void varrVppTestRamp(void) {
uint8_t i = 1;
while (i < 256) {
varVppSetVppIndex(i);
delay(400);
Serial.println(i, DEC);
varVppMeasureVpp(1);
i++;
}
delay(2000);
varVppSetVppIndex(0);
}
static int8_t varVppCalibrate(void) {
#if 0
// only for testing and debugging
varrVppTestRamp();
return OK;
#endif
if (varVppCalibrateVpp()) {
varVppStoreWiperCalib();
} else {