//***********************************************//
//*******Bluetooth Remote Control Car************//
//******with Arduino, HC-05 Bluetooth Module*****//
//*************and Android SmartPhone************//
//***********************************************//
//**********Designed and Programmed**************//
//************by Kostas Kokoras******************//
//************[email protected]*****************//

#include <SoftwareSerial.h>
#define RxD 7
#define TxD 8


int recvChar;
int buzzer=3;
int motor_forw_back1=5;
int motor_forw_back2=6;
int motor_left_right1=9;
int motor_left_right2=10;
int bat_Voltmeter_pin=A0;
int front_lights_pin=2;
int back_lights_pin=4;


float R1=4610.0;
float R2=4650.0;

boolean front_lights, back_lights=false;

int pwm_percent;
int pwm_value;
int pwm_steer;
int pwm_steer_delay;

SoftwareSerial blueToothSerial(RxD,TxD);

#include "pitches.h"

// notes in the melody:
int melody[] = {
   NOTE_E7, NOTE_D7, NOTE_C7, NOTE_C7, NOTE_C7, NOTE_D7, 
   NOTE_E7, NOTE_F7, NOTE_G7, NOTE_G7, NOTE_G7, NOTE_E7};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
   8, 8, 4, 4, 8, 8, 
   8, 8, 4, 4, 4, 4 };
   
long echo_millis,current_millis;



void setup()
{
   Serial.begin(38400);
   pinMode(RxD, INPUT);
   pinMode(TxD, OUTPUT);
   
   pinMode(3,OUTPUT);
   pinMode(motor_forw_back1, OUTPUT);
   digitalWrite(motor_forw_back1,LOW);
   pinMode(motor_forw_back2, OUTPUT);
   digitalWrite(motor_forw_back2,LOW);
   
   pinMode(motor_left_right1, OUTPUT);
   digitalWrite(motor_left_right1,LOW);
   pinMode(motor_left_right2, OUTPUT);
   digitalWrite(motor_left_right2,LOW);
   
   pinMode(bat_Voltmeter_pin,INPUT);
   
   pinMode(front_lights_pin,OUTPUT);
   pinMode(back_lights_pin,OUTPUT);
   
   pwm_percent=60;
   pwm_value=int((255*pwm_percent)/100);
   pwm_steer=150;
   pwm_steer_delay=120;
   
   echo_millis=0;
   current_millis=0;
   
   blueToothSerial.begin(38400);
}

//-----------------------------------------------------//
void bat_Voltmeter()
{
 
   float bat_volt_read=0.0;
   for(int i=0;i<30;i++){
    bat_volt_read=bat_volt_read+(analogRead(bat_Voltmeter_pin) * (5.0/1023.0));
   }
   //float bat_Volt=bat_volt_read/30;
   bat_volt_read=bat_volt_read/30;
   float bat_Volt = bat_volt_read / (R2/(R1 + R2));
   Serial.println(bat_Volt,2);
   int int_bat_volt=int(bat_Volt);
   int flt_bat_volt=int((bat_Volt-float(int_bat_volt))*100);
   blueToothSerial.flush();
   blueToothSerial.write(flt_bat_volt);
   blueToothSerial.write(int_bat_volt);
 
}

void loop()
{
  
   current_millis=millis();
   if (current_millis-echo_millis>4000.0) {
     //recvChar=0;
     echo_millis=current_millis;
     Serial.println("Remote Control out of range...");
     
     digitalWrite(motor_forw_back1,HIGH);
      digitalWrite(motor_forw_back2,HIGH);
      
      digitalWrite(motor_left_right1,HIGH);
      digitalWrite(motor_left_right2,HIGH);
      
     digitalWrite(front_lights_pin,HIGH);
     digitalWrite(back_lights_pin,HIGH);
     tone(buzzer,2000,300);
     delay(500);
     digitalWrite(front_lights_pin,LOW);
     digitalWrite(back_lights_pin,LOW);
     tone(buzzer,1000,300);
     delay(500);
     noTone(buzzer);
   }
  
    
   if (blueToothSerial.available()){  
     recvChar = blueToothSerial.read();
     //Serial.print(recvChar);
   

   
   switch(recvChar){
    case 0:{// ALL STOP
      digitalWrite(motor_forw_back1,HIGH);
      digitalWrite(motor_forw_back2,HIGH);
      
      digitalWrite(motor_left_right1,HIGH);
      digitalWrite(motor_left_right2,HIGH);
      
      if (!front_lights) digitalWrite(front_lights_pin,LOW);
      if (!back_lights) digitalWrite(back_lights_pin,LOW);
      
      Serial.println("Stop - Straight");
    } 
    break;
    case 1:{// FORWARD
      digitalWrite(motor_forw_back1,LOW);
      analogWrite(motor_forw_back2,pwm_value);
      
      digitalWrite(motor_left_right1,HIGH);
      digitalWrite(motor_left_right2,HIGH);
      
      if (!front_lights) digitalWrite(front_lights_pin,HIGH);
      if (!back_lights) digitalWrite(back_lights_pin,LOW);
      
      Serial.print("Forward - Straight @ ");Serial.print(pwm_percent);Serial.println("%");
    } 
    break;
    case 2:{// BACKWARD
      digitalWrite(motor_forw_back2,LOW);
      analogWrite(motor_forw_back1,pwm_value);
      
      digitalWrite(motor_left_right1,HIGH);
      digitalWrite(motor_left_right2,HIGH);
      
      if (!front_lights) digitalWrite(front_lights_pin,LOW);
      if (!back_lights)digitalWrite(back_lights_pin,HIGH);
      
      Serial.print("Backward - Straight @ ");Serial.print(pwm_percent);Serial.println("%");
    } 
    break;
    case 4:{// FORWARD - LEFT
      digitalWrite(motor_forw_back1,LOW);
      analogWrite(motor_forw_back2,pwm_value);
      
      digitalWrite(motor_left_right2,LOW);
      digitalWrite(motor_left_right1,HIGH);
      delay(pwm_steer_delay);
      analogWrite(motor_left_right1,pwm_steer);
      
      if (!front_lights) digitalWrite(front_lights_pin,HIGH);
      if (!back_lights) digitalWrite(back_lights_pin,LOW);
      
      Serial.print("Forward - Left @ ");Serial.print(pwm_percent);Serial.println("%");
    } 
    break;
    case 7:{// FORWARD - RIGHT
      digitalWrite(motor_forw_back1,LOW);
      analogWrite(motor_forw_back2,pwm_value);
      
      digitalWrite(motor_left_right1,LOW);
      digitalWrite(motor_left_right2,HIGH);
      delay(pwm_steer_delay);
      analogWrite(motor_left_right2,pwm_steer);
      
      if (!front_lights) digitalWrite(front_lights_pin,HIGH);
      if (!back_lights) digitalWrite(back_lights_pin,LOW);
      
      Serial.print("Forward - Right @ ");Serial.print(pwm_percent);Serial.println("%");
    } 
    break;
    case 5:{// BACKWARD - LEFT
      digitalWrite(motor_forw_back2,LOW);
      analogWrite(motor_forw_back1,pwm_value);
      
      digitalWrite(motor_left_right2,LOW);
      digitalWrite(motor_left_right1,HIGH);
      delay(pwm_steer_delay);
      analogWrite(motor_left_right1,pwm_steer);
      
      if (!front_lights) digitalWrite(front_lights_pin,LOW);
      if (!back_lights) digitalWrite(back_lights_pin,HIGH);
      
      Serial.print("Backward - Left @ ");Serial.print(pwm_percent);Serial.println("%");
    } 
    break;
    case 8:{// BACKWARD - RIGHT
      digitalWrite(motor_forw_back2,LOW);
      analogWrite(motor_forw_back1,pwm_value);
      
      digitalWrite(motor_left_right1,LOW);
      digitalWrite(motor_left_right2,HIGH);
      delay(pwm_steer_delay);
      analogWrite(motor_left_right2,pwm_steer);
      
      if (!front_lights) digitalWrite(front_lights_pin,LOW);
      if (!back_lights) digitalWrite(back_lights_pin,HIGH);
      
      Serial.print("Backward - Right @ ");Serial.print(pwm_percent);Serial.println("%");
    } 
    break;
    case 3:{// STOP - LEFT
      digitalWrite(motor_forw_back1,HIGH);
      digitalWrite(motor_forw_back2,HIGH);
      
      digitalWrite(motor_left_right2,LOW);
      digitalWrite(motor_left_right1,HIGH);
      delay(pwm_steer_delay);
      analogWrite(motor_left_right1,pwm_steer);
      
      if (!front_lights) digitalWrite(front_lights_pin,LOW);
      if (!back_lights)digitalWrite(back_lights_pin,LOW);
      
      Serial.println("Stop - Left");
    } 
    break;
    case 6:{// STOP - RIGHT
      digitalWrite(motor_forw_back1,HIGH);
      digitalWrite(motor_forw_back2,HIGH);
      
      digitalWrite(motor_left_right1,LOW);
      digitalWrite(motor_left_right2,HIGH);
      delay(pwm_steer_delay);
      analogWrite(motor_left_right2,pwm_steer);
      
      if (!front_lights) digitalWrite(front_lights_pin,LOW);
      if (!back_lights) digitalWrite(back_lights_pin,LOW);
      
      Serial.println("Stop - Right");
    } 
    break;
    case 10:{// 1st gear set pwm to 50%
      pwm_percent=50;
      pwm_value=int((255*pwm_percent)/100);
    }
    break;
    case 20:{// 2st gear set pwm to 75%
      pwm_percent=75;
      pwm_value=int((255*pwm_percent)/100);
    }
    break;
    case 30:{// 3st gear set pwm to 100%
      pwm_percent=100;
      pwm_value=int((255*pwm_percent)/100);
    }
    break;
    case 66:{//check Battery Voltage and Send it & check remote control if in range
      echo_millis=millis();
      bat_Voltmeter();
    }
    break;
    case 77:{//Horn
      for (int thisNote = 0; thisNote < 12; thisNote++) {

       // to calculate the note duration, take one second 
       // divided by the note type.
       //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
       int noteDuration = 1000/noteDurations[thisNote];
       tone(buzzer, melody[thisNote],noteDuration);
  
       // to distinguish the notes, set a minimum time between them.
       // the note's duration + 30% seems to work well:
       int pauseBetweenNotes = noteDuration * 1.30;
       delay(pauseBetweenNotes);
       // stop the tone playing:
       noTone(buzzer);
      }
      echo_millis=millis();
    }
    break;
    case 88:{//Front Lights
      if (front_lights) {
        digitalWrite(front_lights_pin,LOW);
        front_lights=false;      
      } else {
        digitalWrite(front_lights_pin,HIGH);
        front_lights=true;
      }
    }
    
    break;
    case 99:{//Back Lights
      if (back_lights) {
        digitalWrite(back_lights_pin,LOW);
        back_lights=false;      
      } else {
        digitalWrite(back_lights_pin,HIGH);
        back_lights=true;
      }
    }
    break;
    case 254:{//Bluetooth disconnect
      digitalWrite(motor_forw_back1,HIGH);
      digitalWrite(motor_forw_back2,HIGH);
      
      digitalWrite(motor_left_right1,HIGH);
      digitalWrite(motor_left_right2,HIGH);
      
      digitalWrite(front_lights_pin,LOW);
      digitalWrite(back_lights_pin,LOW);
      
      Serial.println("Stop - Straight");
    }
    break;
   }
   
  }
  
  
 
}