
/*************************************
 *     TIME:2022.1.29
 *     Development Team: Zhiyi Technology Co., Ltd.
 *     INFRARED REMOTE CONTROL
 * 
 **************************************/
#include <IRremote.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_8x16matrix matrix = Adafruit_8x16matrix();

//------- IR REMOTE CODES ---------//
#define FORWARD 16712445  //
#define BACK 16750695     //
#define LEFT 16769055     //
#define RIGHT 16748655    //
#define STOP 16754775     //
#define Buzzer 16756815   //

#define RECV_PIN 2  //IR

#define MOTOAR1 6  //Right front wheel
#define MOTOAR2 7

#define MOTOBL1 9  //Left front wheel
#define MOTOBL2 8

int sound = 3;

static const uint8_t PROGMEM
  smile_bmp[] = { B00111100,
                  B01000010,
                  B10100101,
                  B10000001,
                  B10100101,
                  B10011001,
                  B01000010,
                  B00111100 },

  frown_bmp[] = { B00111100,
                  B01000010,
                  B10100101,
                  B10000001,
                  B10011001,
                  B10100101,
                  B01000010,
                  B00111100 };


//LED indicator definition
#define LEFT_LED 17   //左LED
#define RIGHT_LED 10  //右LED

IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long val;
unsigned long preMillis;

void forward() {
  digitalWrite(MOTOAR1, LOW);   
  digitalWrite(MOTOAR2, HIGH);  

  digitalWrite(MOTOBL1, LOW);   
  digitalWrite(MOTOBL2, HIGH);  

  digitalWrite(LEFT_LED, LOW);
  digitalWrite(RIGHT_LED, LOW);

  Serial.println("Forward");  //Sends a message to the serial monitor

  matrix.clear();
  matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);  //The left dot matrix shows a smile
  matrix.drawBitmap(0, 8, smile_bmp, 8, 8, LED_ON);  //The dot bar on the right shows a smile
  matrix.writeDisplay();
  delay(100);
}

void back() {
  digitalWrite(MOTOAR1, HIGH);
  digitalWrite(MOTOAR2, LOW);

  digitalWrite(MOTOBL1, HIGH);
  digitalWrite(MOTOBL2, LOW);

  digitalWrite(LEFT_LED, HIGH);
  digitalWrite(RIGHT_LED, HIGH);
  Serial.println("Back");

  matrix.clear();
  matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_ON);  //The dot matrix on the left shows frowning
  matrix.drawBitmap(0, 8, frown_bmp, 8, 8, LED_ON);  //The dot matrix on the right shows frowning
  matrix.writeDisplay();
  delay(100);
}

void left() {
  digitalWrite(MOTOAR1, LOW);
  digitalWrite(MOTOAR2, HIGH);

  digitalWrite(MOTOBL1, HIGH);
  digitalWrite(MOTOBL2, LOW);

  digitalWrite(LEFT_LED, HIGH);
  digitalWrite(RIGHT_LED, LOW);

  Serial.println("Left");
}

void right() {

  digitalWrite(MOTOAR1, HIGH);
  digitalWrite(MOTOAR2, LOW);

  digitalWrite(MOTOBL1, LOW);
  digitalWrite(MOTOBL2, HIGH);
  digitalWrite(LEFT_LED, LOW);
  digitalWrite(RIGHT_LED, HIGH);

  Serial.println("Right");
}

void stop() {
  digitalWrite(MOTOAR1, LOW);  
  digitalWrite(MOTOAR2, LOW);  

  digitalWrite(MOTOBL1, LOW);  
  digitalWrite(MOTOBL2, LOW);  

  digitalWrite(LEFT_LED, LOW);
  digitalWrite(RIGHT_LED, LOW);
  Serial.println("Stop");
}


/************BLINKSOUND****/
void blinks() {
  for (int i = 0; i < 5; i++) 
  {
    digitalWrite(sound, HIGH);
    digitalWrite(sound, LOW);
    Serial.println("Blink!");
  }
  delay(1000);
}
//////////////////////////////////
void setup() {
  Serial.begin(115200);
  pinMode(MOTOAR1, OUTPUT);  //before useing io pin, pin mode must be set first
  pinMode(MOTOAR2, OUTPUT);
  pinMode(MOTOBL1, OUTPUT);
  pinMode(MOTOBL2, OUTPUT);
  pinMode(LEFT_LED, OUTPUT);
  pinMode(RIGHT_LED, OUTPUT);

  pinMode(LEFT_LED, OUTPUT);
  pinMode(RIGHT_LED, OUTPUT);
  pinMode(sound, OUTPUT);
  matrix.begin(0x70);  // pass in the address
  Serial.begin(9600);
  stop();
  irrecv.enableIRIn();
}
////////////////////////////////

void loop() {
  if (irrecv.decode(&results)) {
    preMillis = millis();
    val = results.value;
    Serial.println(val);
    irrecv.resume();
    switch (val) {
      case FORWARD: forward(); break;
      case BACK: back(); break;
      case LEFT: left(); break;
      case RIGHT: right(); break;
      case STOP: stop(); break;
      case Buzzer: blinks(); break;
      default: break;
    }
  } else {
    if (millis() - preMillis > 500) {
      stop();
      preMillis = millis();
    }
  }
}

