Project in progress
Air Compressor Controller ver.2

Air Compressor Controller ver.2

Replace an unreliable cheap pressure switch with an Arduino-controlled high current relay. Ver 2 now includes an auto drain valve.

  • 6,296 views
  • 20 comments
  • 39 respects

Components and supplies

Necessary tools and machines

84y7278 40
Drill / Driver, 20V
09507 01
Soldering iron (generic)

About this project

This whole project started when one of my air compressor at work started eating pressure switches and burning out the compressor unit, I replaced the first one with a cheap ($17) off-the-shelf switch and it lasted about a month. The next switch I installed was a higher end model ($215) and it lasted about 2 months. After the third switches, I decided to make my own switch using an Arduino controller and a high current rated relay. The factory switches ranged in price anywhere from $17 to $215, I built this unit for $187 total (not including time). This air compressor has a high cycle rate, that is why it was destroying so many switches. It will cycle anywhere from 30 to 50 times a day.

The Arduino controller had to be fail safe or it would be a hazard to run, so I built into the controller safety interlocks and monitors that if any problem were to present its self the Arduino would shut down. I also reused the original pressure switch as a redundant fail safe that just sits in the background and monitors pressure, if the pressure rises to a set amount it opens the power circuit and shuts down the air compressor.

The Arduino controller also has a 4-line display I use to set the start/stop values and also the high/low analog raw input values I use to monitor the health of the pressure transmitter. I programmed the controller using a menu based program, this way I can use this program for other systems by making a few simple changes to the different menu's.

After building and programming the unit and running it through a series of test, I had a major controller fault after I installed the solenoid, every time the solenoid would de-energize the Arduino would reboot. I fixed that by simply using plastic stand off to mount the Arduino to the aluminium project box, seems that there was some stray voltage or a voltage spike introduced by the solenoid every time it de-energized. Another problem I had during the development phase of this project were my set points. How do I keep my set points if there is a power failure? in comes EEPROM! so after much trial and error using EEPROM for the first time I managed to get the EEPROM to work and work very well. I used the "Get" and "Put" commands so that the EEPROM will last that much longer, see the get and put commands only write to EEPROM if it has changed instead of every loop pass. EEPROM only has so many cycles before they fail, 150000 cycles on average.

I also monitor the raw analog input value from the transmitter, if it drops below .5 vdc that indicates the transmitter or the wires have shorted and that will initiate an alarm on the display "Xmtr Short" and shut down the controller. If the raw analog value goes above 4.5 vdc that indicates the transmitter or the wires have opened and that will initiate and alarm on the display "Xmtr Open" and shut down the controller.

When you go through the 5 menu's you will find that the first 4 menus let you adjust the start/stop/alarm low and alarm high set points, the last menu is a maintenance menu, I put that in their for testing and troubleshooting purposes. You can turn on and off the compressor motor via the +/- buttons. But this menu does not time out and go to menu 6 like the other 4 menus do so heed this warning! "Do not leave the controller in menu 5 with the compressor running because the controller is paused and not watching or monitoring the pressure." Menu 5 is strictly for testing purposes and you must exit to run the compressor with the safeties enabled.

I also added a reset button to the front panel so the unit could be reset without having to open the box. I haven't had to use it but I thought it would be convenient to have. I just paralleled the external reset button over the Arduino's internal reset button.

The compressor unload solenoid is mounted next to the old pressure switch and I used the old switch to hold the solenoid in place with a big tie wrap. then I moved the copper tube from the old switch mechanical unload-er to the new solenoid valve. this was something I completely forgot about when I built the unit and had to rewrite the code to add the second out put for the unload valve, live and learn I guess!

I apologize for the lack of a real print, I just didn't have time to learn to use the Fritzle schematic drawing software, I also apologize for the quality of this work, I'm brand new to Arduino and to this Project Hub, this is my first time publishing anything...lol.

As of this writing the compressor has been working flawlessly for 9 months!

(9/25/19) Update:

Updated the controller, fixing a few LCD bugs, cleaned up the code, and also adding an automated tank drain function, that is accessible via 2 new menu's and can be set to:0-10 sec on time, 0-45 min off time. there is also a menu to run the drain manually. This controls a solenoid that is plumbed into the bottom of the compressor tank. Iv'e found that during the process of this project I needed to drain the water out of the tank, so I figured id add this to the Arduino code. I also changed the schematic to reflect the new changes.

You'll need to add another relay to run the drain solenoid valve.

I hope you find these changes an added benefit to your project.

Thanks

<Please feel free to comment or ask me any questions>

Code

The Controller codeArduino
/*
  WWTP_Compressor_Controller_rev24
   RedTar4
   8/20/19-8/29/19
 
   Analog Resolution is 0-1023 (204.8 per volt or 0.004883v per resolution)
    Pressure sensor is linear:
     0 psi = 0.5v = 102.4
     150 psi = 4.5v = 921.6
*/

// this is the libraries section
#include <Wire.h>                   // Wire library
#include <LiquidCrystal_I2C.h>      // Liquid Crystal I2C library
  LiquidCrystal_I2C lcd(0x27,20,4); // Display address 0x27, I2C 20 x 4
#include <EEPROM.h>                 // EEPROM library
#include <Bounce2.h>                // Bounce2 library
  Bounce debouncer = Bounce();      // instantiate a bounce object

// this is the digital input button variables section
int P1 = 2; // button SET MENU'     // this sets the tag as a discreate input to pin 2
int P2 = 3; // button +             // this sets the tag as a discreate input to pin 3
int P3 = 4; // button -             // this sets the tag as a discreate input to pin 4

// this is the menu section
int menu = 0;                       // this sets the variable tag menu to 0

// this is the analog input variable section
int CompPSIRaw = A0;                // this sets the tag as an analog input to pin A0

// this is the digital output variables section
int CompAlarm = 9;                  // this sets the tag as a discrete output to pin 12
int CompRun = 10;                   // this sets the tag as a discrete output to pin 10
int CompUnloadValve = 11;           // this sets the tag as a discrete output to pin 11
int CompDrain = 12;                 // this sets the tag as a discrete output to pin 12

// this is the variables section
int Start = LOW;                    // this sets the variable tag that stores the start psi set point tolow
int Stop = LOW;                     // this sets the variable tag that stores the stop psi set point to low
int CompRunBit = LOW;               // this sets the variable tag CompRunBit to low
int CompUnloadValveBit = LOW;       // this sets the variable tag CompUnloadValveBit to low
int CompDrainBit = LOW; 
int CompDrainOn = LOW;              // this sets the variable tag CompDrainOn bit 
int CompDrainOff = LOW;             // this sets the variable tag CompDrainOff bit
int CompDrainManual = LOW;          // this sets the variable tag CompDrainManual to low
int CompDrainOffCalc = 0;
int CompAlarmBitL = LOW;            // this sets the variable tag CompAlarmBitL to low
int CompAlarmBitH = LOW;            // this sets the variable tag CompAlarmBitH to low
int CompManual = LOW;               // this sets the variable tag manual to 0
int CompPSIValue = 0;               // this sets the tag CompPSIAlarmL, that will store the value coming from the sensor
int CompPSIAlarmL = LOW;            // this sets the tag CompPSIAlarmL, that will store the value for the raw alarm low setpoint
int CompPSIAlarmH = LOW;            // this sets the tag CompPSIAlarmH, that will store the value for the raw alarm high setpoint

// this is the EEPROM section
int eeAddress1 = 10;                // this sets the eeAddress1 tag and sets the address to 10, eeprom
int eeAddress2 = 20;                // this sets the eeAddress2 tag and sets the address to 20, eeprom
int eeAddress3 = 30;                // this sets the eeAddress3 tag and sets the address to 30, eeprom
int eeAddress4 = 40;                // this sets the eeAddress4 tag and sets the address to 40, eeprom
int eeAddress5 = 50;                // this sets the eeAddress5 tag and sets the address to 50, eeprom
int eeAddress6 = 60;                // this sets the eeAddress6 tag and sets the address to 60, eeprom

// this is the millis section, the "Clock"
long previousMillis = 0;            // this sets the tag "previousMillis", that will store the last time "delay" that was updated
long interval = 30000;              // this sets the tag "interval" for the menu(9) return timer
long intervalSec = 500;             // this sets the tag "intervalSec", at which to blink (milliseconds), 500 = 1 second, 30000 = 1 minute
int ledStateSec = 0;                // this sets the tag "ledStateSec", 


// this is the Debounce section
int buttonState;                    // this set the tag "buttonState", to the current button state from the input pin
int lastButtonState = LOW;          // this set the tag "lastButtonState", to the previous button state from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 100;  // the debounce time; increase if the output flickers

void setup()
{

//  this section assigns the inputs and outputs
 // inputs
  pinMode(P1,INPUT_PULLUP);              // button "MENU"
    debouncer.attach(PI);                // Attach the debouncer to P1 with INPUT_PULLUP mode
    debouncer.interval(debounceDelay);   // interval in ms
  pinMode(P2,INPUT_PULLUP);              // button "+" advance
    debouncer.attach(P2);                // Attach the debouncer to P2 with INPUT_PULLUP mode
    debouncer.interval(debounceDelay);   // interval in ms
  pinMode(P3,INPUT_PULLUP);              // button "-" decrease
    debouncer.attach(P3);                // Attach the debouncer to P3 with INPUT_PULLUP mode
    debouncer.interval(debounceDelay);   // interval in ms
 // outputs
  pinMode(CompAlarm, OUTPUT);            // comperssor alarm relay
   digitalWrite(CompAlarm, LOW);         // initially sets output tag "CompAlarm" low
  pinMode(CompRun, OUTPUT);              // comperssor run relay
   digitalWrite(CompRun, LOW);           // initially sets output tag "CompRun" low
  pinMode(CompUnloadValve, OUTPUT);      // comperssor unloader valve relay
   digitalWrite(CompUnloadValve, LOW);   // initially sets output tag "CompUnloadValve" low
  pinMode(CompDrain, OUTPUT);            // comperssor drain valve relay
   digitalWrite(CompDrain, LOW);         // initially sets output tag "CompDrain" low

// this section retrieves the setpoints from the arduino eeprom so the unit can start up after a power fail
  EEPROM.get(eeAddress1, Start);         // retrieves the start psi from eeprom
  EEPROM.get(eeAddress2, Stop);          // retrieves the stop psi from eeprom
  EEPROM.get(eeAddress3, CompPSIAlarmL); // retrieves the lo alarm from eeprom
  EEPROM.get(eeAddress4, CompPSIAlarmH); // retrieves the hi alarm from eeprom
  EEPROM.get(eeAddress5, CompDrainOn);   // retrieves the hi alarm from eeprom
  EEPROM.get(eeAddress6, CompDrainOff);  // retrieves the hi alarm from eeprom

//  this section starts up the different libraries
  Serial.begin(9600); // start the serial monitor at 9600 baud
  lcd.init();         // start the lcd library
  lcd.backlight();    // turn on the lcd backlight
  lcd.clear();        // clear the cld screen
  Wire.begin();       // start the I2C library
}

void loop()
{

// Update the Bounce instance :
  debouncer.update();

// this is the menu selection section
  if(digitalRead(P1)){menu=menu+1;}            // press the MENU(P1)button and advance through the menu index by 1
   debouncer.attach(PI);                       // Attach the debouncer to P1 with INPUT_PULLUP mode
   debouncer.interval(debounceDelay);          // intervalMin in ms
  if(menu==0){DisplayPSI();}                   // go to the DisplayPSI subroutine
  if(menu==1){DisplayStart();}                 // go to the DisplayStart subroutine
  if(menu==2){DisplayStop();}                  // go to the DisplayStop subroutine
  if(menu==3){DisplayAlarmLow();}              // go to the DisplayAlarmLow subroutine
  if(menu==4){DisplayAlarmHigh();}             // go to the DisplayAlarmHigh subroutine
  if(menu==5){DisplayCompDrainOn();}           // go to the DisplayCompDrainOn subroutine
  if(menu==6){DisplayCompDrainOff();}          // go to the DisplayCompDrainOff subroutine
  if(menu==7){DisplayCompDrainManual();}       // go to the DisplayCompDrainManual subroutine
  if(menu==8){DisplayCompMan();}               // go to the DisplayAutoMan subroutine
  if(menu==9){StoreAll(); delay(500); menu=0;} // go to the StoreAll subroutine and set the menu tag to 0
    delay(100);
}

// this section declares the minutecount variable and sets its initial values
volatile unsigned long secondCount = 0;        // use volatile for shared variables

void DisplayPSI () // main display
{

// this section keeps track of the millis counts (this is the "clock!")
  // millis is running in the background so any program delays wont effect the timing
  // only copies are used so accuracy is mantained
unsigned long currentMillis = millis(); // updates and holds a copy of the SecondMillis
  if (currentMillis - previousMillis >= intervalSec)
  {
   previousMillis = currentMillis;   // updates and holds a copy of the previousMillis
    if (ledStateSec == LOW ){ledStateSec = HIGH; secondCount = secondCount + 1;}
    else {ledStateSec = LOW;}
  }
unsigned long secondCopy;
 secondCopy = secondCount;  //updates and  holds a copy of the secondCount

// this section monitors the live psi and turns the compressor run bit on or off based off setpoints
  int psi = analogRead(0); // this reads the analog input(A0) and scales it
  psi = map(psi, 102, 921, 0, 150);             // this maps the raw analog input value to the converted PSI value
  if (psi <= Start){CompRunBit = HIGH;}         // if psi is less than start setpoint turn on run bit
  if (psi >= Stop ){CompRunBit =  LOW;}         // if psi is greater than stop setpoint turn off run bit
  if (psi <= Start){CompUnloadValveBit =  LOW;} // if psi is less than start setpoint turn off unload bit
  if (psi >= Stop ){CompUnloadValveBit = HIGH;} // if psi is greater than stop setpoint turn on unload bit

// this section monitors the raw analog input for errors
  CompPSIValue = analogRead(CompPSIRaw);
  if (CompPSIValue < CompPSIAlarmL){CompAlarmBitL = HIGH;} // if comppsivalue is less than the CompPSIAlarmL bit, set alarm low bit high
  if (CompPSIValue > CompPSIAlarmL){CompAlarmBitL =  LOW;} // if comppsivalue is greater than the CompPSIAlarmL bit, set alarm low bit low
  if (CompPSIValue < CompPSIAlarmH){CompAlarmBitH =  LOW;} // if comppsivalue is less than the CompAlarmBitH bit, set alarm high bit low
  if (CompPSIValue > CompPSIAlarmH){CompAlarmBitH = HIGH;} // if comppsivalue is greater than the CompAlarmBitH bit, set alarm high bit high

// this section controls the drain timing
  if (CompDrainOn >= secondCount) {CompDrainBit = HIGH;}
   else {CompDrainBit = LOW;}
int CompDrainOffCalc = CompDrainOff * 60;
  if (CompDrainOffCalc <= secondCount + 1) {secondCount = 0;}

// this section turns on or off the digital outputs based on the control and alarm bits
  digitalWrite(CompRun, CompRunBit && !CompAlarmBitL && !CompAlarmBitH);               // comp run safety interlock if sensor fails
  digitalWrite(CompUnloadValve, CompUnloadValveBit || CompAlarmBitL || CompAlarmBitH); // comp unload valve safety interlock if sensor fails
  digitalWrite(CompAlarm, CompAlarmBitL || CompAlarmBitH);                             // comp alarm if sensor fails
  digitalWrite(CompDrain, CompDrainBit);                                               // comp drain valve

// this is the serial monitor setion for testing and debug. remove the "//" to print value to the serial monitor
//  Serial.print(" Sensor raw value ");
//  Serial.print(CompPSIValue);
//  Serial.print(" Sensor psi value ");
//  Serial.print(psi);
//  Serial.print(", Start @ ");
//  Serial.print(Start);
//  Serial.print(", Stop @ ");
//  Serial.print(Stop);
//  Serial.print(",");
//  Serial.print(" Low alarm ");
//  Serial.print(CompPSIAlarmL);
//  Serial.print(",");
//  Serial.print(" High alarm ");
//  Serial.print(CompPSIAlarmH);
//  Serial.print(", CRB ");
//  Serial.print(CompRunBit);
//  Serial.print(", CUL ");
//  Serial.print(CompUnloadValveBit);
//  Serial.print(", CAL ");
//  Serial.print(CompAlarmBitL);
//  Serial.print(", CAH ");
//  Serial.print(CompAlarmBitH);
//  Serial.print(" CompDrain ");
//  Serial.print(CompDrain);
//  Serial.print(" Comp On ");
//  Serial.print(CompDrainOn);
//  Serial.print(" Comp Off ");
//  Serial.print(CompDrainOff);
//  Serial.print(" Comp Off calc ");
//  Serial.print(CompDrainOffCalc);
//  Serial.print(" ledState sec ");
//  Serial.print(ledStateSec);
//  Serial.print(" intervalSec ");
//  Serial.print(intervalSec);
//  Serial.print(", Seconds count ");
//  Serial.print(secondCount);
//  Serial.print(", Seconds copy ");
//  Serial.print(secondCopy);
//  Serial.print(", Previous Millis ");
  Serial.println(previousMillis);

// this is the lcd section
  // line 1
  lcd.setCursor(0,  0); lcd.print("Currently  @ ");  // this prints whats in between the quotes
  lcd.setCursor(13, 0); lcd.print("   ");            // this clears the display field so anything left is deleted
  lcd.setCursor(13, 0); lcd.print(psi);              // this prints the tag value
  lcd.setCursor(17, 0); lcd.print("PSI");            // this prints whats in between the quotes
  // line 2
  lcd.setCursor(0,  1); lcd.print("    Start  @ ");  // this prints whats in between the quotes
  lcd.setCursor(13, 1); lcd.print("   ");            // this clears the display field so anything left is deleted
  lcd.setCursor(13, 1); lcd.print(Start);            // this prints the tag value
  lcd.setCursor(17, 1); lcd.print("PSI");            // this prints whats in between the quotes
  // line 3
  lcd.setCursor(0,  2); lcd.print("    Stop   @ ");  // this prints whats in between the quotes
  lcd.setCursor(13, 2); lcd.print("   ");            // this clears the display field so anything left is deleted
  lcd.setCursor(13, 2); lcd.print(Stop);             // this prints the tag value
  lcd.setCursor(17, 2); lcd.print("PSI");            // this prints whats in between the quotes
  // line 4
  // this section displays the alarm/run status on lcd line 4
  if (CompAlarmBitL && CompAlarmBitH == LOW);        // if CompAlarmBitL and CompAlarmBitH alarm bits are low then its true and prints whats below
   {
    lcd.setCursor(0,  3); lcd.print("      ");       // this clears the display field so anything left is deleted
    lcd.setCursor(0,  3); lcd.print("Sensor OK   "); // this prints whats in between the quotes
    lcd.setCursor(11, 3); lcd.print(" Raw ");        // this prints whats in between the quotes
    lcd.setCursor(16, 3); lcd.print("    ");         // this clears the display field so anything left is deleted
    lcd.setCursor(16, 3); lcd.print(CompPSIValue);   // this prints the tag value
   }
  if (CompAlarmBitL == HIGH){lcd.setCursor(0,  3); lcd.print("ALARM: "); lcd.setCursor(7,  3); lcd.print("Xmtr Open ");} // if the CompAlarmBitL alarm bit is high then its in alarm and prints text
  if (CompAlarmBitH == HIGH){lcd.setCursor(0,  3); lcd.print("ALARM: "); lcd.setCursor(7,  3); lcd.print("Xmtr Short");} // if the CompAlarmBitH alarm bit is high then its in alarm and prints text
      
}

void DisplayStart() // this menu is for adjusting the start psi setpoint
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the start value
  if(digitalRead(P2)== HIGH)
    {
    if (Start == 150){Start = 0;}     // 150 is the max, sets back to 0
    else {Start = Start + 1;}         // incremnent by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (Start == 0){Start = 150;}     // 0 is the min, sets back to 150
    else {Start = Start - 1;}         // decrease by 1 per button press
    }

// this is the lcd section
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("   Start PSI Menu:");
  lcd.setCursor(0, 1); lcd.print("  Set Start PSI to");
  lcd.setCursor(9, 3); lcd.print(Start,DEC);
    delay(100);
}

void DisplayStop() // this menu is for adjusting the stop psi setpoint
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the stop value
  if(digitalRead(P2) == HIGH)
    {
    if (Stop == 150){Stop = 0;}       // 150 is the max, sets back to 0
    else {Stop = Stop + 1;}           // incremnent by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (Stop == 0){Stop = 150;}       // 0 is the min, sets back to 150
    else {Stop = Stop - 1;}           // decrease by 1 per button press
    }

// this is the lcd section
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("   Stop PSI Menu:");
  lcd.setCursor(0, 1); lcd.print("   Set Stop PSI to");
  lcd.setCursor(9, 3); lcd.print(Stop,DEC);
    delay(100);
}

void DisplayAlarmLow() // this menu is for adjusting the raw alarm low setpoint
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the raw low alarm setpoint
  if(digitalRead(P2) == HIGH)
    {
    if (CompPSIAlarmL == 1023){CompPSIAlarmL = 0;} // 1023 is the max, sets to 0
    else {CompPSIAlarmL = CompPSIAlarmL + 1;}      // increase by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (CompPSIAlarmL == 0){CompPSIAlarmL = 1023;} // 0 is the min, sets to 1023
    else {CompPSIAlarmL = CompPSIAlarmL - 1;}      // decrease by 1 per button press
    }

// this is the lcd section
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(" Raw Alarm Lo Menu:");
  lcd.setCursor(0, 1); lcd.print("   Set Lo Alarm to");
  lcd.setCursor(9, 3); lcd.print(CompPSIAlarmL,DEC);
    delay(100);
}

void DisplayAlarmHigh() // this menu is for adjusting the raw alarm high setpoint
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the raw high alarm setpoint
  if(digitalRead(P2) == HIGH)
    {
    if (CompPSIAlarmH == 1023){CompPSIAlarmH = 0;} // 1023 is the max, sets to 0
    else {CompPSIAlarmH = CompPSIAlarmH + 1;}      // increase by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (CompPSIAlarmH == 0){CompPSIAlarmH = 1023;} // 0 is the min, sets to 1023
    else {CompPSIAlarmH = CompPSIAlarmH - 1;}      // decrease by 1 per button press
    }

// this is the lcd section
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(" Raw Alarm Hi Menu:");
  lcd.setCursor(0, 1); lcd.print("   Set Hi Alarm to");
  lcd.setCursor(9, 3); lcd.print(CompPSIAlarmH,DEC);
    delay(100);
}

void DisplayCompDrainOn() // this menu is for adjusting the drain on time setpoint
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the drain on/off setpoint
  if(digitalRead(P2) == HIGH)
    {
    if (CompDrainOn == 10){CompDrainOn = 0;} // 10 is the max, sets to 0
    else {CompDrainOn = CompDrainOn + 1;}    // increase by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (CompDrainOn == 0){CompDrainOn = 10;} // 0 is the min, sets to 10
    else {CompDrainOn = CompDrainOn - 1;}    // decrease by 1 per button press
    }

// this is the lcd section
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("     Drain On: ");
  lcd.setCursor(0, 1); lcd.print("Set Drain on in sec");
  lcd.setCursor(9, 3); lcd.print(CompDrainOn,DEC);


    delay(100);
}

void DisplayCompDrainOff() // this menu is for adjusting the drain off time setpoint
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the drain on/off setpoint
  if(digitalRead(P2) == HIGH)
    {
    if (CompDrainOff == 45){CompDrainOff = 0;} // 45 is the max, sets to 0
    else {CompDrainOff = CompDrainOff + 1;}    // increase by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (CompDrainOff == 0){CompDrainOff = 45;} // 0 is the min, sets to 45
    else {CompDrainOff = CompDrainOff - 1;}    // decrease by 1 per button press
    }

// this is the lcd section
  lcd.clear();
  lcd.setCursor(0, 0); lcd.print("     Drain off:");
  lcd.setCursor(0, 1); lcd.print("Set Drain Off in min");
  lcd.setCursor(9, 3); lcd.print(CompDrainOff,DEC);

    delay(100);
}

void DisplayCompDrainManual() // this menu is for manually turning the drain on/off 
{

// this section advances to menu 9 after 30 sec's, so the program doesn't stall if left on this menu selection
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval)
    {previousMillis = currentMillis; menu = 9;}

// this section reads the +/- buttons and adjusts the raw high alarm setpoint
  if(digitalRead(P2) == HIGH)
    {
    if (CompDrainManual == 1){CompDrainManual = 0;}           // 1 is the max, sets to 0
    else {CompDrainManual = CompDrainManual + 1;}             // increase by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (CompDrainManual == 0){CompDrainManual = 1;}           // 0 is the min, sets to 1
    else {CompDrainManual = CompDrainManual - 1;}             // decrease by 1 per button press
    }
    digitalWrite(CompDrain, CompDrainManual); // turns on/off compDrain relay based on CompDrainManual

// this is the lcd section

  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(" Comp Drain Man:");
  lcd.setCursor(0, 1); lcd.print(" UP to turn On/Off");
  if (CompDrainManual == HIGH){ lcd.setCursor(0, 3); lcd.print("Comp Drain, On");}
  if (CompDrainManual ==  LOW){ lcd.setCursor(0, 3); lcd.print("Comp Drain, Off");}
     delay(100);
}

void DisplayCompMan() // this menu is for manually turning on and off the compressor relay and unload valve relay
{

// this section reads the +/- buttons and adjusts the raw high alarm setpoint
  if(digitalRead(P2) == HIGH)
    {
    if (CompManual == 1){CompManual = 0;}       // 1 is the max, sets to 0
    else {CompManual = CompManual + 1;}         // increase by 1 per button press
    }

  if(digitalRead(P3) == HIGH)
    {
    if (CompManual == 0){CompManual = 1;}       // 0 is the min, sets to 1
    else {CompManual = CompManual - 1;}         // decrease by 1 per button press
    }
    digitalWrite(CompRun, CompManual);          // turns on comp run relay if Compmanual = 1
    digitalWrite(CompUnloadValve, !CompManual); // turns off comp unload relay if Compmanual != 1

// this is the lcd section

  lcd.clear();
  lcd.setCursor(0, 0); lcd.print(" Compressor Man:");
  lcd.setCursor(0, 1); lcd.print(" UP to turn On/Off");
  if (CompManual == HIGH){ lcd.setCursor(0, 2); lcd.print("Comp On, Unload Off");}
  if (CompManual ==  LOW){ lcd.setCursor(0, 2); lcd.print("Comp Off, Unload On");}
  lcd.setCursor(0, 3); lcd.print("Dont forget to exit!");
    delay(100);
}

// this section stores the setpoints into the arduino eeprom so the unit can start up after a power fail
void StoreAll()
{

  lcd.clear();
  EEPROM.put(eeAddress1, Start);          // saves the start psi setpoint to eeprom if different from before
  EEPROM.put(eeAddress2, Stop);           // saves the stop psi setpoint to eeprom if different from before
  EEPROM.put(eeAddress3, CompPSIAlarmL);  // saves the raw low alarm setpoint to eeprom if different from before
  EEPROM.put(eeAddress4, CompPSIAlarmH);  // saves the raw high alarm setpoint to eeprom if different from before
  EEPROM.put(eeAddress5, CompDrainOn);    // retrieves the drain on time from eeprom
  EEPROM.put(eeAddress6, CompDrainOff);   // retrieves the drain off time from eeprom

// this is the lcd section
  lcd.setCursor(0,0); lcd.print("SAVING IN");
  lcd.setCursor(0,1); lcd.print("PROGRESS");
    delay(400);
}
The CircuitArduino
This is the wire circuit thats saved with the code.
/*
 
  The circuit:
 
  Arduino uno r3
       5v to VCC
       gnd to GND
 
  20X4 I2C LCD display:
       SCL:  to A5 on arduino
       SDA:  to A4 on arduino
       VCC:  to VCC
       GND:  to GND

  push buttons: X 4
       button lead 1 to VCC
       button lead 2 to Arduino pins 2,3,4,5
       button lead 2 to lead 1 of 10k ohm resistor
       lead 2 of 10k ohm resistor to GND

  LED / Relays:
       long +LED leads to Arduino digital pins 10,11,12,13
       short -LED leads to 10K ohm resistors, resistors to ground
       if using relays:
       relay coil pin 1 to arduino pin 10,11,12,13
       relay coil pin 2 to ground

  Also be sure to use plastic stand off for all PC boards for isolation and noise dampening     
  After download start the serial monitor
  */

Schematics

Schematic
Arduino print rsoicyt32m

Comments

Similar projects you might like

IR Controller for Air Conditioner

Project in progress by BuddyC

  • 38,033 views
  • 10 comments
  • 26 respects

Reef Controller

Project showcase by Shawn Leclair

  • 16,307 views
  • 0 comments
  • 24 respects

Arduino GrowBox Controller

Project tutorial by Michele Valentini

  • 12,992 views
  • 7 comments
  • 47 respects

Plant Waterer Controller

Project in progress by Paulo Soares

  • 1,678 views
  • 2 comments
  • 6 respects

Soldering Iron Controller for Hakko 907

Project tutorial by Alexander

  • 35,036 views
  • 22 comments
  • 71 respects

RGB LED Strips Controller

Project tutorial by Philippe Libioulle

  • 21,150 views
  • 2 comments
  • 19 respects
Add projectSign up / Login