Complete tire inflation / deflation state machine
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user