////////////////////////////////////////////////////////////////////////////////
// Name:       BolderbotMiniParty                                             //
// Platform:   Arduino Mega 2560                                              //
// Created by: HARB rboek2@gmail.com september 2017 GPL copyrights            //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=16             //
// This program will drive the Bolderbot Mini.                                //
// Based on Simple Motor Shield sketch By arduino.cc user "Krodal" June 2012  //
////////////////////////////////////////////////////////////////////////////////

// SET PRECOMPILER OPTIONS *****************************************************
// Initialse conditional compiling, uncomment to include, comment to exclude ---
// Do comment for runtime versions
#define RS232                     //Uncomment to include Serial Monitor sections
//  #ifdef RS232     //Only include these lines if the variable has been defined

//Set appropriate IR remote control to be used ---------------------------------
//#define Keyes               //Choose IR Remote Control by uncommenting = Keyes
#define Provision         //Choose IR Remote Control by uncommenting = Provision

// Define PINS -----------------------------------------------------------------
#define RECV_PIN    2          //Connection of the IR remote TV control receiver
#define MOTOR2_PWM  3       //Arduino pins for the PWM signals for motor 2 right
#define buzPin      6   //To which DIO pin is the passiv buzzer KY-006 connected
#define MOTOR1_PWM 11        //Arduino pins for the PWM signals for motor 1 left
#define SpeedEncoL 18  //Interrupted input of speed encoder WYC H206, short wire
#define SpeedEncoR 19   //Interrupted input of speed encoder WYC H206, long wire
#define ledRed     44  //3 Colour LED, to which PWM pin this colour is connected
#define ledGre     46  //3 Colour LED, to which PWM pin this colour is connected
#define ledBlu     45  //3 Colour LED, to which PWM pin this colour is connected
#define bat0pin    A0        //Connected to H=1/3 divider = 9Vdc battery, yellow
#define bat1pin    A1           //Connected to H=1/2 divider = 6Vdc pack, orange

// Define the needed header files for the precompiler, no charge if not used ---
#include <IRremote.h>       //Do never use the default by the IDE but replace it
//#include <TimerOne.h>//Needed for reading wheel speed, library manager install
//#include <Wire.h>    //Needed for all TWI/IIC bricks like SRF10 or Gyro GY-521

// Define motor shield settings ------------------------------------------------
#define MOTORLATCH 12      //Arduino pins for the shift register of the enigines
#define MOTORCLK    4
#define MOTORENABLE 7
#define MOTORDATA   8

#define MOTOR1_A  3   //These are used to set the direction of the bridge driver
#define MOTOR1_B  2   //These pins are not Arduino pins, but pins on motorshield
#define MOTOR2_A  1          //Forward and backward settings can be changed here
#define MOTOR2_B  4                 //8-bit bus after the 74HC595 shift register

#define FORWARD  1                   //Translation table for the motor functions
#define BACKWARD 2
#define BRAKE    3
#define RELEASE  4

// Define user settings --------------------------------------------------------
byte alarmVdc0 = 75;            //Powerstate will be set to LOW by 9 Vdc battery
byte alarmVdc1 = 50;                 //Powerstate will be set to LOW by 6.0 pack


// Define variables ------------------------------------------------------------
//byte  twiAdr = 0xE1;     //This is the new TWI-address of the connected SRF 10
//byte  twiSR1 = 113;         //The default address in the datasheet is 224=0xE0
// We seem to must perform a ROR NC on the real address b4 the library reacts ok
                           // but i2c adressing uses the high 7 bits so it's 112
                                       //So 3 flashes means 0xE6 = 230 / 2 = 115
                         //This is a rather bad way to avoid ANDs for read/write
bool ledBinVal = LOW;         //You can chose HIGH-on or LOW-off for LED_BUILTIN
bool flagActive = false;                      //Has a TV remote key been pressed
bool brainMounted = false;               //Default say there is no brain mounted
bool powerState = HIGH;         //Assuming that the batteries are charged enough
word cntrL = 0;                           //Define left wheel counter per second
word cntrR = 0;                          //Define right wheel counter per second
byte Red = 100;             //Brightness of this Color, set by PWM 0=min 255=max
byte Gre = 0;               //Brightness of this Color, set by PWM 0=min 255=max
byte Blu = 0;               //Brightness of this Color, set by PWM 0=min 255=max
word distance = 0;                     //Distance sonar range finder in cm about
byte cmdEngines = 'D';       //The startup colour and the command to the engines
byte inByte = 0;                                      //For incoming serial data
long bat0Vdc = 0;          //Current voltage *10 of H=1/3 divider = 9Vdc battery
long bat1Vdc = 0;         //Current voltage *10 of the H=1/2 divider = 6Vdc pack


#ifdef Keyes                                           //IR Remote Control Keyes
const long butRP = 4294967295UL;     //Any button is continously pressed, REPEAT
const long butUp =   16736925UL;                 //Blue up arrow button, FORWARD
const long butDn =   16754775UL;                  //Blue down arrow button, BACK
const long butLf =   16720605UL;                  //Blue left arrow button, LEFT
const long butRt =   16761405UL;                //Blue right arrow button, RIGHT
const long butOk =   16712445UL;                      //Red OK button, DISENGAGE
const long butMp =   16728765UL;            //Red * (multiply) button, DISENGAGE
const long butNr =   16732845UL;              //Red # (number) button, DISENGAGE
const long but0  =   16730805UL;                 //White 0 button, run program 0
const long but1  =   16738455UL;                 //White 1 button, run program 1
const long but2  =   16750695UL;                 //White 2 button, run program 2
const long but3  =   16756815UL;                 //White 3 button, run program 3
const long but4  =   16724175UL;                 //White 4 button, run program 4
const long but5  =   16718055UL;                 //White 5 button, run program 5
const long but6  =   16743045UL;                 //White 6 button, run program 6
const long but7  =   16716015UL;                 //White 7 button, run program 7
const long but8  =   16726215UL;                 //White 8 button, run program 8
const long but9  =   16734885UL;                 //White 9 button, run program 9
#endif //End of #ifdef Keyes                             IR Remote Control Keyes


#ifdef Provision                                   //IR Remote Control Provision
const long butRP = 4294967295UL;     //Any button is continously pressed, REPEAT
const long butUp = 2645382921UL;                 //Blue up arrow button, FORWARD
const long butDn = 1510218204UL;                  //Blue down arrow button, BACK
const long butLf = 1044084000UL;                  //Blue left arrow button, LEFT
const long butRt =  341443957UL;                //Blue right arrow button, RIGHT
const long butOk = 2090285130UL;                     //Blue OK button, DISENGAGE
const long butMp = 4198925182UL;         //Black -/-- (double) button, DISENGAGE
const long butNr = 3255896299UL;                    //Black AV button, DISENGAGE
const long but0  = 4251643239UL;                 //Black 0 button, run program 0
const long but1  = 2005671744UL;                 //Black 1 button, run program 1
const long but2  = 3075690975UL;                 //Black 2 button, run program 2
const long but3  = 1079910150UL;                 //Black 3 button, run program 3
const long but4  =  771752011UL;                 //Black 4 button, run program 4
const long but5  =  613775946UL;                 //Black 5 button, run program 5
const long but6  =  305207297UL;                 //Black 6 button, run program 6
const long but7  = 3916687738UL;                 //Black 7 button, run program 7
const long but8  = 2229941719UL;                 //Black 8 button, run program 8
const long but9  = 2280455024UL;                 //Black 9 button, run program 9
#endif //End of #ifdef Provision                     IR Remote Control Provision

//END OF PRECOMPILER OPTIONS ---------------------------------------------------

IRrecv irrecv(RECV_PIN);                  //Initialise interrupt pin IR receiver
decode_results results;  //If something IR received, translate it into keynumber

void setup() { //Setup runs once ***********************************************
  disable_jtag();              //Disable jtag to free port C, enabled by default
  #ifdef RS232         //Only include this part if the variable has been defined
    Serial.begin(9600); //Nothing more needed for the Serial Monitor to function
  #endif //End of        Serial not compiled if precompiler variable was not set
  setBrainMounted();          //Set to true (green A8-14 not connected) or false
  if (brainMounted) {                     //Meaning the serial port is connected
    Serial3.begin(9600); //Nothing more needed for serial connection to function
  }
  //Wire.begin();                       //Start i2c bus, no address to be master
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard LED_BUILTIN
  pinMode(buzPin, OUTPUT);                                   //KY-006 buzzer pin
  pinMode(ledRed, OUTPUT);                //Make the LED connections output pins
  pinMode(ledGre, OUTPUT);                //Make the LED connections output pins
  pinMode(ledBlu, OUTPUT);                //Make the LED connections output pins
  pinMode(SpeedEncoL, INPUT_PULLUP);  //Interrupted input speed encoder WYC H206
  pinMode(SpeedEncoR, INPUT_PULLUP);  //Interrupted input speed encoder WYC H206
  analogReference(DEFAULT);                //Accurate enough for Battery Monitor
  irrecv.enableIRIn();                                  // Start the IR receiver
  //Timer1.initialize(100000);  //This timer will create an interrupt every 10 s
  //Timer1.attachInterrupt( timerIsr );                        //Start the timer
  //attachInterrupt(2, docntrL, RISING);      //Increase left cntr on any change
  //attachInterrupt(3, docntrR, FALLING);    //Increase right cntr on any change
  //toggle_ledBin();                                         //Show we are awake
  beep(50);         //Give 0-255 mSec an annoying beep with KY-012 active buzzer
}//--(end setup )---------------------------------------------------------------



void loop() { //KEEP ON RUNNING THIS LOOP FOREVER ******************************
  ledBinVal = digitalRead(SpeedEncoR);                           //Read WYC H206
  digitalWrite(LED_BUILTIN, ledBinVal);         //Set Arduino boards onboard LED
  /*
  checkPower6Vdc();   //Set battery powerState HIGH or LOW according to readings
  if (brainMounted) {                     //Meaning the serial port is connected
    //readSerial3Input();                  //Receive and proces data from Brains
  } //End of if (brainMounted)    Data has been exchanged if a brain was mounted
  #ifdef RS232         //Only include this part if the variable has been defined
    readSerialInput();     //Receives and processes data from the Serial Monitor
  #endif //End of        Serial not compiled if precompiler variable was not set
  readIRreceiver();                   //Receives data from the IR remote control
  writeActuators();         //Performs the robot actions according to the inputs
  delay(100);          //Needed for IR receiver Wait milliseconds, TIME TO SPARE
  #ifdef RS232         //Only include this part if the variable has been defined
    //show_testdata();               //Data for programmer at the Serial Monitor
  #endif //End of        Serial not compiled if precompiler variable was not set
  */
  //toggle_ledBin();                //Toggles the default on-board LED on or off
} //End of void loop()                       //KEEP ON RUNNING THIS LOOP FOREVER
//345678911234567892123456789312345678941234567895123456789612345678971234567898

void checkPower6Vdc() {  //Set battery powerState HIGH or LOW according readings
  bat0Vdc = analogRead(bat0pin);     //Read voltage H=1/3 divider = 9Vdc battery
  bat0Vdc =  bat0Vdc * 15 / 102;                          //Recalculate in a Vdc
  bat1Vdc = analogRead(bat1pin);          //Read value H=1/2 divider = 6Vdc pack
  bat1Vdc =  bat1Vdc * 10 / 102;                          //Recalculate in a Vdc
  if (bat0Vdc > 40) {                        //Meaning batteries are switched on
    if (bat0Vdc < alarmVdc0) {      //If the voltage drops below the alarm level
      powerState = LOW;    //Set that we need to recharge and that we will do so
      beep(200);                                                 //Beep annoying
    }                           //End of If the voltage is below the alarm level
    if (bat1Vdc < alarmVdc1) {      //If the voltage drops below the alarm level
      powerState = LOW;    //Set that we need to recharge and that we will do so
      beep(200);                                                 //Beep annoying
    }                           //End of If the voltage is below the alarm level
  }                                   //End of Meaning batteries are switched on
} //Exit checkPower, set powerState to HIGH or LOW according to readings DONE --

void show_testdata () { //Data for programmer at the Serial Monitor ************
  #ifdef RS232         //Only include this part if the variable has been defined
    if (bat0Vdc < 41) {                     //If True then power is switched off
      Serial.println("Robot power is switched off");            //Some user text
    }else{                                    //So the batteries are switched on
      Serial.print("Bat0=9Vdc=");                               //Some user text
      Serial.print(bat0Vdc, DEC);       //Possible translated in DEC HEX OCT BIN
      Serial.print(" Bat1=6Vdc= ");                             //Some user text
      Serial.print(bat1Vdc, DEC);       //Possible translated in DEC HEX OCT BIN
      Serial.print("  PowerState: ");                           //Some user text
      Serial.println(powerState, DEC);  //Possible translated in DEC HEX OCT BIN
    } //End of showing battery values
    //Serial.print("  Distance:");                                   //Show text
    //Serial.print(distance);                               // print the reading
    //Serial.println(" cm");                                // print the reading
  #endif //End of        Serial not compiled if precompiler variable was not set
} //Exit show_testdata Data for programmer at the Serial Monitor DONE ----------

void readIRreceiver(void) {           //Receives data from the IR remote control
  if (irrecv.decode(&results)) {  //If I did receive anything then lets check it
    switch (results.value) {        //So what value did I receive from TV remote
      case butRP:                 //Some button is being kept on pressed by user
        flagActive = true; //Engines will be released as soon as key is released
      break;                                    //Jump to the end of this switch
      
      case butUp:                               //User has pressed the button up
        cmdEngines = 'F';          //Set command for the motors to drive FORWARD
        flagActive = true; //Engines will be released as soon as key is released
      break;                                    //Jump to the end of this switch

      case butRt:                            //User has pressed the button right
        cmdEngines = 'R';             //Set command for the motors to turn RIGHT
        flagActive = true; //Engines will be released as soon as key is released
      break;                                    //Jump to the end of this switch

      case butLf:                             //User has pressed the button left
        cmdEngines = 'L';              //Set command for the motors to turn LEFT
       flagActive = true;  //Engines will be released as soon as key is released
      break;                                    //Jump to the end of this switch

      case butDn:                             //User has pressed the button down
        cmdEngines = 'B';          //Set command for the motors to turn BACKWARD
        flagActive = true; //Engines will be released as soon as key is released
      break;                                    //Jump to the end of this switch

      case butOk:                               //User has pressed the OK button
        cmdEngines = 'D';                             //Set command ro DISENGAGE
        flagActive = false;         //Engines will not be automatically released
      break;                                    //Jump to the end of this switch

      case but0:                                 //User has pressed the 0 button
        cmdEngines = '0';                                //Set command ro BREAK1
        flagActive = false;         //Engines will not be automatically released
      break;                                    //Jump to the end of this switch

      case but1:                                 //User has pressed the 1 button
        cmdEngines = '1';                              //Set command ro AUTORUN1
        flagActive = false;         //Engines will not be automatically released
      break;                                    //Jump to the end of this switch
    
      case butMp:            //User has pressed the Star / multiply button PANIC
        cmdEngines = 'P';                  //Set command for the motors to PANIC
        flagActive = false;         //Engines will not be automatically released
      break;                                    //Jump to the end of this switch
 
      default://If button case matched, then this default case will be performed
        cmdEngines = 'D';                  //Set command to the motors DISENGAGE
        break;                                  //Jump to the end of this switch
    } //End of switch (results.value) So what value did I receive from TV remote
    #ifdef RS232       //Only include this part if the variable has been defined
      Serial.println(results.value, DEC);   //Handy to decode the remote control
    #endif //End of      Serial not compiled if precompiler variable was not set
    irrecv.resume();                                   // Receive the next value
  } else {                   //Meaning no key at all is pressed at the TV remote
    if (flagActive == true) {    //Special situation if repeated key was pressed
      cmdEngines = 'D';         //Bring the engines to a halt by using DISENGAGE
      flagActive = false;      //Reset, so we know we already halted the engines
    } //End of (flagActive == true)Special situation if repeated key was pressed
  } //End of if (irrecv.decode(&results)     receive anything then lets check it
} //Exit of readIRreceiver              Receives data from the IR remote control


void beep(byte ms) { //Create a beep with KY-006 active buzzer *****************
  while (ms > 0){                            //Timer of the duration of the beep
    digitalWrite(buzPin, HIGH);                 //Push the speaker conus outward
    delay(2);                                    //Determins the fixed frequency
    digitalWrite(buzPin, LOW);                   //Pull the speaker conus inward
    delay(2);                                    //Determins the fixed frequency
    ms--;                                     //Countdown untill we reached zero
  }            //Timer of the duration of the beep has been counted down to zero
} //Exit beep ------------------------------------------------------------------


void setBrainMounted () { //Check connection and set brainMounted accordingly **
  pinMode(14, OUTPUT);  //Blue RS232 line to brains or to pin A8 to signal blond
  digitalWrite(14, HIGH);      //Pull up so we must receive a HIGH at digital A8
  brainMounted = !digitalRead(A8);     //But if A8 still LOW then we have brains
} //Exit setBrainMounted brainMounted = true or false DONE  --------------------


void motor(int nMotor, int command, int speed) { //Main command for engines ****
  int motorA, motorB;      //The commands are: FORWARD, BACKWARD, BRAKE, RELEASE
  if (nMotor >= 1 && nMotor <= 4) {      //Select the motor 1-4, see motorshield
    switch (nMotor) {               //Couple the desired engine to this software
      case 1:                                       //If engine = 1 = left motor
        motorA   = MOTOR1_A;
        motorB   = MOTOR1_B;
        break;
      case 2:
        motorA   = MOTOR2_A;
        motorB   = MOTOR2_B;
        break;
      default:
        break;
    }

    switch (command) {
      case FORWARD:
        motor_output (motorA, HIGH, speed);
        motor_output (motorB, LOW, -1);     // -1: no PWM set
        break;
      case BACKWARD:
        motor_output (motorA, LOW, speed);
        motor_output (motorB, HIGH, -1);    // -1: no PWM set
        break;
      case BRAKE:
        // The AdaFruit library didn't implement a brake.
        // The L293D motor driver ic doesn't have a good
        // brake anyway.
        // It uses transistors inside, and not mosfets.
        // Some use a software break, by using a short
        // reverse voltage.
        // This brake will try to brake, by enabling
        // the output and by pulling both outputs to ground.
        // But it isn't a good break.
        motor_output (motorA, LOW, 255); // 255: fully on.
        motor_output (motorB, LOW, -1);  // -1: no PWM set
        break;
      case RELEASE:
        motor_output (motorA, LOW, 0);  // 0: output floating.
        motor_output (motorB, LOW, -1); // -1: no PWM set
        break;
      default:
        break;
    }
  }
}


// ---------------------------------
// motor_output
//
// The function motor_ouput uses the motor driver to
// drive normal outputs like lights, relays, solenoids,
// DC motors (but not in reverse).
//
// It is also used as an internal helper function
// for the motor() function.
//
// The high_low variable should be set 'HIGH'
// to drive lights, etc.
// It can be set 'LOW', to switch it off,
// but also a 'speed' of 0 will switch it off.
//
// The 'speed' sets the PWM for 0...255, and is for
// both pins of the motor output.
//   For example, if motor 3 side 'A' is used to for a
//   dimmed light at 50% (speed is 128), also the
//   motor 3 side 'B' output will be dimmed for 50%.
// Set to 0 for completelty off (high impedance).
// Set to 255 for fully on.
// Special settings for the PWM speed:
//    Set to -1 for not setting the PWM at all.
//
void motor_output (int output, int high_low, int speed)
{
  int motorPWM;

  switch (output)
  {
    case MOTOR1_A:
    case MOTOR1_B:
      motorPWM = MOTOR1_PWM;
      break;
    case MOTOR2_A:
    case MOTOR2_B:
      motorPWM = MOTOR2_PWM;
      break;
    default:
      // Use speed as error flag, -3333 = invalid output.
      speed = -3333;
      break;
  }

  if (speed != -3333)
  {
    // Set the direction with the shift register
    // on the MotorShield, even if the speed = -1.
    // In that case the direction will be set, but
    // not the PWM.
    shiftWrite(output, high_low);

    // set PWM only if it is valid
    if (speed >= 0 && speed <= 255)
    {
      analogWrite(motorPWM, speed);
    }
  }
}


// ---------------------------------
// shiftWrite
//
// The parameters are just like digitalWrite().
//
// The output is the pin 0...7 (the pin behind
// the shift register).
// The second parameter is HIGH or LOW.
//
// There is no initialization function.
// Initialization is automatically done at the first
// time it is used.
//
void shiftWrite(int output, int high_low)
{
  static int latch_copy;
  static int shift_register_initialized = false;

  // Do the initialization on the fly,
  // at the first time it is used.
  if (!shift_register_initialized)
  {
    // Set pins for shift register to output
    pinMode(MOTORLATCH, OUTPUT);
    pinMode(MOTORENABLE, OUTPUT);
    pinMode(MOTORDATA, OUTPUT);
    pinMode(MOTORCLK, OUTPUT);

    // Set pins for shift register to default value (low);
    digitalWrite(MOTORDATA, LOW);
    digitalWrite(MOTORLATCH, LOW);
    digitalWrite(MOTORCLK, LOW);
    // Enable the shift register, set Enable pin Low.
    digitalWrite(MOTORENABLE, LOW);

    // start with all outputs (of the shift register) low
    latch_copy = 0;

    shift_register_initialized = true;
  }

  // The defines HIGH and LOW are 1 and 0.
  // So this is valid.
  bitWrite(latch_copy, output, high_low);

  // Use the default Arduino 'shiftOut()' function to
  // shift the bits with the MOTORCLK as clock pulse.
  // The 74HC595 shiftregister wants the MSB first.
  // After that, generate a latch pulse with MOTORLATCH.
  shiftOut(MOTORDATA, MOTORCLK, MSBFIRST, latch_copy);
  delayMicroseconds(5);    // For safety, not really needed.
  digitalWrite(MOTORLATCH, HIGH);
  delayMicroseconds(5);    // For safety, not really needed.
  digitalWrite(MOTORLATCH, LOW);
}

void readSerial3Input(void) {              //Receive and proces data from Brains
  Serial3.setTimeout(1000);
  if (Serial3.available() > 0) {          //Send data only when you receive data
    inByte = Serial3.read();                            //Read the incoming byte
    Serial.print("I received: ");                             //Say what you got
    Serial.println(inByte, DEC);        //Possible translated in DEC HEX OCT BIN
    if (inByte == 48) {                              //Halt ASCII 0 for Stop All
      cmdEngines = '0';
    }
    if (inByte == 97) {                    //ASCII 98 = a for Autorun, Red/Green
      cmdEngines = 'A';
    }
    if (inByte == 103) {                            //ASCII 82 = g for Go, Green
      cmdEngines = 'G';
    }
    if (inByte == 114) {                                 //ASCII 114 = r for Red
      cmdEngines = 'R';
    }
    if (inByte == 108) {                               //ASCII 108 = l for Lemon
      cmdEngines = 'L';
    }
    if (inByte == 98) {                                  //ASCII 98 = b for Blue
      cmdEngines = 'B';
    }
    //Serial3.print(cmdEngines);            //Tell the master what you are doing
    toggle_ledBin();            //Toggles the LED_BUILTIN on-board LED on or off
  }//End of  if (Serial.available() > 0)
} //Exit readSerial3Input    Receives and processes data from the Serial Monitor


void readSerialInput(void) {    //Receiv and proces data from the Serial Monitor
#ifdef RS232           //Only include this part if the variable has been defined
  if (Serial.available() > 0) {           //Send data only when you receive data
    inByte = Serial.read();                             //Read the incoming byte
    Serial.print("The keyboard just said: ");                 //Say what you got
    Serial.println(inByte, DEC);        //Possible translated in DEC HEX OCT BIN
    
    if (inByte == 100) {                           //d to disengage both engines
      cmdEngines = 'D';
    }
    if (inByte == 104) {                                //h to halt both engines
      cmdEngines = 'D';
    }
    if (inByte == 115) {                                //s to stop both engines
      cmdEngines = 'D';
    }
    if (inByte == 49) {                                         //1 for Autorun1
      cmdEngines = '1';
    }
    if (inByte == 102) {                                         //f for forward
      cmdEngines = 'F';
    }
    if (inByte == 114) {                                      //r for right turn
      cmdEngines = 'R';
    }
    if (inByte == 108) {                                       //l for left turn
      cmdEngines = 'L';
    }
    if (inByte == 98) {                                         //b for backward
      cmdEngines = 'B';
    }
    if (inByte == 32) {                                    //spacebar for break1
      cmdEngines = '0';
    }
    if (inByte == 112) {                                           //p for panic
      cmdEngines = 'P';
    }
    toggle_ledBin();            //Toggles the LED_BUILTIN on-board LED on or off
  }//End of  if (Serial.available() > 0
#endif //End of          Serial not compiled if precompiler variable was not set
} //End of SUBserialInput    Receives and processes data from the Serial Monitor


void writeActuators(void) { //Performs the robot actions according to the inputs
  switch (cmdEngines) {                          //Translate commands in actions
    case 'F' :                                         //Command F means FORWARD
      motor(1, FORWARD, 255);    //Engages Motornr 1=left engine, Command, Speed
      motor(2, FORWARD, 230);   //Engages Motornr 2=right engine, Command, Speed
      Red = 100;            //Brightness of this Color, set by PWM 0=min 255=max
      Gre = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Blu = 50;             //Brightness of this Color, set by PWM 0=min 255=max
      break;                                    //Jump to the end of this switch
    
    case 'R' :                                      //Command R means turn RIGHT
      motor(1, FORWARD, 255);    //Engages Motornr 1=left engine, Command, Speed
      motor(2, BACKWARD, 255);  //Engages Motornr 2=right engine, Command, Speed
      Red = 255;            //Brightness of this Color, set by PWM 0=min 255=max
      Gre = 64;             //Brightness of this Color, set by PWM 0=min 255=max
      Blu = 64;             //Brightness of this Color, set by PWM 0=min 255=max
      break;                                    //Jump to the end of this switch

    case 'L' :                                       //Command L means turn LEFT
      motor(1, BACKWARD, 255);   //Engages Motornr 1=left engine, Command, Speed
      motor(2, FORWARD, 255);   //Engages Motornr 2=right engine, Command, Speed
      Red = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Gre = 30;             //Brightness of this Color, set by PWM 0=min 255=max
      Blu = 20;             //Brightness of this Color, set by PWM 0=min 255=max
      break;                                    //Jump to the end of this switch

    case 'B' :                                        //Command B means BACKWARD
      motor(1, BACKWARD, 255);   //Engages Motornr 1=left engine, Command, Speed
      motor(2, BACKWARD, 255);  //Engages Motornr 2=right engine, Command, Speed
      Red = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Gre = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Blu = 50;             //Brightness of this Color, set by PWM 0=min 255=max
      break;                                    //Jump to the end of this switch

    case 'D' :                                       //Command D means DISENGAGE
      motor(1, RELEASE, 255);    //Engages Motornr 1=left engine, Command, Speed
      motor(2, RELEASE, 255);   //Engages Motornr 2=right engine, Command, Speed
      Red = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Gre = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Blu = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      break;                                    //Jump to the end of this switch

    case '0' :                                          //Command 0 means BREAK1
      motor(1, BRAKE, 255);      //Engages Motornr 1=left engine, Command, Speed
      motor(2, BRAKE, 255);     //Engages Motornr 2=right engine, Command, Speed
      Red = 255;            //Brightness of this Color, set by PWM 0=min 255=max
      Gre = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      Blu = 0;              //Brightness of this Color, set by PWM 0=min 255=max
      break;                                    //Jump to the end of this switch
      
    case '1' :                                        //Command 1 means AUTORUN1
      if (distance < 20) {              //Turn as long as you see a close object
        motor(1, BACKWARD, 255); //Engages Motornr 1=left engine, Command, Speed
        motor(2, BACKWARD, 100);//Engages Motornr 2=right engine, Command, Speed
        delay (150);
      } else {                              //Nothing in the way: drive straight
        motor(1, FORWARD, 255);  //Engages Motornr 1=left engine, Command, Speed
        motor(2, FORWARD, 220); //Engages Motornr 2=right engine, Command, Speed
      }
      if (Red == 100) {                                    //Toggle Red an Green
        Red =   0;          //Brightness of this Color, set by PWM 0=min 255=max
        Gre = 100;          //Brightness of this Color, set by PWM 0=min 255=max
        Blu =   0;          //Brightness of this Color, set by PWM 0=min 255=max
        beep(1);    //Give 0-255 mSec an annoying beep with KY-012 active buzzer
      } else {                                             //Toggle Red an Green
        Red = 100;          //Brightness of this Color, set by PWM 0=min 255=max
        Gre =   0;          //Brightness of this Color, set by PWM 0=min 255=max
        Blu =   0;          //Brightness of this Color, set by PWM 0=min 255=max
      }
      break;                                    //Jump to the end of this switch

    default:      //If no case matched, then this default case will be performed
      break;                                    //Jump to the end of this switch
  } //End of switch (cmdEngines) Translate commands in actions DONE ------------

 
  analogWrite(ledRed, Red);   //Set the brightness of this LED and illuminate it
  analogWrite(ledGre, Gre);   //Set the brightness of this LED and illuminate it
  analogWrite(ledBlu, Blu);   //Set the brightness of this LED and illuminate it
} //End of SUBsetActuators    Performs the robot actions according to the inputs


void disable_jtag(void) { //Disable jtag to free port C, enabled by default ****
#if defined(JTD)                           //Not all AVR controller include jtag
  MCUCR |= ( 1 << JTD );                                //Write twice to disable
  MCUCR |= ( 1 << JTD );                                       //So stutter once
#endif                                            //End of conditional compiling
} //Exit jtag_disable ----------------------------------------------------------


void toggle_ledBin(void) { //Toggles the LED_BUILTIN on-board LED on or off ****
  ledBinVal = !ledBinVal;                                         //Toggle value
  digitalWrite(LED_BUILTIN, ledBinVal);         //Set Arduino boards onboard LED
} //Exit toggle_ledBin ---------------------------------------------------------


void docntrR() { //Increases the right wheel speed sensor by 1 *****************
  cntrR++;                                       //Increase +1 the counter value
} //Exit docntR ----------------------------------------------------------------


void docntrL() { //Increases the left wheel speed sensor by 1 ******************
  cntrL++;                                       //Increase +1 the counter value
} //Exit docntL ----------------------------------------------------------------

void timerIsr() { //Timer has reached its maximum ******************************
  //Timer1.detachInterrupt();                                   //Stop the timer
  //Serial.print("Motor Speed R:");
  //Serial.print(cntrR, DEC);
  //Serial.print(" L:");
  //Serial.print(cntrL, DEC);
  //Serial.println(" pulses per 0.1 s");
  cntrR = 0;                                             //Reset counter to zero
  cntrL = 0;                                             //Reset counter to zero
  //Timer1.attachInterrupt( timerIsr );                 //Enable the timer again
} //Exit timerIsr --------------------------------------------------------------



////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO MEGA 2560                                    //
// Board  -Atmel- PIN - IDE - Function          - External Connection    FUNC //
//                                                                            //
// CONNECTIONS RAILS TOP LEFT: DIGITAL PWM<~> ******************************* //
//? SCL   -  28 - PC5 -19/A5- ADC5/SCL/PCINT13  -                         TWI //
//? SDA   -  27 - PC4 -18/A4- ADC4/SDA/PCINT12  -                         TWI //
// AREF   -  31 - REF -     - AREF              -                         REF //
// GND    -  32 - GND -     - GND               -                         GND //
// 13 PWM -  26 - PB7 -  13 - OC0A/OC1C/PCINT17 - LED Arduino LED_BUILTIN PWM //
// 12 PWM -  18 - PB6 -  12 - OC1B/PCINT16      - Motorshield             PWM //
// 11 PWM -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  - Motorshield             PWM //
// 10 PWM -  16 - PB2 -  10 - SS/OC1B/PCINT2    - Motorshield             PWM //
//  9 PWM -  15 - PB1 -   9 - OC1A/PCINT1       - Motorshield             PWM //
//  8 PWM -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  - Motorshield             DIO //
//                                                                            //
// CONNECTIONS RAILS TOP MIDDLE: DIGITAL PWM<~> ***************************** //
//  7 PWM -  13 - PD7 -   7 - PCINT23/AIN1      - Motorshield             PWM //
//  6 PWM -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 - Motorshield M4 => FREE  PWM //
//  5 PWM -  11 - PD5 -   5 - PCINT21/OC0B/T1   - Motorshield M3=> Buzzer PWM //
//  4 PWM -   6 - PD4 -   4 - PCINT20/XCK/T0    - Motorshield             PWM //
//  3 PWM -   5 - PD3 -   3 - PCINT19/OC2B/INT1 - Motorshield             PWM //
//  2 PWM -   4 - PD2 -   2 - PCINT18/INT0      - IR TV remote receiver   INT //
//  1 TX0 -   3 - PD1 -   1 - PCINT17/TXD       - Serial monitor          TX0 //
//  0 RX0 -   2 - PD0 -   0 - PCINT16/RCD       - Serial Monitor          RC0 //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 14 TX3 -  13 - PD7 -   7 - PCINT23/AIN1      -                         DIO //
// 15 RX3 -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 -                         PWM //
// 16 TX2 -  11 - PD5 -   5 - PCINT21/OC0B/T1   - Brains RX1 Yellow       TX2 //
// 17 RX2 -   6 - PD4 -   4 - PCINT20/XCK/T0    - Brains TX1 Blue         RX2 //
// 18 TX1 -   5 - PD3 -   3 - PCINT19/OC2B/INT1 - Speed encoder Right     INT //
// 19 RX1 -   4 - PD2 -   2 - PCINT18/INT0      - Speed encoder Left      INT //
// 20 SDA -   3 - PD1 -   1 - PCINT17/TXD       - SDA Yellow SRF10        SDA //
// 21 SCL -   2 - PD0 -   0 - PCINT16/RCD       - SCL White  SRF10        SCL //
//                                                                            //
// CONNECTIONS RAILS BOTTOM LEFT: POWER ************************************* //
// 5V    -   7 - VCC -     - VCC               -                          VCC //
// RES   -   1 - RES -     - PCINT14/RESET     -                          RES //
// 3.3V  -     -     -     -                   -                              //
// 5V    -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// Vin   -     -     -     -                   -                              //
//                                                                            //
// CONNECTIONS RAILS BOTTOM CENTER: ANALOG IN ******************************* //
// A0    -  23 - PC0 -A0/14- ADC0/PCINT8       -                          ADC //
// A1    -  24 - PC1 -A1/15- ADC1/PCINT9       -                          ADC //
// A2    -  25 - PC2 -A2/16- ADC2/PCINT10      -                          ADC //
// A3    -  26 - PC3 -A3/17- ADC3/PCINT12      -                          ADC //
// A4    -  27 - PC4 -A4/18- ADC4/SDA/PCINT12  -                          TWI //
// A5    -  28 - PC5 -A5/19- ADC5/SCL/PCINT13  -                          TWI //
//                                                                            //
// CONNECTIONS RAILS BOTTOM RIGHT: ANALOG IN ******************************** //
// A11   -  89 - PK0 -     - ADC1 4/PCINT?     -                          ADC //
// A12 = 88 = PK1 ADC15/PCINT?     =                                      ADC //
// A13 = 87 = PK2 ADC14/PCINT?     = IR line follow OUT1                  ADC //
// A15 = 86 = PK3 ADC15/PCINT?     = IR line follow OUT2                  ADC //
// A12 = 85 = PK4 ADC14/PCINT?     = IR line follow OUT3                  ADC //
// A13 = 84 = PK5 ADC15/PCINT?     = IR line follow OUT4                  ADC //
// A14 = 83 = PK6 ADC14/PCINT22    = Battery monitor H=1/2 6Vdc pack      ADC //
// A15 = 82 = PK7 ADC15/PCINT23    = Battery monitor H=1/3 9Vdc battery   ADC //
//                                                                            //
// CONNECTIONS RAILS QUER RIGHT ********************************************* //
// 44  = 40 = PL5 OC5C             = 3 Color led Blue                     PWM //
// 45  = 39 = PL4 OC5B             = 3 Color led Red                      PWM //
// 46  = 38 = PL3 OC5A             = 3 Color led Green                    PWM //
// 50  = 22 = PB3 MISO/PCINT3      =                                      SPI //
// 51  = 21 = PB2 MOSI/PCINT2      =                                      SPI //
// 52  = 20 = PB1 SCK/PCINT1       =                                      SPI //
// 53  = 19 = PB1 SS/PCINT0        =                                      SPI //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898
////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered by using the STK500)                          //
// On-Chip Debug Enabled: off                            (OCDEN=0)            //
// JTAG Interface Enabled: off                           (JTAGEN=0)           //
// Preserve EEPROM mem through the Chip Erase cycle: On  (EESAVE = 0)         //
// Boot Flash section = 2048 words, Boot startaddr=$3800 (BOOTSZ=00)          //
// Boot Reset vector Enabled, default address=$0000      (BOOTSTR=0)          //
// CKOPT fuse (operation dependent of CKSEL fuses        (CKOPT=0)            //
// Brown-out detection level at VCC=2,7V;                (BODLEVEL=1)         //
// Ext. Cr/Res High Freq.; Start-up time: 16K CK + 64 ms (CKSEL=1111 SUT=11)  //
// LOCKBITS (are dangerous to change, since they cannot be reset)             //
// Mode 1: No memory lock features enabled                                    //
// Application Protect Mode 1: No lock on SPM and LPM in Application Section  //
// Boot Loader Protect Mode 1: No lock on SPM and LPM in Boot Loader Section  //
////////////////////////////////////////////////////////////////////////////////