Pololu Zumo

A few friends and I have started work on a sumo robot that uses a pololu zumo kit as a base. We are attempting to get a three pin ultrasonic sensor to work but we are not entirely sure on how to modify the sample code to factor in our ultrasonic sensor. Is there any example code we can download and modify, or any way to change the pin relays on the zumo shield. Any help would be appreciated.

Post links to the datasheets for the Zumo kit and the ultrasonic sensor.

If you have written some code attempting to get the sensor to work please post the code. And please use the code button </> so your code looks like this and is easy to copy to a text editor

…R

Here is the code, and here are links to the zumo datasheets: Pololu Zumo Shield for Arduino User’s Guide

BorderDetectWUS.ino (5.46 KB)

</>
#include <ZumoBuzzer.h>
#include <ZumoMotors.h>
#include <Pushbutton.h>
#include <QTRSensors.h>
//#include <ZumoReflectanceSensorArray.h>

#define LED 13

// this might need to be tuned for different lighting conditions, surfaces, etc.
#define QTR_THRESHOLD 1500 // microseconds

// these might need to be tuned for different motor types
#define REVERSE_SPEED 400 // 0 is stopped, 400 is full speed
#define TURN_SPEED 400
#define FORWARD_SPEED 200 // 200 original
#define REVERSE_DURATION 110 // ms
#define TURN_DURATION 200 // ms //150 works
ZumoBuzzer buzzer;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON); // pushbutton on pin 12

#define NUM_SENSORS 2
unsigned int sensor_values[NUM_SENSORS];
QTRSensorsRC sensors ((unsigned char) {4,5}, NUM_SENSORS);
int turns;
int Maxturns;
const int pingPin = 11;

//ZumoReflectanceSensorArray sensors(QTR_NO_EMITTER_PIN);

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
//int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

//int pingPin = 11; //the digital pin connected to the PIR sensor’s output
int ledPin = 13;

void waitForButtonAndCountDown()
{
digitalWrite(LED, HIGH);
button.waitForButton();
digitalWrite(LED, LOW);

// play audible countdown
for (int i = 0; i < 3; i++)
{
delay(1000);
buzzer.playNote(NOTE_G(3), 200, 15);
}
delay(1000);
buzzer.playNote(NOTE_G(4), 500, 15);
delay(1000);
}

void setup()
{
delay(500);

Serial.begin(9600);
// uncomment if necessary to correct motor directions
motors.flipLeftMotor(true);
motors.flipRightMotor(true);

pinMode(LED, HIGH);
waitForButtonAndCountDown();
//pinMode(pirPin, INPUT);
//pinMode(ledPin, OUTPUT);
//digitalWrite(pirPin, LOW);
turns=0;
turns = random(3,10);

}

void loop()
{
if (button.isPressed())
{
// if button is pressed, stop and wait for another press to go again
motors.setSpeeds(0, 0);
button.waitForRelease();
waitForButtonAndCountDown();
}

sensors.read(sensor_values);

if (sensor_values[0] < QTR_THRESHOLD)
{
if(turns>=Maxturns){
//motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
//delay(REVERSE_DURATION);
int time=random(100,225);
motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
delay(time);
motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
turns = random(3,10);
turns=0;
}
// if leftmost sensor detects line, reverse and turn to the right
//motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
//delay(REVERSE_DURATION);
motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
delay(TURN_DURATION);
motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
turns++;
}
else if (sensor_values[1] < QTR_THRESHOLD)
{
if(turns>=Maxturns){
//motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
//delay(REVERSE_DURATION);
int time=random(100,225);
motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
delay(time);
motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
turns = random(3,10);
turns=0;
}
// if rightmost sensor detects line, reverse and turn to the left
motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
//delay(REVERSE_DURATION);
motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
delay(TURN_DURATION);
motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
turns++;
poop();
}
//else if(digitalRead(7)){
// motors.setSpeeds(0,0);
//}

else
{
// otherwise, go straight
motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
}
}

//The loop for the ultra sonic sensor
void poop() {
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:

long duration, inches, cm;

// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);

// The same pin is used to read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);

// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);

Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print(“cm”);
Serial.println();

delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax’s datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}

There is a lot of stuff on that Pololu page. Which is the relevant bit?

And please modify Reply #3 and use the code button </> so your code looks like this and is easy to copy to a text editor

…R

Sorry about the length of time it took to respond. here is my code in the proper format.

#include <QTRSensors.h>


#include <ZumoBuzzer.h>
#include <ZumoMotors.h>
#include <Pushbutton.h>
#include <QTRSensors.h>
//#include <ZumoReflectanceSensorArray.h>

#define LED 13
 
// this might need to be tuned for different lighting conditions, surfaces, etc.
#define QTR_THRESHOLD  1500 // microseconds
  
// these might need to be tuned for different motor types
#define REVERSE_SPEED     400 // 0 is stopped, 400 is full speed
#define TURN_SPEED        400
#define FORWARD_SPEED     200 // 200 original
#define REVERSE_DURATION  110 // ms
#define TURN_DURATION     200 // ms //150 works
ZumoBuzzer buzzer;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON); // pushbutton on pin 12
 
#define NUM_SENSORS 2
unsigned int sensor_values[NUM_SENSORS];
QTRSensorsRC sensors ((unsigned char[]) {4,5}, NUM_SENSORS);
int turns;
int Maxturns;
const int pingPin = 7;
 
//ZumoReflectanceSensorArray sensors(QTR_NO_EMITTER_PIN);

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
//int calibrationTime = 30;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 5000;  

boolean lockLow = true;
boolean takeLowTime;  

//int pingPin = 11;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;



void waitForButtonAndCountDown()
{
  digitalWrite(LED, HIGH);
  button.waitForButton();
  digitalWrite(LED, LOW);
   
  // play audible countdown
  for (int i = 0; i < 3; i++)
  {
    delay(1000);
    buzzer.playNote(NOTE_G(3), 200, 15);
  }
  delay(1000);
  buzzer.playNote(NOTE_G(4), 500, 15);  
  delay(1000);
}
 
void setup()
{
  delay(500);
 
 
  Serial.begin(9600);
  // uncomment if necessary to correct motor directions
  motors.flipLeftMotor(true);
  motors.flipRightMotor(true);
   
  pinMode(LED, HIGH);
  waitForButtonAndCountDown();
  //pinMode(pirPin, INPUT);
  //pinMode(ledPin, OUTPUT);
  //digitalWrite(pirPin, LOW);
  turns=0;
  turns = random(3,10);

}

void loop()
{
  if (button.isPressed())
  {
    // if button is pressed, stop and wait for another press to go again
    motors.setSpeeds(0, 0);
    button.waitForRelease();
    waitForButtonAndCountDown(); 
  }

  sensors.read(sensor_values);
  
  if (sensor_values[0] < QTR_THRESHOLD)
  {
    if(turns>=Maxturns){
      //motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
      //delay(REVERSE_DURATION);
      int time=random(100,225);
      motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
     delay(time);
      motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
      turns = random(3,10);
      turns=0;
    }
    // if leftmost sensor detects line, reverse and turn to the right
    //motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
    //delay(REVERSE_DURATION);
    motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
    delay(TURN_DURATION);
    motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
    turns++;
  }
  else if (sensor_values[1] < QTR_THRESHOLD)
  {
    if(turns>=Maxturns){
      //motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
      //delay(REVERSE_DURATION);
      int time=random(100,225);
      motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
     delay(time);
      motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
      turns = random(3,10);
      turns=0;
    }
    // if rightmost sensor detects line, reverse and turn to the left
    motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
    //delay(REVERSE_DURATION);
    motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
    delay(TURN_DURATION);
    motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
    turns++;
    poop();
  }
  //else if(digitalRead(7)){
  //  motors.setSpeeds(0,0);
  //}

  else
  {
    // otherwise, go straight
    motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
  }
     }

  //The loop for the ultra sonic sensor  
  void poop() {
  // establish variables for duration of the ping,
  // and the distance result in inches and centimeters:
  
  long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}
long microsecondsToInches(long microseconds) {
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

Thanks for any help.

      turns = random(3,10);
      turns=0;

Please explain this bit of code.

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

Surely you know what unit of measure is common in your country…

What is the purpose of the poop() function when the variables it values go out of scope as soon as they have been printed?

TeamCannonFodder: Sorry about the length of time it took to respond. here is my code in the proper format.

Thanks for posting the code properly. However you did not say what part of the Pololu page is relevant - and which would place the code in some sort of context.

Those long delay()s in the function waitForButtonAndCountDown() are prbably a big obstacle. Realistically if you want a responsive program you should not have the delay() function anywhere. Use millis() to manage timing as illustrated in Several Things at a Time

As @PaulS has mentioned the function poop() does some stuff but has no means to share its results with the rest of the program. A simple solution would be to change the variables inches and cm to be global variables.

...R

A simple solution would be to change the variables inches and cm to be global variables.

A better solution, in my opinion, would be to make poop() return a value - the distance in inches OR cm, whichever is useful.

PaulS: A better solution, in my opinion, would be to make poop() return a value - the distance in inches OR cm, whichever is useful.

I was assuming that approach would be less easy for a beginner to understand.

...R

I have some new code, but it still has some major issues. The ultrasonic sensor now picks up data, but it no longer chances motor speed. Here is my code:

#include <Pushbutton.h>



#include <QTRSensors.h>

#include <ZumoMotors.h>

#include <ZumoBuzzer.h>

#define LED 13
 
// this might need to be tuned for different lighting conditions, surfaces, etc.
#define QTR_THRESHOLD  1500 // microseconds
  
// these might need to be tuned for different motor types
#define REVERSE_SPEED     400 // 0 is stopped, 400 is full speed
#define TURN_SPEED        400
#define FORWARD_SPEED     200 // 200 original
#define REVERSE_DURATION  110 // ms
#define TURN_DURATION     200 // ms //150 works
ZumoBuzzer buzzer;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON); // pushbutton on pin 12
 
#define NUM_SENSORS 2
unsigned int sensor_values[NUM_SENSORS];
QTRSensorsRC sensors ((unsigned char[]) {4,5}, NUM_SENSORS);
int turns;
int Maxturns;
 
//ZumoReflectanceSensorArray sensors(QTR_NO_EMITTER_PIN
#include "Arduino.h"
class Ultrasonic
{
  public:
    Ultrasonic(int pin);
        void DistanceMeasure(void);
    long microsecondsToCentimeters(void);
    long microsecondsToInches(void);
  private:
    int _pin = 11;//pin number of Arduino that is connected with SIG pin of Ultrasonic Ranger.
        long duration;// the Pulse time received;
};
Ultrasonic::Ultrasonic(int pin)
{
  _pin = 11;
}
/*Begin the detection and get the pulse back signal*/
void Ultrasonic::DistanceMeasure(void)
{
    pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(_pin, HIGH);
  delayMicroseconds(5);
  digitalWrite(_pin,LOW);
  pinMode(_pin,INPUT);
  duration = pulseIn(_pin,HIGH);
}
/*The measured distance from the range 0 to 400 Centimeters*/
long Ultrasonic::microsecondsToCentimeters(void)
{
  return duration/29/2; 
}
/*The measured distance from the range 0 to 157 Inches*/
long Ultrasonic::microsecondsToInches(void)
{
  return duration/74/2; 
}

Ultrasonic ultrasonic(7);
void UltraSet()
{
  long RangeInInches;
  long RangeInCentimeters;
  ultrasonic.DistanceMeasure();// get the current signal time;
    RangeInInches = ultrasonic.microsecondsToInches();//convert the time to inches;
  RangeInCentimeters = ultrasonic.microsecondsToCentimeters();//convert the time to centimeters
 // Serial.println("The distance to obstacles in front is: ");
  //Serial.print(RangeInInches);//0~157 inches
 // Serial.println(" inch");
//Serial.print(RangeInCentimeters);//0~400cm
//  Serial.println(" cm");
 
//motors.setSpeeds(400,400);
if(RangeInInches < 12)
{
motors.setSpeeds(400,400);
Serial.print("randy savage");
}
}
void waitForButtonAndCountDown()
{
  digitalWrite(LED, HIGH);
  button.waitForButton();
  Serial.println("Button Pressed");
  digitalWrite(LED, LOW);
   
  // play audible countdown
  for (int i = 0; i < 3; i++)
  {
    delay(1000);
    buzzer.playNote(NOTE_G(3), 200, 15);
  }
  delay(1000);
  buzzer.playNote(NOTE_G(4), 500, 15);  
  delay(1000);
}

void setup() {
  // put your setup code here, to run once:
delay(500);
 
 
  Serial.begin(9600);
  Serial.println("Setup Started");
  // uncomment if necessary to correct motor directions
  motors.flipLeftMotor(true);
  motors.flipRightMotor(true);
  Serial.println("Setup motors");
   
  pinMode(LED, HIGH);
  Serial.println("Setup LED");
  waitForButtonAndCountDown();
  Serial.println("Derp Counted");
  //pinMode(pirPin, INPUT);
  //pinMode(ledPin, OUTPUT);
  //digitalWrite(pirPin, LOW);
  turns=0;
  turns = random(3,10);
  Serial.print("Setup Finished");
}

void loop() {
  // put your main code here, to run repeatedly:
 if (button.isPressed())
  {
    // if button is pressed, stop and wait for another press to go again
    motors.setSpeeds(0, 0);
    button.waitForRelease();
    waitForButtonAndCountDown(); 
  }

  sensors.read(sensor_values);
  
  if (sensor_values[0] < QTR_THRESHOLD)
  {
    if(turns>=Maxturns){
     motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
      delay(REVERSE_DURATION);
      int time=random(100,225);
      motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
     delay(time);
      motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
      turns = random(3,10);
      turns=0;
    }
    // if leftmost sensor detects line, reverse and turn to the right
    //motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
    //delay(REVERSE_DURATION);
    motors.setSpeeds(TURN_SPEED, -TURN_SPEED);
    delay(TURN_DURATION);
    motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
    turns++;
    Serial.print("Running Loop");
  }
  else if (sensor_values[1] < QTR_THRESHOLD)
  {
    if(turns>=Maxturns){
      //motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
      //delay(REVERSE_DURATION);
      int time=random(100,225);
      motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
     delay(time);
      motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
      turns = random(3,10);
      turns=0;
    }
    // if rightmost sensor detects line, reverse and turn to the left
    motors.setSpeeds(-REVERSE_SPEED, -REVERSE_SPEED);
    //delay(REVERSE_DURATION);
    motors.setSpeeds(-TURN_SPEED, TURN_SPEED);
    delay(TURN_DURATION);
    motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
    turns++;
  }
 

  else
  {
    // otherwise, go straight
    motors.setSpeeds(-FORWARD_SPEED, FORWARD_SPEED);
  }
   delay(1000);
UltraSet();
}

I don’t know where the glitch is so here is all of my code.

Please use the Auto Format tool to indent your code properly as that makes it very much easier to read. It may also help you to spot the problem.

What tests have you carried out to find the problem? - so that we don't have to wast time on those.

...R

The sensor give an output, as can be seen by the line that says "Randy Savage". The only problems is that the motors do not stay at 400,400 for long enough to make a difference....

TeamCannonFodder: The sensor give an output, as can be seen by the line that says "Randy Savage". The only problems is that the motors do not stay at 400,400 for long enough to make a difference....

I had intended to ask what "Randy Savage" means - and I still don't know.

Please Auto Format and re-post your code.

...R