OmniWorm: an Omni-directional Robot Inchworm

by drewtoby in Circuits > Robots

2114 Views, 5 Favorites, 0 Comments

OmniWorm: an Omni-directional Robot Inchworm

main.jpg
inchworm.jpg
back.jpg
inside_top.jpg
inside_forwards.jpg
inside_backwards.jpg
supplies.jpg
simple_draft.jpg
hacked_servo.jpg
My first Instructable! This tutorial will show you how to build an "Omniworm," or omni-directional robot that is also capable of inchworm-like movement. I have attached two videos below to illustrate:




 



It can be used as a normal ultrasonic obstacle-avoiding robot until it unfolds >:)

The folding wheels only spin when unfolded thanks to two ball tilt switches (one for each motor).

The Arduino is the microcontroller running the robot! I am using the Duemilanove.

As of now its just a fun build. However, I plan to adapt and apply this design for a future project!

Gather Materials and Tools

supplies.jpg
Well... fun and somewhat pricey. Although I made the body out of cardboard, expect to spend over $100 (unless if you have a lot of the stuff at home).


Below Are the Needed Tools:

Soldering Iron with Solder

Hot Glue Gun with Plenty of Hot Glue

Scissors

Wire Cutter

Pocket Knife

Screwdrivers

Wire Strippers

Battery Charger (It may be worth to invest in one of THESE or something similar)



Below Are the Needed Materials:

Cardboard (find around the house or at work)

     Alternatives: PVC Sheet, Thin Plywood, Etc.

Thin Dowel Rod or Metal Rod (local hardware store)

Arduino Duemilanove/Uno (or Chinaduino/Ruggeduino will work)

Your own H-bridge setup or Rugged Motor Driver/Motor Driver Shield (both are compatible, one is more powerful)

     Exception: You don't need the above if you are using 360 degree servos as servos =)

x2 Batteries (I am using THESE. Don't Overpower your Servos!!!)

x2 Male and Female Battery Connectors (I prefer Deans Connectors)

x2 Tilt Sensors (like THESE)

x6 Servos (140 degrees of movement needed with the Arduino. I am using THESE)

x6 Servo Horns (Arms) for the Respective Servos

x4 Mini Breadboards (like THESE)

x4 Gearboxes/Servos (THESE Servos with Wheels or Something like THIS)

     NOTE: I am using those servos as DC motors. Don't let me confuse you. Hey, the servos' electronics were shot!

Sugru

     Optional Depending on Wheel Diameter. I had to Extend my Wheels.

HC-SR04 UltraSonic Sensor (Yay AMAZON!)

Jumper Wires (Buy Some GOOD Ones! This Robot Moves!)


Buy as many of the servos new off Ebay as possible to save yourself a bunch of money. Actually, anything that you can find new on Ebay go for! For the rest, try to purchase everything from one or two places. Jameco is the place I always check!

Make the Chassis

simple_draft.jpg
Here is my simple cutout design. You will have to measure your batteries and wheels, then adapt the design accordingly. You may have to remove part of the side to allow the servo horn (arm) to move freely.

Solder Your Electronics

hacked_servo.jpg
Here is my hacked 360 servo! If your are interested I am just using it as a dc motor by taking off the back, pulling off the three wires, putting the screws back in (with a little hot glue to keep the gearbox together), and soldering wires directly to the motor ONLY.

Dc Motors will need soldered. Be careful to not pull off the tabs! Hot glue helps.

You can either solder your Ultrasonic Sensor or try using Female Jumper Cables.

You will need enough wire to connect the soldered component to the breadboard.

Here is a good tutorial if you have not soldered before. Be careful! Try to avoid soldering the ultrasonic sensors by using female jumper cables.



Mount Your Electronics Then Wire Away!

inside_top.jpg
Mounting is one of the hardest parts.

SERVOS: Be sure to set your servos to the closed or opened position via Arduino, then attach your servo horn (arm) accordingly. This sketch may help. Remember, not all servos go to 0 or 180! The 313WP servos only go from 20 to 160 degrees. Once set accordingly, hot-glue your rod to the servo horn (arm). Then carefully glue the servo to the moving section, and the rod to the stable section. Give enough room for the sections to open and close without hitting each other. Leave a little room for wires.

Batteries: I put mine on either side of the fixed drive wheels.

Arduino: I put mine on top of one of the batteries.

Ultrasonic Sensor: I only used one on the front next to the wheel. It can really go anywhere, and more than one can be used. Just adjust your program accordingly!

Mount a breadboard by each folding tire, and 1-2 in the middle. This is where the tilt sensors will go.

Wheels: You can see where I put mine. If they don't touch the ground, then use sugru to extend the wheels! (It is the yellow, white, and black stuff on my fixed wheels.)

Be sure to use enough hot glue! Oh, and don't burn yourself like I did XD


Wiring is easy but time-consuming.

You will need to leave extra wire to prevent the connections from coming undone when the robot unfolds (wire with it unfolded and leave a little extra wire). Start by connecting the ground of the extra battery to the Arduino's, and the outputs of the Arduino to the fixed breadboard. Wire accordingly from there. The ultrasonic sensor uses the Arduino's 5v pin. To use the tilt sensor just add one of your servo's or dc motor's wire to one end, and then connect the other end to the correct wire. When the ball is down the current will go through. Play with it so it only allows current to go through when the side is unfolded.


Glued the sides of your robot on once the wiring and mounting are complete.

Program, Then Enjoy Your New Robot!

inchworm.jpg
/*



Below is the obstacle-avoiding code for OmniWorm! Feel free to adapt it accordingly.
------------------------------------------------------------------------------------



What you need to change:
------------------------




SERVO CODE: Two servos may turn different directions for each angle
sent to it. Therefore, test each servo seperatly. Set them to the
max angle before you mount them to ensure the robot will fold into
a box and that the servos will not push seperate directions. Also,
you may need to use the sixth servo (servoFront2) depending on the
weight of your design. Mine is only 3lbs total so I don't need it :P


SERVOS: 313WP servos go from 20 to 160 degrees without editing the
servo library. 140 degrees is good enough for this application
though. If you use different servos, you may get more or less than
140 degrees. If the servo is rated for 180 degrees and you get a
lot less, either use pwm or try changing the min and max pulsewidths
in the servo library (servo.h). To edit the file, downoad Notepad++


MOTOR CODE: I am using a half-broken rugged motor driver from rugged
circuits. The pin labled EM is soldered to Dir2 on the shield as the
normal pin was not changing direction. If you are using the same
shield, then erase EM and carry on! If you are using an h-bridge,
then feel free to use pins 3, 11-13 or choose your own. Be careful
not to overpower the circuit though! Below are links to tutorials.
The last link is where you can buy the shield that I am using!

http://itp.nyu.edu/physcomp/Labs/DCMotorControl

http://www.ecs.umass.edu/ece/m5/tutorials/H-Bridge_tutorial.html

http://www.societyofrobots.com/schematics_h-bridgedes.shtml

http://www.ruggedcircuits.com/motor-control/rugged-motor-driver


MOTORS: Do your wallet a big favor and don't tear apart namebrand
Parallex servos to run as DC motors (unless if they were broken
like mine were). If you do hack them, simply unscrew the back,
pull the three wires off, put the screws back in to hold the
gearbox together (some hotglue might help), and carefully solder a
wire to each DC motor end ONLY. Excess solder might strain the setup.
But I would simply buy yellow robot wheels/gearboxs off ebay.
Search for "robot wheel" and they will pop up. Alternativly, use
the 360 degree servos as... well... servos! You can add or
subtract angles for forward/backward movement.


FUNCTIONS: You will have to edit the functions (or play with wires)
to get it to work with your design. Some good old trial and error
will do the trick!



A few words of advice:
----------------------



If you are using an external power source for your servos, connect
the ground to the arduino's ground. Also, be careful not to plug
your battery in backwords or short it out... it can easily kill
your servos. Furthermore, if you overpower a servo it may die. Start
your servos off at low power and work your way up. My setup is
pushing it... >:)


I would suggest that you find (or make!) your own h-bridge to contol
your motors. Also, connect the ground to the arduino. Be careful to
not overpower your setup! Finally, a reset function keeps the setup
from shorting.

Don't forget you need tilt sensors if you are going to stop the side
wheels from moving when drawing current!

Don't feel limited to the pins I am using. Choose your own digital
pins!!!


My code is adapted from:
------------------------



http://www.ruggedcircuits.com/rugged-motor-driver

http://arduino.cc/en/Reference/ServoWrite

http://arduinobasics.blogspot.com/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html



*/

#include <Servo.h>
//Include the Servo Library so we don't have to use PWM

Servo servoFront;
Servo servoFront2;
Servo servoTail;
Servo servoTail2;
Servo servoBack;
Servo servoBack2;

//This defines our servo names (servoFront etc.)


// Enable (PWM) outputs (Rugged Shield)
#define EN1_PIN 3
#define EN2_PIN 11

// Direction outputs (Rugged Shield)
#define DIR1_PIN 12
#define DIR2_PIN 13
#define EM 10 //Cause 13 don't want to work. Unlucky number! =/


#define echoPin 8 // Echo Pin (for ultrasonic sensor)
#define trigPin 9 // Trigger Pin (for ultrasonic sensor)


int maximumRange = 200; // Maximum range needed (can change)
int minimumRange = 0; // Minimum range needed (can change)
long duration, distance; // Duration used to calculate distance

void setup() {

  servoFront.attach(6);
  servoTail.attach(1);
  servoTail2.attach(2);
  servoBack.attach(4);
  servoBack2.attach(5);

  pinMode(EN1_PIN, OUTPUT);
  digitalWrite(EN1_PIN, LOW);
  pinMode(EN2_PIN, OUTPUT);
  digitalWrite(EN2_PIN, LOW);
  pinMode(DIR1_PIN, OUTPUT);
  digitalWrite(DIR1_PIN, LOW);
  pinMode(DIR2_PIN, OUTPUT);
  digitalWrite(DIR2_PIN, LOW);

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //Setup the Inputs/Outputs for motors/servos/sensor

  closed();
  delay (1000);

  //Keeps the robot folded before the loop starts.
}

void loop(){
  reset;
  delay(50);
  closed();
  scan(); //measures distance via ultrasonic sensor
  delay(90);

  if (distance <= 20 && distance >= 0){ //if the distance is less than 15 cm
    opened();
    delay(1000);
    reset();
    delay(50);
    spin_right();
    opened();
    delay(1500);
    closed();
    delay(1000);
    scan();
    delay(800);
    if (distance <= 15 && distance >= 0){
      opened();
      delay(1000);
      reset();
      delay(50);
      spin_left();
      opened();
      delay(2200);
    }
    else {
      reset();
      delay(50);
      inch();
      inch();
      inch();
      inch();
      inch();
    }   
  }

  else { //if the distance is greater than 15 cm
    reset();
    delay(50);
    closed();
    forward();
    delay(1000);
  }   
}

/*
Below are functions we call through out our loop. It makes life a lot
easier, as you can control multiple pins and servos at once!
*/

void closed(){
  servoFront.write(20);
  servoTail.write(20);
  servoTail2.write(160);
  servoBack.write(20);
  servoBack2.write(160);
}

void opened(){
  servoFront.write(140);
  servoTail.write(20);
  servoTail2.write(160);
  servoBack.write(100);
  servoBack2.write(80);
}   

void inch(){
  closed();
  delay(1000);
  servoTail.write(160);
  servoTail2.write(20);
  delay(1000);
  servoTail.write(160);
  servoTail2.write(20);
  servoBack.write(160);
  servoBack2.write(20);
  delay(1000);
  servoTail.write(20);
  servoTail2.write(160);
  servoBack.write(160);
  servoBack2.write(20);
  delay(1000);
  servoFront.write(140);
  delay(1000);


void spin_right(){
  digitalWrite(DIR1_PIN, HIGH);
  analogWrite(EN1_PIN, 255);   
  digitalWrite(DIR2_PIN, HIGH);
  analogWrite(EN2_PIN, 255);
  digitalWrite(EM, HIGH);
}

void spin_left(){
  digitalWrite(DIR1_PIN, LOW);
  analogWrite(EN1_PIN, 255);   
  digitalWrite(DIR2_PIN, HIGH);
  analogWrite(EN2_PIN, 255);   
  digitalWrite(EM, LOW);
}

void backward(){
  digitalWrite(DIR1_PIN, HIGH);
  analogWrite(EN1_PIN, 255);   
  digitalWrite(DIR2_PIN, LOW); 
  digitalWrite(EM, HIGH);
  analogWrite(EN2_PIN, 255);  
}

void forward(){
  digitalWrite(DIR2_PIN, HIGH);
  analogWrite(EN2_PIN, 255);   
  digitalWrite(DIR1_PIN, LOW); 
  analogWrite(EN1_PIN, 255);  
  digitalWrite(EM, HIGH);
}

void reset(){
  analogWrite(EN2_PIN, 0);     
  analogWrite(EN1_PIN, 0);     
  delay(15);
}

void scan(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  //Calculate the distance (in cm) based on the speed of sound.
  distance = duration/58.2;

  delay(50);
}