Arduino Air Pressure Controller

Hello there guys,

I have kind of an ambitious project that I would like to jump into but I am unsure as to the feasibility and also the coding aspects.

What I am looking to create is a project that has 5 air pressure sensors (0.5-4.5v output) which are read by the arduino, and then displayed onto a serial LCD (4x20). This part I can see being relatively easy. Still unsure as to the coding of it but in theory it makes sense.

Now for the tricky part, I have the arduino hooked up to an 8 channel relay board (4 inflate and 4 deflate relays), I would like to have it so that i have a series of momentary push buttons (at least 3) that can be depressed once and then arduino automatically inflate or deflate and maintain all 4 pressures using the relays (which are connected to solenoid valves). The 5th sensor is for the air tank pressure which would just need to be constantly read from the sensor and displayed in the middle of the LCD.

Is this even possible? And would anyone be willing to help with the coding aspect at all?

Thanks!

Totally that's what I'm going to do, I'll order one of the pressure sensors and the LCD now and see if I cant get it working. Any help with coding would be greatly appreciated haha

Hey guys so I am trying to figure out the scaling for the pressure sensor reading. From what the spec sheet says, the sensor reads 0.5 volts at 0psi, 2.5v at 50psi and 4.5v at 100psi, supposedly scaled linearly.

Any ideas on how to get what I should imagine will be a 0.5-4.5v signal and convert it back to a psi reading to be displayed on the LCD?

Thanks for any help!

float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) { 
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
int a;
float volts, psi;
...
a = analogRead(INPUT_PIN); //Get analog value 0-1023 from input pin
volts = mapFloat(a, 0, 1023, 0, 5); //assumes 5V Arduino
psi = mapFloat(volts, 0.5, 4.5, 0, 100); //pressure sensor model Xxxx mapping of volts to psi

You can skip the intermediate volts variable but it's nice to show your working in the code so that you can understand it when you come back to look at this code in 6 months from now.

Awesome thanks so much for clarifying that! I had it almost figured out but that will definitely work. Then I should just use a basic serial write command to shoot that pressure over to the serial LCD right? My parts should be here early next week so I can start messing around with it physically and not just in code. Thanks again for the help. This is my first real Arduino project so its going to be one heck of a learning curve haha.

Hey guys,

So the sensor and the LCD came in and I have go the LCD working OK so far I think. I'm just having a hard time getting the code MorganS described above to work keeps coming up with an error:

Build options changed, rebuilding all
sketch_may23d.ino: In function 'void loop()':
sketch_may23d:9: error: a function-definition is not allowed here before '{' token
sketch_may23d:14: error: expected primary-expression before '...' token
sketch_may23d:14: error: expected ';' before '...' token
sketch_may23d:16: error: 'mapFloat' was not declared in this scope
a function-definition is not allowed here before '{' token

I just cant seem to get it working. Any thoughts??

Thanks!

Never mind got it working! Is there any way to make the value displayed rounded up to the nearest psi? right now the reading is 0.00 and it would be a lot cleaner if it was just rounded up or down. Thanks!

if you know how to use code tags, post your code.
if you do not know about code tags, at the main forum there a sticky thread about how to use this forum.
it shows you how to use code tags.

Here's the code I have so far, I successfully have all four pressures displayed in the 4 corners of the screen and the tank pressure in the middle(once i get the sensor I will add in the code for that to read, right now its just XXX.XX) on a 500ms refresh.

I really need to find a way to round the pressures to the nearest PSI with no decimals as it will look a lot cleaner and .00psi accuracy is not needed in this application.

Let me know if you have any ideas as to how to accomplish this:

Thanks!

#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) { 
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float volts, psi, volts2, psi2, volts3, psi3, volts4, psi4;

void setup()
{
  lcd.begin(20,4);      
  lcd.backlight(); 
}

void loop() 
{
  int reading = analogRead(A0);
  int reading2 = analogRead(A1);
  int reading3 = analogRead(A2);
  int reading4 = analogRead(A3);
  volts = mapFloat(reading, 0, 1023, 0, 5);
  psi = mapFloat(volts, 0.42, 4.5, 0, 100);
  volts2 = mapFloat(reading2, 0, 1023, 0, 5);
  psi2 = mapFloat(volts2, 0.42, 4.5, 0, 5);
  volts3 = mapFloat(reading3, 0, 1023, 0, 5);
  psi3 = mapFloat(volts3, 0.42, 4.5, 0, 5);
  volts4 = mapFloat(reading4, 0, 1023, 0, 5);
  psi4 = mapFloat(volts4, 0.42, 4.5, 0, 5);
  lcd.setCursor(0,0);
  lcd.print("*LF*");
  lcd.setCursor(0,1);
  lcd.print(psi);
  lcd.setCursor(16,0);
  lcd.print("*RF*");
  lcd.setCursor(16,1);
  lcd.print(psi2);
  lcd.setCursor(0,2);
  lcd.print("*LR*");
  lcd.setCursor(0,3);
  lcd.print(psi3);
  lcd.setCursor(16,2);
  lcd.print("*RR*");
  lcd.setCursor(16,3);
  lcd.print(psi4);
  lcd.setCursor(8,1);
  lcd.print("TANK");
  lcd.setCursor(7,2);
  lcd.print("XXX.XX");
  delay(500);
  lcd.clear();
}

change float to int.

do all your math and stuff as you are, but add psiForLCD to allow you to put it into an integer.

int psiForLCD

psiForLCD1 = psi1

lcd.print(psiForLCD1); // print the integer of psi1

instead of

lcd.print(psi); // this prints a floating point value

Awesome! Thanks so much! Now I'm going to spend some time working on a 5v digital input momentary trigger turning on a relay until a set pressure is reached then. This project is turning out to be a lot of fun! Thanks for help again!

Hi,
Can you show us a diagram of the layout of the pressure system, where valves, pressure sensors, tank etc are with respect to each other.
REPLY rather than QUICK REPLY and it has an attachment facility, so you can post your file as an attachment.

Tom.... :slight_smile:

Hey guys I need some advice.

Right now I'm doing all of my experimenting with an old Arduino Diecimila board I had when I was in high school. Now obviously this is not going to be stout enough to hold and run the whole program when finished as i think the program just to read the sensors and display them to the LCD used 44% of the memory. Also I need 5 analog inputs for the 5 pressure sensors but the LCD that I have uses pins A4 and A5 (as SDA and SCL). This is also where the current board falls short as it only has the 6 input pins.

I am quite happy to pull the trigger on a new board I'm just unsure as which one to get. I look at the Uno and Due. I was just confused as the Due doesn't accept 5v digital inputs and that is what the 8 momentary push buttons would be running, or could i just run them off the 3.3v line and still have them trigger set pressures? Also the relay board that I have to control the air valves requires a 5v pull to ground, i doubt the digital input/output pins of the Due could handle this?

Thanks for any advice!

UNO allows the use of shields.very useful.

nano is smaller but does not have shields.
pro-mini, well some pro-mini's have 2 additional analog pins available.

Nano has a screw terminal carrier board.
http://www.ebay.com/itm/like/111663036416?lpid=82&chn=ps

.

Ended up with a mega cloan. Should all be here Wednesday (thank you Amazon Prime! lol)

I'm working on putting together a diagram of everything now so it'll be more logical.

oharris91:
Hey guys I need some advice.

Right now I'm doing all of my experimenting with an old Arduino Diecimila board I had when I was in high school. Now obviously this is not going to be stout enough to hold and run the whole program when finished as i think the program just to read the sensors and display them to the LCD used 44% of the memory. Also I need 5 analog inputs for the 5 pressure sensors but the LCD that I have uses pins A4 and A5 (as SDA and SCL). This is also where the current board falls short as it only has the 6 input pins.

I am quite happy to pull the trigger on a new board I'm just unsure as which one to get. I look at the Uno and Due. I was just confused as the Due doesn't accept 5v digital inputs and that is what the 8 momentary push buttons would be running, or could i just run them off the 3.3v line and still have them trigger set pressures? Also the relay board that I have to control the air valves requires a 5v pull to ground, i doubt the digital input/output pins of the Due could handle this?

Thanks for any advice!

5 volts to the relay, the N type transistor is controlled with the 3.5v from the Arduino.
you can use a logic level mosfet.

www.gravitech.us carries a bunch of Nano shields
http://search.store.yahoo.net/yhst-27389313707334/cgi-bin/nsearch?query=nano&searchsubmit=Go&vwcatalog=yhst-27389313707334&.autodone=http%3A%2F%2Fwww.gravitech.us%2F

I offer a Mega screw shield for securely connecting things if needed:
http://www.crossroadsfencing.com/BobuinoRev17/

If your Mega clone turns out to not all it could be, I also offer a 32 IO Atmega1284P boards with 8 analog inputs, dual hardware serial ports, 16K SRAM, and in various form factors, including this one with screw terminals, RS232 driver, SD card with complete buffering, battery backed RTC (DS1307), and some protype area along with +5/Gnd available at each IO pin.

This is the code I have so far which seems to work great, however I had the thought that while it may work great for just reading and displaying the sensors to the LCD, will the delay command in the program not cause problems when I come to write more code with the preset pressures waiting for the digital I/O to control the relays? If so, do I need the delay command or is there another way to clear the lcd and let the values be reset? Thanks!

#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) { 
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float volts, psi, volts2, psi2, volts3, psi3, volts4, psi4;

void setup()
{
  lcd.begin(20,4);      
  //lcd.backlight(); 
}

void loop() 
{
  int reading = analogRead(A0);
  int reading2 = analogRead(A1);
  int reading3 = analogRead(A2);
  int reading4 = analogRead(A3);
  volts = mapFloat(reading, 0, 1023, 0, 5);
  psi = mapFloat(volts, 0.42, 4.5, 0, 100);
  volts2 = mapFloat(reading2, 0, 1023, 0, 5);
  psi2 = mapFloat(volts2, 0.42, 4.5, 0, 5);
  volts3 = mapFloat(reading3, 0, 1023, 0, 5);
  psi3 = mapFloat(volts3, 0.42, 4.5, 0, 5);
  volts4 = mapFloat(reading4, 0, 1023, 0, 5);
  psi4 = mapFloat(volts4, 0.42, 4.5, 0, 5);
  int psiForLCD;
  psiForLCD = psi;
  int psiForLCD2;
  psiForLCD2 = psi2;
  int psiForLCD3;
  psiForLCD3 = psi3;
  int psiForLCD4;
  psiForLCD4 = psi4;
  lcd.setCursor(0,0);
  lcd.print(" LF");
  lcd.setCursor(0,1);
  lcd.print(psiForLCD);
  lcd.setCursor(16,0);
  lcd.print(" RF");
  lcd.setCursor(16,1);
  lcd.print(psiForLCD2);
  lcd.setCursor(0,2);
  lcd.print(" LR");
  lcd.setCursor(0,3);
  lcd.print(psiForLCD3);
  lcd.setCursor(16,2);
  lcd.print(" RR");
  lcd.setCursor(16,3);
  lcd.print(psiForLCD4);
  lcd.setCursor(8,1);
  lcd.print("TANK");
  lcd.setCursor(7,2);
  lcd.print("XXX.XX");
  delay(500);
  lcd.clear();
}

a single delay of 500 should not effect most programs.
when I do a simple stepper routine, I often put in 8 delays of 3.

sometimes delay is the best and easiest solution.

however, if you want to eliminate that, just use millis() and a timer.

if(millis()-then>500){
  then=millis();
  toggle=HIGH;
}

this will change the condition of the toggle to HIGH
// now, you can either create a state machine, or put the whole program into an if statement

if (toggle==HIGH) {

//whole program goes here)

toggle=LOW  // changes toggle back to LOW
}
if(millis()-then>500){
  then=millis();
  toggle=HIGH;
}   
} // end of void loop

I tried the method you mentioned above, I think I'll just stick with the delay function to make it just a little simpler (for now this may change if the delay effects any other code).

Now I am trying to get the momentary buttons (with pulldown resistors) to activate the relays until a set pressure is reached (different pressure for all four sensors) I have started the digitalRead and Write commands in the code below, just unsure how to get it to inflate to a set pressure. Any ideas appreciated greatly. (The relay board is active low, so in order to activate the relays and the valves I have to pull the digital IO pin to ground. Also would it be possible to get a double tap of the momentary button to activate the function mentioned above? This would eliminate any accidental button pushes.

Thanks!

#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) { 
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float volts, psi, volts2, psi2, volts3, psi3, volts4, psi4;
const int button1Pin = 13;
const int relay1Pin = 2;
int button1State = 0;


void setup()
{
  lcd.begin(20,4);      
  lcd.backlight();
  pinMode(button1Pin, INPUT);
  pinMode(relay1Pin, OUTPUT);
}
void loop()
{
//Displaying Values to LCD 
  int reading = analogRead(A0);
  int reading2 = analogRead(A1);
  int reading3 = analogRead(A2);
  int reading4 = analogRead(A3);
  volts = mapFloat(reading, 0, 1023, 0, 5);
  psi = mapFloat(volts, 0.42, 4.5, 0, 100);
  volts2 = mapFloat(reading2, 0, 1023, 0, 5);
  psi2 = mapFloat(volts2, 0.42, 4.5, 0, 5);
  volts3 = mapFloat(reading3, 0, 1023, 0, 5);
  psi3 = mapFloat(volts3, 0.42, 4.5, 0, 5);
  volts4 = mapFloat(reading4, 0, 1023, 0, 5);
  psi4 = mapFloat(volts4, 0.42, 4.5, 0, 5);
  int psiForLCD;
  psiForLCD = psi;
  int psiForLCD2;
  psiForLCD2 = psi2;
  int psiForLCD3;
  psiForLCD3 = psi3;
  int psiForLCD4;
  psiForLCD4 = psi4;
  lcd.setCursor(0,0);
  lcd.print(" LF");
  lcd.setCursor(0,1);
  lcd.print(psiForLCD);
  lcd.setCursor(16,0);
  lcd.print(" RF");
  lcd.setCursor(16,1);
  lcd.print(psiForLCD2);
  lcd.setCursor(0,2);
  lcd.print(" LR");
  lcd.setCursor(0,3);
  lcd.print(psiForLCD3);
  lcd.setCursor(16,2);
  lcd.print(" RR");
  lcd.setCursor(16,3);
  lcd.print(psiForLCD4);
  lcd.setCursor(8,1);
  lcd.print("TANK");
  lcd.setCursor(7,2);
  lcd.print("XXX.XX");
  delay(500);
  lcd.clear();
  
 //Reading Button 1
  button1State = digitalRead(button1Pin);
  if (button1State == HIGH){
    digitalWrite(relay1Pin, LOW);
    //Need a way of hitting the momentary button once and then relays being operated
    //unitl a set pressure is reached by the sensors (different pressure for all 4 sensors)
    //then each relay shutting off?? If possible a double tap of the button would be better.
}
  else {
    digitalWrite(relay1Pin, HIGH);
  }
}