Society of Robots - Robot Forum
Electronics => Electronics => Topic started by: jlowe64 on October 17, 2010, 12:38:37 PM
-
Hi,
I started to build the WalBot QT from here: http://www.societyofrobots.com/member_tutorials/node/45 (http://www.societyofrobots.com/member_tutorials/node/45)
I thought I could just save some cash and use my Ultrasonic Ping Sensor from Parallax, but it doesn't work. I know the wires are a little different on the circuit board for the other sensor, but I am wiring it up like is states in the Parallax info sheet.
I noticed the other ultrasonic sensor uses one wire for sending signal and one for receiving information, however the Ultrasonic Ping Sensor uses one I/O wire for that.
I have everything working sorta, but the ping sensor isn't able to send its information to the arduino and therefore the robot just goes forward all the time.
Could I get some help? I hope this makes some sort of sense. Thanks in advance.
Jerrett
-
The Parallax Ping))) uses a different mechanism entirely:
Try this:
#define pingPin // define it
long duration, inches, cm;
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = duration / 74 / 2;
cm = microseconds / 29 / 2;
-
I feel like an idiot.. but I tried to integrate that code.. I understand what it does on its basic level without integrating it into this other code.. but once I try to integrate it throws a lot of errors. :-/
Here's the original code:
/*This is a program by Brandon Sweeney to control the autonomous robot Walbot, it implements the
LV MAX EZ1 sonar rangefinder and outputs the voltage signal sent from the rangefinder and its
conversion in inches. This data is then used to control the actions of Walbot.
This material is free, just give me credit for using it*/
int Motor1A = 10; // H-Bridge input 1
int Motor1B = 11; // H-Bridge input 2
int enable = 3; // H-Bridge motor 1 enable
int Motor2A = 9; // H-Bridge input 3
int Motor2B = 8; // H-Bridge input 4
int enable2 = 5; // H-Bridge motor 2 enable
int ultraAn = 0; // select the input pin for the ultrasonic sensor
int UltraEnable = 12; // sets enable to pin 12
int ledPin = 13; // sets the indicator led to pin 13
float val[10]; // array to store first 10 values coming from the sensor
float valSum=0; // sum of first 10 readings
float valAvg=0; // average of the first 10 readings
float dist = 0; // variable to store the converted distance in inches
// ********************Guns don't kill people. Chuck Norris kills People. **************************//
void straight() // go straight function
{
digitalWrite(enable, HIGH);
digitalWrite(Motor1A, HIGH);
digitalWrite(Motor1B,LOW);
digitalWrite(enable2, HIGH);
digitalWrite(Motor2A, HIGH);
digitalWrite(Motor2B,LOW);
}
//************************ Chuck Norris does not sleep. He waits.********************************//
void turnRight() // turn right function
{
digitalWrite(enable, HIGH);
digitalWrite(Motor1A, LOW);
digitalWrite(Motor1B,HIGH);
digitalWrite(enable2, HIGH);
digitalWrite(Motor2A, HIGH);
digitalWrite(Motor2B,LOW);
}
//************When the Boogeyman goes to sleep every night, he checks his closet for Chuck Norris.****************//
float distCalc() // distance calculating function converts analog input to inches
{
valSum = 0; // resets valSum to zero after every loop
for (int i=0; i<=9; i++) // for loop to gather first 10 int's
{
val[i] = analogRead(ultraAn); // read the value from the sensor
valSum = (val[i]+valSum); // adds the first 10 values for averaging
}
digitalWrite(UltraEnable, LOW); // disables sonar
valAvg = (valSum/10); // calculates the average
dist = ((valAvg/204.8)/.009765625); // converts the analog value to distance in inches
return dist; // return the distance values to the rest of the program
}
//********Chuck Norris is the reason why Waldo is hiding.********Chuck Norris counted to infinity - twice.********//
void avoideWalls()
{
if(dist < 16) // if the distance is less than 20 inches
{
digitalWrite(ledPin, HIGH); // turn on the LED
turnRight(); // turns Walbot right using turnRight function
delay(100);
else // otherwise
{
digitalWrite(ledPin, LOW); // turn off the LED
straight(); // go straight using the straight function
}
}
//*****Chuck Norris can slam a revolving door.******Chuck Norris does not get frostbite. Chuck Norris bites frost*****//
void setup()
{
pinMode(Motor1A, OUTPUT); // sets motor pin 1A as output
pinMode(Motor1B, OUTPUT); // sets motor pin 1B as output
pinMode(Motor2A, OUTPUT); // sets motor pin 2A as output
pinMode(Motor2B, OUTPUT); // sets motor pin 2B as output
pinMode(enable, OUTPUT); // sets enable2 as output
pinMode(enable2, OUTPUT); // sets enable as output
pinMode(UltraEnable, OUTPUT); // sets enable as output
pinMode(ledPin, OUTPUT); // sets ledPin as output
straight(); // initializes Walbot to go straight
}
//*****Chuck Norris can win a game of Connect Four in only three moves.******Chuck Norris can divide by zero.*****//
void loop() {
digitalWrite(UltraEnable, HIGH); // turns on sonar
distCalc(); // gets the distance value from distCalc function
avoideWalls(); // tells Walbot not to run into inanimate objects by calling avoideWalls function
delay(20); // delay for 20 milliseconds
}
I would really appreciate some help. :-/
This is driving me nuts!
-
Hey,
What you need to do is make a simple method for returning the distance value. An example would be like this:
long duration;
long ping(int numIter) {
duration = 0; // reset duration value
for (int i = 0; i < numIter; i++) {
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
pinMode(pingPin, INPUT);
duration += pulseIn(pingPin, HIGH); // add the current reading to the total
}
return duration / 74 / 2 / numIter; // return averaged value in inches
}
This will replace your distCalc function, as the distCalc is inefficient and not really suited for the Ping))). The numIter parameter is the number of readings to average, for something like the Ping))), 10 is probably too much; you can find your own optimal number through experimentation.
Also, I noticed that you have this in your code:
int Motor1A = 10; // H-Bridge input 1
int Motor1B = 11; // H-Bridge input 2
int enable = 3; // H-Bridge motor 1 enable
int Motor2A = 9; // H-Bridge input 3
int Motor2B = 8; // H-Bridge input 4
int enable2 = 5; // H-Bridge motor 2 enable
int ultraAn = 0; // select the input pin for the ultrasonic sensor
int UltraEnable = 12; // sets enable to pin 12
int ledPin = 13; // sets the indicator led to pin 13
float val[10]; // array to store first 10 values coming from the sensor
float valSum=0; // sum of first 10 readings
float valAvg=0; // average of the first 10 readings
float dist = 0; // variable to store the converted distance in inches
I find that it is wasteful to define pins as ints, as a #define statement is probably better.
#define a b
// is equivalent to
int a = b;
// for pin def, in any case where the pin number will not change during runtime.
Also, with the Ping))), you can remove the fields for valAvg and valSum and val[], they're replaced in functionality by duration. Another thing that tends to be good robot code is to avoid use of float and double wherever possible - your Arduino does not have a floating point math coprocessor, and so integer math is much preferred. It's not like your sensor will return things accurate to the decimal regardless.
Lastly, in your algorithm, it says
if (dist < 16) // if the distance is less than 20 inches
which doesn't seem to make sense - 16 is not 20, after all.
Good luck with your robot, and I hope this helps =).
-
Thank you so much for all this. I'm going to start coding a new program today. I'll see if I have some success!
Thanks!!
J ;D
-
Okay.. been working with that code and I think I almost have it.
Right now it goes forward.. but doesn't detect anything from the ping sensor. The ping sensor is sending out echoes, though, which is more than it was doing.
Here's what I have:
#define Motor1A 10 // H-Bridge input 1
#define Motor1B 11 // H-Bridge input 2
#define enable 3 // H-Bridge motor 1 enable
#define Motor2A 9 // H-Bridge input 3
#define Motor2B 8 // H-Bridge input 4
#define enable2 5 // H-Bridge motor 2 enable
#define ledPin 13 // sets the indicator led to pin 13
#define pingPin 12
void straight() // go straight function
{
digitalWrite(enable, HIGH);
digitalWrite(Motor1A, HIGH);
digitalWrite(Motor1B, LOW);
digitalWrite(enable2, HIGH);
digitalWrite(Motor2A, HIGH);
digitalWrite(Motor2B,LOW);
}
void turnRight() // turn right function
{
digitalWrite(enable, HIGH);
digitalWrite(Motor1A, LOW);
digitalWrite(Motor1B, HIGH);
digitalWrite(enable2, HIGH);
digitalWrite(Motor2A, HIGH);
digitalWrite(Motor2B,LOW);
}
long duration;
long ping(int numIter = 3) {
duration = 0; // reset duration value
for (int i = 0; i < numIter; i++) {
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
pinMode(pingPin, INPUT);
duration += pulseIn(pingPin, HIGH); // add the current reading to the total
}
return duration / 74 / 2 / numIter; // return averaged value in inches
}
void avoideWalls()
{
if(duration < 10) // if the distance is less than 10 inches
{
digitalWrite(ledPin, HIGH); // turn on the LED
turnRight(); // turns Walbot right using turnRight function
delay(100);
}
else // otherwise
{
digitalWrite(ledPin, LOW); // turn off the LED
straight(); // go straight using the straight function
}
}
void setup()
{
pinMode(Motor1A, OUTPUT); // sets motor pin 1A as output
pinMode(Motor1B, OUTPUT); // sets motor pin 1B as output
pinMode(Motor2A, OUTPUT); // sets motor pin 2A as output
pinMode(Motor2B, OUTPUT); // sets motor pin 2B as output
pinMode(enable, OUTPUT); // sets enable2 as output
pinMode(enable2, OUTPUT); // sets enable as output
pinMode(pingPin, OUTPUT); // sets pingPin as output
pinMode(pingPin, INPUT); // sets pingPin as output
pinMode(ledPin, OUTPUT); // sets ledPin as output
straight(); // initializes Walbot to go straight
}
void loop() {
digitalWrite(pingPin, HIGH); // turns on sonar
ping();
avoideWalls(); // tells Walbot not to run into inanimate objects by calling avoideWalls function
delay(20); // delay for 20 milliseconds
}
I added a number here:
long ping(int numIter = 3)
Was trying different numbers but it doesn't seem to make a difference. When I didn't have any number at all there, the robot was in a permanent right turn motion. Very odd.
I added Ping(); here. I don't know if that is right (I'm a total noob with arduino code). I figured I needed to pull a number in the loop from the distance. I dunno if this is right, though.
void loop() {
digitalWrite(pingPin, HIGH); // turns on sonar
ping();
avoideWalls(); // tells Walbot not to run into inanimate objects by calling avoideWalls function
delay(20); // delay for 20 milliseconds
}
Thanks SO MUCH for all your help! It's been magnificent.