////////////////////////////////////////////////////////////////////////////////
// Official name:     Bolderbot mini Serial Monitor Single run Test 01        //
// Hardware platform: Bolderbot Mini                                          //
// Pin connections:   Arduino Mega 2560                                       //
// Created:           March 2016                                              //
// Created by:        HARB                                                    //
// This program shows a PWM LED dimming while outputing the settings. When    //
// started up it will show the onboard LED burning and the tricolor LED will  //
// fade the red LED and show the Green and Blue LED in a fainted way. You can //
// alter the changing LED in Green or Blue by opening the Serial monitor and  //
// entering a gG or bB or rR. Also the IR remote TV control unit can be used  //
// to switch the light color. 1=red 2=Green 3=Blue. Next stwep is to integrate//
// the engines. 1=Red=Rest, 2=Green=GO, 3=Blue=Backwards. You can also enter  //
// the Serial monitor commands r, g or b. The speed encoders have also been   //
// implemented. You could use the EEPROM to remember the last settings.       //
////////////////////////////////////////////////////////////////////////////////
// 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  //
////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS                                                            //
// A14 = 83 = PK6 ADC14/PCINT22    =                                          //
// A15 = 82 = PK7 ADC15/PCINT23    =                                          //
// C00 =  2 = PE0 RXD0/PCINT8      = Serial monitor, also on-board LED    RX0 //
// C01 =  3 = PE1 TXD0             = Serial monitor, also on-board LED    TX0 //
// C18 = 46 = PD2 TXD1/INT3        =                                      TX1 //
// C19 = 45 = PD2 RXD1/INT2        = IR TV remote control receiver        RX1 //
// C20 = 44 = PD1 SDA/INT1         = Speed encoder Left                   TWI //
// C21 = 43 = PD0 SCL/INT0         = Speed encoder Right                  TWI //
// D13 = 26 = PB7 OCOA/OC1C/PCINT7 = On board user LED, on=high off=low       //
// D44 = 40 = PL5 OC5C/PWM         = 3 color led Blue                         //
// D45 = 39 = PL4 OC5B/PWM         = 3 color led Red                          //
// D46 = 38 = PL3 OC5A/PWM         = 3 color led Green                        //
// D50 = 22 = PB3 MISO/PCINT3      =                                      SPI //
// D51 = 21 = PB2 MOSI/PCINT2      =                                      SPI //
// D52 = 20 = PB1 SCK/PCINT1       =                                      SPI //
// D53 = 19 = PB1 SS/PCINT0        =                                      SPI //
////////////////////////////////////////////////////////////////////////////////

// SET PRECOMPILER OPTIONS *****************************************************

// Initialse conditional compiling, uncomment to include, comment to exclude ---
// #define RS232 1                 //Include RS232 sections to output debug info
//  #ifdef RS232       //Only include this part if the variable has been defined

// Define precompiler variables ------------------------------------------------
#define    LED               PB7         //Arduino boards contain an onboard LED
// #define F_CPU        16000000                //Speed of the connected crystal
// #define UART0_BAUD      57600                               //UART0 baud rate

///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 <AFMotor.h>    //Motors shield, Copyright Adafruit Industries LLC, 2009
#include <TimerOne.h>      //Currently needed for reading wheel speed per second

//DEFINE VARIABLES -------------------------------------------------------------
AF_DCMotor motorL(3);        //Connects the left engine to shield DC motorport 3
AF_DCMotor motorR(4);        //Connects the left engine to shield DC motorport 4
const int RECV_PIN = 19;       //Connection of the IR remote TV control receiver
//3 COLOR LED breakout, common ground,      connect these pins preferably to PWM
const int ledRed = 44;         //Define to which PWM pin this color is connected
const int ledGre = 45;         //Define to which PWM pin this color is connected
const int ledBlu = 46;         //Define to which PWM pin this color is connected
unsigned int cntrL = 0;                   //Define left wheel counter per second
unsigned int cntrR = 0;                   //Define left wheel counter per second
//END OF PRECOMPILER OPTIONS ---------------------------------------------------


void jtag_disable(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_led(void) { //Toggles the default on-board LED on or off ***********
  if bit_is_clear(PORTB, LED)                           //Test if the LED is off
    PORTB |= (1 << LED);                           //If LED=off then turn LED on
  else                                                 //Else the LED must be on
    PORTB &= ~(1 << LED);                                //Then turn the LED off
  //Or fe:     state = !state;
} //Exit toggle_led ------------------------------------------------------------

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 --------------------------------------------------------------

IRrecv irrecv(RECV_PIN); //Why not in setup, what is the difference?
decode_results results;


void setup() {
  Timer1.initialize(100000);    //This timer will create an interrupt after 1 s
  Timer1.attachInterrupt( timerIsr );                 //Start the 1 second timer

  attachInterrupt(2, docntrL, RISING);        //Increase left cntr on any change
  attachInterrupt(3, docntrR, FALLING);       //Increase right cntr on any change

  Serial.begin(9600);   //Nothing more needed for the Serial Monitor to function
  irrecv.enableIRIn();                                  // Start the IR receiver

  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

  DDRB |= (1 << LED);                            //Set onboard LED-pin as output
  PORTB |= (1 << LED);                               //Initally onboard LED = on

  motorL.run(RELEASE);                               //Disengages this DC engine
  motorR.run(RELEASE);                               //Disengages this DC engine
  motorL.setSpeed(255);                                //Turn on the left engine
  motorR.setSpeed(255);                               //Turn on the right engine


} //End of setup

int Red = 4;                //Brightness of this color, set by PWM 0=min 255=max
int Gre = 4;                //Brightness of this color, set by PWM 0=min 255=max
int Blu = 4;                //Brightness of this color, set by PWM 0=min 255=max
// jtag_disable();             //Disable jtag to free port C, enabled by default

int inByte = 0;                                       //For incoming serial data
int Color = 'R';                                 //The startup color to be faded

//interrupts();

void loop() {                                //KEEP ON RUNNING THIS LOOP FOREVER
  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

  if (Serial.available() > 0) {           //Send data only when you receive data
    inByte = Serial.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 == 66) {                                  //ASCII 66 = B for Blue
      Color = 'B';
    }
    if (inByte == 98) {                                  //ASCII 98 = b for Blue
      Color = 'B';
    }
    if (inByte == 82) {                                   //ASCII 82 = R for Red
      Color = 'R';
    }
    if (inByte == 114) {                                 //ASCII 114 = r for Red
      Color = 'R';
    }
    if (inByte == 71) {                                //ASCII 71 = G for Green
      Color = 'G';
    }
    if (inByte == 103) {                               //ASCII 103 = g for Green
      Color = 'G';
    }
    toggle_led();                   //Toggles the default on-board LED on or off
  }

  if (irrecv.decode(&results)) {
    if (results.value == 1025) {
      Color = 'R';
    }
    if (results.value == 66561) {
      Color = 'R';
    }
    if (results.value == 1345) {
      Color = 'R';
    }
    if (results.value == 3393) {
      Color = 'R';
    }


    if (results.value == 1026) {
      Color = 'G';
    }
    if (results.value == 66562) {
      Color = 'G';
    }
    if (results.value == 1346) {
      Color = 'G';
    }
    if (results.value == 3394) {
      Color = 'G';
    }


    if (results.value == 1027) {
      Color = 'B';
    }
    if (results.value == 66563) {
      Color = 'B';
    }
    if (results.value == 1347) {
      Color = 'B';
    }
    if (results.value == 3395) {
      Color = 'B';
    }
    Serial.println(results.value, DEC);    //Needed to decode the remote control
    irrecv.resume(); // Receive the next value
  }

  if (Color == 'R') {                                   //Fade the red led, REST
    motorR.run(RELEASE);                             //Disengages this DC engine
    motorL.run(RELEASE);                             //Disengages this DC engine
    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 1) {    //Fading Red
      analogWrite(ledRed, fadeValue);      //Sets the value, range from 0 to 255
      delay(5);                    //Wait milliseconds to see the dimming effect
    } //End for (int fadeValue = 0 ; fadeValue <= 255; etc     END OF fading Red
  } //End of  if (Color = 'R')


  if (Color == 'B') {                             //Fade the blue led, BACKWARDS
    motorR.run(BACKWARD);                //Engages this DC engine into backwards
    motorL.run(BACKWARD);                //Engages this DC engine into backwards
    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 1) {   //Fading blue
      analogWrite(ledBlu, fadeValue);      //Sets the value, range from 0 to 255
      delay(5);                    //Wait milliseconds to see the dimming effect
    } //End for (int fadeValue = 0 ; fadeValue <= 255; etc    END OF fading Blue
  } //End of  if (Color = 'B')


  if (Color == 'G') {                                   //Fade the green led, GO
    motorR.run(FORWARD);                   //Engages this DC engine into forward
    motorL.run(FORWARD);                   //Engages this DC engine into forward
    for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 1) {  //Fading green
      analogWrite(ledGre, fadeValue);      //Sets the value, range from 0 to 255
      delay(5);                    //Wait milliseconds to see the dimming effect
    } //End for (int fadeValue = 0 ; fadeValue <= 255; etc   END OF fading Green
  } //End of  if (Color = 'G')

} //End of void loop()                       //KEEP ON RUNNING THIS LOOP FOREVER
//345678911234567892123456789312345678941234567895123456789612345678971234567898