Nodding and moving your robot’s head

Notice how your robot’s IR sensor is mounted on a frame that can move in 2 planes? Try moving it with your hand, don’t be too vigorous with them, they’re rather flimsy and plastic!

So it’s all well and good moving the head by hand, but it would be much more userful doing this programmatically. There are two servo motors attached to each bracket, allow 180 degrees of control. We can make the robot look left and right; and up and down, so let’s do just that:

#include <Servo.h>
#include <DFRduino.h>


DFRduino robot;

void setup() {
}

void loop() {
  // Look forward
  // Unfortunately my robot's vertical servo is not calibrated very
  // well, so looking ahead is 130 degrees, less points it up, more
  // makes it click a lot -- if your's clicks a lot, pull out the cable,
  // and rewrite your code so that it won't put it to such extreme a
  // position
  robot.setVerticalHeadPosition(130);
  // Wait for the servo to move
  delay(500);
  // Look upwards
  robot.setVerticalHeadPosition(40);
  // Wait for the servo to move
  delay(500);
}

You may find that your robot’s head isn’t pointing forward, so we can modify the sketch above to do that using setHorizontalHeadPosition, this works as you’d expected, unlike setVerticalHeadPosition:

#include <Servo.h>
#include <DFRduino.h>


DFRduino robot;

void setup() {
  // We set the horizontal head position just once.
  // There's no point repeatedly doing it as we're not changing it in
  // our loop.
  robot.setHorizontalHeadPosition(90);
}

void loop() {
  // Look forward
  // Unfortunately my robot's vertical servo is not calibrated very
  // well, so looking ahead is 130 degrees, less points it up, more
  // makes it click a lot -- if your's clicks a lot, pull out the cable,
  // and rewrite your code so that it won't put it to such extreme a
  // position
  robot.setVerticalHeadPosition(130);
  // Wait for the servo to move
  delay(500);
  // Look upwards
  robot.setVerticalHeadPosition(40);
  // Wait for the servo to move
  delay(500);
}

We could do something more interesting…

#include <Servo.h>
#include <DFRduino.h>


DFRduino robot;
int xIncrement = 1;
int yIncrement = 1;

int x = 0;
int y = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  // '||' means OR
  if (x > 180 || x < 0) {
    xIncrement *= -1;
  }

  // The furthest down y can go is 160 degrees. If it tries to go more
  // than that the library will print out an error in the serial monitor
  if (y > 160 || y < 0) {
    // 
    yIncrement *= -1;
  }

  x += xIncrement;
  y += yIncrement;

  robot.setHorizontalHeadPosition(x);
  robot.setVerticalHeadPosition(y);
  delay(20);
}

See if you can figure this out by reading the code, If not, read on!

  1. Set x = 0, y = 0.
  2. Each time we loop check to see if x > 180 or x < 0, if this is the case, then change the sign of xIncrement (so we either increase, or decrease our angle)
  3. Each time we loop check to see if y > 160 or y < 0, if this is the case, then change the sign of yIncrement (so we either increase, or decrease our angle)
  4. Add xIncrement to x and add yIncrement to y.
  5. Set our angles by x and y.
  6. Delay for 20ms, this gives our servo a bit of time to move 1 degree. Play around with this value, see how fast it can go before it doesn’t operate correctly. Can you explain what happens when you leave the delay out?

Time to move on and use everything you’ve learnt to write an obstacle avoidance program for your robot