Control the moving direction of the 4-wheel smart car with photoresistor module
Introduction
Today we will teach you how to control the smart car to achieve five directions of steering with three photoresistors.
Components:
1x Adeept Remote Control Smart Car Kit
3x Photoresistor Module
18x Male to Female Jumper Wires
1x glue gun
1x blocks
Experimental circuit connection diagram:
Install the three photoresistor modules as shown in the picture below. The three modules should be installed at 90 degree.
Experimental code is as follow: AdeeptPhotoresistorMotor
/***********************************************************
File name: AdeeptMotor.ino
Description:
Website: www.adeept.com
E-mail: support@adeept.com
Author: Tom
Date: 2019/03/04
***********************************************************/
#include <Servo.h>
Servo dirServo; // define servo to control turning of smart car
int dirServoPin = 2; // define pin for signal line of the last servo
float dirServoOffset = 0; // define a variable for deviation(degree) of the servo
int dirServoDegree=90;
Servo ultrasonicServo; // define servo to control turning of ultrasonic sensor
int ultrasonicPin = 3; // define pin for signal line of the last servo
float ultrasonicServoOffset = 0; // define a variable for deviation(degree) of the servo
int ultrasonicServoDegree=90;
const int dirAPin = 7; // define pin used to control rotational direction of motor A
const int pwmAPin = 6; // define pin for PWM used to control rotational speed of motor A
const int dirBPin = 4; // define pin used to control rotational direction of motor B
const int pwmBPin = 5; // define pin for PWM used to control rotational speed of motor B
#define FORWARD HIGH
#define BACKWARD LOW
int photoresistor2Pin = 2; // photoresistor connected to analog pin 0
int photoresistor3Pin = 3; // photoresistor connected to analog pin 0
int photoresistor4Pin = 4; // photoresistor connected to analog pin 0
int dirDegree = 90;
void setup() {
dirServo.attach(dirServoPin); // attaches the servo on servoDirPin to the servo object
ultrasonicServo.attach(ultrasonicPin); // attaches the servo on ultrasonicPin to the servo object
pinMode(dirAPin, OUTPUT); // set dirAPin to output mode
pinMode(pwmAPin, OUTPUT); // set pwmAPin to output mode
pinMode(dirBPin, OUTPUT); // set dirBPin to output mode
pinMode(pwmBPin, OUTPUT); // set pwmBPin to output mode
pinMode(photoresistor2Pin, INPUT);//Set analog 0 port mode, the INPUT for the input
pinMode(photoresistor3Pin, INPUT);//Set analog 0 port mode, the INPUT for the input
pinMode(photoresistor4Pin, INPUT);//Set analog 0 port mode, the INPUT for the input
Serial.begin(9600); //opens serial port, sets data rate to 9600 bps
}
void loop()
{
// Serial.print(analogRead(2)); //send data to the serial monitor
// Serial.print(" "); //send data to the serial monitor
// Serial.print(analogRead(3)); //send data to the serial monitor
// Serial.print(" "); //send data to the serial monitor
// Serial.println(analogRead(4)); //send data to the serial monitor
delay(20); //delay 0.05 s
if((analogRead(2)>960)){
dirDegree = 180;
}
if((analogRead(2)>960)&&(analogRead(3)>960)){
dirDegree = 135;
}
if((analogRead(3)>960)&&(analogRead(2)<960)&&(analogRead(4)<960)){
dirDegree = 90;
}
if((analogRead(3)>960)&&(analogRead(4)>960)){
dirDegree = 45;
}
if((analogRead(4)>960)&&(analogRead(3)<960)){
dirDegree = 0;
}
if(dirDegree>ultrasonicServoDegree){ultrasonicServoDegree++;}
if(dirDegree<ultrasonicServoDegree){ultrasonicServoDegree--;}
int motorSpd = 200;
bool motorDir = motorSpd > 0 ? FORWARD : BACKWARD;
motorSpd = abs(constrain(motorSpd, -512, 512));
motorSpd = map(motorSpd, 0, 512, 0, 255);
// control the steering and travelling of the smart car
ctrlCar0(map(ultrasonicServoDegree, 0, 180, 30, 150),ultrasonicServoDegree, motorDir, motorSpd);
//ctrlCar1(dirServoDegree,motorDir, motorSpd);
}
void ctrlCar0(byte dirServoDegree,byte ultrasonicServoDegree, bool motorDir, byte motorSpd) {
dirServo.write(dirServoDegree + dirServoOffset);
ultrasonicServo.write(ultrasonicServoDegree + ultrasonicServoOffset);
// digitalWrite(dirAPin, motorDir);
// digitalWrite(dirBPin, motorDir);
// analogWrite(pwmAPin, motorSpd);
// analogWrite(pwmBPin, motorSpd);
}
void ctrlCar1(byte dirServoDegree, bool motorDir, byte motorSpd) {
dirServo.write(dirServoDegree + dirServoOffset);
digitalWrite(dirAPin, motorDir);
digitalWrite(dirBPin, motorDir);
analogWrite(pwmAPin, motorSpd);
analogWrite(pwmBPin, motorSpd);
}
Explanation for code:
- The control method of the motor and the servo of the code has been explained in the previous blog, you can click to review
First, let’s take a look at the port assignment settings of the photoresistor modules. The code is as follows:
int photoresistor2Pin = 2; // photoresistor connected to analog pin 0
int photoresistor3Pin = 3; // photoresistor connected to analog pin 0
int photoresistor4Pin = 4; // photoresistor connected to analog pin 0
Next, in the Arduino initialization function (setup()), configure the port of the photoresistor as the analog pin input function, the code is as follows:
pinMode(photoresistor2Pin, INPUT);//Set analog 0 port mode, the INPUT for the input
pinMode(photoresistor3Pin, INPUT);//Set analog 0 port mode, the INPUT for the input
pinMode(photoresistor4Pin, INPUT);//Set analog 0 port mode, the INPUT for the input
Finally, you can know the illumination information collected by the three photoresistor modules through reading the data of the analog pin. The three data “analogRead (2)”, “analogRead (3)” and “analogRead (4)” corresponds to three photoresistor modules. By judging these three data can generally determine the direction information of the light source.
if((analogRead(2)>960)){
dirDegree = 180;
}
if((analogRead(2)>960)&&(analogRead(3)>960)){
dirDegree = 135;
}
if((analogRead(3)>960)&&(analogRead(2)<960)&&(analogRead(4)<960)){
dirDegree = 90;
}
if((analogRead(3)>960)&&(analogRead(4)>960)){
dirDegree = 45;
}
if((analogRead(4)>960)&&(analogRead(3)<960)){
dirDegree = 0;
}
Five angle information relative to the photoresistor module: 0 degrees, 45 degrees, 90 degrees, 135 degrees and 180 degrees.
2. The data of “960” in the code is the data read through the serial port. The data collected by the photoresistor is different under different lighting conditions. The stronger the light, the larger the data will be.
At first, we failed in this experiment because the flashlight is similar to the indoor light. When we replace with the strong flashlight or lowered indoor light, we could complete the experiment. In this lesson, we only need to read the data of the photoresistor module under the bright conditions in the room through the serial port, and record the three data. Next, read the data of the three photoresistor modules illuminated by the flashlight. Then compare these three data. The three data under the indoor light are all fluctuating around “910”. When the flashlight illuminates these three modules, the data are above “990”, so we take a middle value as “960”.
The code to read the data of the serial port is as follow:
Serial.print(analogRead(2)); //send data to the serial monitor
Serial.print(" "); //send data to the serial monitor
Serial.print(analogRead(3)); //send data to the serial monitor
Serial.print(" "); //send data to the serial monitor
Serial.println(analogRead(4)); //send data to the serial monitor
3. In the process of controlling the car, we need to pay attention to the range of the rotation angle of the servo that controls the direction of the car. The 4-wheel smart car relies on the rotation of the front wheels to control the steering. However, the rotation range of the front wheels is limited by the structure of the car, generally is in the range of 30 to 150 degrees.
ctrlCar0(map(ultrasonicServoDegree, 0, 180, 30, 150),ultrasonicServoDegree, motorDir, motorSpd);
Conclusion:
We should notice the fluctuations in data and the effects of indoor light sources when using the photoresistors. Based on this experiment, we can further optimize the program algorithm and complete the robot with automatic tracking function.