Getting started with Arduino X CodeRover.
1 - Controlling the motors on the CodeRover Core.
There are two motors on the CodeRover Core that you can control using Arduino. They are connected to Pin 5 & 4 for Motor 1 and Pin 6 & 7 for Motor 2.
void setup()
{
//put your setup code here to run once:
pinMode(4,OUTPUT); pinMode(5,OUTPUT); // motor 1
pinMode(6,OUTPUT); pinMode(7,OUTPUT); // motor 2
}
With two motors, we can use different combinations to control CodeRover. Here are four functions that will move CodeRover move forward, move backward, spin right, spin left, and stop.
void forward(){
digitalWrite(4,LOW);
analogWrite(5,0xFF);
digitalWrite(7,LOW);
analogWrite(6,0xFF);
}
void backward(){
digitalWrite(4,HIGH);
analogWrite(5,0x00);
digitalWrite(7,HIGH);
analogWrite(6,0x00);
}
void turnLeft(){
digitalWrite(4,LOW);
analogWrite(5,0xFF);
digitalWrite(7,HIGH);
analogWrite(6,0x00);
}
void turnRight(){
digitalWrite(4,HIGH);
analogWrite(5,0x00);
digitalWrite(7,LOW);
analogWrite(6,0xFF);
}
void stop(){
digitalWrite(4,LOW);
analogWrite(5,LOW);
digitalWrite(7,LOW);
analogWrite(6,LOW);
}
Put your code here to see how each function works.
void loop(){
//put your main code here to runn repeatedly;
forward();
}
2 - Control CodeRover with delay();
Here is a very useful function that will pause the program for the amount of time in milliseconds that you can specify as input.
With this function, you can use the five functions mentioned above to program CodeRover's movements'
void loop(){
//put your main code here to runn repeatedly;
forward();
delay(2000);
turnRight();
delay(1000);
}
Once you put the above code in a loop and run it, CodeRover will move forward for 2 seconds, and then spin to the right for 1 second and repeat forever.
3 - Working with RGB LED
There are three RGB LEDs on the bottom of the CodeRover Core that you can program and It is fairly easy to control the color of RGB LEDs. RGB LEDs are controlled with 3 pins, each controlling one color of the RGB LEDs.
int Red=9;
int Green=10;
int Blue=11;
void setup(){
pinMode(Red,OUTPUT); //Red
pinMode(Green,OUTPUT); //Green
pinMode(Blue,OUTPUT); //Blue
}
We created this RGBControl function so you can test out how different values of RGB changes RGB led's color. Each input ranges from 0 to 255.
void RGBControl(int r,int g,int b){
analogWrite(Red,r);
analogWrite(Green,g);
analogWrite(Blue,b);
}
Test different combinations of values or use the chart below to display different colors.
void loop(){
//put your main code here to runn repeatedly;
RGBControl(0,255,0); // Shows green light
}
4 - Servo motor control
On the Arduino Uno Shield, there are 3 connectors, that you can use to control servo motors. For the purpose of this tutorial, take out an SG90 or MG90s Servo Motor and connect the yellow pin to Pin-12 and make sure the brown pin is connected to GND.
To control the servo with Arduino Uno, you will need to use Arduino's Servo library.
#include <Servo.h>
Then name your Servo variable SG90_one;
Servo SG90_one;
In the setup function, attach the servo to pin-12.
void setup() {
SG90_one.attach(12);
}
In the loop function, control servo movement with an integer to represent degrees.
void loop() {
int degree;
// put your main code here to run repeatedly:
SG90_one.write(degree);
}
Read more about the servo library here.
5 - PWM motor control
There are many different ways to control the speed of DC motors, another very simple and easy way to control the motor's speed and direction is to use the Pulse Width Modulation method.
In this example code, you will also see how we can use hall sensors on the CodeRover Core to keep track of two motor rotations. By counting how many times each motor rotates, we can adjust each motor's speed to make sure CodeRover drives in a relatively straight line.
int Motor1PWM=5;
int Motro1Ctl=4;
int Motor2PWM=6;
int Motor2Ctl=7;
int Hall1=0;
int Hall2=1;
volatile long HallCount1=0;
volatile long HallCount2=0;
long err; //straight detection
void setup() {
//put your setup code here to run once:
pinMode(Motor11,OUTPUT); pinMode(Motor12,OUTPUT); // motor 1
pinMode(Motor21,OUTPUT); pinMode(Motor22,OUTPUT); // motor 2
attachInterrupt(Hall1, EncoderA, FALLING); //Hall Sensor1
attachInterrupt(Hall2, EncoderB, FALLING); //Hall Sensor2
}
There is a 4 pole magnetic encoder on the back of each motor, each spinning right next to a hall sensor. When the hall sensor detects a change in the presence and the magnitude of the magnetic field, the EncoderA, and EncoderB functions will be called to keep track of how many times the encoder has turned.
void EncoderA() {
count1++;
}
void EncoderB(){
count2++;
}
Similar to the previous code that controls motors. We have forward, backward, turnRight, turnLeft, and stop functions with PWM controls.
int turnLeft(int angle, int speed)
{
count1=0;
while(1)
{
analogWrite(Motor1PWM,speed);
digitalWrite(Motor1Ctl,LOW);
analogWrite(Motor2PWM,255-speed);
digitalWrite(Motor2Ctl,HIGH);
if(count1>angle*1.36)break;
}
stay();
delay(1000);
}
int turnRight(int angle, int speed)
{
count2=0;
while(1)
{
analogWrite(Motor1PWM,speed);
digitalWrite(Motor1Ctl,LOW);
analogWrite(Motor2PWM,255-speed);
digitalWrite(Motor2Ctl,HIGH);
if(count2>angle*1.36)break;
}
stay();
delay(1000);
}
int forward(int dis, int speed)
{
count1=0;
count2=0;
while(1)
{
err=(count2-count1)*0.5;
digitalWrite(Motor1Ctl,LOW);
digitalWrite(Motor2Ctl,LOW);
analogWrite(Motor1PWM,speed+err);
analogWrite(Motor2PWM,speed-err);
if(count2>dis*15)break;
}
stay();
delay(1000);
}
int backward(int dis, int speed)
{
count1=0;
count2=0;
while(1)
{
err=(count1-count2)*0.5;
digitalWrite(Motor1Ctl,HIGH);
digitalWrite(Motor2Ctl,HIGH);
analogWrite(Motor1PWM,255-speed+err);
analogWrite(Motor2PWM,255-speed-err);
if(count2>dis*15)break;
}
stop();
delay(1000);
}
void stop()
{
analogWrite(Motor1PWM,255);
digitalWrite(Motor1Ctl,HIGH);
analogWrite(Motor2PWM,255);
digitalWrite(Motor2Ctl,HIGH);
}
You can try plugins 0-255 for speed, angle, and distance variables to see how each function works. You can also test with your CodeRover to find the correct relationship between encoder count and turning angle.
void loop(){
//put your main code here to runn repeatedly;
advance(55, 55);
}
6 - Line tracing robot
In this example code, you will learn how to make a line tracing CodeRover SUMO. We will be using 2 IR sensors to trace along a black line on a white surface. IR sensor will send a HIGH or LOW signal when it detects a white surface or a black surface.
Just like previous codes, we need to set up pins for motors and IR sensors.
int motor1PWM=5;
int motro1Ctl=4;
int motor2PWM=6;
int motor2Ctl=7;
int track1=8;
int track2=9;
void setup() {
// put your setup code here, to run once:
//motor1
pinMode(motor1PWM,OUTPUT); pinMode(motro1Ctl,OUTPUT);
//motor2
pinMode(motor2PWM,OUTPUT); pinMode(motro2Ctl,OUTPUT);
//IR sensors
pinMode(track1, INPUT);
pinMode(track2, INPUT);
}
Although the robot is driving alone in a line, it is actually performing a very simple task. If the right IR sensor detects a black line, the robot turns right. If the left IR sensor detects a black line, the robot turns left. Therefore we only need two functions to control CodeRover SUMO's left-turn and right-turn movements.
void turnLeft(int speed){
analogWrite(motor1PWM,speed);
digitalWrite(motor1Ctl,LOW);
analogWrite(motor2PWM,255-speed);
digitalWrite(motor2Ctl,HIGH);
}
void turnRight(int speed){
analogWrite(motor1PWM,255-speed);
digitalWrite(motor1Ctl,HIGH);
analogWrite(motor2PWM,speed);
digitalWrite(motor2Ctl,LOW);
}
In the main loop, compare the two IR sensor values to determine which IR sensor is closer to the black line. If neither is detecting a black line, then we can tell the robot to go straight.
void loop() {
// put your main code here, to run repeatedly:
int T1,T2;
T1=digitalRead(track1);
T2=digitalRead(track2);
if(T1>T2){
turnRight(55);
}
else if(T1<T2){
turnLeft(55);
}
else{
analogWrite(motor1PWM,0);
digitalWrite(motor1Ctl,HIGH);
analogWrite(motor2PWM,0);
digitalWrite(motor2Ctl,HIGH);
}
}
This is the simplest way to perform line tracing. Now that you understand how a robot follows a line, there is more interesting stuff you can read online tracing and PID algorithms here, here, and here.
7 - Color detection module
If you pledged CodeRover OFF-ROAD, a GY-33 Color detection module comes with your pledge! Here is a sample code showing you how to use it.
In this sample code, the Color detection module will detect color and display RGB color values on the serial monitor. Before running this code, make sure to download the Adafruit_TCS34725 library. You can also find a detailed tutorial on this module here.
#include <Wire.h>
#include "Adafruit_TCS34725.h"
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("Color View Test!");
if (tcs.begin())
{
Serial.println("Found sensor");
delay(200);
}
else
{
Serial.println("No TCS34725 found ... check your connections");
while (1); // halt!
}
}
void color(){
// uint16_t r, g, b, c, colorTemp, lux;
uint16_t ir;
uint16_t r, g, b, c;
uint16_t r_comp, g_comp, b_comp, c_comp;
float red, green, blue;
float rg,rb;
int i=0;
tcs.setInterrupt(false); // turn on LED
for(i=0;i<2;i++)
{
delay(60); // takes 60ms to read
tcs.getRawData(&r, &g, &b, &c);
ir = (r + g + b > c) ? (r + g + b - c) / 2 : 0;
r_comp = r - ir;
g_comp = g - ir;
b_comp = b - ir;
c_comp = c - ir;
}
Serial.print("C:\t"); Serial.print(c_comp);
Serial.print("\tR:\t"); Serial.print(r_comp);
Serial.print("\tG:\t"); Serial.print(g_comp);
Serial.print("\tB:\t"); Serial.print(b_comp);
Serial.println();
}
void loop() {
color();
}
This is a pretty standard tutorial, maybe later we can work on a sample code that will make CodeRover drive according to different colors.
8 - Light sensor module
Light sensors come with a CodeRover OFF-ROAD reward. Connect your light sensor to pin A6 on the Arduino Uno Shield to run this example code.
void setup() {
// put your setup code here, to run once:
pinMode(A6,INPUT);
}
Now in the loop, we will read the value from the specified A6 digital pin. Depending on the light sensor state, the integer light variable will be either 1, HIGH, or 0, LOW.
void loop() {
int light;
// put your main code here, to run repeatedly:
light = analogRead(A6);
Serial.println(light);
}
Finally, open the serial monitor, you should be able to see light value changes between 0 and 1 when you move the light sensor away or closer to a light source.
9 - Ultrasonic sensor module
Ultrasonic sensor, aka distance sensor, has a simple working principle. This module emits a high-frequency sound at 40kHz. If there is an obstacle or object, the sound will bounce back to the sensor. Using the (travel time * speed of sound) we will be able to calculate the distance the sound traveled. The Trig pin is used to send the sound and the Echo pin is used to receive reflected sound.
int trigPin = 2; // Trigger
int echoPin = 3; // Echolong duration, cm, inches
float duration;
double cm, inches;
void setup() {
//Serial Port begin
Serial.begin (9600);//Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
//before triggering a HIGH pulse, send a short LOW pulse,
//to make sure every HIGH pulse is clean.
digitalWrite(trigPin,LOW);
delayMicroseconds(5);
// trigger a 10 microseconds HIGH pulse.
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//echo pin receives sound
//duration is the time between sending a HIGH pulse and
//echo received by sensor.
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
// Convert the time into a distance
cm = (duration/2) / 29.1;
inches = (duration/2) / 74;
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
//delay 250 miliseconds before running this loop again.
delay(250);
}
10 - Avoid obstacles using an ultrasonic sensor
In this sample code, we are building a robot that will avoid obstacles using an ultrasonic sensor. For the purpose of this sample code, we created a very simple logic:
1. Robot will drive forward when there is nothing in front.
2. Robot will turn to the left and then drive forward if an obstacle is detected.
int trigPin = 2; // Trigger
int echoPin = 3; // Echolong duration, cm, inches
float duration; // duration
void setup() {
//Serial Port begin
Serial.begin (9600);//Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void distance(){
digitalWrite(trigPin,LOW);
delayMicroseconds(5);
// trigger a 10 microseconds HIGH pulse.
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//echo pin receives sound
//duration is the time between sending a HIGH pulse and
//echo received by sensor.
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
// Convert the time into a distance
cm = (duration/2) / 29.1;
inches = (duration/2) / 74;
}
Just like before, we are using an ultrasonic sensor to check the distance between the robot and the obstacle. The following codes are used to control the robot's movement.
int motor1PWM=5;
int motro1Ctl=4;
int motor2PWM=6;
int motor2Ctl=7;
int hall1=0;
int hall2=1;
volatile long hallCount1=0;
volatile long hallCount2=0;
long err; //straight detection
float duration;
double cm, inches;
void setup() {
//put your setup code here to run once:
pinMode(motor11,OUTPUT); pinMode(motor12,OUTPUT); // motor 1
pinMode(motor21,OUTPUT); pinMode(motor22,OUTPUT); // motor 2
//Hall Sensor1
attachInterrupt(Hall1, EncoderA, FALLING);
//Hall Sensor2
attachInterrupt(Hall2, EncoderB, FALLING);
}
void EncoderA() {
count1++;
}
void EncoderB(){
count2++;
}
int turnLeft(int angle, int speed)
{
count1=0;
while(1)
{
analogWrite(motor1PWM,speed);
digitalWrite(motor1Ctl,LOW);
analogWrite(motor2PWM,255-speed);
digitalWrite(motor2Ctl,HIGH);
if(count1>angle*1.36)break;
}
stay();
delay(1000);
}
int turnRight(int angle, int speed)
{
count2=0;
while(1)
{
analogWrite(motor1PWM,speed);
digitalWrite(motor1Ctl,LOW);
analogWrite(motor2PWM,255-speed);
digitalWrite(motor2Ctl,HIGH);
if(count2>angle*1.36)break;
}
stay();
delay(1000);
}
void forward(){
digitalWrite(motor1Ctl,LOW);
analogWrite(motor1PWM,0xFF);
digitalWrite(motor2Ctl,LOW);
analogWrite(motor2PWM,0xFF);
}
void stop()
{
analogWrite(motor1PWM,255);
digitalWrite(motor1Ctl,HIGH);
analogWrite(motor2PWM,255);
digitalWrite(motor2Ctl,HIGH);
}
Now in the main loop. The logic is:
Every 250 milliseconds
Check distance
if the distance is smaller than a certain amount turn left
else drive forward.
void loop() {
distance();
if(cm<5){
turnLeft(90,55);
}
else{
forward();
}
//delay 250 miliseconds before running this loop again.
delay(250);
}
Commentaires