CEB Press Control Code v19.01

From Open Source Ecology
Jump to navigation Jump to search

Code

https://github.com/OpenSourceEcology/OSE_CEB_Press_v19.01

Notes

Manual Control Code

  • Selection of 9, 10, 11, 12 for UDLR.

/* Open Source Ecology CEB Press v19.01 with Arduino Uno or Mega as controller of choice.

CC-BY-SA, GPLv3, and OSE License for Distributive Economics
Use Mega to keep consistency with OSE D3D 3D Printer to minimize GVCS part count.
Switches FET's HIGH/LOW to control two hydraulic solenoids,
measures piston motion time relative to pressure sensor trigger,
and repeats cycle while auto calibrating timing from previous cycles and startup positions.
Extension time is measured. Orientation of machine is such that cylinder retracts to the right.
See sequence at http://bit.ly/2Hnuk6F
Faults should be self-resolving based on pressing sequence: pressure trigger reverses direction
at fault point and no block results. There is one likely place for faults to occur: soil load into chamber.
Uses HiLetgo Relay Shield 5V 4 Channel for Arduino:
https://www.amazon.com/HiLetgo-Relay-Shield-Channel-Arduino/dp/B07F7Y55Z7/ref=sr_1_2?ie=UTF8&qid=1547696929&sr=8-2&keywords=hiletgo+relay+shield
Note pins must be trimmed flat under Relay 1 connector and must be insulated to prevent shorts.
Relay 1 is controlled by digital pin 7
Relay 2 is controlled by digital pin 6
Relay 3 is controlled by digital pin 5
Relay 4 is controlled by digital pin 4
A high written to a pin turns the relay ON
A low written to a pin turns the relay OFF
Contributions by:
Abe Anderson
http://opensourceecology.org/wiki/AbeAnd_Log
Marcin Jakubowski
http://opensourceecology.org/wiki/Marcin_Log
Unfamiliar with code structures? See https://www.arduino.cc/en/Reference/HomePage
*/

//defines to make it easier for non-coders to make adjustments for troubleshooting and custom changes

  1. define SOLENOID_UP 7 //Extension. See pin mapping above.
  2. define SOLENOID_DOWN 6 //swap these pin numbers for wire inversion
  3. define SOLENOID_LEFT 5 //Extension.
  4. define SOLENOID_RIGHT 4 //swap these pin numbers for wire inversion
  1. define PRESSURE_SENSOR 13 //Needs pins adjacent to get 8-pin dupont housing for both selector and sensor
  2. define SELECTOR_QUARTER 12 //Second 8-pin Dupont housing for the solenoids
                             //Reset is the shutdown/initialization procedure. All procedures are selected by
  1. define SELECTOR_HALF 11 //the WHILE function. QUARTER to FULL refers to brick thickness.
  2. define SELECTOR_THREEQUARTER 10 //Secondary cylinder timing is measured only.
  3. define SELECTOR_FULL 9 //Primary cylinder thickness setting is based on secondary cylinder motion.
  1. define PRESSURE_SENSOR_DEBOUNCE 20 //milliseconds to delay for pressure sensor debounce
  2. define DELAY 500 // 1/2 sec extra to compress brick via main Cyl (default 500ms)
                                       //custom function declarations

bool lowPressure(); //function to read pressure sensor bool resetSelected(); // bool quarterSelected(); // bool halfSelected(); // bool threequarterSelected(); // bool fullSelected(); //

                                       //Global variables

unsigned long drawerExtTime = 0; //Time measurement for calibrating motion. unsigned long previousMillis = 0; //time measurement for expansion

void setup() {

 //initialize pin I/O Inputs and turn everything off to avoid startup glitches
 pinMode(PRESSURE_SENSOR, INPUT_PULLUP);
   pinMode(SELECTOR_QUARTER, INPUT_PULLUP);
 pinMode(SELECTOR_HALF, INPUT_PULLUP);
 pinMode(SELECTOR_THREEQUARTER, INPUT_PULLUP);
 pinMode(SELECTOR_FULL, INPUT_PULLUP);
 pinMode(SOLENOID_RIGHT, OUTPUT);
 digitalWrite(SOLENOID_RIGHT, LOW);
 pinMode(SOLENOID_LEFT, OUTPUT);
 digitalWrite(SOLENOID_LEFT, LOW);
 pinMode(SOLENOID_DOWN, OUTPUT);
 digitalWrite(SOLENOID_DOWN, LOW);
 pinMode(SOLENOID_UP, OUTPUT);
 digitalWrite(SOLENOID_UP, LOW);

}

void loop() {

                                            //Step 0 Reset/Initialize - Brick pressing sequence - http://bit.ly/2Hnuk6F
 while (fullSelected() == true) {          // happens when 9 is selected
   digitalWrite(SOLENOID_UP, HIGH);

}

   digitalWrite(SOLENOID_UP, LOW);


 while (threequarterSelected() == true) {               //10 selected
   digitalWrite(SOLENOID_DOWN, HIGH);
 }
   digitalWrite(SOLENOID_DOWN, LOW);
  
    while (halfSelected() == true) {          // happens when 11 is selected
   digitalWrite(SOLENOID_LEFT, HIGH);

}

   digitalWrite(SOLENOID_LEFT, LOW);


 while (quarterSelected() == true) {               //12 selected
   digitalWrite(SOLENOID_RIGHT, HIGH);
 }
   digitalWrite(SOLENOID_RIGHT, LOW);


} //end of loop

                                                //custom function definitions
                                                //reads pressure sensor state HIGH is false and LOW is true

bool lowPressure() {

 if (digitalRead(PRESSURE_SENSOR) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(PRESSURE_SENSOR) == HIGH) {
     return true;
   }
   else {
     return false;
   }
 }
 else {
   return false;
 }}
 //reads selector  - HIGH is false, LOW is true- SELECTOR_RESET, SELECTOR_QUARTER, SELECTOR_HALF, SELECTOR_3QUARTERS, SELECTOR_FULL,
 bool resetSelected() {
   if (threequarterSelected() == false && halfSelected() == false && fullSelected() == false) {
     return true;
   }
   else {
     return false;
   }}
 bool quarterSelected() {
 if (digitalRead(SELECTOR_QUARTER) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_QUARTER) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool halfSelected() {
 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool threequarterSelected() {
 if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
   bool fullSelected() {
 if (digitalRead(SELECTOR_FULL) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_FULL) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}

Drawer Cylinder Bounce Test

  1. define SOLENOID_UP 7 //Extension. See pin mapping above.
  2. define SOLENOID_DOWN 6 //swap these pin numbers for wire inversion
  3. define SOLENOID_LEFT 5 //Extension.
  4. define SOLENOID_RIGHT 4 //swap these pin numbers for wire inversion
  1. define PRESSURE_SENSOR 13 //Needs pins adjacent so only 1 dupont connector is used
  2. define SELECTOR_RESET 12 //Activated when nothing is selected.
  3. define SELECTOR_QUARTER 11 //Reset is the shutdown/initialization procedure. All procedures are selected by
  4. define SELECTOR_HALF 10 //the WHILE function. QUARTER to FULL refers to brick thickness.
  5. define SELECTOR_THREEQUARTER 9 //Secondary cylinder timing is measured only.
  6. define SELECTOR_FULL 8 //Primary cylinder thickness setting is based on secondary cylinder motion.
  1. define PRESSURE_SENSOR_DEBOUNCE 20 //milliseconds to delay for pressure sensor debounce
  2. define DELAY 500 // 1/2 sec extra to compress brick via main Cyl (default 500ms)
                                       //custom function declarations

bool lowPressure(); //function to read pressure sensor bool resetSelected(); // //bool quarterSelected(); // bool halfSelected(); // bool threequarterSelected(); // bool fullSelected(); //

                                       //Global variables

unsigned long drawerExtTime = 0; //Time measurement for calibrating motion. unsigned long previousMillis = 0; //time measurement for expansion

void setup() {

 //initialize pin I/O Inputs and turn everything off to avoid startup glitches
 pinMode(PRESSURE_SENSOR, INPUT_PULLUP);
 pinMode(SELECTOR_HALF, INPUT_PULLUP);
 pinMode(SELECTOR_THREEQUARTER, INPUT_PULLUP);
 pinMode(SELECTOR_FULL, INPUT_PULLUP);
 pinMode(SOLENOID_RIGHT, OUTPUT);
 digitalWrite(SOLENOID_RIGHT, LOW);
 pinMode(SOLENOID_LEFT, OUTPUT);
 digitalWrite(SOLENOID_LEFT, LOW);
 pinMode(SOLENOID_DOWN, OUTPUT);
 digitalWrite(SOLENOID_DOWN, LOW);
 pinMode(SOLENOID_UP, OUTPUT);
 digitalWrite(SOLENOID_UP, LOW);
 Serial.begin(9600);                    // In case we need to use the serial monitor

}

void loop() { //DRAWER CYLINDER BOUNCE CODE


while (lowPressure() == true) {

   digitalWrite(SOLENOID_RIGHT, HIGH);

}

   digitalWrite(SOLENOID_RIGHT, LOW);    //No delay after this like in manual code.
                                        

while (lowPressure() == true) {

   digitalWrite(SOLENOID_LEFT, HIGH);     //Reversal is immediate

}

   digitalWrite(SOLENOID_LEFT, LOW); 
                                                  

}


//End of Loop bool lowPressure() { //custom function definitions

 if (digitalRead(PRESSURE_SENSOR) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(PRESSURE_SENSOR) == HIGH) {
     return true;
   }
   else {
     return false;
   }
 }
 else {
   return false;
 }}
 //reads selector  - HIGH is false, LOW is true- SELECTOR_RESET, SELECTOR_QUARTER, SELECTOR_HALF, SELECTOR_3QUARTERS, SELECTOR_FULL,
 bool resetSelected() {
   if (quarterSelected() == false && threequarterSelected() == false && halfSelected() == false && fullSelected() == false) {
     return true;
   }
   else {
     return false;
   }}
   

bool quarterSelected() {

 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool halfSelected() {
 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool threequarterSelected() {
 if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
   bool fullSelected() {
 if (digitalRead(SELECTOR_FULL) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_FULL) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}


Main Cylinder Bounce Testing

  • Testing bounce of main cylinder on real machine.
  • Code works using manual switching, where the state goes randomly between up and down as a result of manual switching. This is because it is not possible to do an instantaneous switch by hand; microprocessor looping is faster.

//defines to make it easier for non-coders to make adjustments for troubleshooting and custom changes


  1. define SOLENOID_UP 7 //Extension. See pin mapping above.
  2. define SOLENOID_DOWN 6 //swap these pin numbers for wire inversion
  3. define SOLENOID_LEFT 5 //Extension.
  4. define SOLENOID_RIGHT 4 //swap these pin numbers for wire inversion
  1. define PRESSURE_SENSOR 13 //Needs pins adjacent so only 1 dupont connector is used
  2. define SELECTOR_RESET 12 //Activated when nothing is selected.
  3. define SELECTOR_QUARTER 11 //Reset is the shutdown/initialization procedure. All procedures are selected by
  4. define SELECTOR_HALF 10 //the WHILE function. QUARTER to FULL refers to brick thickness.
  5. define SELECTOR_THREEQUARTER 9 //Secondary cylinder timing is measured only.
  6. define SELECTOR_FULL 8 //Primary cylinder thickness setting is based on secondary cylinder motion.
  1. define PRESSURE_SENSOR_DEBOUNCE 20 //milliseconds to delay for pressure sensor debounce
  2. define DELAY 500 // 1/2 sec extra to compress brick via main Cyl (default 500ms)
                                       //custom function declarations

bool lowPressure(); //function to read pressure sensor bool resetSelected(); // //bool quarterSelected(); // bool halfSelected(); // bool threequarterSelected(); // bool fullSelected(); //

                                       //Global variables

unsigned long drawerExtTime = 0; //Time measurement for calibrating motion. unsigned long previousMillis = 0; //time measurement for expansion

void setup() {

 //initialize pin I/O Inputs and turn everything off to avoid startup glitches
 pinMode(PRESSURE_SENSOR, INPUT_PULLUP);
 pinMode(SELECTOR_HALF, INPUT_PULLUP);
 pinMode(SELECTOR_THREEQUARTER, INPUT_PULLUP);
 pinMode(SELECTOR_FULL, INPUT_PULLUP);
 pinMode(SOLENOID_RIGHT, OUTPUT);
 digitalWrite(SOLENOID_RIGHT, LOW);
 pinMode(SOLENOID_LEFT, OUTPUT);
 digitalWrite(SOLENOID_LEFT, LOW);
 pinMode(SOLENOID_DOWN, OUTPUT);
 digitalWrite(SOLENOID_DOWN, LOW);
 pinMode(SOLENOID_UP, OUTPUT);
 digitalWrite(SOLENOID_UP, LOW);
 Serial.begin(9600);              // In case we need to use the serial monitor

}

void loop() {


while (lowPressure() == true) {

   digitalWrite(SOLENOID_DOWN, HIGH);

}

   digitalWrite(SOLENOID_DOWN, LOW);    //No delay after this like in manual code.
                                        

while (lowPressure() == true) {

   digitalWrite(SOLENOID_UP, HIGH);     //Reversal is immediate

}

   digitalWrite(SOLENOID_UP, LOW); 
                                                  

}


//End of Loop bool lowPressure() { //custom function definitions

 if (digitalRead(PRESSURE_SENSOR) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(PRESSURE_SENSOR) == HIGH) {
     return true;
   }
   else {
     return false;
   }
 }
 else {
   return false;
 }}
 //reads selector  - HIGH is false, LOW is true- SELECTOR_RESET, SELECTOR_QUARTER, SELECTOR_HALF, SELECTOR_3QUARTERS, SELECTOR_FULL,
 bool resetSelected() {
   if (quarterSelected() == false && threequarterSelected() == false && halfSelected() == false && fullSelected() == false) {
     return true;
   }
   else {
     return false;
   }}
   

bool quarterSelected() {

 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool halfSelected() {
 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool threequarterSelected() {
 if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
   bool fullSelected() {
 if (digitalRead(SELECTOR_FULL) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_FULL) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}

Nonselection Procedure

  • We are using a four position switch for 1/4, 1/2, 3/4, and full bricks
  • Switch has positions 0-4 - or 5 total
  • The switch happens to have an off position (0) which does not make any connections
  • We can use the non-selection condition to do a fifth pseudo-selection - the reset procedure
  • Code for resetSelected (nonselection of all choices) is: if (quarterSelected() == false && halfSelected == false && threequarterSelected == false && fullSelected == false ) {}
  • Testing this:

//defines to make it easier for non-coders to make adjustments for troubleshooting and custom changes


  1. define SOLENOID_UP 4 //Extension. See pin mapping above.
  2. define SOLENOID_DOWN 5 //swap these pin numbers for wire inversion
  3. define SOLENOID_LEFT 6 //Extension.
  4. define SOLENOID_RIGHT 7 //swap these pin numbers for wire inversion
  1. define PRESSURE_SENSOR 13 //Needs pins adjacent so only 1 dupont connector is used
  2. define SELECTOR_RESET 12 //Activated when nothing is selected.
  3. define SELECTOR_QUARTER 11 //Reset is the shutdown/initialization procedure. All procedures are selected by
  4. define SELECTOR_HALF 10 //the WHILE function. QUARTER to FULL refers to brick thickness.
  5. define SELECTOR_THREEQUARTER 9 //Secondary cylinder timing is measured only.
  6. define SELECTOR_FULL 8 //Primary cylinder thickness setting is based on secondary cylinder motion.
  1. define PRESSURE_SENSOR_DEBOUNCE 20 //milliseconds to delay for pressure sensor debounce
  2. define DELAY 500 // 1/2 sec extra to compress brick via main Cyl (default 500ms)
                                       //custom function declarations

bool lowPressure(); //function to read pressure sensor bool resetSelected(); // //bool quarterSelected(); // bool halfSelected(); // bool threequarterSelected(); // bool fullSelected(); //

                                       //Global variables

unsigned long drawerExtTime = 0; //Time measurement for calibrating motion. unsigned long previousMillis = 0; //time measurement for expansion

void setup() {

 //initialize pin I/O Inputs and turn everything off to avoid startup glitches
 pinMode(PRESSURE_SENSOR, INPUT_PULLUP);
 pinMode(SELECTOR_HALF, INPUT_PULLUP);
 pinMode(SELECTOR_THREEQUARTER, INPUT_PULLUP);
 pinMode(SELECTOR_FULL, INPUT_PULLUP);
 pinMode(SOLENOID_RIGHT, OUTPUT);
 digitalWrite(SOLENOID_RIGHT, LOW);
 pinMode(SOLENOID_LEFT, OUTPUT);
 digitalWrite(SOLENOID_LEFT, LOW);
 pinMode(SOLENOID_DOWN, OUTPUT);
 digitalWrite(SOLENOID_DOWN, LOW);
 pinMode(SOLENOID_UP, OUTPUT);
 digitalWrite(SOLENOID_UP, LOW);
 Serial.begin(9600);

}

void loop() {

        Serial.println(resetSelected());                                            

while (resetSelected() == true) { //goes only up to trigger of pressure, no matter how long pressure trigger is

   digitalWrite(SOLENOID_UP, HIGH);

}

   digitalWrite(SOLENOID_UP, LOW);              //                     
   delay(2000);                                  //gives time to release trigger (momentary switch should be used to make this easier)
                                       //reads pressure sensor state HIGH is false and LOW is true

}

//End of Loop bool lowPressure() { //custom function definitions

 if (digitalRead(PRESSURE_SENSOR) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(PRESSURE_SENSOR) == HIGH) {
     return true;
   }
   else {
     return false;
   }
 }
 else {
   return false;
 }}
 //reads selector  - HIGH is false, LOW is true- SELECTOR_RESET, SELECTOR_QUARTER, SELECTOR_HALF, SELECTOR_3QUARTERS, SELECTOR_FULL,
 bool resetSelected() {
   if (quarterSelected() == false && threequarterSelected() == false && halfSelected() == false && fullSelected() == false) {
     return true;
   }
   else {
     return false;
   }}
   

bool quarterSelected() {

 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool halfSelected() {
 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool threequarterSelected() {
 if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
   bool fullSelected() {
 if (digitalRead(SELECTOR_FULL) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_FULL) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}

Action Based on Selection of 2 Options

  • Same as above, but trigger an action by while (quarterSelected() == true && halfSelected == true) {}
  • This works.

while (fullSelected() == true && threequarterSelected() == true) {

   digitalWrite(SOLENOID_UP, HIGH);

}

   digitalWrite(SOLENOID_UP, LOW);              //                                                 

}

Cylinder Bounce Code Simulation

To test solenoids sensing pressure and reversing solenoids upon pressure trigger, ma nually simulated logic is the following. This simulates a cylinder bouncing between full retraction and full extension, which are both high pressure trigger points.

  • Turn solenoid UP on - while pressure low
  • Turn solenoid UP off - as soon as pressure triggers, and move solenoid Down.
  • Trigger is done manually simply by switching pin 13 on (touching jumper from ground to 13)
  • The opposite action occurs until the pressure is triggered again. Length of pressure trigger doesn't matter.
  • If the pressure trigger is longer that 2 seconds, then we don't know where in the program loop we are and either UP or DOWN will occur
  • In real life, the solenoid should be off momentarily, and next step should follow immediately

Code:

//defines to make it easier for non-coders to make adjustments for troubleshooting and custom changes

//defines to make it easier for non-coders to make adjustments for troubleshooting and custom changes

  1. define SOLENOID_UP 4 //Extension. See pin mapping above.
  2. define SOLENOID_DOWN 5 //swap these pin numbers for wire inversion
  3. define SOLENOID_LEFT 6 //Extension.
  4. define SOLENOID_RIGHT 7 //swap these pin numbers for wire inversion
  1. define PRESSURE_SENSOR 13 //Needs pins adjacent so only 1 dupont connector is used
  2. define SELECTOR_RESET 12 //Activated when nothing is selected.
  3. define SELECTOR_QUARTER 11 //Reset is the shutdown/initialization procedure. All procedures are selected by
  4. define SELECTOR_HALF 10 //the WHILE function. QUARTER to FULL refers to brick thickness.
  5. define SELECTOR_THREEQUARTER 9 //Secondary cylinder timing is measured only.
  6. define SELECTOR_FULL 8 //Primary cylinder thickness setting is based on secondary cylinder motion.
  1. define PRESSURE_SENSOR_DEBOUNCE 20 //milliseconds to delay for pressure sensor debounce
  2. define DELAY 500 // 1/2 sec extra to compress brick via main Cyl (default 500ms)
                                       //custom function declarations

bool lowPressure(); //function to read pressure sensor bool resetSelected(); // //bool quarterSelected(); // bool halfSelected(); // bool threequarterSelected(); // bool fullSelected(); //

                                       //Global variables

unsigned long drawerExtTime = 0; //Time measurement for calibrating motion. unsigned long previousMillis = 0; //time measurement for expansion

void setup() {

 //initialize pin I/O Inputs and turn everything off to avoid startup glitches
 pinMode(PRESSURE_SENSOR, INPUT_PULLUP);
 pinMode(SELECTOR_HALF, INPUT_PULLUP);
 pinMode(SELECTOR_THREEQUARTER, INPUT_PULLUP);
 pinMode(SELECTOR_FULL, INPUT_PULLUP);
 pinMode(SOLENOID_RIGHT, OUTPUT);
 digitalWrite(SOLENOID_RIGHT, LOW);
 pinMode(SOLENOID_LEFT, OUTPUT);
 digitalWrite(SOLENOID_LEFT, LOW);
 pinMode(SOLENOID_DOWN, OUTPUT);
 digitalWrite(SOLENOID_DOWN, LOW);
 pinMode(SOLENOID_UP, OUTPUT);
 digitalWrite(SOLENOID_UP, LOW);

}

void loop() {


while (lowPressure() == true) { //goes only up to trigger of pressure, no matter how long pressure trigger is

   digitalWrite(SOLENOID_UP, HIGH);

}

   digitalWrite(SOLENOID_UP, LOW);              //                     
   delay(2000);                                  //gives time to release trigger (momentary switch should be used to make this easier)

while (lowPressure() == true) { //moves in reverse direction until next trigger

   digitalWrite(SOLENOID_DOWN, HIGH);

}

   digitalWrite(SOLENOID_DOWN, LOW);            //moves on to next step, next step should continue until next trigger                      
   delay(2000);                                                

} //reads pressure sensor state HIGH is false and LOW is true

                                                //End of Loop

bool lowPressure() { //custom function definitions

 if (digitalRead(PRESSURE_SENSOR) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(PRESSURE_SENSOR) == HIGH) {
     return true;
   }
   else {
     return false;
   }
 }
 else {
   return false;
 }}
 //reads selector  - HIGH is false, LOW is true- SELECTOR_RESET, SELECTOR_QUARTER, SELECTOR_HALF, SELECTOR_3QUARTERS, SELECTOR_FULL,
 bool resetSelected() {
   if (threequarterSelected() == false && halfSelected() == false && fullSelected() == false) {
     return true;
   }
   else {
     return false;
   }}
 bool halfSelected() {
 if (digitalRead(SELECTOR_HALF) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_HALF) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
 bool threequarterSelected() {
 if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_THREEQUARTER) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}
   bool fullSelected() {
 if (digitalRead(SELECTOR_FULL) == HIGH) {
   delay(PRESSURE_SENSOR_DEBOUNCE);
   if (digitalRead(SELECTOR_FULL) == HIGH) {
     return false;
   }
   else {
     return true;
   }
 }
 else {
   return true;
 }}