Complete tire inflation / deflation state machine

This commit is contained in:
Tanner Collin 2022-09-17 20:36:01 -06:00
parent ace6c671a6
commit 0755bcfe40
3 changed files with 154 additions and 29 deletions

View File

@ -15,8 +15,8 @@ float offsetMultiplier = 0.0;
void initSimulation() {
simulating = true;
simulatedPressure = (float) random(10, 30);
inflatePSIPerSecond = random(8, 12) / 100.0;
deflatePSIPerSecond = random(35, 45) / 100.0;
inflatePSIPerSecond = 0.0303;
deflatePSIPerSecond = 0.0958;
deflateOffsetMultiplier = random(3, 10) / 100.0;
inflateOffsetMultiplier = 1.0 - deflateOffsetMultiplier;
offsetMultiplier = 1.0;
@ -25,10 +25,15 @@ void initSimulation() {
void tickSimulation() {
static unsigned long lastTick = millis();
if (millis() > lastTick + 100) {
float pressureDelta = (millis() - lastTick) / 1000.0 * pressureChangeRate;
simulatedPressure += pressureDelta;
lastTick = millis();
Serial.print("Simulated pressure: ");
Serial.println(simulatedPressure);
}
}
void measurePressure(float &pressureValue, int pin) {
@ -43,6 +48,18 @@ void measurePressure(float &pressureValue, int pin) {
}
}
void resamplePressure(float &pressureValue, int pin) {
if (simulating) {
float adjusted = simulatedPressure + (random(-100, 100) / 100.0);
adjusted *= offsetMultiplier;
pressureValue = adjusted;
} else {
int sensorValue = analogRead(pin);
float adjusted = 0.098 * sensorValue - 16.56 + 3.58;
pressureValue = adjusted;
}
}
void setSoleniod(int solenoidState) {
if (solenoidState == SOLENOID_STOP) {
pressureChangeRate = 0.0;

View File

@ -10,6 +10,7 @@
void initSimulation();
void tickSimulation();
void measurePressure(float &pressureValue, int pin);
void resamplePressure(float &pressureValue, int pin);
void setSoleniod(int solenoidState);
#endif

View File

@ -42,8 +42,11 @@ enum screenStates {
BOOT_UP,
PRESSURE,
SET_POINT,
INIT_RUN,
BEGIN_RUN,
MEASURING,
RUNNING,
SAY_DONE,
SAY_CANCEL,
SAY_HOLD,
SAY_TIMEOUT,
@ -56,7 +59,16 @@ enum buttonStates enterButton = OPEN;
enum buttonStates downButton = OPEN;
float pressureValue = 0.0;
int pressureSetPoint = 69;
int debounceValue(float value) {
static int prevValue = (int) value;
if (abs(prevValue - value) > 0.4) {
prevValue = (int) value;
}
return prevValue;
}
void setup()
{
@ -73,6 +85,8 @@ void setup()
#ifdef SIMULATE
initSimulation();
#endif
resamplePressure(pressureValue, PRESSURE_SENSOR_PIN);
}
void loop() {
@ -91,12 +105,27 @@ void runUI() {
static unsigned long timer = millis();
static unsigned long runTime = millis();
static int pressureSetPoint = 0;
static unsigned long startTime = millis();
//static float initialPressure = 0.0;
//static float runningPressure = 0.0;
static float sampledPressure = 0.0;
static bool isInflating = false;
static bool isDeflating = false;
int num_dots = 0;
int debouncedPressureValue = debounceValue(pressureValue);
oled.clearDisplay();
Serial.print("pressure: ");
Serial.print(pressureValue);
Serial.print(", sampled: ");
Serial.print(sampledPressure);
Serial.print(", setpoint: ");
Serial.print(pressureSetPoint);
Serial.println("");
switch (screenState) {
case BOOT_UP:
if (millis() >= timer + 2000) {
@ -120,28 +149,28 @@ void runUI() {
nextState = PRESSURE;
timer = millis();
} else if (enterButton == HELD) {
setSoleniod(SOLENOID_DEFLATE);
; // settings?
} else if (upButton == PRESSED) {
screenState = SET_POINT;
pressureSetPoint = (int) pressureValue;
pressureSetPoint = debouncedPressureValue+1;
timer = millis();
} else if (downButton == PRESSED) {
screenState = SET_POINT;
pressureSetPoint = (int) pressureValue;
pressureSetPoint = debouncedPressureValue-1;
timer = millis();
} else if (upButton == HELD) {
screenState = SET_POINT;
pressureSetPoint = (int) pressureValue;
pressureSetPoint = debouncedPressureValue+1;
timer = millis();
} else if (downButton == HELD) {
screenState = SET_POINT;
pressureSetPoint = (int) pressureValue;
pressureSetPoint = debouncedPressureValue-1;
timer = millis();
}
oled.setCursor(0,0);
oled.setTextSize(3);
oled.print((int) pressureValue);
oled.print(debouncedPressureValue);
oled.print(" PSI");
oled.display();
@ -153,8 +182,8 @@ void runUI() {
nextState = SET_POINT;
timer = millis();
} else if (enterButton == HELD) {
screenState = BEGIN_RUN;
timer = millis();
screenState = INIT_RUN;
} else if (upButton == PRESSED) {
timer = millis();
pressureSetPoint++;
@ -186,28 +215,79 @@ void runUI() {
break;
case BEGIN_RUN:
if (millis() >= timer + 2000) {
screenState = RUNNING;
runTime = millis();
}
case INIT_RUN:
//initialPressure = pressureValue;
startTime = millis();
timer = millis();
screenState = BEGIN_RUN;
oled.setCursor(0,0);
oled.setTextSize(1);
oled.println("");
oled.setTextSize(2);
if (pressureSetPoint > (int) pressureValue) {
if (pressureSetPoint > debouncedPressureValue) {
oled.print("INFLATING");
} else if (pressureSetPoint < (int) pressureValue) {
setSoleniod(SOLENOID_INFLATE);
isInflating = true;
isDeflating = false;
} else if (pressureSetPoint < debouncedPressureValue) {
oled.print("DEFLATING");
setSoleniod(SOLENOID_DEFLATE);
isDeflating = true;
isInflating = false;
} else {
oled.print("DONE");
setSoleniod(SOLENOID_STOP);
screenState = SAY_DONE;
nextState = PRESSURE;
}
oled.display();
break;
case BEGIN_RUN:
if (millis() >= timer + 5000) {
//runningPressure = pressureValue;
setSoleniod(SOLENOID_STOP);
screenState = MEASURING;
timer = millis();
}
break;
case MEASURING:
if (millis() >= timer + 3000) {
sampledPressure = pressureValue;
if (isInflating && (int) sampledPressure >= pressureSetPoint) {
screenState = SAY_DONE;
nextState = PRESSURE;
} else if (isDeflating && (int) sampledPressure <= pressureSetPoint) {
screenState = SAY_DONE;
nextState = PRESSURE;
} else {
screenState = RUNNING;
}
timer = millis();
}
if (millis() < timer + 500) {
// wait for solenoids to settle before averaging
resamplePressure(pressureValue, PRESSURE_SENSOR_PIN);
}
setSoleniod(SOLENOID_STOP);
oled.setCursor(0,0);
oled.setTextSize(1);
oled.println("");
oled.setTextSize(2);
oled.print("MEASURING");
oled.display();
break;
case RUNNING:
if (enterButton == PRESSED) {
screenState = SAY_CANCEL;
@ -223,21 +303,32 @@ void runUI() {
timer = millis();
}
if (isInflating && millis() >= timer + 20000) {
screenState = MEASURING;
timer = millis();
} else if (isDeflating && millis() >= timer + 10000) {
screenState = MEASURING;
timer = millis();
}
if (isInflating) {
setSoleniod(SOLENOID_INFLATE);
} else if (isDeflating) {
setSoleniod(SOLENOID_DEFLATE);
}
oled.setCursor(0,0);
oled.setTextSize(3);
oled.print((int) pressureValue);
oled.print((int) sampledPressure);
oled.println(" PSI");
oled.setTextSize(1);
if (pressureSetPoint > (int) pressureValue) {
if (isInflating) {
oled.print("INFLATING");
} else if (pressureSetPoint < (int) pressureValue) {
} else if (isDeflating) {
oled.print("DEFLATING");
} else {
oled.print("DONE");
}
num_dots = (int) ((millis() - runTime) / 400) % 4;
num_dots = (int) ((millis() - startTime) / 400) % 4;
for (int i = 0; i < num_dots; i++) {
oled.print(".");
}
@ -246,6 +337,22 @@ void runUI() {
break;
case SAY_DONE:
if (millis() >= timer + 3000) {
screenState = nextState;
timer = millis();
}
oled.setCursor(0,0);
oled.setTextSize(3);
oled.print("DONE");
oled.display();
break;
case SAY_CANCEL:
if (millis() >= timer + 1000) {
screenState = nextState;