//Declaration of buttons
byte PHorario = 3;     //Clockwise/counterclockwise button
byte PVel = 2;         //Speed button

//Declaration of Driver pins
byte IN1=4;  // 28BYJ48 In1
byte IN2=5;  // 28BYJ48 In2
byte IN3=6;  // 28BYJ48 In3
byte IN4=7;  // 28BYJ48 In4

int horario=1;

//*** Create Matrix with Motor Steps ***//

int paso=4; //Variable indicating the number of steps of the matrices
int Cpaso=0; //Step counter

int vel[2]={8,15}; //Speed vector 0-15 approximately
int Cvel=0; //Speed counter

int conf=1; //Variable that configures the step sequence

//step sequence 1
const int UnPaso[4] = {B1000,B0100,B0010,B0001};
 
//step sequence 2
const int DosPasos[4] = {B1100,B0110,B0011,B1001};

// Half-step sequence
byte const MedioPaso[8] = {B1000,B1100,B0100,B0110,B0010,B0011,B0001,B1001};

//Function that sets the output port bits starting from the initial pin to the end pin
void puerto(int bits,int ini,int fin){
  for(int i=ini;i<=fin;i++)
  {
    digitalWrite(i,bitRead(bits,i-ini));
  }
}

void setup() {
  //Configure 2 Button Pins as INPUTS
  pinMode (2,INPUT);
  pinMode (3,INPUT);

  //Configure 4 Digital Pins as OUTPUTS
  for(int i=IN1;i<=IN4;i++){
    pinMode(i,OUTPUT);
  }
}

void loop() {

  //******************************************************************************//
  //***********    Check Buttons   ***********************************************//
  //******************************************************************************//
  
  // Clockwise Rotation
  if(digitalRead(PHorario) && horario==1){  // Check if clockwise button is pressed
    delay(500); //Debounce
    horario=0;
    Cpaso=-1;
  }
  else if(digitalRead(PHorario) && horario==0){
    delay(500); //Debounce
    Cpaso=paso;
    horario = 1;
  }

  // Motor Speed
  if(digitalRead(PVel)){ // Check if speed button is pressed
    delay(100); //Debounce
    while(digitalRead(PVel)); //Wait until button is released
    delay(100); //Debounce
    Cvel++;
    //Reset if already passed through both speeds
    if(Cvel>1)
      Cvel=0;
  }

  //******************************************************************************//
  //***********    Logic for counters   ******************************************//
  //******************************************************************************//
  if(horario==1){
    Cpaso++;                        //Increment the step counter
    if(Cpaso>=paso)
       Cpaso=0;                          //Set step counter to zero 
  } 
  else{
    Cpaso--;                        //Decrement the step counter
    if(Cpaso<0)
       Cpaso=paso-1;                  //Set counter equal to the step
  }
  

  //******************************************************************************//
  //***********    Motor Movement Sequence   *************************************//
  //******************************************************************************//

  switch(conf){
    case 1:
      puerto(UnPaso[Cpaso],IN1,IN4); //Send information from table to port
      paso=4;
      break;
    case 2:
      puerto(DosPasos[Cpaso],IN1,IN4); //Send information from table to port
      paso=4;
      break;
    case 3:
      puerto(MedioPaso[Cpaso],IN1,IN4); //Send information from table to port
      paso=8;
      break;
  }
  delay(vel[Cvel]); //Delay of 100 milliseconds
  
}