//PIN Setup
//====================================================
//Dispenser Motor initalisation
const int MotorSpeed = 6;
const int MotorSeq = 4;
const int MotorRet = 7;
//Tap Solenoid Pins
const int TapSol1 = 8;
const int TapSol2 = 9;
const int TapSol3 = 10;
//Tap LDR Pins
const int HomeLDR = 0;
const int Tap1LDR = 1;
const int Tap2LDR = 2;
const int Tap3LDR = 3;
const int EndLDR = 4;
//Signal LED pins
unsigned long currentMillis = 0; //stores the value of millis() in each iteration of loop()
const int RedLed = 13; //Red LED is on PIN number 13
byte RedLedState = LOW; //used to record whether the LED is on or off (LOW = Off)
const int RedLedInterval = 1000; // Number of milliseconds between blinks
const int RedLedDuration = 500; //Number of milliseconds that the LED is on for
unsigned long previousRedLedMillis = 0; //will store last time LED was updated
const int GreenLed = 1; //Green LED is on PIN number 12
byte GreenLedState = LOW; //used to record whether the LED is on or off (LOW = Off)
const int GreenLedInterval = 1000; // Number of milliseconds between blinks
const int GreenLedDuration = 500; //Number of milliseconds that the LED is on for
unsigned long previousGreenLedMillis = 0; //will store last time LED was updated
//Tap Selection Button Pins
const int TapBut1 = 11;
const int TapBut2 = 12;
const int TapBut3 = 13;
//Home Position Micro-Switch
const int HomePosSwitch = 0;
//==========================================================
//Motor Speed
const int SequenceSpeed = 100;
const int ApproachSpeed = 80;
const int HomeCheckSpeed = 80;
//Glass Filling Timers(ms)
const int Tap1 = 10000;
const int Tap2 = 10000;
const int Tap3 = 10000;
//Motor Sequence Timers
const int TapApproach = 5000;
const int EndApproach = 5000;
const int HomeApproach = 5000;
//general vars
boolean Direction = true;
int TapNumber = 0;
int TapSolenoid = 0;
int FillingTime = 0;
int LDRDetect = 0;
//Pre-initalisation sequence
void setup()
{
pinMode(MotorSpeed, OUTPUT );
pinMode(MotorSeq, OUTPUT );
pinMode(MotorRet, OUTPUT );
pinMode(TapSol1, OUTPUT);
pinMode(TapSol2, OUTPUT);
pinMode(TapSol3, OUTPUT);
pinMode(HomeLDR, INPUT);
pinMode(Tap1LDR, INPUT);
pinMode(Tap2LDR, INPUT);
pinMode(Tap3LDR, INPUT);
pinMode(EndLDR, INPUT);
pinMode(TapBut1, INPUT);
pinMode(TapBut2, INPUT);
pinMode(TapBut3, INPUT);
pinMode(RedLed, OUTPUT);
pinMode(GreenLed, OUTPUT);
pinMode(HomePosSwitch, INPUT);
}
//====================================================
// Main program sequence
void loop(){
updateRedLedState();
if (digitalRead (TapBut1) == HIGH){
TapNumber = Tap1LDR;
TapSolenoid = TapSol1;
FillingTime = Tap1;
}
else if (digitalRead (TapBut2) == HIGH){
TapNumber = Tap2LDR;
TapSolenoid = TapSol2;
FillingTime = Tap2;
}
else if (digitalRead (TapBut3) == HIGH){
TapNumber = Tap3LDR;
TapSolenoid = TapSol3;
FillingTime = Tap3;
}
if ((TapNumber > 0) && (TapSolenoid > 0) && (FillingTime > 0)){
operateDispenser(TapNumber, TapSolenoid, FillingTime);
}
}
//========================================================================
//FUNCTION DEFINITIONS
//Puts the beer dispenser into a error state - Stops Motor/Flashes Red LED
void updateRedLedState(){
if (RedLedState == LOW) {
if (currentMillis - previousRedLedMillis >= RedLedInterval){
RedLedState = HIGH;
previousRedLedMillis += RedLedInterval;
}
}
else {
if (currentMillis - previousRedLedMillis >= RedLedDuration){
RedLedState = LOW;
previousRedLedMillis += RedLedDuration;
}
}
}
void EmergencyStop(){
digitalWrite( 4, LOW );
digitalWrite( 7, LOW );
digitalWrite( 6, LOW );
digitalWrite(RedLed, RedLedState);
}
//Function to trigger the solenoid and fill the glass
int GlassFill(int TapSole, int FillTime){
switch (TapSole) {
case 8:
digitalWrite(TapSol1, HIGH);
delay(FillTime);
digitalWrite(TapSol1, LOW);
break;
case 9:
digitalWrite(TapSol2, HIGH);
delay(FillTime);
digitalWrite(TapSol2, LOW);
break;
case 10:
digitalWrite(TapSol3, HIGH);
delay(FillTime);
digitalWrite(TapSol3, LOW);
break;
default:
return -1;
}
}
/*
LDR Scanner scans the chosen LDR (Beer Tap) every 10ms for the trolley when it is in approach to chosen position.
This also takes an ambient light reading when triggered. There is also a built in timer on this function which allows the system
to enter an error state in case an LDR fails to sense the LED mounted on the trolley. The system will enter 'EmergencyStop'
*/
int LDRScan (int LDR, int Time){
int Ambient = 0;
int Reading = 0;
int TimerCount = 0;
Ambient = analogRead(LDR);
Reading = Ambient;
while ((Reading >= (Ambient - 100))&&(TimerCount < Time)){ //for false triggers increase ambient off set, for detection failures or lack of sensitivity decrease off set.
Reading = analogRead(LDR);
delay(10);
TimerCount ++;
}
if (TimerCount == Time)
{
return -1;
}
else
{
return 1;
}
}
//Function to control the motor direction and speed
void MotorDrive(boolean Direction, int Speed){
analogWrite( MotorSpeed, Speed);
if (Direction)
{
digitalWrite( MotorSeq, HIGH);
digitalWrite( MotorRet, LOW);
}
else
{
digitalWrite( MotorSeq, LOW);
digitalWrite( MotorRet, HIGH);
}
}
//Function to call the motor on ChannelB H-Bridge to stop
void MotorStop()
{
digitalWrite( 4, LOW );
digitalWrite( 7, LOW );
digitalWrite( 6, LOW );
}
//======================================================================
/*
Main Schedule of the process from start to finish of the automatic Beer Dispenser - this schedule goes through and calls functions of code
in seperated tabs
*/
int operateDispenser (int TapNumber, int TapSolenoid, int FillingTime){
delay (1500);
Direction = true;
//Home to Tap Approach
MotorDrive(Direction, SequenceSpeed);
delay(TapApproach);
MotorDrive(Direction, ApproachSpeed);
//Tap Position LDR
LDRDetect = LDRScan(TapNumber, 500);
if (LDRDetect == 1)
{
MotorStop();
delay(1000);
}
else
{
EmergencyStop();
}
delay(1500);
//Filling Glass
GlassFill(TapSolenoid, FillingTime);
delay(1500);
//Tap to End Approach
MotorDrive(Direction, SequenceSpeed);
delay(EndApproach);
MotorDrive(Direction, ApproachSpeed);
//End Position LDR
LDRDetect = LDRScan(EndLDR, 500);
if (LDRDetect == 1)
{
MotorStop();
}
else
{
EmergencyStop();
}
delay (10000);
//End to Home Approach
Direction = false;
MotorDrive(Direction, SequenceSpeed);
delay(HomeApproach);
MotorDrive(Direction, ApproachSpeed);
MotorStop();
}
___
**** The end ten second delay is temporary, it will be replaced with the green LED Blinking function to indicate remove glass***
**** The Home Position Micro switch hasn't been programmed in yet, so the end of the sequence doesn't have it****
**** Green LED and RED Led functions need to be programmed still