/* 

 Adam Cecchetti adam@cecchetti.com 
 Copyright 2009

*/ 

#include <Servo.h>

Servo Oven_Flap_Servo; 
Servo Oven_Tray_Servo; 


#define System_Init_Delay 100
#define Stepper_Signal_Delay_Nema23 2
#define Stepper_Signal_Delay 250
#define Bread_Stepper_Signal_Delay 300
#define Cheese_Stepper_Delay 500
#define Bread_Stepper_Delay 2000

#define Home_Delay 1500

#define Sammich_Delay 1000
#define Bread_Fall_Delay 4000 
#define Sammich_Cooking_Delay 180000
#define Stepper_Controller_Delay 50

#define Bread_Turn_Cycles 600
#define Cheese_Turn_Cycles 600

#define Tray_Insert_Servo_Position 0 
#define Tray_Remove_Servo_Position 180
#define Flap_Open_Position 180
#define Flap_Closed_Position 0

#define Bread_Stepper_StepPin  4
#define Bread_Stepper_DirPin   5
#define Cheese_Stepper_StepPin 6
#define Cheese_Stepper_DirPin  7

#define Oven_Tray_Servo_Signal_Pin 9
#define Oven_Flap_Servo_Signal_Pin 10
#define Bread_Controller_Enable_Pin 11
#define Cheese_Controller_Enable_Pin 12

int debug = 1; 

// Not used assign for debugging 
int Debug_Speed = 0; 

/* Control functions */ 


void Enable_Contollers(){
  digitalWrite(Bread_Controller_Enable_Pin, HIGH);    
  digitalWrite(Cheese_Controller_Enable_Pin, HIGH);    
  delay(Stepper_Controller_Delay); 
}

void Disable_Controllers(){
  digitalWrite(Bread_Controller_Enable_Pin, LOW);    
  digitalWrite(Cheese_Controller_Enable_Pin, LOW);    
}


void Open_Oven_Flap(){
   if(debug)
     Serial.println("Open Flap"); 
   Oven_Flap_Servo.write(Flap_Open_Position); 
}

void Close_Oven_Flap(){
  if(debug)
   Serial.println("Close Flap"); 
   Oven_Flap_Servo.write(Flap_Closed_Position); 
}


void Insert_Oven_Tray(){
   if(debug)
     Serial.println("Insert Tray"); 
   Oven_Tray_Servo.write(Tray_Insert_Servo_Position); 
}

void Remove_Oven_Tray() {
  if(debug)
    Serial.println("Remove Tray");
  Oven_Tray_Servo.write(Tray_Remove_Servo_Position); 
}

void Turn_Bread(){ 

  int Bread_Turn_Count = 0;
 Enable_Contollers();

 if(debug)
    Serial.println("Turn Bread");
  for (Bread_Turn_Count = 0; Bread_Turn_Count < Bread_Turn_Cycles; Bread_Turn_Count++){
      digitalWrite(Bread_Stepper_StepPin, HIGH);
      delayMicroseconds(Stepper_Signal_Delay_Nema23);
      digitalWrite(Bread_Stepper_StepPin, LOW);
      delayMicroseconds(Bread_Stepper_Delay);  
    } 
  
  
  Disable_Controllers();
}

void Turn_Cheese(){
 
 int Cheese_Turn_Count = 0; 
  
 Enable_Contollers();  
  if(debug)
    Serial.println("Turn Cheese");  
    
    for (Cheese_Turn_Count = 0; Cheese_Turn_Count < Cheese_Turn_Cycles; Cheese_Turn_Count++){
      digitalWrite(Cheese_Stepper_StepPin, HIGH);
      delayMicroseconds(Stepper_Signal_Delay);
      digitalWrite(Cheese_Stepper_StepPin, LOW);
      delayMicroseconds(Cheese_Stepper_Delay);  
    }
    
 Disable_Controllers();
}


void Home_System() {
 if(debug)
   Serial.println("Home System");
 Open_Oven_Flap(); 
 delay(Home_Delay);
 Insert_Oven_Tray(); 
 delay(Home_Delay);
 Close_Oven_Flap();
 delay(Home_Delay);
 }



void Sammich() {
  Serial.println("Cooking Sammich"); 
  Open_Oven_Flap();
  delay(Sammich_Delay);
  Remove_Oven_Tray();
  delay(Sammich_Delay);
  Turn_Bread();
  delay(Sammich_Delay);
  Turn_Cheese();
  delay(Sammich_Delay);
  Turn_Bread();
  delay(Bread_Fall_Delay); 
  Insert_Oven_Tray(); 
  delay(Sammich_Delay);
  Close_Oven_Flap();
  delay(Sammich_Cooking_Delay); 
  Open_Oven_Flap(); 
  delay(Sammich_Delay);  
  Remove_Oven_Tray(); 
  
}
    /* System init */

void setup()
{
  Oven_Flap_Servo.attach(Oven_Flap_Servo_Signal_Pin);   
  Oven_Tray_Servo.attach(Oven_Tray_Servo_Signal_Pin); 
  pinMode(Bread_Stepper_StepPin, OUTPUT);
  pinMode(Bread_Stepper_DirPin, OUTPUT);
  pinMode(Cheese_Stepper_StepPin, OUTPUT);
  pinMode(Cheese_Stepper_DirPin, OUTPUT);
  pinMode(Bread_Controller_Enable_Pin, OUTPUT);
  pinMode(Cheese_Controller_Enable_Pin, OUTPUT);
    
  digitalWrite(Bread_Stepper_DirPin, LOW);
  digitalWrite(Bread_Stepper_StepPin, LOW);
  digitalWrite(Cheese_Stepper_DirPin, LOW);
  digitalWrite(Cheese_Stepper_StepPin, LOW);
  digitalWrite(Bread_Controller_Enable_Pin, LOW);    
  digitalWrite(Cheese_Controller_Enable_Pin, LOW);    

  delay(System_Init_Delay);  
  Serial.begin(19200);
  Serial.print("Ready");
  delay(System_Init_Delay);  
  Home_System(); 
  delay(System_Init_Delay);  
  Print_Menu();

}

void Print_Menu(){ 
  Serial.println( " Debug On/Off: q , Open Flap: w , Close Flap: s ");
  Serial.println( " Make sammich: m , Inst Tray: a , Remov Tray: d "); 
  Serial.println( " Turn Bread  : e , Turn Chee: r" ); 
}  

/* main loop */ 
void loop()
{
 
 
  //Not used: Assign for debugging a component
  static int Variable_Speed = 0;

  if ( Serial.available()) {
    
    Print_Menu();
   char ch = Serial.read();

    switch(ch) {
        case '0'...'9':
        Variable_Speed = 100 * ( ch - '0');
        break;
      case 'w':
         Open_Oven_Flap();       
       break; 
      case 's':
         Close_Oven_Flap();
        break;
      case 'a':
         Insert_Oven_Tray();
        break;
       case 'd':
         Remove_Oven_Tray();
        break;  
       case 'e':
         Turn_Bread();
       break; 
       case 'r': 
         Turn_Cheese();
       break;        
       case 'm':
          Sammich();
       break; 
    }
  }
}
