Author Topic: Need a little help with one of the Society of Robots tutorials  (Read 890 times)

0 Members and 1 Guest are viewing this topic.

Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Need a little help with one of the Society of Robots tutorials
« 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

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

Offline rbtying

  • Supreme Robot
  • *****
  • Posts: 452
  • Helpful? 31
Re: Need a little help with one of the Society of Robots tutorials
« Reply #1 on: October 17, 2010, 12:51:14 PM »
The Parallax Ping))) uses a different mechanism entirely:

Try this:
Code: [Select]
  #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;

Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Need a little help with one of the Society of Robots tutorials
« Reply #2 on: October 19, 2010, 10:23:34 PM »
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:
Code: [Select]
/*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!

Offline rbtying

  • Supreme Robot
  • *****
  • Posts: 452
  • Helpful? 31
Re: Need a little help with one of the Society of Robots tutorials
« Reply #3 on: October 20, 2010, 12:00:15 AM »
Hey, 
    What you need to do is make a simple method for returning the distance value.  An example would be like this:

Code: [Select]
  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:
Code: [Select]
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. 
Code: [Select]
#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
Code: [Select]
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 =).

Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Need a little help with one of the Society of Robots tutorials
« Reply #4 on: October 20, 2010, 06:25:34 AM »
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!!

;D

Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Need a little help with one of the Society of Robots tutorials
« Reply #5 on: October 20, 2010, 09:51:13 AM »
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:
Code: [Select]
#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:

Code: [Select]
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.
Code: [Select]
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.


 


Get Your Ad Here

data_list