mirror of
https://github.com/ole00/afterburner.git
synced 2025-02-16 03:33:18 +00:00
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:
parent
103a99ab7a
commit
3ee0147d88
@ -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
|
||||
|
90
aftb_vpp.h
90
aftb_vpp.h
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user