// constants const int BEER_INLET_SENSOR_THRESHOLD_MS = 500; // min value returned from beer inlet sensor to determine whether associated solenoid should be closed. const int PUSH_THRESHOLD_MS = 2500; // how long to push cans number const int RAISE_THRESHOLD_MS = 1000; // how long it takes to raise/lower cans; const int PURGE_THRESHOLD_MS = 2000; // how long to purge // digital outputs const int canPusherSolenoid = 2; /* solenoid to push cans forward over a 2500ms duration to avoid jolting Speed controlled by throttle on ram, then retract until cycle starts again*/ const int fillRailSolenoid = 3; /* solenoid for filler rail, should start raised/gohigh until cans are in place, then drop/golow to fill cans. raise/gohigh again once all the fillsense see voltage*/ const int canPurgeSolenoid = 4; /* solenoid for co2 purge, once fill rail is down/golow co2sol to open/gohigh for 2000 - 9000ms then close/golow. Ability to change this would be good.*/ const int beerInlet1Solenoid = 5; /* solenoid for beer inlet1, to open/gohigh when fill rail is down/golow, delay to avoid fill before rail is fully down. to close/golow again when the fillsense1 sees a voltage.*/ const int beerInlet2Solenoid = 6; /* solenoid for beer inlet2, to open/gohigh when fill rail is down/golow, delay to avoid fill before rail is fully down. to close/golow again when the fillsense2 sees a voltage.*/ const int beerInlet3Solenoid = 7; /* solenoid for beer inlet3, to open/gohigh when fill rail is down/golow, delay to avoid fill before rail is fully down. to close/golow again when the fillsense3 sees a voltage.*/ // digital inputs const int startButton = 8; // analog inputs // beer inlet sensors, used to detect when a can is full. 5 volts on fill tube and pin on stainless wire set to desired level. // beer completes the circuit sending the pin high. const int beerInlet1Sensor = A0; const int beerInlet2Sensor = A1; const int beerInlet3Sensor = A2; const int ledPin = 13; enum CanFillStateMachine { START, PUSH, PUSHING, RAISE, START_PURGE_AND_FILL, PURGE_AND_FILL, LOWER, ALL_STOP }; CanFillStateMachine currentState(START); unsigned long startOfState = 0L; // used to keep track of how long we are in a particular state. bool running = false; void setup() { Serial.begin(9600); // set all solenoid to output mode pinMode(canPusherSolenoid, OUTPUT); pinMode(fillRailSolenoid, OUTPUT); pinMode(canPurgeSolenoid, OUTPUT); pinMode(beerInlet1Solenoid, OUTPUT); pinMode(beerInlet2Solenoid, OUTPUT); pinMode(beerInlet2Solenoid, OUTPUT); // set buttons to input mode pinMode(startButton, INPUT); /** [PXL] when voltage is detected on all three of these sensors lower the fill rail * also not sure about the pinMode for these sensors * */ pinMode(beerInlet1Sensor, INPUT_PULLUP); pinMode(beerInlet2Sensor, INPUT_PULLUP); pinMode(beerInlet3Sensor, INPUT_PULLUP); shutdownAll(); } void shutdownAll() { digitalWrite(canPusherSolenoid, LOW); digitalWrite(fillRailSolenoid, LOW); digitalWrite(beerInlet1Solenoid, LOW); digitalWrite(beerInlet2Solenoid, LOW); digitalWrite(beerInlet3Solenoid, LOW); digitalWrite(canPurgeSolenoid, LOW); running = false; } void loop() { // if we are running, pressing the stop button will cause everythig to stop if (running) { if (digitalRead(startButton) == HIGH) { currentState = ALL_STOP; } } switch (currentState) { case START: { /** this is the starting state of the automated can filler. * assumption is that three empty cans are on the ramp. */ /* set next state to push */ Serial.println("Press start button"); if (digitalRead(startButton) == HIGH) { currentState = PUSH; startOfState = millis(); running = true; } } break; case PUSH: Serial.println("Starting..."); digitalWrite(canPusherSolenoid, HIGH); currentState = PUSHING; startOfState = millis(); case PUSHING: { Serial.println("Pushing cans"); if (millis() - startOfState >= PUSH_THRESHOLD_MS) { Serial.println("Done pushing"); digitalWrite(canPusherSolenoid, LOW); delay(500); // wait a bit /* set next state to RAISE */ currentState = RAISE; startOfState = millis(); } } break; case RAISE: { Serial.println("Raising cans"); if (millis() - startOfState >= RAISE_THRESHOLD_MS) { /* Possible PROBLEM? need to know what mechanism is being used to raise cans. Can we just * set it at HIGH and leave it there until we detect beer? * */ digitalWrite(fillRailSolenoid, LOW); currentState = START_PURGE_AND_FILL; startOfState = millis(); } else { digitalWrite(fillRailSolenoid, HIGH); } } break; case START_PURGE_AND_FILL: { Serial.println("Starting purge & fill"); digitalWrite(canPurgeSolenoid, HIGH); digitalWrite(beerInlet1Solenoid, HIGH); digitalWrite(beerInlet2Solenoid, HIGH); digitalWrite(beerInlet3Solenoid, HIGH); currentState = PURGE_AND_FILL; startOfState = millis(); } break; case PURGE_AND_FILL: { int nBeerInlet1Sensor = analogRead(beerInlet1Sensor); int nBeerInlet2Sensor = analogRead(beerInlet2Sensor); int nBeerInlet3Sensor = analogRead(beerInlet3Sensor); int shutdownCount = 0; Serial.println("Purging & filling"); if (millis() - startOfState >= PURGE_THRESHOLD_MS) { digitalWrite(canPurgeSolenoid, LOW); Serial.println("Purge done"); } if (nBeerInlet1Sensor > BEER_INLET_SENSOR_THRESHOLD_MS) { digitalWrite(beerInlet1Solenoid, LOW); Serial.println("Shutdown beer inlet 1"); shutdownCount++; } if (nBeerInlet2Sensor > BEER_INLET_SENSOR_THRESHOLD_MS) { digitalWrite(beerInlet2Solenoid, LOW); Serial.println("Shutdown beer inlet 2"); shutdownCount++; } if (nBeerInlet3Sensor > BEER_INLET_SENSOR_THRESHOLD_MS) { digitalWrite(beerInlet3Solenoid, LOW); Serial.println("Shutdown beer inlet 3"); shutdownCount++; } if (shutdownCount == 3) { Serial.println("Done filling"); currentState = LOWER; startOfState = millis(); } } break; case LOWER: { Serial.println("Lowering..."); digitalWrite(fillRailSolenoid, LOW); if (millis() - startOfState >= RAISE_THRESHOLD_MS) { currentState = ALL_STOP; } } break; case ALL_STOP: { shutdownAll(); currentState = START; } break; } }