I also did a redesign of the variable speed and it is so much better. I still need to add smoothing to the ping sensors. I think it will help more. These things will hopefully happen on Tuesday this week.
----------------------------------------
On Wednesday, I finished the lego car and uploaded the code, which is posted below. It was moderatly okay, after I fixed many issues with speed and power. But it was not good enough so I had to ponder the power issues I was having. The main problem was that variable speed equation ran the power from 0 to 255 as from the arduino outputs. This however also meant that the voltage to the motor was from 0 to 12 volts. And so, it did not work so well.
After pondering the issue for a while, I realized that I needed to set my equation so that the voltage would be between about 10 and 12 volts. That might translate into 200 to 255 on the arduino. I have not done this yet but will put it into the next round.
The other issue was that I was spinning my gear ratio from the motor to the wheels was a 1:1. This is not how electric motors are meant to work. They need high spinning speeds to low spinning wheels. So I also put this mechanical change into the next model.
The final issue was that when having a rear wheel turning, the back end actually pushes out to one side or the other which, when close to a side wall, was enough to steer the back end into the wall. You will see this in the video.
This is a video of the first Lego Car. It drives with only the input from two Ping Sensors pointing right and left and one IR Sensor pointing front.
This is the new design of the Lego Car. It has the same sensors but is now front wheel drive. The front wheels can still turn 360 degrees as in the previous model.
-------------------------
This code is updated and better then previous versions.
Note:: You need to have the NewPing.h library which is avail from the Arduino Libraries.
// for the IR Sensor
int IRpin = 0; // analog pin for reading the IR sensor
float volts = 0; // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
float forward_distance = 0; // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk
// for both ping sensors
#include <NewPing.h>
#define trig_right 8 // Arduino pin tied to trigger pin on ping sensor.
#define echo_right 9 // Arduino pin tied to echo pin on ping sensor.
#define max_distance_right 200 // Maximum distanceance we want to ping for (in centimeters). Maximum sensor distanceance is rated at 400-500cm.
NewPing sonar_right(trig_right, echo_right, max_distance_right); // NewPing setup of pins and maximum distanceance.
unsigned int pingSpeed_right = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer_right = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
int cm_right = 50;
#define trig_left 12 // Arduino pin tied to trigger pin on ping sensor.
#define echo_left 13 // Arduino pin tied to echo pin on ping sensor.
#define max_distance_left 200 // Maximum distanceance we want to ping for (in centimeters). Maximum sensor distanceance is rated at 400-500cm.
NewPing sonar_left(trig_left, echo_left, max_distance_left); // NewPing setup of pins and maximum distanceance.
unsigned int pingSpeed_left = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer_left = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
int cm_left = 50;
// for the stearing servo
#include <Servo.h>
Servo myservo;
int center = 75; //the center position for the servo is 90 degrees
// for the dirve
int motor = 11; //When doing analog, you must use int and not define.
int motor_speed = 0;
void IR_1(){
volts = analogRead(IRpin)*0.0048828125; // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
forward_distance = 65*pow(volts, -1.10); // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk
if(forward_distance <= 30) //this is the domain of the sensor, 30 to 140 cm.
forward_distance = 30;
if(forward_distance >= 140)
forward_distance = 140;
motor_speed = 155*forward_distance/110-30*155/110+150; //this is the equation for variable motor speed.
if(forward_distance == 30){ // this 155 corrisponds to 30 cm. I want the motor turned off!
motor_speed = 0;
}
// motor_speed = (255/110)*(forward_distance-30); //this is used for when there is an LED Test Light in Place
Serial.print(forward_distance); // print the distance
Serial.print("cm Forward Distance ");
Serial.print(motor_speed);
Serial.println("mph domain is 155 to 255");
}
void Ping_Right(){
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distanceance pings.
if (millis() >= pingTimer_right) { // pingSpeed_1 milliseconds since last ping, do another ping.
pingTimer_right += pingSpeed_right; // Set the next ping time.
cm_right = sonar_right.ping_cm(); // Send out the ping, get the results in centimeters.
if(cm_right <= 15) //this is the domain of the sensor. 15 to 60 cm.
cm_right = 15;
if(cm_right >= 60)
cm_right = 60;
Serial.print(cm_right); // Print the result (0 = outside the set distanceance range, no ping echo)
Serial.println(" cm Ping Sensor RIGHT");
delay(10);
}
}
void Ping_Left(){
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distanceance pings.
if (millis() >= pingTimer_left) { // pingSpeed_1 milliseconds since last ping, do another ping.
pingTimer_left += pingSpeed_left; // Set the next ping time.
cm_left = sonar_left.ping_cm(); // Send out the ping, get the results in centimeters.
if(cm_left <= 15) //this is the domain of the sensor. 15 to 60 cm.
cm_left = 15;
if(cm_left >= 60)
cm_left = 60;
Serial.print(cm_left); // Print the result (0 = outside the set distanceance range, no ping echo)
Serial.println(" cm Ping Sensor LEFT");
}
}
void setup() {
Serial.begin(9600); // start the serial port
myservo.attach(7);
myservo.write(center);
}
void loop() {
IR_1();
while (forward_distance >= 70 && forward_distance <= 140){ //Variable speed, No Turns
analogWrite(motor, motor_speed);
myservo.write(center);
IR_1();
Serial.println("---#1 Variable speed, No Turns");
}
while (forward_distance >= 50 && forward_distance < 70){ //Variable speed, Little Turns
analogWrite(motor, motor_speed);
Ping_Right();
Ping_Left();
if (cm_right > cm_left){
myservo.write(center - 25);
Serial.println("---#3 Turn a Little Left");
}
else {
myservo.write(center + 25);
Serial.println("---#4 Turn a Little Right");
}
IR_1();
}
while (forward_distance >= 30 && forward_distance < 50){ //Variable speed, big Turns
analogWrite(motor, motor_speed);
Ping_Right();
Ping_Left();
if (cm_right > cm_left){
myservo.write(center - 45);
Serial.println("---#6 Turn a lot Left");
}
else {
myservo.write(center + 45);
Serial.println("---#7 Turn a lot Right");
}
IR_1();
}
}
No comments:
Post a Comment