#include #include #include #include #define DEBUG 0 #define TIMEOUT_TIME 7000 #define BUTTON_HOLD_TIME 500 #define BUTTON_PRESS_TIME 20 #define UP_BUTTON 31 #define ENTER_BUTTON 30 #define DOWN_BUTTON 27 #define PRESSURE_SENSOR_PIN A0 Adafruit_FeatherOLED oled = Adafruit_FeatherOLED(); static const unsigned char PROGMEM arrow[] = { B10000000, B11000000, B11100000, B11000000, B10000000}; //oled.drawBitmap(0, 1, arrow, 8, 5, 1); enum buttonStates { OPEN, CLOSED, CHECK_PRESSED, PRESSED, HELD, NUM_BUTTONSTATES }; enum screenStates { BOOT_UP, PRESSURE, SET_POINT, BEGIN_RUN, RUNNING, SAY_CANCEL, SAY_HOLD, SAY_TIMEOUT, SETTINGS, NUM_SCREENSTATES }; enum buttonStates upButton = OPEN; enum buttonStates enterButton = OPEN; enum buttonStates downButton = OPEN; float pressureValue = 0.0; int pressureSetPoint = 69; void setup() { Serial.begin(115200); oled.init(); pinMode(UP_BUTTON, INPUT_PULLUP); pinMode(ENTER_BUTTON, INPUT); // Has external pullup pinMode(DOWN_BUTTON, INPUT_PULLUP); } void loop() { measurePressure(); pollButtons(); runUI(); } void measurePressure() { int sensorValue = analogRead(PRESSURE_SENSOR_PIN); float adjusted = 0.098 * sensorValue - 16.56 + 3.58; pressureValue = 0.99 * pressureValue + 0.01 * adjusted; } void runUI() { static enum screenStates screenState = BOOT_UP; static enum screenStates nextState = BOOT_UP; static unsigned long timer = millis(); static unsigned long runTime = millis(); int num_dots = 0; oled.clearDisplay(); switch (screenState) { case BOOT_UP: if (millis() >= timer + 2000) { screenState = PRESSURE; } oled.setCursor(0,0); oled.setTextSize(2); oled.println("STC TECH"); oled.setTextSize(1); oled.println(""); oled.print(" INITIALIZING"); oled.display(); break; case PRESSURE: if (enterButton == PRESSED) { screenState = SAY_HOLD; nextState = PRESSURE; timer = millis(); } else if (enterButton == HELD) { ; } else if (upButton == PRESSED) { screenState = SET_POINT; pressureSetPoint = (int) pressureValue; timer = millis(); } else if (downButton == PRESSED) { screenState = SET_POINT; pressureSetPoint = (int) pressureValue; timer = millis(); } else if (upButton == HELD) { screenState = SET_POINT; pressureSetPoint = (int) pressureValue; timer = millis(); } else if (downButton == HELD) { screenState = SET_POINT; pressureSetPoint = (int) pressureValue; timer = millis(); } oled.setCursor(0,0); oled.setTextSize(3); oled.print((int) pressureValue); oled.print(" PSI"); oled.display(); break; case SET_POINT: if (enterButton == PRESSED) { screenState = SAY_HOLD; nextState = SET_POINT; timer = millis(); } else if (enterButton == HELD) { screenState = BEGIN_RUN; timer = millis(); } else if (upButton == PRESSED) { timer = millis(); pressureSetPoint++; } else if (downButton == PRESSED) { timer = millis(); pressureSetPoint--; } else if (upButton == HELD) { timer = millis(); pressureSetPoint++; delay(75); } else if (downButton == HELD) { timer = millis(); pressureSetPoint--; delay(75); } else if (millis() >= timer + TIMEOUT_TIME) { screenState = SAY_TIMEOUT; nextState = PRESSURE; timer = millis(); } oled.setCursor(0,0); oled.setTextSize(3); oled.print(pressureSetPoint); oled.println(" PSI"); oled.setTextSize(1); oled.println("TARGET"); oled.display(); break; case BEGIN_RUN: if (millis() >= timer + 2000) { screenState = RUNNING; runTime = millis(); } oled.setCursor(0,0); oled.setTextSize(1); oled.println(""); oled.setTextSize(2); if (pressureSetPoint > (int) pressureValue) { oled.print("INFLATING"); } else if (pressureSetPoint < (int) pressureValue) { oled.print("DEFLATING"); } else { oled.print("DONE"); } oled.display(); break; case RUNNING: if (enterButton == PRESSED) { screenState = SAY_CANCEL; nextState = PRESSURE; timer = millis(); } else if (upButton == PRESSED) { screenState = SAY_CANCEL; nextState = PRESSURE; timer = millis(); } else if (downButton == PRESSED) { screenState = SAY_CANCEL; nextState = PRESSURE; timer = millis(); } oled.setCursor(0,0); oled.setTextSize(3); oled.print((int) pressureValue); oled.println(" PSI"); oled.setTextSize(1); if (pressureSetPoint > (int) pressureValue) { oled.print("INFLATING"); } else if (pressureSetPoint < (int) pressureValue) { oled.print("DEFLATING"); } else { oled.print("DONE"); } num_dots = (int) ((millis() - runTime) / 400) % 4; for (int i = 0; i < num_dots; i++) { oled.print("."); } oled.display(); break; case SAY_CANCEL: if (millis() >= timer + 1000) { screenState = nextState; timer = millis(); } oled.setCursor(0,0); oled.setTextSize(3); oled.print("CANCEL"); oled.display(); break; case SAY_HOLD: if (millis() >= timer + 500) { screenState = nextState; timer = millis(); } oled.setCursor(0,0); oled.setTextSize(3); oled.print("HOLD"); oled.display(); break; case SAY_TIMEOUT: if (millis() >= timer + 1000) { screenState = nextState; timer = millis(); } oled.setCursor(0,0); oled.setTextSize(3); oled.print("TIMEOUT"); oled.display(); break; } } void pollButtons() { static unsigned long upButtonTime = 0; static unsigned long enterButtonTime = 0; static unsigned long downButtonTime = 0; processButtonState(UP_BUTTON, upButton, upButtonTime); processButtonState(ENTER_BUTTON, enterButton, enterButtonTime); processButtonState(DOWN_BUTTON, downButton, downButtonTime); if (DEBUG) { if (upButton == PRESSED) { Serial.println("up button pressed"); } else if (upButton == HELD) { Serial.println("up button held"); } if (enterButton == PRESSED) { Serial.println("enter button pressed"); } else if (enterButton == HELD) { Serial.println("enter button held"); } if (downButton == PRESSED) { Serial.println("down button pressed"); } else if (downButton == HELD) { Serial.println("down button held"); } } } void processButtonState(int buttonPin, buttonStates &buttonState, unsigned long &buttonTime) { bool pinState = !digitalRead(buttonPin); switch(buttonState) { case OPEN: if (pinState) { buttonState = CLOSED; buttonTime = millis(); } break; case CLOSED: if (millis() >= buttonTime + BUTTON_HOLD_TIME) { buttonState = HELD; } if (pinState) { ; } else { buttonState = CHECK_PRESSED; } break; case CHECK_PRESSED: if (millis() >= buttonTime + BUTTON_PRESS_TIME) { buttonState = PRESSED; } else { buttonState = OPEN; } break; case PRESSED: buttonState = OPEN; break; case HELD: if (!pinState) { buttonState = OPEN; } break; default: break; } }