Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/23/14 4:07 p.m.

You guys help me with everything else, why not my school work too?

I have an Arduino project that allows you to hook this box to a tire and it will inflate/deflate the tire to your desired pressure (as necessary). Obviously the "inflate" side of the house is connected to an air compressor, the deflate side of the house is vented to the atmosphere.

The problem is, the sensor will read the tire pressure just fine, but when the deflate valve opens the pressure drops 6psi below what the tire pressure is. That means three things:

1) if your tire is currently at 32psi and you want it at 26psi then the valve will click open, the pressure will instantly drop 6psi as read by the sensor, and the valve will close because the program thinks the job is complete

2) if your tire is 32psi and you want it at 30psi you reach a bit of an error state and the valve just stays open (unless you do like I did and cover the port with your finger to bump the pressure back up until it reaches a point in the program when it will command it closed)

3)If your tire is 32psi and you want it at 20psi then the deflate valve will open, the pressure will immediately read 26psi (as read by the sensor), and will continue to deflate until the pressure reads 20psi. As soon as the valve closes the pressure returns to 26psi

I've got an understanding of the concept at work here that is causing the pressure sensor to read low. That's not the issue. The problem is the guy doing the programming side of the house absolutely refuses to run a "loop" I suggested:

  • read sensor

  • turn off sensor input

  • open deflate valve

  • delay 3 seconds

  • close deflate valve

  • delay 2 seconds

  • read sensor

  • if low then repeat. If input value = tire pressure then go to next step

  • process complete

Can anyone think of another way of increasing the accuracy of the pressure sensor when the deflate valve is open?

I've already tried a "buffer" (adding 6psi to everything) it doesn't work because the inaccuracy varies with tire pressure.

Restricting air flow at the vent didn't help much either.

I tried blocking/unblocking the port manually with my finger (to simulate PWM) at a 2-second on / 2-second off interval and got it within +/-2 psi but that's as close as it will get, and I personally want it at about +/- 1psi to be acceptable.

Unfortunately I absolutely suck at programming and usually goof up more than I fix so I'm afraid to just stick my hand in and take over...

Any suggestions?

Thanks

mazdeuce
mazdeuce UberDork
9/23/14 4:37 p.m.

Does the valve open and close fast enough to give it a "flutter" for lack of a better term. Sort of the two second loop, but see how short you can get it. Pressure stabilizes very quickly, it's just a matter of how quickly the valve can open/shut and take a reading and decide.
Two seconds is hisssssssssss - read
One second is hisssss - read
1/10 of a second is hsreadhsreadhsread

youngfg
youngfg New Reader
9/23/14 5:09 p.m.

Get another programmer and use the loop.

Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/23/14 5:18 p.m.

Mazdeuce: That is exactly what I was just going to try. I made a quick change to the code that I think will work, but cant test it till tomorrow morning.

Streetwiseguy
Streetwiseguy PowerDork
9/23/14 6:38 p.m.

Put the pressure sensor inside the tire, or make the opening in the valve between the inside of the tire and the sensor larger.

Sorry if that's a mechanical answer, but its all you gonna get out of me.

Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/23/14 9:23 p.m.

Meh, I pretty much said the same thing.

The guy is pretty adamant that there is a mechanical solution. The latest offering was "why don't we make a pressure reservoir attached to the sensor to slow the drop rate of the pressure reading?"

I basically told him we'd need a "Huge reservoir" (about the same size as the tire) and that it'd probably have a "pretty dang big" effect on the rate of tire deflation (if the reservoir is deflating then the tire isn't)

sigh. Group work...

moparman76_69
moparman76_69 SuperDork
9/23/14 9:27 p.m.

Locally some gas stations have new air machines which air the tire to a preset pressure by adding air then sampling the pressure through the hose then adding more air etc. until the pressure is acheived. Pretty much the loop you describe and it works pretty much flawlessly.

Kenny_McCormic
Kenny_McCormic PowerDork
9/23/14 9:41 p.m.

Install a needle valve on the exhaust port, right at the solenoid valve, turn it down until you see no pressure difference, then a touch more(so it flows less than the valve stem).

Streetwiseguy
Streetwiseguy PowerDork
9/23/14 10:04 p.m.
Kenny_McCormic wrote: Install a needle valve on the exhaust port, right at the solenoid valve, turn it down until you see no pressure difference, then a touch more(so it flows less than the valve stem).

I like this idea too.

ProDarwin
ProDarwin UltraDork
9/24/14 12:43 a.m.

Use the loop, or do what mazdeuce said and pulse the valve faster and faster as you get closer to the target value. Or use a valve you can progressively close so there is no need for PWM.

RossD
RossD PowerDork
9/24/14 7:46 a.m.
Kenny_McCormic wrote: Install a needle valve on the exhaust port, right at the solenoid valve, turn it down until you see no pressure difference, then a touch more(so it flows less than the valve stem).

This. You need a restriction greater than the restriction of the exhaust valve after the exhaust valve. It sounds like the restriction of the valve/hose is 6 psi at the flow rate. With a needle valve you can dial it in.

GameboyRMH
GameboyRMH GRM+ Memberand MegaDork
9/24/14 8:01 a.m.
youngfg wrote: Get another programmer and use the loop.

Either this or the needle valve idea could work. I'd be tempted to write an algorithm to closely predict the amount of open time needed for a desired pressure drop. I think it would be fun to do the programming but I don't have much free time during the week. I think a bug is causing the #2 condition though.

Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/24/14 8:18 a.m.

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);

}

GameboyRMH
GameboyRMH GRM+ Memberand MegaDork
9/24/14 8:36 a.m.

Use pastebin.com to share your code, the GRM forum formatting rules might mangle it. Less scrolling down that way too

Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/24/14 8:44 a.m.

it won't let me open pastebin at work

GameboyRMH
GameboyRMH GRM+ Memberand MegaDork
9/24/14 9:02 a.m.

Changing this code:

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);

}

To this:

if(setValue > sensorValue)

{

digitalWrite(increaseValve, HIGH);

increaseValveState = true;

}

else if(setValue < sensorValue) {

digitalWrite(decreaseValve, HIGH);

decreaseValveState = true;

delay(250);

digitalWrite(decreaseValve, LOW);

delay(250);

}

Should make it work without you holding Enter.

Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/24/14 12:47 p.m.

Awesome.

I've got another change I'm going to try as well. I essentially made a "do while" loop out of the statement you removed the enter button on.

Cant wait to try it out.

Good times

MadScientistMatt
MadScientistMatt UberDork
9/24/14 2:51 p.m.

I agree with the needle valve idea. I suspect what you have going on is like this:

  1. On the inflation side, the flow rates are fairly low, which keeps the pressure drop through the inflation valve to a minimum.

  2. When the dump valve opens, the air flows out very rapidly. Consequently, you have a significant pressure drop across the inflation valve, and the sensor is measuring pressure post-drop.

  3. When both valves close, pressure equalizes again - and climbs to the pressure in the tire.

The solution would be to slow down the deflation until it reached a point where pressure drop through the valve is negligible.

Hungary Bill
Hungary Bill GRM+ Memberand Dork
9/25/14 8:08 a.m.

Well, my "do while" code had a few bugs so I loaded up the code with the "enter" buttons edited out and it worked! (yaaaaaaay)

Unfortunately the power demands for the electro-pneumatic solenoids are kind of high and I think my batteries may be giving up the ghost.

http://www.youtube.com/watch?v=hGvDjCgkMso&feature=em-upload_owner

good times. Thanks again guys!

You'll need to log in to post.

Our Preferred Partners
T7Vor2R6mcAJ9PFxKXjOMBWNcJH6vAxbOXR4TMmkHY1FhOXrvfs2QKxIN1GsTZNR