Zumo Robot vibrating

Hello,

I’m using a Zumo Shield robot with HCSR04 sensors. When I try the LineFollower, BorderDetect, etc. examples with Zumo Shield it’s working as expected. For the sensors when I try the example UltrasonicSensorExample, I’m able to read the distance as expected. The problem starts when I try to unite these LineFollower and Sensor together. My robot follows the line, it stops when it sees an object 10cm ahead of it. The problem is that it’s vibrating while it’s moving. I’m not sure “vibrating” is the right word for it but in any case I couldn’t find anything online for this problem. I’ve included a video of it here: IMG_1214

Any help would be appreciate. Here’s the code I’m using as well:

#include <Wire.h>
#include <ZumoShield.h>

ZumoBuzzer buzzer;
ZumoReflectanceSensorArray reflectanceSensors;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON);
int lastError = 0;

// This is the maximum speed the motors will be allowed to turn.
// (400 lets the motors go at top speed; decrease to impose a speed limit)
const int MAX_SPEED = 200;

// Pins
const int TRIG_PIN = A4;
const int ECHO_PIN = A5;

// Anything over 400 cm (23200 us pulse) is "out of range"
const unsigned int MAX_DIST = 580;

void setup()
{
  // Play a little welcome song
  buzzer.play(">g32>>c32");

  // Initialize the reflectance sensors module
  reflectanceSensors.init();

  // Wait for the user button to be pressed and released
  button.waitForButton();

  // Turn on LED to indicate we are in calibration mode
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);

  // The Trigger pin will tell the sensor to range find
  pinMode(TRIG_PIN, OUTPUT);
  digitalWrite(TRIG_PIN, LOW);  
  pinMode(ECHO_PIN, INPUT);
  
  // Wait 1 second and then begin automatic sensor calibration
  // by rotating in place to sweep the sensors over the line
  delay(1000);
  int i;
  for(i = 0; i < 80; i++)
  {
    if ((i > 10 && i <= 30) || (i > 50 && i <= 70))
      motors.setSpeeds(-200, 200);
    else
      motors.setSpeeds(200, -200);      
    reflectanceSensors.calibrate();


    // Since our counter runs to 80, the total delay will be
    // 80*20 = 1600 ms.
    delay(20);
  }
  motors.setSpeeds(0,0);

  // Turn off LED to indicate we are through with calibration
  digitalWrite(13, LOW);
  buzzer.play(">g32>>c32");

  // Wait for the user button to be pressed and released
  button.waitForButton();

  // Play music and wait for it to finish before we start driving.
  buzzer.play("L16 cdegreg4");
  while(buzzer.isPlaying());
}

void loop()
{
  unsigned long t1;
  unsigned long t2;
  unsigned long pulse_width;
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  while ( digitalRead(ECHO_PIN) == 0 );
  t1 = micros();
  while ( digitalRead(ECHO_PIN) == 1);
  t2 = micros();
  
  pulse_width = t2 - t1;
  
  unsigned int sensors[6];
  int position = reflectanceSensors.readLine(sensors, QTR_EMITTERS_ON, 1);
  int error = position - 2500;
  int speedDifference = error / 4 + 6 * (error - lastError);
  lastError = error;
  int m1Speed = MAX_SPEED + speedDifference;
  int m2Speed = MAX_SPEED - speedDifference;
  int i;
  if (pulse_width >= MAX_DIST)   {
    if (m1Speed < 0)
      m1Speed = 0;
    if (m2Speed < 0)
      m2Speed = 0;
    if (m1Speed > MAX_SPEED)
      m1Speed = MAX_SPEED;
    if (m2Speed > MAX_SPEED)
      m2Speed = MAX_SPEED;     
    motors.setSpeeds(m1Speed, m2Speed);
    }
  else if (pulse_width <= MAX_DIST)
    motors.setSpeeds(0, 0); 
//    for(i = 0; i < 40; i++)     {
//      if (i> 0 && i <= 30)
//        motors.setSpeeds(-200,200);
//      else
//        motors.setSpeeds(200,200);
//       }
  
}

Hello.

Thank you for posting a clear video showing the problem. What Arduino board are you using?

One immediate concern is that as your code is written now if there is a very long pulse width from your ultrasonic sensor, it might take a while before your robot gets to reading the reflectance sensors and adjusting the motor speed. You could try adding a timeout feature (or something to that effect) and see if that helps. An easy way to do that might be to use Arduino’s pulseIn() function instead of checking micros() manually, and you could probably just make the timeout value equal to MAX_DIST.

If that does not work, try adding some Serial.print() lines to your code so you can monitor your robot’s ultrasonic sensor and line position measurements while it is running. Can you post a sample of what that outputs so we can see what is going on?

Also, did you have the ultrasonic senor connected to the same pins when you were testing that by itself?

- Patrick

Hi PatrickM,

First of all thank you so much for the quick reply!

I tried adding delay() after everytime my robot does a sensor reading. It didn’t fix the “vibrating” of my robot. I tried using pulseIn instead of micros(), but I’m only getting 0 when I try to monitor it on the serial port. I might be using the function incorrectly. Please bare with me because I’m very new to this.
Screenshot 2022-04-09 at 10.46.29 am

I’ve added some Serial.print() lines as you recommended to monitor robot’s measurements. Here’s my results:
Screenshot 2022-04-09 at 11.08.54 am

Thank you again Patrick!

Can you answer my question about what Arduino you are using? Also, can you add another Serial.print() to your program that reports the raw pulse width readings from the HC-SR04 and post a new sample output? Please also post the complete and up-to-date program you use to generate that output.

By the way, I am not sure how adding a delay after your sensor readings would make your line follower smoother, so I suggest removing that if you have not already.

- Patrick

Also please check if your robot’s battery is fully charged.