From 0755bcfe402d07acf736861935f90c0f3707cfa0 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sat, 17 Sep 2022 20:36:01 -0600 Subject: [PATCH] Complete tire inflation / deflation state machine --- firmware/main/hardware.cpp | 27 +++++-- firmware/main/hardware.h | 1 + firmware/main/main.ino | 155 +++++++++++++++++++++++++++++++------ 3 files changed, 154 insertions(+), 29 deletions(-) diff --git a/firmware/main/hardware.cpp b/firmware/main/hardware.cpp index 45cc8ed..2a2a9c7 100644 --- a/firmware/main/hardware.cpp +++ b/firmware/main/hardware.cpp @@ -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(); - float pressureDelta = (millis() - lastTick) / 1000.0 * pressureChangeRate; + if (millis() > lastTick + 100) { + float pressureDelta = (millis() - lastTick) / 1000.0 * pressureChangeRate; - simulatedPressure += pressureDelta; - lastTick = millis(); + 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; diff --git a/firmware/main/hardware.h b/firmware/main/hardware.h index 8c9f0cc..2da6853 100644 --- a/firmware/main/hardware.h +++ b/firmware/main/hardware.h @@ -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 diff --git a/firmware/main/main.ino b/firmware/main/main.ino index 31ba962..2b2743f 100644 --- a/firmware/main/main.ino +++ b/firmware/main/main.ino @@ -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;