Robot guinea pig using Arduino

When I joined recently, I mentioned my daughter and I were building a robot guinea pig based on the Droid kit and Arduino. There’s a lot to cover, so in this post, I’ll lay out our requirements and the parts list. Next will come our Arduino code, and a discussion of problems we ran into getting it to work. Finally, some pictures. The guinea pig as documented here is not the end-state design, as we intend to redo the mounts to make it more compact, and 3D print an outer body to make it look more like a real guinea pig.

Our goals were to do the following:

  • Respond to petting
  • Scamper autonomously with no use of remote control
  • Sense obstacles in order to change directions
  • Squeak like a real guinea pig

We used the Droid kit as a base because it provided several parts we would otherwise have a hard time fabricating. Specifically:

  • Mounting block
  • Wheel frame
  • Drive gear
  • Axle
  • Large wheel x2
  • Spike gear
  • Wheel hook
  • Small wheel

We also used the following bits from the Droid:

  • Proximity sensor
  • Servo motor (cross-axle)
  • DC motor (cross-axle)

We purchased the following additional bits to complete the design:

  • Arduino
  • Makey Makey
  • MP3 player
  • Speaker
  • Wire x3
  • powerSnap
  • Rechargeable battery
  • USB power bit

The completed circuit is mounted along one long panel of the Droid mounting block, except for the proximity sensor, which is attached to the front of the block to act as eyes and terminated with a powerSnap. The mounting block is connected to the wheel frame in a very different manner than intended, so that the circuit is parallel to the ground, and the servo motor is mounted at the front, as far from the drive wheels as possible. USB power is attached to the Arduino on the D0 input, the proximity sensor on A0, and the Makey Makey on A1. The MP3 player is attached to the D0 output, the servo motor to D5, and the DC motor to D9. The Arduino’s motor outputs are set to analog mode, the servo to turn mode, and the DC motor to var mode.

We initially tried to power the project from the 9V battery power bit included from the Droid kit, but it drained very quickly with the additional load of the MP3 player, speaker, and Makey Makey. I also feel it important to mention that the MP3 player and speaker were a very expensive solution to the fact the sound effects bit was discontinued right before we started this project. Needing two bits to replace the one added considerable bulk and cost. We won’t look to replace the bits should a new version of the sound effects bit return, but it was sorely missed.

In my next post in this topic, I’ll cover our code and some issues we had getting it to work.

Here is our source code for the robot guinea pig:

int musicPin = 1;
int makeyPin = A1;
int motorPin = 9;
int proximityPin = A0;
int servoPin = 5;

int makeyValue = 0;
int proximityValue = 0;

void setup() {
  Serial.begin(9600);
  pinMode(proximityPin, INPUT);
  pinMode(musicPin, OUTPUT);
  pinMode(makeyPin, INPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(servoPin, OUTPUT);
}

void loop() {
  analogWrite(motorPin, 127);
  analogWrite(servoPin, 0);
  delay(1000);
  proximityValue = analogRead(proximityPin);
  makeyValue = analogRead(makeyPin);
  if (makeyValue > 100)
  {
    digitalWrite(musicPin, HIGH);
  }
  else
  {
    digitalWrite(musicPin, LOW);
    if (proximityValue > 100)
    {
      analogWrite(motorPin, 0);
      delay(1000);
      analogWrite(motorPin, 127);
      analogWrite(servoPin, 70);
      delay(300);
      analogWrite(motorPin, 255);
      delay(1000);
      analogWrite(servoPin, 0);
      analogWrite(motorPin, 127);
    }
    else
    {
      Serial.println("Do nothing");
    }
    int randomMove = random(10);
    if (randomMove < 5)
    {
      delay(3000);
      analogWrite(motorPin, 255);
      delay(3000);
      analogWrite(motorPin, 127);
    }
  }
}

Briefly, what this code does:

  • Initialize the various pins to be read
  • Make sure the motors are in neutral positions before reading sensors
  • Read the two input sensors, proximity and Makey Makey
  • If the guinea pig is being petted, per Makey Makey, squeak
  • Otherwise, quit squeaking and check if it needs to back up and turn
  • If it does not need to turn, move forward 50% of the time

Most of this code was written by my 9-year-old daughter, albeit with substantial guidance from me – she could not find these functions in documentation online, but once she knew what they did, we discussed what we wanted it to do, and then she could apply them. I mention this largely to encourage people not to be afraid to drop a child into the Arduino Sketch IDE – it is not the drag-and-drop sort of interface typically aimed at the age group, but when you’ve got a really motivated kid, they will not let brackets and semicolons intimidate them. Just expect to do a lot of handholding.

We had several problems I would like to document for those who might like to duplicate this project:

First, we were surprised to find out that Sketch seems somewhat inconsistent in recognizing pins by name/number. As you can see above, the analog pins are addressed as A0 and A1. Initially, we tried to refer to the digital pins by the numbers above, and it did not work for all of them. Notably, the servo motor and MP3 player did not appear to respond to signals. Changing the assigned numbers to the pin names described in this document:

Arduino Pin Mapping

seemed to help, and then stop working after a few recompilations. I’m not sure what finally got these pin assignments to work as expected, but I thought I should mention that we ran into this issue.

Reading the sensors correctly also proved to be a matter of trial and error. As you can see, we read the Makey Makey and proximity sensor as analog values – we did not start this way. I expected they would likely be binary on/off sorts of switches. This is not the case. The documentation under “How It Works” for their bit pages doesn’t mention how to read them. It would be helpful to have information like this be readily discoverable. Once we figured it out, we realized that we needed to filter out responses to noise, which is why the tests using these signals check for values > 100 rather than 0. A proximity sensor genuinely close to a wall is likely to return a real value between 500-700 in our design (overhanging parts keep it from getting closer/higher). Even now, the robot occasionally goes into the backup loop even when it’s nowhere near an obstacle.

The servo motor was a special challenge to debug in use, because we did not really understand what the range of input values would do, or that 255 = 0 for these purposes. We initially settled on a value of 90 to try to make right-angle turns, but this essentially turns the servo into a parking brake as the wheel is exactly perpendicular to the drive axle at that point. 70 turned out to be a reasonably good compromise that provides a fairly sharp turn, albeit not enough to avoid a wall in a single pass. This was another bit for which it would have been very helpful to have some documentation under “how it works”. We did try the Servo library available with Sketch, but it produced surprisingly poor results – notably, much smaller turns of the wheel than we expected for a given angular input.

It also took us a while to determine the values for driving the motor. We knew that it could be reversed in “var” mode, but the documentation for the bit doesn’t detail that 0 is actually full reverse, and stop is 127 on a 255-step scale. I ultimately found this information by searching the forums.

If you try to duplicate this project, a word of advice – trying to update the code while the Arduino is mounted within this body, connected to multiple motors, is a VERY bad idea. The robot will try to drive off. To mitigate this, we debugged our issues reading the sensors by hooking them up (through the Arduino) to the MP3 player. However, when we were trying to figure out problems with the motors, having them hooked up was largely unavoidable. It’s good to have two people present just so someone can hold the robot in the air while making code changes.

In my next post, I’ll put up some pictures of the fully assembled robot.




1 Like

thanks for sharing, well done.
I especially like the quote about the Arduino IDE and nine year olds :slight_smile: