////////////////////////////////////////////////////////////////////////////////
// Name:       KY-023                                                         //
//             Arduino joystick, connections is North, switches 3 relays      //
// Platform:   Arduino Mega 2560                                              //
// Created by: HARB, September 2016, GPL copyrights                           //
// http://robotigs.com/robotigs/includes/parts_header.php?idpart=192          //
// Problem are the waiting times between changes                              //
////////////////////////////////////////////////////////////////////////////////

// SET PRECOMPILER OPTIONS *****************************************************
// Define precompiler settings and variables------------------------------------
// Define PINS -----------------------------------------------------------------
const int JoyStick_X = A14;                                   //X West-East axis
const int JoyStick_Y = A15;                                                  //Y
const int JoyStick_Z = 22;                                              //Switch
const int pinLeRun  = 4;        //Pin 4 to single relay motor LEFT On/Off, white
const int pinLeDire = 5;    //Pin 5 to relay motor LEFT Forward/Backward, yellow
const int pinLeGear = 6; //Pin 6 to double relay LEFT motor Low/High gear, green

//Declare variables ------------------------------------------------------------
bool ledBinVal   = LOW;          //LED_BUILTIN, you can chose HIGH=on or LOW=off
int x, y, z;                    //Joystick current readings. Z should be boolean
String motorTarget = "FFFF";     //Direction Joystick=Slow Fast+Forward Backward
bool relLeRunNow = 0;      //LEFT wheel single relay On/Off current value, Off=0
bool relLeDireNow = 1;   //LEFT wheel dual relay Forw/Backw value now, Forward=1
bool relLeGearNow = 1;  //LEFT wheel dual relay Slow/Fast GEAR value now, Slow=1
bool LeRunSet  = 0;             //LEFT wheel On/Off value to bet set asap, Off=0
bool LeDireSet = 1;     //LEFT wheel Forward/Backward value to be set, Forward=1
bool LeGearSet = 1;          //LEFT wheel Slow/Fast GEAR value to be set, Slow=1
byte tmp1 = 0;                                            //Used in calculations
byte tmp2 = 0;                                            //Used in calculations
///Define the needed header files for the precompiler, no charge if not used ---
//END OF PRECOMPILER OPTIONS ---------------------------------------------------


void setup() { //Setup runs once ***********************************************
  Serial.begin(9600);   //Nothing more needed for the Serial Monitor to function
  pinMode(LED_BUILTIN, OUTPUT);          //Arduino boards contain an onboard LED
  
  digitalWrite(pinLeRun, LeRunSet);      //Default OFF=0 pin 4 for On/Off, white
  digitalWrite(pinLeDire, LeDireSet); //FORWARD=1 pin 5 Forward/Backward, yellow
  digitalWrite(pinLeGear, LeGearSet);    //SLOW=1 pin 6 for Low/High gear, green
  
  pinMode(pinLeRun, OUTPUT);               //Pin 4 to single relay On/Off, white
  pinMode(pinLeDire, OUTPUT);   //Pin 5 to double relay Forward/Backward, yellow
  pinMode(pinLeGear, OUTPUT);       //Pin 6 to double relay Low/High gear, green

  pinMode (JoyStick_X, INPUT);    //Reads a value between 0 - 1023. Center = 511
  pinMode (JoyStick_Y, INPUT);    //Reads a value between 0 - 1023. Center = 511
  pinMode (JoyStick_Z, INPUT_PULLUP);        //Reads push 1=NotPressed 0=Pressed

  Serial.println("Relay motor driver controller");                 //Hello world
}//--(end setup )---------------------------------------------------------------


void loop() { //KEEP ON RUNNING THIS LOOP FOREVER ******************************
  readJoystick();             //Read the user joystick input settings x, y and z
  calcMotorsTarget();     //Translate joystick into Slow Fast + Forward Backward
  calcMotorsSet();                  //What should the engines actually be set to
  runMotors();                    //Set engines according to above aquiered data
  showPropulsion();   //Show the relay settings and joystick data at serial port
  delay (100);
} //End of void loop()                       //KEEP ON RUNNING THIS LOOP FOREVER

void calcMotorsSet(void) { //What should the engines actually be set to do *****
  tmp1 = motorTarget.charAt(0);  //Extract the first character of the LEFT motor
  if (tmp1 == 48) {                    //48==0 Meaning entire left engine is off
    LeRunSet = 0;                               //LEFT wheel On/Off value, Off=0
    LeDireSet = 1;            //LEFT wheel Forw/Backw DIRECTION value, Forward=1
    LeGearSet = 1;                     //LEFT wheel Slow/Fast GEAR value, Slow=1
   }else{                      //Meaning motor must be running, so it must be ON
     LeRunSet = 1;                              //LEFT wheel On/Off value, Off=0   
     if (tmp1 == 70) {                             //Set GEAR, 70 means F = Fast 
       LeGearSet = 0;           //LEFT wheel Slow/Fast GEAR value, Slow=1 Fast=0
     }else{                                                  //83 means S = Slow
       LeGearSet = 1;           //LEFT wheel Slow/Fast GEAR value, Slow=1 Fast=0 
     }                  //End of if (tmp1 == 70) Setting gear, 70 means F = Fast
     tmp2 = motorTarget.charAt(1);    //Extract the second character of the left
     if (tmp2 == 70) {                     //Set DIRECTION, 70 means F = Forward
       LeDireSet = 1;       //FORWARD left wheel direction, Forward=1 Backward=0
     }else{                                                  //83 means S = Slow
       LeDireSet = 0;      //BACKWARD left wheel direction, Forward=1 Backward=0
     }                  //End of if (tmp1 == 70) Setting gear, 70 means F = Fast
   } //End of if (tmp1 == 0)                  Setting relays left engine is done
} //Exit calcMotorsSet ---------------------------------------------------------


void calcMotorsTarget(void) { //Translate joystick into Slow-Fast + Forw-Backw *
  if (y < 253){                              //Meaning the joystick points North
    if (x > 755) {                      //Meaning the joystick points North-West
      motorTarget = "SFFF";  //LEFT wheel Slow Forward, RIGHT wheel Fast Forward
    }else{                              //Points to the North but not North-West
      motorTarget = "FFFF";  //LEFT wheel Fast Forward, RIGHT wheel Fast Forward
    } //End of if (x > 755)               Meaning the joystick points North-West
  } //End of  if (y < 253)                     Meaning the joystick points North

  if (y > 252 && y < 756){    //Meaning the joystick centers in North-South axis
    if (x > 755) {                     //Meaning the joystick points Center-West
      motorTarget = "SBSF"; //LEFT WHEEL Slow Backward, RIGHT wheel Slow Forward, turn left on the spot !!!!!!!!!!!!!!!!!!!!!!!!!!!bREAK PAUSE
    }else{                                           //All North but Center-West
      motorTarget = "0000";      //LEFT WHEEL 00, RIGHT wheel 00 LEFT WHEEL halt
    } //End of if (x > 755)               Meaning the joystick points North-East
  }
  
  if (y > 755){                              //Meaning the joystick points South
    if (x > 755) {                      //Meaning the joystick points South-West
      motorTarget = "SBSF";                           //LEFT WHEEL slow backward
    }else{                                            //All South but South-West
      motorTarget = "FBSF";                           //LEFT WHEEL fast backward
    } //End of if (x > 755)               Meaning the joystick points South-West
  }
} //Exit calcMotorsTarget,translate Direction and Gear given by Joystick -------


void runMotors(void) {  //Set relays according to above aquiered data **********
  digitalWrite(pinLeRun, LeRunSet);       //Default OFF=0 pin 4 for relay On/Off
  digitalWrite(pinLeDire, LeDireSet); //Def FORWARD=1 pin 5 for Forward/Backward
  digitalWrite(pinLeGear, LeGearSet);  //Default SLOW=1 pin 6 for Slow/Fast gear
  relLeRunNow = LeRunSet;                       //LEFT wheel On/Off value, Off=0
  relLeDireNow = LeDireSet;             //LEFT wheel Forw/Backw value, Forward=1
  relLeGearNow = LeGearSet;            //LEFT wheel Slow/Fast GEAR value, Slow=1
  LeRunSet  = 0;                     //LEFT wheel Security reset On/Off to Off=0
} //Exit runMotors -------------------------------------------------------------

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

void readJoystick(void) { //Read the user joystick input x, y and z ************
  y = analogRead (JoyStick_X);    //Reads a value between 0 - 1023. Center = 511
  x = analogRead (JoyStick_Y);    //Reads a value between 0 - 1023. Center = 511
  z = digitalRead (JoyStick_Z);              //Reads push 1=NotPressed 0=Pressed
} //Exit readJoystick ----------------------------------------------------------

void showPropulsion(void) { //Show the relay- and joystick data at serial port *
  Serial.print (x, DEC);
  Serial.print (",");
  Serial.print (y, DEC);
  Serial.print (",");
  Serial.print (z, DEC);
  Serial.print (",");
  Serial.print (motorTarget);
  Serial.print (",");
  Serial.println (tmp1);
} //Exit showPropulsion, show the relay- and joystick data at serial port ------

////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO UNO                                          //
// Board -Atmel- PIN - IDE - Function          - Connection               ALT //
//                                                                            //
// 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  -  21 - REF -     - AREF              -                              //
// GND   -  22 - GND -     - GND               -                              //
// 13    -  19 - PB5 -  13 - SCK/PCINT5        - Arduino LED_BUILTIN LED  SPI //
// 12    -  18 - PB4 -  12 - MISO/PCINT4       -                          SPI //
// ~11   -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  -                          PWM //
// ~10   -  16 - PB2 -  10 - SS/OC1B/PCINT2    -                          PWM //
// ~9    -  15 - PB1 -   9 - OC1A/PCINT1       -                          PWM //
// 8     -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  -                          DIO //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 7     -  13 - PD7 -   7 - PCINT23/AIN1      -                          DIO //
// ~6    -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 -                          PWM //
// ~5    -  11 - PD5 -   5 - PCINT21/OC0B/T1   -                          PWM //
// ~4    -   6 - PD4 -   4 - PCINT20/XCK/T0    -                          PWM //
// ~3    -   5 - PD3 -   3 - PCINT19/OC2B/INT1 -                          INT //
// ~2    -   4 - PD2 -   2 - PCINT18/INT0      -                          INT //
// TX->1 -   3 - PD1 -   1 - PCINT17/TXD       - Serial monitor           TXD //
// RX<-0 -   2 - PD0 -   0 - PCINT16/RCD       - Serial Monitor           RCD //
//                                                                            //
// CONNECTIONS RAILS BOTTOM LEFT: POWER ************************************* //
// 5V    -   7 - VCC -      - VCC              - Output to breadboard     VCC //
// RES   -   1 - RES -      - PCINT14/RESET    -                          RES //
// 3.3V  -     -     -     -                   -                              //
// 5V    -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// Vin   -     -     -     -                   -                              //
//                                                                            //
// CONNECTIONS RAILS BOTTOM RIGHT: 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  - Input divider H=1/4      TWI //
////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898