#include <LiquidCrystal.h>
#include <LedControl.h>
#include <Servo.h>
#include <IRremote.h>
// *******REMARK**********
/*
Cause of the weird orientation of the dot matrix
moving right looks like its moving down
moving left looks like its moving up
moving up looks like its moving right
moving down looks like its moving left
Basically the "top" of the matrix is where the wires are
*/
// <<<<<< MATRIX QUIRKS >>>>>>>>>>>
/*
coordinates set up in (x,y)
top right is (0,0)
bottom left is (7,7)
increasing in the x value goes left
increasing on the y value goes down
.setLed(device, x,y, true or false)
*/
// <<<<<<< IR REMOTE QUIRKS >>>>>>>>
/*
using the black buttons as directional
"up": plus button is -50135296
"down": minus button is 1738080000
"left": previous button is 534839040
"right": next button is 1871773440
power button: 1570963200
*/
/*
Arduino Pin LCD Pin
12 RS
11 E
10 D4
9 D5
8 D6
7 D7
*/
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
/* ****NEW REMARKS****
WhHEEL MOTORS (bottom two servo)
The two servos at the bottom are two represent the wheel motors
The actual motors only have a V+ and GND ports
I connected the V+ on the wheel servo digital 52 and digital 50
to serve as the power supply. Ignore the SIG port as the real
motors will not have them (Give simple commands in testing to see
if they work)
right motor: V+ pin 52. SIG pin 6
left motor: V+ pin 50. SIG pin 5
ULTRASONIC SENSOR
Use like previous lab
TRIG pin 49
ECHO pin 47
PHOTORESISTOR (slide potentiometer on the left)
There is no photoresistor like the one we have so I used this in
its place. the actual thing will also only have V+ and GND
Photoresistor: SIG pin 2
LED LIGHTS
Set pin to HIGH if light is low and LOW if light is high
Right LED:pin 45
Left LED: pin 43
TEMPERATURE SENSOR (Potentiometer on the right)
again, the wokwi does not have this so I used a potentiometer
in its place
Temp sensor: SIG pin 13
HATCH SERVO (Servo on the far right)
Opens and close the hatch related to temp sensor
Use as normal (open to 90 and close to 0)
Hatch Servo: SIG pin 4
STEERING SERVO (Servo at the top)
Use for the steering left and right
Steering Servo: SIG pin 3
The rest is the same as lab 3
Only analog stick was removed
*/
// ---------------- MATRIX IMAGES --------------
// moon
const uint8_t moon[][8] = {
{
0b00111100,
0b01111110,
0b11110000,
0b11100000,
0b11100000,
0b11110000,
0b01111110,
0b00111100
}};
const int moon_len = sizeof(moon)/8;
const uint8_t sun[][8] = {
{
0b00111100,
0b01111110,
0b11110000,
0b11100000,
0b11100000,
0b11110000,
0b01111110,
0b00111100
}};
const int sun_len = sizeof(sun)/8;
// --------- IR Remote -----------
const int REMOTE_PIN = 51;
const long int leftCheck = 534839040;
const long int rightCheck= 1871773440;
const long int powerCheck = 1570963200;
long int userInput;
/*
Arduino Pin Matrix Pin
16 DIN
15 CS
14 CLK
*/
const int DIN = 16;
const int CS = 15;
const int CLK = 14;
const int device = 0;
LedControl matrix = LedControl(DIN, CLK, CS, 1);
// Ultra Sonic Sensor Pins
const int trigPin = 49;
const int echoPin = 47;
const int threshold = 10;
// DC motors for Wheels (controlled by ultra sonic)
const int rightWheelMotorPin = 52;
const int leftWheelMotorPin = 50;
// Headlights and Photoresistor
const int photoPin = 2;
const int leftLEDPin = 45;
const int rightLEDPin = 43;
boolean isDark = false;
// Servo Pins and setup
Servo steeringServo;
const int steeringServoPin = 3;
// Hatch and Temp Sensor
const int tempSensorPin = 13;
Servo hatchServo;
const int hatchServoPin = 4;
boolean isCold = false;
void setup() {
// Matrix startup code
// 0 refers to the first unit aka the one we are using
matrix.shutdown(device,false);
matrix.setIntensity(device,8);
matrix.clearDisplay(device);
// IR Remote startup code
IrReceiver.begin(REMOTE_PIN);
// lcd startup code
lcd.begin(16,2);
lcd.print("Smart Car");
delay(1500); //1500 ms => 1.5 second
lcd.clear();
lcd.setCursor(0,0);
// Ultra Sonic setup code
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Wheels and Steering Servo
pinMode(rightWheelMotorPin, OUTPUT);
pinMode(leftWheelMotorPin, OUTPUT);
steeringServo.attach(steeringServoPin);
// Headlights and Photoresistor
pinMode(photoPin, INPUT);
pinMode(leftLEDPin, OUTPUT);
pinMode(rightLEDPin, OUTPUT);
// Temp sensor and Hatch Servo
pinMode(tempSensorPin, INPUT);
hatchServo.attach(hatchServoPin);
Serial.begin(9600);
}
int i = 0;
void loop(){
//Below is the code for the photo resistor that controls the headlights
int lightLevel = analogRead(photoPin);
int mappedLightLevel = map(lightLevel, 0, 1023, 0, 255);
if(mappedLightLevel < 100){
digitalWrite(leftLEDPin, HIGH);
digitalWrite(rightLEDPin, HIGH);
isDark = true;
}
else if(mappedLightLevel >= 100){
digitalWrite(leftLEDPin, LOW);
digitalWrite(rightLEDPin, LOW);
isDark = false;
}
// this line will take the reading convert it to celsius from 0 to 30 degrees
int celsius = map( ((analogRead(tempSensorPin) - 20) * 3.04), 0, 1023, 0, 30 );
// if the current temperature is less than 15 degrees C, then close hatch
if(celsius < 15){
hatchServo.write(0);
isCold = true;
}
else if(celsius >= 15){
hatchServo.write(90);
isCold = false;
}
// run if it's dark and cold
if(isDark && isCold){
displayImage(moon[i]);
if(++i >= moon_len){
i = 0;
}
}
// run if its not dark and if its not cold
else if(!isDark && !isCold){
displayImage(sun[i]);
if(++i >= sun_len){
i = 0;
}
}
send_pulse();
// Car's direction code (Ultrasensor and Wheel motors)
long int duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;
if(distance <= threshold){
stop_car();
}
else if(distance > threshold){
start_car();
}
lcd.setCursor(0,0);
lcd.print("Distance: ");
if(distance < 10){
lcd.print(distance);
lcd.print("cm ");
}
else if(10 <= distance && distance <= 99){
lcd.print(distance);
lcd.print("cm ");
}
else{ // for when distance >= 100
lcd.print(distance);
lcd.print("cm");
}
// Code that Runs when user presses a button on the remote (Steering)
if(IrReceiver.decode() == true){
userInput = IrReceiver.decodedIRData.decodedRawData;
IrReceiver.resume();
if(userInput == rightCheck){
Serial.println("Turning right");
steeringServo.write(0);
}
if(userInput == leftCheck){
Serial.println("turning left");
steeringServo.write(180);
}
if(userInput == powerCheck){
stop_car();
}
}
//delay(333); // this delay is needed for images to print correctly
}
// ------------ User Defined Functions ---------------
void displayImage(const byte* image){
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
matrix.setLed(0,i,j, bitRead(image[i], 7-j));
}
}
}
void send_pulse(){
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
}
void stop_car(){
analogWrite(leftWheelMotorPin, 0);
analogWrite(rightWheelMotorPin, 0);
}
void start_car(){
analogWrite(leftWheelMotorPin, 255);
analogWrite(rightWheelMotorPin, 255);
}