The needle valve is an awesome idea!
I made a half-hazard change to the code and I can get the valve to cycle (loop) while I hold the "enter" button, but lack the skills to change the code to cycle without the "enter" button. In testing I got accuracy within less than 1psi.
If someone was up to the challenge, it's the part between the red brackets that I'm trying to get to loop until input pressure = user set pressure
(I also have it on word format that is much more readable)
Good times.
The code:
/*
* Version 3 code eliminates bugs with button presses and other inefficiencies in control of the device. The user will be instructed to attach the tire chuck
* and press the confirm button. The tire pressure and default set pressure will be displayed. The user will then press either
* the increase or decrease button until they have reached the desired pressure. The user will then press the confirm button to initiate the tire service process.
*
* Version 3.1 code makes some minor changes to text displayed throughout process. Also adds a flashing screen once the process is complete until the user
* presses the confirm button. One final change made to the range that the user can select for tire service. The range has been limited to between 0 and 60.
*
* There are two functions used for testing that simulate the device being hooked up to a compressor or pump. After the user
* confirms the pressure, the displayed sensor value will increment or decrement until it reaches the user set pressure value.
* Since a comparison of the values results in equivalance, the valve closes automatically.
*
* NOTE: In the compareValues() function, there are two lines of code with a function using tone(). These are built in functions for using a cheap little
* buzzer that came with the Arduino kit. If you are testing with the speaker circuit, then you will have to modify the code. I think that using the
* digitalWrite to the pin that is used for the speaker will work but I haven't actually tested that, yet.
* NOTE 2: If you are ready to test with a real speaker circuit and the valves connected. You should just have to change the tone() function calls to the digitalWrite
* as mentioned in "NOTE", uncomment all of the readSensor() and delete the inflateTire() and deflateTire() functions if using the sensor and/or valves.
*/
char ESC = 0xFE; //variable given to hex number that must be used to initiate LCD commands that is used multiple times
const int increaseButton = 2; //variable to represent increase button given a value to represent pin 2 of the Arduino
const int decreaseButton = 3; //variable to represent decrease button given a value to represent pin 3 of the Arduino
const int confirmButton = 4; //variable to represent the confirmation/enter button given a value to represent pin 4 of the Arduino
const int increaseValve = 5; //variable to represent the increase solenoid valve given a value to represent pin 5 of the Arduino
const int decreaseValve = 6; //variable to represent the decrease solenoid valve given a value to represent pin 6 of the Arduino
const int buzzer = 13;
int increaseButtonState = LOW; //variable to represent the state of the increase button
int decreaseButtonState = LOW; //variable to represent the state of the decrease button
int confirmButtonState = LOW; //variable to represent the state of the confirm button
boolean increaseValveState = false; //default increment valve state with true meaning open and false meaning closed
boolean decreaseValveState = false; //default decrement valve state with true meaning open and false meaning closed
boolean processComplete = false; //variable when true means process complete
int sensorValue = 0; //this is a dummy value for testing
int setValue = 0; //initializes the setValue that will be displayed
void setup()
{
Serial.begin(9600); //Sets up communication with the PC for data trasnmission at 9600 baud
setupLCD(); //Function call to initialize the LCD for start up use of the device.
readSensor(); //Initially reads the sensor so that the default setValue can be set.
setValue = sensorValue;
/
* Sets three pins as inputs to observe a change in the signal on them.
* Sets two pins as outputs to send a signal dependent on the comparison of
* the actual tire pressure and the user set pressure.
/
pinMode(increaseButton, INPUT);
pinMode(decreaseButton, INPUT);
pinMode(confirmButton, INPUT);
pinMode(increaseValve, OUTPUT);
pinMode(decreaseValve, OUTPUT);
pinMode(buzzer, OUTPUT);
}
void (* resetFunc) (void) = 0;
void loop()
{
//This do..while waits for the user to select what pressure is required and press the confirm button.
do{
readSensor();
displayPressure();
readButtons();
}
while((confirmButtonState == LOW) && (increaseValveState == false) && (decreaseValveState == false));
//This do..while will display the values while comparing them to see whether inflation or deflation is needed.
do{
readSensor();
displayPressure();
readButtons();
compareValues();
}
while(processComplete != true);
//This do..while will call lcdFlash() repetitively until the user presses the confirm button
do{
lcdFlash();
readButtons();
}while(confirmButtonState == LOW);
delay(500);
resetFunc();
}
/*
-
This function will turn the LCD display on and display a message for the user to attach the tire chuck
-
and press enter. This will allow the pressure to be read after the chuck is on the tire making both the
-
set value and actual pressure value the same, and still allowing for the user to change the set value
-
to the desired tire pressure for the operation.
*/
void setupLCD()
{
//Turn on display and turn off blinking cursor
Serial.write(ESC);
Serial.write(0x41);
Serial.write(ESC);
Serial.write(0x4C);
//This loop will tell the user to connect the tire chuck and press enter and will wait to enter the main loop until
//the confirm/enter button is pressed or held.
do{
clearDisplay();
Serial.print("Connect to Tire");
cursorSet(0x42);
Serial.print("Press Enter");
readButtons();
}
while(confirmButtonState == LOW);
}
/
* This function will display the pressure of the tire and the default set pressure for
* the user to visually compare to decide whether the tire needs to be inflated or deflated.
* Uses a call to a function created to keep the user set value that is displayed within the
* specified range in the arguments.
/
void displayPressure()
{
setValue = rangeConstraint(setValue, 0, 60);
clearDisplay();
Serial.print("Tire - PSI: ");
Serial.print(sensorValue);
cursorSet(0x40);
Serial.print("Set Pressure: ");
Serial.print(setValue);
}
/
* This function uses a variable for the tire pressure called "sensorValue"
* and sets it to receive the data on the analog pin A0 of the Arduino.
* The necessary conversions to display a correct pressure value are done and stored back
* into the variable.
/
int readSensor()
{
sensorValue = analogRead(A1);
float voltage = sensorValue*(5.0/1023.0);
sensorValue = (((voltage - 0.2)/(4.7 - 0.2))*100);
}
/
* This function will allow the buttons to be read. Pin 2 on the Arduino is connected to the button designated
* as the increase button and will increase the setValue displayed on the LCD with each button press. Pin 3 on
* the Arduino is connected to a button designated as the decrease button and will decrease the setValue displayed
* on the LCD with each button press Pin 4 is connected to a button designated as the confirm button.
/
void readButtons()
{
confirmButtonState = digitalRead(confirmButton);
increaseButtonState = digitalRead(increaseButton);
if((increaseButtonState == HIGH) && (increaseValveState == false))
setValue++;
decreaseButtonState = digitalRead(decreaseButton);
if((decreaseButtonState == HIGH) && (increaseValveState == false))
setValue--;
delay(250);
}
/
* This function compares the actual tire pressure value with the user set
* pressure value. If the values are different and depending on which one is
* larger, a signal will be sent to the SSR of the valve that needs to open.
* A boolean variable representing the valve state, true for open and false for
* closed, will change states. This will allow either valve to close again as soon
* as a comparison of the values results in equivalance.
/
void compareValues()
{
if((setValue > sensorValue) && (confirmButtonState == HIGH))
{
digitalWrite(increaseValve, HIGH);
increaseValveState = true;
}
else if((setValue < sensorValue) && (confirmButtonState == HIGH))
{
digitalWrite(decreaseValve, HIGH);
decreaseValveState = true;
delay(250);
digitalWrite(decreaseValve, LOW);
delay(250);
}
else if((setValue == sensorValue) && (increaseValveState == true))
{
digitalWrite(increaseValve, LOW);
tone(buzzer, 100, 2000);
increaseValveState = false;
processComplete = true;
}
else if((setValue == sensorValue) && (decreaseValveState == true))
{
digitalWrite(decreaseValve, LOW);
tone(buzzer, 100, 2000);
decreaseValveState = false;
processComplete = true;
}
}
/
* This function is used to keep the value that the user can set to between 0 and 60 psi.
* This is a limit set during design to avoid potentially damaging higher pressures.
/
int rangeConstraint(int value, int minimum, int maximum)
{
if(value < minimum)
return minimum;
else if(value > maximum)
return maximum;
}
/
* This function is designed to allow the LCD to flash. It will display a message and clear the screen.
* When this function is called in the main loop it is placed in a do..while until the user presses the
* the confirm button.
/
void lcdFlash()
{
clearDisplay();
Serial.print("Process Complete");
cursorSet(0x45);
Serial.print(sensorValue);
Serial.print(" PSI");
delay(500);
clearDisplay();
delay(500);
}
/
* These functions are used only to eliminate code use. Contained within the functions
* are commands for controlling the LCD display. clearDisplay() contains the commands to
* clear the display and set the cursor to row 1, column 1. cursorSet(*) contains the
* commands to set the cursor anywhere within the two rows and 16 columns. The argument
* is used so that the programmer may set the hex value that chooses where to set the cursor
* to whatever is needed for that screen.
/
void clearDisplay()
{
Serial.write(ESC);
Serial.write(0x51);
}
void cursorSet(int hexValue)
{
Serial.write(ESC);
Serial.write(0x45);
Serial.write(hexValue);
}