Introduction: Itsy Bitsy: an Untethered Climbing Robot

My goal for this project was to design & build a small untethered climbing robot and to record it in my very first Instructable (woohoo!). The result is the robot shared here, which uses a rack and pinion system to pin itself between parallel surfaces and a simple lever mechanism and prismatic joint to inch its way forward. I hope you enjoy, and I'm looking forward to your feedback on what I can improve in the design and documentation.

Supplies

  • Tools:
    • 3D printer (or access to one) - for reference, I printed the components in PLA on an Ender 3 Pro
    • Soldering iron
    • Wire strippers
    • Hot melt glue gun
    • Screwdrivers
    • Multimeter
    • Computer with Arduino IDE installed
    • USB cable and 5V FTDI board, for programming the Arduino [Link]
    • LiPo Battery Charger [Link]
  • Materials:
    • Qty 1 - 5V Arduino Pro Mini, or equivalent [Link]
    • Qty 1 - LM2596 buck coverter (link is to a 6 pack) [Link]
    • Qty 2 - 3.7V, 1Ah LiPo Batteries [Link]
    • Qty 2 - JST right angle connectors [Link]
    • Qty 3 - Tower Pro SG90 micro servo and accompanying hardware (link is to a 5 pack) [Link]
    • Qty 1 - Panel mount SPDT toggle switch [Link]
    • 0.1" pitch breakaway headers [Link]
    • Robot Parts - Printed in PLA or preferred printing material (download the files from Thingiverse: https://www.thingiverse.com/thing:4607768)
      • Qty 1 - Head Cover
      • Qty 1 - Top Frame
      • Qty 1 - Bottom Frame
      • Qty 2 - Spur Gear
      • Qty 4 - Rack Gear Clamp
      • Qty 4 - Guide Plate
      • Qty 1 - Separated Clevis
      • Qty 1 - Motor Lever Arm
      • Qty 1 - Motor Drive Arm
    • Qty 2 - M3 Washers (or similar size)
    • Miscellaneous wire, for making electrical connections

Step 1: Design

This section briefly recaps my design approach for this project. If you'd like to start building a robot, feel free to jump to Step 2!

Motivation

A 4" x 4" x 4' aluminum channel (seen in the intro video) is what initially inspired me to build this robot. Left over from a previous project, I was looking at it one day and wondered if I could design something that could climb up it.

With this vision in mind, these were the design constraints I established when I started on this project:

  • The robot should be made mostly of 3d printed components (to explore my recently purchased Ender 3 Pro)
  • The robot should be light and small enough to lift its own weight while climbing
  • The robot should be entirely self-contained ("untethered") in terms of power supply, controls and actuators

Design Concepts

I have always enjoyed watching gears do their thing, so I was motivated to look into some way of climbing that could incorporate this machine element. A rack (long, straight gear) and pinion ('traditional', circular gear) seemed like the simplest way to achieve a clamping feature that would pin the robot in place while it 'pulled' or 'pushed' itself up. This was the line of thinking that led to the top and bottom rack gear clamp assemblies.

I had initially considered a third rack and pinion arrangement to address the 'pull / push' component of the climbing action as well, but it proved simpler and lighter to accomplish this with the basic linkage represented in the final design.

Analysis

Before jumping into the modeling of this robot, I analyzed two key performance requirements:

  1. Could it clamp / pin itself in place while climbing without sliding down?
  2. Could it push / pull itself up while climbing?

I put together a quick MS Excel sheet to perform the calculations that proved the servos I had selected and the geometry / gearing I had in mind could do the job. Doing these checks in a spreadsheet saved a lot of time and allowed me to think through various scenarios (what if I added a 0.1kg cover? What if I changed the gear size?) without having to physically test them. By the time I was printing something, I was able to make an educated guess that it would work as expected.

Iteration

Of course the analysis has to be backed up with actual results, and things rarely work as planned the first time! This is a rough snapshot of the 4 main iterations I took in developing this robot:

  1. Test the rack and pinion clamping mechanism by itself - can it "clamp" and hold itself in place?
    • Result:
      • Yes it can! but the two offset rack gears cause the robot to twist a bit... will this be a problem during climbing?
    • Next Steps:
      • Model the full climbing mechanism to see if/how it performs.
  2. Test a pair of rack and pinion mechanisms along with the push/pull linkage while "tethered" (batteries, controller and other components not mounted to the robot) - can it climb?
    • Result:
      • Yes it can! but the twist caused by offset rack gears does look like a problem. The robot takes a few steps forward and then slips out of place. It performs better if we speed up the motion a bit!
    • Next Steps:
      • Stiffen up the frame, enlarge the "foot" area on the rack gear clamps, and model the robot with onboard batteries and controller to test the untethered design.
  3. Test the untethered design - while carrying the batteries and controller, can it climb?
    • Result:
      • Yes it can! and the changes we made seem to make the climbing ability more consistent. Things are looking promising.
    • Next Steps:
      • Clean up the cable routing and add an on/off switch. Try printing in green, because maybe it wants to be a frog?
  4. Test the (hopefully) final design - does it still climb if we print it in green PLA?
    • Result:
      • Unfortunately, no. The green glossy PLA I selected was much more slippery and unfortunately couldn't even crawl very well, let alone climb.
    • Next Steps:
      • Try several modifications to the geometry to improve climbing ability (no luck!), and eventually switch back to matte black PLA (which works!).

Reflection and Future Work

This project was a lot of fun to complete and reinforced for me the importance of careful observation and deliberate improvement when working on a project with so many variables. There were certainly times when frustration caused me to step away from this for a week or two, but the challenge of getting ItsyBitsy to climb always brought me back. If I were to put further time towards this project, I would focus on:

  • Re-modeling the full assembly in Fusion 360 for ease of sharing
  • Further improvement of the "foot" of the rack gear, possibly by implementing a flexure or a mechanism like the whippletree!
  • Redistributing the components to lower the center of gravity (CG) and better align it with the climbing forces (currently the CG is rather high and offset, so the robot tends to tip as it climbs unless it's 'back' is against a wall)
  • Improving the code to remove the reliance on delay() functions
  • Adding sensing / indication (light, sound, etc...)

Thanks for reading! On to building a robot!

Step 2: Electronics

  1. Ensure that each of your LiPo batteries are charged.
  2. Solder up the electronics per the general schematic in the first image. Some key points:
    • Solder the female JST connectors such that they are in series. [We do this because we would like the voltage of the two batteries to add, so that we see a total of ~7.4V on the input of the Arduino and buck converter.]
    • Solder 3x 3-pin male headers near the output of the buck converter, as shown. [These are intended to interface with the servo motors, and allow us to easily disconnect the motors without having to de-solder the lead wires.]
    • Solder 1x 6-pin male header into the Arduino for programming with the FTDI board, as shown.
    • The wire lengths are approximately as follows.
      • JST connectors <> Buck converter & Arduino: 65mm (2.5")
      • Arduino <> 3x 3-pin male headers - servo drive signal: 65mm (2.5")
      • Buck converter <> 3x 3-pin male headers - power and ground: 25mm (1")
  3. Adjust the buck converter output to 5V. [We do this because the servos are rated for a maximum of 6V, so we don't want to supply the full battery voltage to them.]
    • Connect your charged batteries to the circuit and ensure the switch is "on" to allow current to flow the buck converter.
    • Set your multimeter to read DC voltage and place the leads on the output terminals of the buck converter.
    • Use a screwdriver to *gently* adjust the screw on the potentiometer until the output voltage reads 5V on the multimeter. See this video around the 1:50 mark for an example of this adjustment.

Step 3: Preliminary Mechanical Assembly

The following steps detail the mechanical assembly of the robot. Where applicable, the named 3D printed part names are listed in italics. I've done my best to tag each photo with respect to the step it relates to.

  1. Gather up your printed components (any printing supports removed) and plug in the hot melt glue gun. Make sure the glue gun is in a safe location (like on scrap cardboard) to avoid burning / dripping glue on anything.
  2. Insert the Separated Clevis into the Bottom Frame and secure with a dab of hot glue.
  3. Insert the "short" side of the Motor Drive Arm into the Separated Clevis and check that the arm can rotate.
  4. Apply a dab of hot glue in each of the four constraint holes in the Bottom Frame, then place two Rack Gear Clamps over the Bottom Frame so the two constraint holes are visible in each rack gear slot. Before the glue solidifies, secure each rack gear with a Guide Plate by gently pressing the pins of the guide plate into the constraint holes.
  5. Perform the same process to assemble the remaining two Rack Gear Clamps to the Top Frame using a bit of hot glue and the remaining two Guide Plates.
  6. Insert the two LiPo batteries into the Top Frame, pulling the cables through the openings.
  7. Install the Arduino and buck converter onto the Top Frame using a drop of hot glue each. Install the toggle switch onto the Top Frame and tighten the nut to secure it in place.
  8. Secure the JST connectors to the side of the Top Frame using a few drops of hot glue.
  9. Locate your servos and confirm that you have two mounting screws for each (these have a flat tip). Use a screwdriver to install two of the servos (we'll call these the "Top" and "Mid" servos) onto the Top Frame and one (the "Bot" servo) onto the Bottom Frame in the designated locations.
  10. Install the Motor Lever Arm onto the Motor Drive Arm and check that each arm can still rotate. Slide the Bottom Frame onto the Top Frame.
  11. Route the servo motor wires through the three routing points as indicated. Connect the servo motors to the three sets of headers at the output of the buck converter. Connect the batteries to the JST connectors. Confirm that all of the wires are not pinched or kinked.

Step 4: Setting the Actuator Locations

The following steps detail the procedure for ensuring the mechanical actuator components (Spur Gears and Motor Lever Arm) are installed in the correct location on the servos. We will use a bit of code that leverages the Arduino <Servo> library to position the servos in an "extended" orientation, and then install the components while the servos are holding this position.

[Note] Confirm that the "Top, Mid, Bot" servo wires are connected to the appropriate 3-pin headers for each of their drive pins (9, 10 and 11 respectively). If you decide to use different pins to drive your servos, modify the below code to reflect the pins you choose.

Paste the following into your Arduino IDE, then read on below to continue with the mechanical assembly:

// ItsyBitsy Extend Calibration by blimblarp

#include <Servo.h>

Servo TopServo;
Servo MidServo;
Servo BotServo;

const byte TopExt = 0;
const byte MidExt = 80;
const byte BotExt = 0;

void setup() {
  //Attach all of the servos to their respective PWM pins
  TopServo.attach(9);
  MidServo.attach(10);
  BotServo.attach(11); 
}

void loop() {
  //Extend all servos for setting position
  TopServo.write(TopExt);
  MidServo.write(MidExt);
  BotServo.write(BotExt);
}
  1. Ensure the toggle switch is ON so the Arduino, buck converter and servos are receiving power from the batteries. Insert the FTDI programming board into the 6-pin header on the Arduino and upload the code. Once the code has been uploaded, you should see/hear the servos driven to and held in a position.
  2. Locate the pointed tip threaded fastener that came with your servos (one for each). Extend the Rack Gear Clamps and gently press a Spur Gear onto the Bottom Frame servo ("Bot" servo) drive shaft, as indicated.
  3. Secure the Spur Gear to the drive shaft with one M3 washer and the specified fastener. Repeat this assembly process for the Top Frame servo ("Top" servo) as shown.
  4. Gently press the Motor Lever Arm onto the drive shaft of the other Top Frame servo ("Mid" servo) approximately in the location shown. Use the remaining pointed tip threaded fastener to fasten the Motor Lever Arm to the drive shaft - no M3 washer is needed.

At this point, you can flip the toggle switch to OFF and get ready for the final step!

Step 5: Final Programming, Testing and Troubleshooting

Movement Code

This step shares the code to get ItsyBitsy moving!

This code uses delays to step ItsyBitsy through its motions - it could be improved so other actions could be efficiently taken in the main loop (polling sensors, blinking LEDs, etc...), but I kept it simple and sub-optimal for this proof of concept.

// ItsyBitsy Move! by blimblarp

#include <Servo.h>

Servo TopServo;
Servo MidServo;
Servo BotServo;

const byte TopExt = 0;
const byte TopRet = 40;
const byte MidExt = 80;
const byte MidRet = 0;
const byte BotExt = 0;
const byte BotRet = 40;
const int  DelayPeriod = 70;

void setup() {
  //Attach all of the servos to their respective PWM pins
  TopServo.attach(9);
  MidServo.attach(10);
  BotServo.attach(11);

  //Start with all servos retracted
  TopServo.write(TopRet);
  MidServo.write(MidRet);
  BotServo.write(BotRet);
}

void loop() {

  //Clamp with the bottom servo to prepare for the move upward
  BotServo.write(BotExt);
  delay(DelayPeriod);

  //Retract the top servo to prepare for the move upward
  TopServo.write(TopRet);
  delay(DelayPeriod);

  //Extend the middle servo to stretch upward
  MidServo.write(MidExt);
  delay(DelayPeriod);

  //Clamp with the top servo to prepare for the pull up
  TopServo.write(TopExt);
  delay(DelayPeriod);

  //Unclamp the bottom servo to allow the move upward
  BotServo.write(BotRet);
  delay(DelayPeriod);

  //Retract the middle servo to perform the pull
  MidServo.write(MidRet);
  delay(DelayPeriod);
}

Once the code is uploaded, you should see motion like in the following video:

Climbing, Crawling, Dancing and more!

Once you've confirmed that it moves as expected, snap on the protective Head Cover over the Arduino & buck converter and let your robot loose on the world! ItsyBitsy can crawl, climb (slowly), dance around and provide other forms of amusement. A long and relatively straight piece of wood/metal spaced ~4" from a wall/baseboard make for decent parallel surfaces to test your robot's climbing and crawling skills, just watch out for pinched fingers in those gears!

Thanks for reading, and I hope you have fun with your new robot friend! Your feedback is welcome and appreciated.

Troubleshooting

  • ItsyBitsy has trouble climbing / is slipping when it tries to climb:
    • Make sure that the top rack gears are fully extending when TopServo.write(TopExt) is called, and likewise for BotServo. If needed, you can adjust the values in the code to change the extension / retraction position.
    • If you are writing "0" to the servo and still aren't getting enough extension, you can disassemble the spur gear and repeat the previous assembly step.
    • Try speeding up or slowing down the climbing motions to see if that improves climbing performance. This is done by changing the value of "DelayPeriod".
    • Try climbing on a higher friction surface or adding a high friction material to the rack gear clamp surfaces (rubber bands, a swipe of glue stick, etc...). Different filaments have different friction coefficients - I've had the best luck with a matte black PLA and had trouble climbing with glossy PLA.
  • One or more of the servos are 'whining' and not moving as expected:
    • Test the movement of each servo individually by commenting out the other servos' commands in the above code. If only one is not moving, it may be jammed (try moving it by hand with the power off), or you may be writing to the servo a value that is beyond the physical range of the robot.
    • Check to see if any hot glue or debris made its way onto a bearing surface and is causing high friction or a jam.
    • If all servos are moving sluggishly or getting stuck, the batteries may just need a recharge.
  • I can hear / feel a servo rotating but the related spur gear / motor lever arm is not moving:
    • The printed component may be slipping on the motor drive shaft, so make sure the fastening screw is hand-tight. If needed, you can remove the printed component and apply a dab of hot glue before re-installing it.
Make it Move Contest 2020

Runner Up in the
Make it Move Contest 2020