You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

355 lines
7.0 KiB

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_FeatherOLED.h>
#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;
}
}