
Bob the biped
So I’ve started a new robot project 🙂 A while ago a cute little biped robot was posted on Letsmakerobots.com. And so Bob the biped was born. The cool thing about Bob is that everyone can 3D print his own. The files needed to print Bob can be found on Thingiverse. To built your own Bob you just need the 3D parts, 4 little servos and your favorite micro controller. Lots of people started building their own so I was getting a bit jealous. I wanted my own Bob! Someone very friendly on LMR offered to print me one. An offer I could not refuse. So my Bob was printed in the US, but built in Belgium. He’s very easy to put together, I just needed to clean up the 3D printed parts. I had to do a little bit of filing to make my servos and SR04 sensor fit. To fit a small power switch I drilled a 6mm hole in the back.
Bob is pretty small so you can’t fit a standard Arduino inside it’s head. An Arduino Nano or Micro fits though. I chose to design my own PCB, based on the ATmega328 in a TQFP package. I named it the Mini Bajduino. To power the servos and micro controller I chose to use a small 300mAh 2S Lipo battery. To drop the voltage to 5V for the servos I use a LM2596 board, you can find these very cheaply on Ebay. I used a small piece of perfboard to distribute the power of the LM2596 to the servos. I also put a 74HC595 shift register and 8 220ohm resistors on the PCB. The shift register controls the 8 leds in Bobs mouth. Bobs eyes are a SR04 ultrasonic sensor. I wasn’t easy to fit all the parts inside Bobs head. I had to cut the servo cables and use short wires to connect the leds. After a bit of fiddling I managed to fit all the parts.

Bob the biped
I have quite a bit of experience controlling servos with Arduino. Still it took me many hours to find a good walking gait for Bob. I wanted to make Bob walk smoothly. So I used the same basic “timer code” I used for my hexapod. At the moment I have coded the basic walking gaits so Bob can walk forward/backward/left/right. I think he walks pretty smoothly? The servo positions can use some fine tuning. But that’s for later. I also need to program a obstacle avoiding function so Bob can walk around autonomously.
Bob in action:
Here is the code for the basic walking gait:
// http://www.bajdi.com
// Bob the biped
// Basic walking gait code
#include <Servo.h>
// 4 servos
Servo leftFootServo;
Servo leftHipServo;
Servo rightFootServo;
Servo rightHipServo;
const int offset = 20; //how many degrees we want to move the servos
// Servo positions
// Left foot servo
const int leftFootC = 85; // centered
const int leftFootD = leftFootC-offset; // foot down
const int leftFootU = leftFootC+offset; // foot up
// Left hip servo
const int leftHipC = 85; // centered
const int leftHipL = leftHipC+offset; // hip left
const int leftHipR = leftHipC-offset; // hip right
// Right foot servo
const int rightFootC = 90;
const int rightFootD = rightFootC-offset;
const int rightFootU = rightFootC+offset;
// Right hip servo
const int rightHipC = 100;
const int rightHipL = rightHipC-offset;
const int rightHipR = rightHipC+offset;
// Servo positions we want the servo to move to (in small steps)
float leftFootPos;
float leftHipPos;
float rightFootPos;
float rightHipPos;
// Servo postions written to the servos
float leftFootPosInt = leftFootC;
float leftHipPosInt = leftHipC;
float rightFootPosInt = rightFootC;
float rightHipPosInt = rightHipC;
// Calculated values for moving servos in small steps (position we want to move to - current servo position / steps)
float leftFootStep;
float leftHipStep;
float rightFootStep;
float rightHipStep;
const int steps = 20; // divide every servo move in 20 steps
byte speed = 40; // time between steps
unsigned long SuperTurboTimer;
byte SuperTurboStep = 1;
unsigned long SuperTurboMillis;
unsigned long timer;
byte direction;
byte legInStep = 1;
void setup()
{
leftFootServo.write(leftFootC);
leftFootServo.attach(4);
leftHipServo.write(leftHipC);
leftHipServo.attach(5);
rightFootServo.write(rightFootC);
rightFootServo.attach(7);
rightHipServo.write(rightHipC);
rightHipServo.attach(6);
delay(3000);
}
void loop()
{
//direction = 0; //stopped
direction = 1; // forward
// direction = 2; // backward
// direction = 3; // left
// direction = 4; // right
walk();
}
// This function makes Bob walk
void walk()
{
SuperTurboMillis = millis();
if (SuperTurboMillis >= timer){
timer = timer+speed;
legInStep = legInStep + 1;
if (legInStep == steps + 1){
legInStep = 1;
}
if (legInStep == 1)
{
leftFootStep = (leftFootPos - leftFootPosInt) / steps;
leftHipStep = (leftHipPos - leftHipPosInt) / steps;
rightFootStep = (rightFootPos - rightFootPosInt) / steps;
rightHipStep = (rightHipPos - rightHipPosInt) / steps;
}
leftFootPosInt = leftFootPosInt + leftFootStep;
leftHipPosInt = leftHipPosInt + leftHipStep;
rightFootPosInt = rightFootPosInt + rightFootStep;
rightHipPosInt = rightHipPosInt + rightHipStep;
}
if (SuperTurboMillis >= SuperTurboTimer){
SuperTurboTimer = SuperTurboTimer+(steps*speed);
SuperTurboStep = SuperTurboStep +1;
if (SuperTurboStep == 7){
SuperTurboStep = 1;
}
}
if (direction == 0) // stop, both feet on the ground
{
leftFootPos = leftFootC;
leftHipPos = leftHipC;
rightFootPos = rightFootC;
rightHipPos = rightHipC;
}
if (direction == 1) // forward walking gait
{
if (SuperTurboStep == 1)
{
leftFootPos = leftFootU;
rightFootPos = rightFootD;
}
if (SuperTurboStep == 2)
{
leftHipPos = leftHipL;
rightHipPos = rightHipR;
}
if (SuperTurboStep == 3)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
if (SuperTurboStep == 4)
{
leftFootPos = leftFootD;
rightFootPos = rightFootU;
}
if (SuperTurboStep == 5)
{
leftHipPos = leftHipR;
rightHipPos = rightHipL;
}
if (SuperTurboStep == 6)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
}
if (direction == 2) // backward walking gait
{
if (SuperTurboStep == 1)
{
leftFootPos = leftFootU;
rightFootPos = rightFootD;
}
if (SuperTurboStep == 2)
{
leftHipPos = leftHipR;
rightHipPos = rightHipL;
}
if (SuperTurboStep == 3)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
if (SuperTurboStep == 4)
{
leftFootPos = leftFootD;
rightFootPos = rightFootU;
}
if (SuperTurboStep == 5)
{
leftHipPos = leftHipL;
rightHipPos = rightHipR;
}
if (SuperTurboStep == 6)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
}
if (direction == 3) // left walking gait
{
if (SuperTurboStep == 1)
{
leftFootPos = leftFootU;
rightFootPos = rightFootD;
}
if (SuperTurboStep == 2)
{
leftHipPos = leftHipL;
rightHipPos = rightHipL;
}
if (SuperTurboStep == 3)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
if (SuperTurboStep == 4)
{
leftFootPos = leftFootD;
rightFootPos = rightFootU;
}
if (SuperTurboStep == 5)
{
leftHipPos = leftHipR;
rightHipPos = rightHipR;
}
if (SuperTurboStep == 6)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
}
if (direction == 4) // right walking gait
{
if (SuperTurboStep == 1)
{
leftFootPos = leftFootU;
rightFootPos = rightFootD;
}
if (SuperTurboStep == 2)
{
leftHipPos = leftHipR;
rightHipPos = rightHipR;
}
if (SuperTurboStep == 3)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
if (SuperTurboStep == 4)
{
leftFootPos = leftFootD;
rightFootPos = rightFootU;
}
if (SuperTurboStep == 5)
{
leftHipPos = leftHipL;
rightHipPos = rightHipL;
}
if (SuperTurboStep == 6)
{
leftFootPos = leftFootC;
rightFootPos = rightFootC;
}
}
leftFootServo.write(leftFootPosInt);
leftHipServo.write(leftHipPosInt);
rightFootServo.write(rightFootPosInt);
rightHipServo.write(rightHipPosInt);
}
Bob now has his own website: http://www.bobrobot.com/




