Introduction: Simple 18dof Hexapod, Arduino Nano (optionally With Pololu Maestro)
Hello,
Here is a simple hexapod that can be built by hand very quickly. The mechanical design is not great, but it is very much in the KISS (keep it stupidly simple) style and should be doable in a weekend for builders of novice to medium experience.
I won't be improving this project any time soon, and people seem to visit my blog from pololu, so I thought I'd go ahead and document it as is. I built this for a sophomore mechanical engineering class at MIT. The wires and six legs make it look complicated, but since the legs are just the same thing repeated 6 times, it's simpler than it appears. Additionally, I did not implement remote controls so all the code runs autonomously (zero input, multiple output system).
Again, this is documentation of the exact steps involved in a semi-working project. No theoretical underpinnings for designing your own hexapod are really explained here.
A complete picture set of the build process exists here: 2.007 Hexapod (Spring 2011). The first few pictures on there are from Aluminum Hexalinkagepod, based off of the Parallax boebot hexapod.
A set of blog posts exists here: http://orangenarwhals.blogspot.com/search/label/hexaringapod
I would specifically recommend this post: http://orangenarwhals.blogspot.com/2011/05/dreaming-of-dancing-hexapods-2007.html
A video explaining the design process in 7 minutes (this instructables goes into the construction but not the design): http://youtu.be/qTh-OGA_LeM
and here is a video of it at the end:
Here is a simple hexapod that can be built by hand very quickly. The mechanical design is not great, but it is very much in the KISS (keep it stupidly simple) style and should be doable in a weekend for builders of novice to medium experience.
I won't be improving this project any time soon, and people seem to visit my blog from pololu, so I thought I'd go ahead and document it as is. I built this for a sophomore mechanical engineering class at MIT. The wires and six legs make it look complicated, but since the legs are just the same thing repeated 6 times, it's simpler than it appears. Additionally, I did not implement remote controls so all the code runs autonomously (zero input, multiple output system).
Again, this is documentation of the exact steps involved in a semi-working project. No theoretical underpinnings for designing your own hexapod are really explained here.
A complete picture set of the build process exists here: 2.007 Hexapod (Spring 2011). The first few pictures on there are from Aluminum Hexalinkagepod, based off of the Parallax boebot hexapod.
A set of blog posts exists here: http://orangenarwhals.blogspot.com/search/label/hexaringapod
I would specifically recommend this post: http://orangenarwhals.blogspot.com/2011/05/dreaming-of-dancing-hexapods-2007.html
A video explaining the design process in 7 minutes (this instructables goes into the construction but not the design): http://youtu.be/qTh-OGA_LeM
and here is a video of it at the end:
Required items (hardware):
~ Vertical bandsaw (unless you have a lot of patience with a razor)
~ 1/4'' plastic sheet (any reasonable thickness such that the plastic is fairly rigid is fine. I used 1/4'' ABS)
~ About 6'' of
~ 18 R/C servos (I recommend standard size, I've seen hexapods with the tiny 9g servos, but I think that it would be hard to cut out the holes for such servos by hand), complete with the "+" shaped servo horns and servo center screws that should come with the kit.
I used 6 Hitec-311 and 12 Vigor VS-2 servos because that was what I could scavenge for.
~ Screwdriver
~ 4-40 bolts and locknuts (about 48 of them), or whatever bolts fit through your servo flange holes (the side holes). At least 3/8'' long (enough for the 1/4'' plastic or Al and a locknut to fit on there).
~ Drill and drill bit, ideally also a drill press
~ Ratchet or socket wrench for 4-40 bolts
~ Ideally, a vice or clamp
~ Ideally, a horizontal bandsaw
~Optional: Scrap 2x4 wood
~ Measuring instrument, ruler or vastly preferably calipers
~ Optional: Deburring tool
Required items (electronics):
~ Arduino nano + breadboard + male headers (for the servos)
~ Either 6 Y-splitter servo cables or a pololu serial servo controller (because the default arduino library only supports 12 servos). I bought an 24ch one, but obviously didn't need all 24 ch, not sure why I did that. >.<;; but I am a conservative person and tend to make large purchases just in case. I'm working on fixing this.
I guess another option is to use an arduino mega.
~ Laptop and usb programming cable appropriate for your flavor of arduino
~ Male Headers
~ Jumper wires (or single core wire suitable for breadboards)
~ Potentially some servo extension cables, female-to-female (and you stick headers in them to make them female-to-male) will come in handy.
~ Breadboard (probably a standard 700 point one is best if you are putting the nano onto the breadboard)
~ Battery pack (I recommend a rechargeable battery flavor of battery pack, as the 18 servos are power hungry)
~~ so you could use a 4xAA battery pack and it'd be fine (the servos are nominally 5V servos but they will run fine at 6v, they will just be a bit twitchy because their circuitry/feedback+controls are designed for 5v use), but if they were alkaline batteries (~3000mAh) they would run out after an hour or less of use
~~alternatively, use a LM7805 chip to regulate a lipo battery pack, which runs at 7.4v, down to 5V. These linear power regulators dissipate the extra energy as heat. For how to use one, please google "7805 tutorial". For instance, see: http://jumptuck.com/2011/11/15/voltage-regulation-friend-7805/.
Time required: 1 weekend if you just follow my design. I encourage you to design your own hexapod though, once you see how easy it is!
What I used also included a 2.007 (that's a course at MIT) carrier board (looks like https://sites.google.com/site/2007arduino/). This just brings the servo pins out for easy access, as well as has a built in breadboard and a switching power regulator* that can supply up to 3A at 5v, which is probably enough for the 18 servos. It seemed to function a-okay, but my code only ever had 6 servos moving at any given time.
I also made my own battery pack out of some Sanyo UR18650U batteries that were donated to MITERS by Tesla. They are 3.6V, so I made a 2-series, 3 parallel battery pack for a 7.2V 3.3Ah battery pack. This is obviously overkill. At 3.3 Ah and continuously drawing 3A, I could run my hexapod for over an hour. I've found that 10-20 minutes is plenty of runtime for hexapod.
*as opposed to a LM7805 linear power regulator, a switching power regulator is much more efficient.
Note:The hexapod CAD files are for Solidworks 2012 and do not detail nuts and bolts, they are for reference only. I also made a diameter versus radius error on the body, so the body is too big.
==
Submitted by MITERS for the Instructables Sponsorship Program.
~ Vertical bandsaw (unless you have a lot of patience with a razor)
~ 1/4'' plastic sheet (any reasonable thickness such that the plastic is fairly rigid is fine. I used 1/4'' ABS)
~ About 6'' of
~ 18 R/C servos (I recommend standard size, I've seen hexapods with the tiny 9g servos, but I think that it would be hard to cut out the holes for such servos by hand), complete with the "+" shaped servo horns and servo center screws that should come with the kit.
I used 6 Hitec-311 and 12 Vigor VS-2 servos because that was what I could scavenge for.
~ Screwdriver
~ 4-40 bolts and locknuts (about 48 of them), or whatever bolts fit through your servo flange holes (the side holes). At least 3/8'' long (enough for the 1/4'' plastic or Al and a locknut to fit on there).
~ Drill and drill bit, ideally also a drill press
~ Ratchet or socket wrench for 4-40 bolts
~ Ideally, a vice or clamp
~ Ideally, a horizontal bandsaw
~Optional: Scrap 2x4 wood
~ Measuring instrument, ruler or vastly preferably calipers
~ Optional: Deburring tool
Required items (electronics):
~ Arduino nano + breadboard + male headers (for the servos)
~ Either 6 Y-splitter servo cables or a pololu serial servo controller (because the default arduino library only supports 12 servos). I bought an 24ch one, but obviously didn't need all 24 ch, not sure why I did that. >.<;; but I am a conservative person and tend to make large purchases just in case. I'm working on fixing this.
I guess another option is to use an arduino mega.
~ Laptop and usb programming cable appropriate for your flavor of arduino
~ Male Headers
~ Jumper wires (or single core wire suitable for breadboards)
~ Potentially some servo extension cables, female-to-female (and you stick headers in them to make them female-to-male) will come in handy.
~ Breadboard (probably a standard 700 point one is best if you are putting the nano onto the breadboard)
~ Battery pack (I recommend a rechargeable battery flavor of battery pack, as the 18 servos are power hungry)
~~ so you could use a 4xAA battery pack and it'd be fine (the servos are nominally 5V servos but they will run fine at 6v, they will just be a bit twitchy because their circuitry/feedback+controls are designed for 5v use), but if they were alkaline batteries (~3000mAh) they would run out after an hour or less of use
~~alternatively, use a LM7805 chip to regulate a lipo battery pack, which runs at 7.4v, down to 5V. These linear power regulators dissipate the extra energy as heat. For how to use one, please google "7805 tutorial". For instance, see: http://jumptuck.com/2011/11/15/voltage-regulation-friend-7805/.
Time required: 1 weekend if you just follow my design. I encourage you to design your own hexapod though, once you see how easy it is!
What I used also included a 2.007 (that's a course at MIT) carrier board (looks like https://sites.google.com/site/2007arduino/). This just brings the servo pins out for easy access, as well as has a built in breadboard and a switching power regulator* that can supply up to 3A at 5v, which is probably enough for the 18 servos. It seemed to function a-okay, but my code only ever had 6 servos moving at any given time.
I also made my own battery pack out of some Sanyo UR18650U batteries that were donated to MITERS by Tesla. They are 3.6V, so I made a 2-series, 3 parallel battery pack for a 7.2V 3.3Ah battery pack. This is obviously overkill. At 3.3 Ah and continuously drawing 3A, I could run my hexapod for over an hour. I've found that 10-20 minutes is plenty of runtime for hexapod.
*as opposed to a LM7805 linear power regulator, a switching power regulator is much more efficient.
Note:The hexapod CAD files are for Solidworks 2012 and do not detail nuts and bolts, they are for reference only. I also made a diameter versus radius error on the body, so the body is too big.
==
Submitted by MITERS for the Instructables Sponsorship Program.
Attachments
Step 1: Make the Paper Templates for Femur and Tibia Segments
We'll be using paper templates to mark out six of the same thing (six legs).
My tibia ended up (after a few iterations) being 1.4x3.75 inches, with holes marked appropriately for where the servo horns would go.
My coxa ended up being 1.42x4.83 inches, with an appropriately sized hole cut out for the servo. The curve on the leg is an arbitrary "it looks nice" curve I cut out directly on the bandsaw (I started out with rectangular legs).
The CAD model you see in the pictures is a later and better (read: smaller and lighter, more appropriate for the servos) revision than the paper templates, and should give you some idea of how it the hexapod is assembled. So ignore the dimensions written on the paper template in the pictures.
Once you are done making the templates, mark them onto the plastic sheet in preparation for cutting. For marking the holes, sharpie bleeds through paper so just line the paper templates up with the plastic and mark the template with sharpie and it should show up on the plastic. I actually cut the legs out and then marked the holes; you can do it in any order.
My tibia ended up (after a few iterations) being 1.4x3.75 inches, with holes marked appropriately for where the servo horns would go.
My coxa ended up being 1.42x4.83 inches, with an appropriately sized hole cut out for the servo. The curve on the leg is an arbitrary "it looks nice" curve I cut out directly on the bandsaw (I started out with rectangular legs).
The CAD model you see in the pictures is a later and better (read: smaller and lighter, more appropriate for the servos) revision than the paper templates, and should give you some idea of how it the hexapod is assembled. So ignore the dimensions written on the paper template in the pictures.
Once you are done making the templates, mark them onto the plastic sheet in preparation for cutting. For marking the holes, sharpie bleeds through paper so just line the paper templates up with the plastic and mark the template with sharpie and it should show up on the plastic. I actually cut the legs out and then marked the holes; you can do it in any order.
Step 2: Cut Out the Femur and Tibia Segments
I used a vertical bandsaw for cutting out the femur and tibia segments. Make sure to wear safety glasses and take appropriate safety precautions (no loose hair/jewelry/clothing, etc.).
For the tibia and cutting out where the servo fits through, since the bandsaw blade can't just turn around when you hit the inside corners, instead of one continuous cut, you make two half-moon cuts from opposite sides and then go through and cut the back edge. See the first picture.
For the tibia and cutting out where the servo fits through, since the bandsaw blade can't just turn around when you hit the inside corners, instead of one continuous cut, you make two half-moon cuts from opposite sides and then go through and cut the back edge. See the first picture.
Step 3: Drill Out the Servo Horns and Leg Segments
The servo horns and should have holes the same size for the bolts to drop through and be locked in place with locknuts. Look up "tap and drill sizing chart" on google, then clearance or through hole fits, for whatever size screw you ended up getting. Basically, the holes should be the major diameter of the screws, so that the body of the screw fits through but not the cap.
For instance, for 4-40 screws (#4 size screws with 40 threads per inch), I look up http://www.physics.ncsu.edu/pearl/Tap_Drill_Chart.html and see that I can use either a size 32 or size 30 drill bit for a clearance hole. Probably I will use a size 32, in case my hole is drilled off-center, I have some leeway for the bolt to still fit through even if the femur/tibia segment holes are not lined up perfectly with the servo flange holes.
To prevent too much burring on the back side and give the vice something thick to clamp on to, I put a block of wood behind the servo horns. These holes can all be done free-form with just a hand-drill because the plastic is so soft, especially with a center drill for the femur/tibia segments, but you just won't get nice cuts (and be careful not to send things flying if you don't press down with your hand hard enough). Actually, I really can't recommend doing it without clamps or a vice, for safety's sake.
To make it easier the next time around: I would have used self-tapping screws, or perhaps even just normal screws as the plastic is pretty soft, and then drilled sizing for aluminum (75% thread), e.g. for 4-40 I would have used a size 43 bit. This way, I don't have to deal with the whole locknut thing which takes extra tools and forever to tighten. I would have to have self-tapping screws of the right length, though, since they have pointy ends which might hurt if they stuck out of the plastic.
Yea, locknuts are much better than just two nuts tightened together, which always loosen unless you use locktite, but if you mess up something they take forever to un-tighten and re-tighten.
For instance, for 4-40 screws (#4 size screws with 40 threads per inch), I look up http://www.physics.ncsu.edu/pearl/Tap_Drill_Chart.html and see that I can use either a size 32 or size 30 drill bit for a clearance hole. Probably I will use a size 32, in case my hole is drilled off-center, I have some leeway for the bolt to still fit through even if the femur/tibia segment holes are not lined up perfectly with the servo flange holes.
To prevent too much burring on the back side and give the vice something thick to clamp on to, I put a block of wood behind the servo horns. These holes can all be done free-form with just a hand-drill because the plastic is so soft, especially with a center drill for the femur/tibia segments, but you just won't get nice cuts (and be careful not to send things flying if you don't press down with your hand hard enough). Actually, I really can't recommend doing it without clamps or a vice, for safety's sake.
To make it easier the next time around: I would have used self-tapping screws, or perhaps even just normal screws as the plastic is pretty soft, and then drilled sizing for aluminum (75% thread), e.g. for 4-40 I would have used a size 43 bit. This way, I don't have to deal with the whole locknut thing which takes extra tools and forever to tighten. I would have to have self-tapping screws of the right length, though, since they have pointy ends which might hurt if they stuck out of the plastic.
Yea, locknuts are much better than just two nuts tightened together, which always loosen unless you use locktite, but if you mess up something they take forever to un-tighten and re-tighten.
Step 4: Attach Servos to Femur and Tibia
Time to break out the screwdriver and socket wrench!
I used bins to keep all the servo stuff organized, but that's entirely optional.I used bins to keep all the servo stuff organized, but that's entirely optional.
It's easy to zone out and put one or the other servo horn facing the wrong way or flipped or whatever -- again, locknuts are a pain to redo.
Make sure to use the center screw to screw into the servo. This keeps the leg segment from falling off of the servo.
I used bins to keep all the servo stuff organized, but that's entirely optional.I used bins to keep all the servo stuff organized, but that's entirely optional.
It's easy to zone out and put one or the other servo horn facing the wrong way or flipped or whatever -- again, locknuts are a pain to redo.
Make sure to use the center screw to screw into the servo. This keeps the leg segment from falling off of the servo.
Step 5: Bandsaw and Drill the Coxa Segments
These segments are cut out of the 1/4'' angle aluminum stock. They should be just longer than the servo flanges. I did this on the horizontal bandsaw and cut them to by 0.45'' wide. You could in theory do it on the vertical bandsaw if you had parallels set up on one side and a push stick. Definitely don't try cutting this out just free form with two hands, because 0.45'' is way too close to the blade for you to not lose a finger.
I measured the distance to each of the two holes by using calipers on the servo and estimating by eye where the centers of the holes were.
I gently scribed where each hole would go by setting my calipers to the right distance and then locking it, then brushing the tip of my el cheapo calipers across the aluminum. See http://www.botlanta.org/uploads/pdf/caliper_abuse.pdf for more details on how to do this (written by my friend, charles guan / teamtestbot / etotheipiplusone / e0designs). Sharpie may be applied beforehand so you can see the scribed line better afterwards.
Then I went in with a center punch and center punch all of the holes.
Finally I went in with a drill press and drilled out all of the holes, then used a deburring tool on all the edges.
I measured the distance to each of the two holes by using calipers on the servo and estimating by eye where the centers of the holes were.
I gently scribed where each hole would go by setting my calipers to the right distance and then locking it, then brushing the tip of my el cheapo calipers across the aluminum. See http://www.botlanta.org/uploads/pdf/caliper_abuse.pdf for more details on how to do this (written by my friend, charles guan / teamtestbot / etotheipiplusone / e0designs). Sharpie may be applied beforehand so you can see the scribed line better afterwards.
Then I went in with a center punch and center punch all of the holes.
Finally I went in with a drill press and drilled out all of the holes, then used a deburring tool on all the edges.
Step 6: Attach Servos to Coxa Segments
What the title says.
If any of the holes are off-center, remember that you really only need to attach two screws (one on either side) to the servo, not all four flange screws.
Repeat six times. Yea, you see what I mean about using self-tapping screws instead of bolts+locknuts now, because that is a _lot_ of locknuts to tighten.
If any of the holes are off-center, remember that you really only need to attach two screws (one on either side) to the servo, not all four flange screws.
Repeat six times. Yea, you see what I mean about using self-tapping screws instead of bolts+locknuts now, because that is a _lot_ of locknuts to tighten.
Step 7: Mark Out the Body
If you can, print out the template I provided. Otherwise, as follows:
Design: Again, no real math went into the design of this hexapod. I simply eyeballed how close together the legs could be and drew out a circle that big. See the paper on the right in the first picture for how I thought about it.
I treated it as an exercise to mark out that circle with just calipers, no compass. To do so, refer to www.botlanta.org/uploads/pdf/caliper_abuse.pdf again, starting on page 27.
Specifically, for a hexagon, referring to (http://media.photobucket.com/user/oldtiffie/media/Black_book/Polygon_measure1.jpg), the side length is just one-half the diameter.
So using the caliper technique (scribing two arcs of 1/2*D and finding the center point to determine the next point on the hexagon), I marked out six dots and then draw arcs between them to complete a circle (diameter = 5.9'').
Then I placed the servo horn on there and marked out where the center of the servo horn would go, then marked out another circle that big (diameter = 5.3'') with 6 points. Finally, I marked out two holes for each of the servo horns (four is really overkill) by just placing the servo horn center over the center dot and then orienting like an "X" instead of a "+" and using pencil to mark the two holes.
Tape the template onto the plastic, bandsaw in a circle, drill out the holes. Done!
Design: Again, no real math went into the design of this hexapod. I simply eyeballed how close together the legs could be and drew out a circle that big. See the paper on the right in the first picture for how I thought about it.
I treated it as an exercise to mark out that circle with just calipers, no compass. To do so, refer to www.botlanta.org/uploads/pdf/caliper_abuse.pdf again, starting on page 27.
Specifically, for a hexagon, referring to (http://media.photobucket.com/user/oldtiffie/media/Black_book/Polygon_measure1.jpg), the side length is just one-half the diameter.
So using the caliper technique (scribing two arcs of 1/2*D and finding the center point to determine the next point on the hexagon), I marked out six dots and then draw arcs between them to complete a circle (diameter = 5.9'').
Then I placed the servo horn on there and marked out where the center of the servo horn would go, then marked out another circle that big (diameter = 5.3'') with 6 points. Finally, I marked out two holes for each of the servo horns (four is really overkill) by just placing the servo horn center over the center dot and then orienting like an "X" instead of a "+" and using pencil to mark the two holes.
Tape the template onto the plastic, bandsaw in a circle, drill out the holes. Done!
Attachments
Step 8: Assemble Legs Onto Body
Make sure to put the servo horns on the body first, assembling with bolts+locknuts, and then attach the servo with the center screw. Because it doesn't go on the other way!
The first picture shows some posts I hot glued on. These didn't last. But that brings to mind
Revision: I would have included some standoffs for the controlboard to sit on and with space underneath for the battery pack to velcro in.
The second picture is from an older revision, but shows the order of installation.
Congratulations! You have a complete hexapod body! That wasn't so bad.
The first picture shows some posts I hot glued on. These didn't last. But that brings to mind
Revision: I would have included some standoffs for the controlboard to sit on and with space underneath for the battery pack to velcro in.
The second picture is from an older revision, but shows the order of installation.
Congratulations! You have a complete hexapod body! That wasn't so bad.
Step 9: Wire 'er Up! 12 Servo Output Version
Note: Servos go Ground-Power-Signal, usually black-red-yellowororange, with convention on most PCBs placing the GND facing out.
12 SERVO OUTPUT VERSION
Suitable for limitations of default Arduino servo library. See first two pictures for wiring with the 2.007 nano carrier board.
Breadboard Setup
If you don't have a 2.007 carrier board (not for sale as of 24 June 2013, although that may change), put the nano on the breadboard and wire accordingly, with the 5V source in the picture being replaced by your 5v source (e.g. LM7805 with a 4xAA battery pack as described in the first step). You don't want to just put 4xAA into your arduino on "VIN" and then use the "5V" on the arduino because that puts it through a regulator that cannot handle enough current to supply all 18 servos -- your hexapod will be droopy and sleepy as overcurrent protection kicks in on the arduino, unless you just fry your arduino. You must supply both the arduino and the lm7805 circuit from the 4xAA battery pack and then use the LM7805 circuit output to supply your servos in order to not starve them of current.
See https://www.instructables.com/id/How-to-use-a-breadboard/ if you've never used a breadboard before
Servo Wiring
Okay, so we have six Y-splitter cables. They will be controlling 12 servos total (2 each). Then we have 6 more independent legs, for 12 servo outputs required total. Now pick a face to be the front of the hexapod, and mentally split the legs evenly down either side. The front and back servos (coxa, femur, tibia) of each side will be wired together, and the middle legs will be independent.
Thus, in the code, we will only need 12 servo outputs, like so:
/*
~front~
A D
B E
C F
~back~
*/
Servo E_coxa;
Servo E_femur;
Servo E_tibia;
Servo B_coxa;
Servo B_femur;
Servo B_tibia;
Servo AC_coxa;
Servo AC_femur;
Servo AC_tibia;
Servo DF_coxa;
Servo DF_femur;
Servo DF_tibia;
Note: In the picture, I have the letters placed incorrectly around the circular hexapod. Notice that it doesn't matter for explaining how the tripod gait works.
12 SERVO OUTPUT VERSION
Suitable for limitations of default Arduino servo library. See first two pictures for wiring with the 2.007 nano carrier board.
Breadboard Setup
If you don't have a 2.007 carrier board (not for sale as of 24 June 2013, although that may change), put the nano on the breadboard and wire accordingly, with the 5V source in the picture being replaced by your 5v source (e.g. LM7805 with a 4xAA battery pack as described in the first step). You don't want to just put 4xAA into your arduino on "VIN" and then use the "5V" on the arduino because that puts it through a regulator that cannot handle enough current to supply all 18 servos -- your hexapod will be droopy and sleepy as overcurrent protection kicks in on the arduino, unless you just fry your arduino. You must supply both the arduino and the lm7805 circuit from the 4xAA battery pack and then use the LM7805 circuit output to supply your servos in order to not starve them of current.
See https://www.instructables.com/id/How-to-use-a-breadboard/ if you've never used a breadboard before
Servo Wiring
Okay, so we have six Y-splitter cables. They will be controlling 12 servos total (2 each). Then we have 6 more independent legs, for 12 servo outputs required total. Now pick a face to be the front of the hexapod, and mentally split the legs evenly down either side. The front and back servos (coxa, femur, tibia) of each side will be wired together, and the middle legs will be independent.
Thus, in the code, we will only need 12 servo outputs, like so:
/*
~front~
A D
B E
C F
~back~
*/
Servo E_coxa;
Servo E_femur;
Servo E_tibia;
Servo B_coxa;
Servo B_femur;
Servo B_tibia;
Servo AC_coxa;
Servo AC_femur;
Servo AC_tibia;
Servo DF_coxa;
Servo DF_femur;
Servo DF_tibia;
Note: In the picture, I have the letters placed incorrectly around the circular hexapod. Notice that it doesn't matter for explaining how the tripod gait works.
Step 10: Wire 'er Up! Pololu Serial Servo Controller, 18 Servo Version
18 SERVO OUTPUT VERSION
Pololu
The following instructions are for the 2.007 board, however, they are detailed enough that they should explain what you need to do. Essentially, you need 5 wires: a single "servo output" (just an output pin, plus ground and power for the pololu board) and VSRV and GND for the servos. The two grounds should be connected somewhere (anywhere) in your circuit.
1. Look at labeled picture http://www.pololu.com/docs/0J40/1.b
2. What you need on pololu-side: serial going through to RX pin on pololu, power to VSRV and VIN, ground to GND, and lots of servos
'3. According to our eventual code:
#include <NewSoftSerial.h> #NOTE: July 2013: NewSoftSerial is included by default now, do not use this code -- see later steps in this instructables
#define txPin 2
NewSoftSerial mySerial(rxPin, txPin);
void setup(){
mySerial.begin(9600);
delay(1000);
}
we should take a servo female-female wire, put one end on servo male header pins for pin 2 of Arduino.
4. RX/TX and Microntroller power: Put other end white wire (or yellow or whatever wire is SIG) on RX on maestro, and red (VIN) and black (GND). Should look like the second picture, the wire-with-masking-tape, with black facing "out" toward the USB port.
5. Servo power: see first picture, the two non-servo cables (the red wire and black wire going to the breadboard) are screwed into the blue terminal block on the maestro. The breadboard has 5V and GND from the 8.4V battery going through the linear regulator on the carrier board. I'm actually stealing 5V from a servo pin. See the black wire soldered to Dig9Output, 5V in the upper left of this pic (which is actually carrying 5V, not GND) (via a female header pin so I wasn't soldering straight to the carrier board pins) (ignore the gazillion extraneous wires)
6. Remove VSRV=VIN jumper
Why remove the jumper? Well, a. Makes the pololu RX pin happier (compare to setup below) b. Setting that jumper seems to current-limit the power going to the servos, leading to my sad-servo symptoms. aka unable-to-walk hexapod.
Whether you will find this to be true, I don't know, but certainly this was a very frustrating point for me.
Servo Wiring
Straightforward. Plug in your 18 servos. (Yep, an 18ch maestro would have worked just fine instead of the 24ch one I bought. Even a 12ch one would work, but you would have to split your servo code between arduino and pololu servos and that could get messy).
Pololu
The following instructions are for the 2.007 board, however, they are detailed enough that they should explain what you need to do. Essentially, you need 5 wires: a single "servo output" (just an output pin, plus ground and power for the pololu board) and VSRV and GND for the servos. The two grounds should be connected somewhere (anywhere) in your circuit.
1. Look at labeled picture http://www.pololu.com/docs/0J40/1.b
2. What you need on pololu-side: serial going through to RX pin on pololu, power to VSRV and VIN, ground to GND, and lots of servos
'3. According to our eventual code:
#include <NewSoftSerial.h> #NOTE: July 2013: NewSoftSerial is included by default now, do not use this code -- see later steps in this instructables
#define txPin 2
NewSoftSerial mySerial(rxPin, txPin);
void setup(){
mySerial.begin(9600);
delay(1000);
}
we should take a servo female-female wire, put one end on servo male header pins for pin 2 of Arduino.
4. RX/TX and Microntroller power: Put other end white wire (or yellow or whatever wire is SIG) on RX on maestro, and red (VIN) and black (GND). Should look like the second picture, the wire-with-masking-tape, with black facing "out" toward the USB port.
5. Servo power: see first picture, the two non-servo cables (the red wire and black wire going to the breadboard) are screwed into the blue terminal block on the maestro. The breadboard has 5V and GND from the 8.4V battery going through the linear regulator on the carrier board. I'm actually stealing 5V from a servo pin. See the black wire soldered to Dig9Output, 5V in the upper left of this pic (which is actually carrying 5V, not GND) (via a female header pin so I wasn't soldering straight to the carrier board pins) (ignore the gazillion extraneous wires)
6. Remove VSRV=VIN jumper
Why remove the jumper? Well, a. Makes the pololu RX pin happier (compare to setup below) b. Setting that jumper seems to current-limit the power going to the servos, leading to my sad-servo symptoms. aka unable-to-walk hexapod.
Whether you will find this to be true, I don't know, but certainly this was a very frustrating point for me.
Servo Wiring
Straightforward. Plug in your 18 servos. (Yep, an 18ch maestro would have worked just fine instead of the 24ch one I bought. Even a 12ch one would work, but you would have to split your servo code between arduino and pololu servos and that could get messy).
Step 11: 12 Servo Code
This is for a simple tripod gait. Note that I just fix the tibia joints in place, which is not ideal, but makes the code very understandable. I would say this code is a good jumping off point. The servos in this code are attached on pins 2 through 13.
E_coxa.attach(2);
E_femur.attach(3);
E_tibia.attach(4);
B_coxa.attach(5);
B_femur.attach(6);
B_tibia.attach(7);
AC_coxa.attach(11);
AC_femur.attach(12);
AC_tibia.attach(13);
DF_coxa.attach(8);
DF_femur.attach(9);
DF_tibia.attach(10);
The only values you should need to adjust are AC_up, AC_down, COXA_CW, COXA_CCW, and potentially TIBIA. Probably you don't need to adjust them much if you are also using standard 180deg servos like I am. These I experimentally determined to be the limits if I didn't want the legs crashing into each other or into the main body of the hexapod (going too far up).
https://github.com/nouyang/18-servo-hexapod/blob/master/arduino_may13_2011.pde
Or, as copied below:
======================
#include <Servo.h>
#define TIBIA 45
#define DELAY 300
#define COXA_CCW 70
#define COXA_CW 105
/*
~front~
A D
B E
C F
~back~
*/
#define AC_UP 92
#define AC_DOWN 125
int UP = AC_UP;
int DOWN = AC_DOWN;
Servo E_coxa;
Servo E_femur;
Servo E_tibia;
Servo B_coxa;
Servo B_femur;
Servo B_tibia;
Servo AC_coxa;
Servo AC_femur;
Servo AC_tibia;
Servo DF_coxa;
Servo DF_femur;
Servo DF_tibia;
void setup()
{
digitalWrite(2, OUTPUT);
digitalWrite(3, OUTPUT);
digitalWrite(4, OUTPUT);
digitalWrite(5, OUTPUT);
digitalWrite(6, OUTPUT);
digitalWrite(7, OUTPUT);
digitalWrite(8, OUTPUT);
digitalWrite(9, OUTPUT);
digitalWrite(10, OUTPUT);
digitalWrite(11, OUTPUT);
digitalWrite(12, OUTPUT);
digitalWrite(13, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
E_coxa.attach(2);
E_femur.attach(3);
E_tibia.attach(4);
B_coxa.attach(5);
B_femur.attach(6);
B_tibia.attach(7);
AC_coxa.attach(11);
AC_femur.attach(12);
AC_tibia.attach(13);
DF_coxa.attach(8);
DF_femur.attach(9);
DF_tibia.attach(10);
}
void loop()
{
for (int i=0; i<=2; i++){
walkfwd();
}
for (int j=0; j<=2; j++){
walkbwd();
}
for (int k=0; k<=2; k++){
turnleft();
}
for (int l=0; l<=2; l++){
turnright();
}
}
void walkbwd() {
tibia();
b1();
b2();
b3();
b4();
}
void walkfwd() {
tibia();
tri1();
tri2();
tri3();
tri4();
}
void turnleft() {
tibia();
l1();
l2();
l3();
l4();
}
void turnright() {
tibia();
r1();
r2();
r3();
r4();
}
void tibia() {
AC_tibia.write(TIBIA);
B_tibia.write(TIBIA);
DF_tibia.write(TIBIA);
E_tibia.write(TIBIA);
}
void tri1() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void tri2() {
AC_femur.write(AC_DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void tri3() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void tri4() {
AC_femur.write(AC_UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
void b1() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void b2() {
AC_femur.write(AC_DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void b3() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void b4() {
AC_femur.write(AC_UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
void l1() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void l2() {
AC_femur.write(DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void l3() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void l4() {
AC_femur.write(UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
void r1() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void r2() {
AC_femur.write(DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void r3() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void r4() {
AC_femur.write(UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
E_coxa.attach(2);
E_femur.attach(3);
E_tibia.attach(4);
B_coxa.attach(5);
B_femur.attach(6);
B_tibia.attach(7);
AC_coxa.attach(11);
AC_femur.attach(12);
AC_tibia.attach(13);
DF_coxa.attach(8);
DF_femur.attach(9);
DF_tibia.attach(10);
The only values you should need to adjust are AC_up, AC_down, COXA_CW, COXA_CCW, and potentially TIBIA. Probably you don't need to adjust them much if you are also using standard 180deg servos like I am. These I experimentally determined to be the limits if I didn't want the legs crashing into each other or into the main body of the hexapod (going too far up).
https://github.com/nouyang/18-servo-hexapod/blob/master/arduino_may13_2011.pde
Or, as copied below:
======================
#include <Servo.h>
#define TIBIA 45
#define DELAY 300
#define COXA_CCW 70
#define COXA_CW 105
/*
~front~
A D
B E
C F
~back~
*/
#define AC_UP 92
#define AC_DOWN 125
int UP = AC_UP;
int DOWN = AC_DOWN;
Servo E_coxa;
Servo E_femur;
Servo E_tibia;
Servo B_coxa;
Servo B_femur;
Servo B_tibia;
Servo AC_coxa;
Servo AC_femur;
Servo AC_tibia;
Servo DF_coxa;
Servo DF_femur;
Servo DF_tibia;
void setup()
{
digitalWrite(2, OUTPUT);
digitalWrite(3, OUTPUT);
digitalWrite(4, OUTPUT);
digitalWrite(5, OUTPUT);
digitalWrite(6, OUTPUT);
digitalWrite(7, OUTPUT);
digitalWrite(8, OUTPUT);
digitalWrite(9, OUTPUT);
digitalWrite(10, OUTPUT);
digitalWrite(11, OUTPUT);
digitalWrite(12, OUTPUT);
digitalWrite(13, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
E_coxa.attach(2);
E_femur.attach(3);
E_tibia.attach(4);
B_coxa.attach(5);
B_femur.attach(6);
B_tibia.attach(7);
AC_coxa.attach(11);
AC_femur.attach(12);
AC_tibia.attach(13);
DF_coxa.attach(8);
DF_femur.attach(9);
DF_tibia.attach(10);
}
void loop()
{
for (int i=0; i<=2; i++){
walkfwd();
}
for (int j=0; j<=2; j++){
walkbwd();
}
for (int k=0; k<=2; k++){
turnleft();
}
for (int l=0; l<=2; l++){
turnright();
}
}
void walkbwd() {
tibia();
b1();
b2();
b3();
b4();
}
void walkfwd() {
tibia();
tri1();
tri2();
tri3();
tri4();
}
void turnleft() {
tibia();
l1();
l2();
l3();
l4();
}
void turnright() {
tibia();
r1();
r2();
r3();
r4();
}
void tibia() {
AC_tibia.write(TIBIA);
B_tibia.write(TIBIA);
DF_tibia.write(TIBIA);
E_tibia.write(TIBIA);
}
void tri1() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void tri2() {
AC_femur.write(AC_DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void tri3() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void tri4() {
AC_femur.write(AC_UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
void b1() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void b2() {
AC_femur.write(AC_DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void b3() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void b4() {
AC_femur.write(AC_UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
void l1() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void l2() {
AC_femur.write(DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void l3() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void l4() {
AC_femur.write(UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
void r1() {
AC_coxa.write(COXA_CW);
E_coxa.write(COXA_CW);
DF_coxa.write(COXA_CCW);
B_coxa.write(COXA_CCW);
delay(DELAY);
};
void r2() {
AC_femur.write(DOWN);
E_femur.write(DOWN);
DF_femur.write(UP);
B_femur.write(UP);
delay(DELAY);
};
void r3() {
AC_coxa.write(COXA_CCW);
E_coxa.write(COXA_CCW);
DF_coxa.write(COXA_CW);
B_coxa.write(COXA_CW);
delay(DELAY);
};
void r4() {
AC_femur.write(UP);
E_femur.write(UP);
DF_femur.write(DOWN);
B_femur.write(DOWN);
delay(DELAY);
};
Step 12: 18 Servo Code
See "12 servo" for notes on adjusting the constants. Code is at
https://github.com/nouyang/18-servo-hexapod/blob/master/pololu_aug17-2012.pde.
Explanation:
See documentation at http://www.pololu.com/docs/0J40/5.e
a. BYTE is a parameter that pecifies the base (format) to us http://www.arduino.cc/en/Serial/Print
b. target is a non-negative integer less than 8192 (it can be written in binary notation with 14 or fewer digits)
e.g. 6000, or in binary: 01011101110000
c. 0x7F is 01111111 in binary, which infinity zeros to the left, so "&"ing (bitwise AND) it masks out all the digits in target (when target is written in binary) except the last 7 digits (only 1 AND 1 == 1. all other combinations == 0)
01011101110000
& 00000001111111
= 00000001110000
d. right shift operator, shifts last seven digits (numbers 7 through 13) in target off into empty space and so now the "new" last seven digits were originally bits #0 to 6 (see color-coded pololu doc). Mask with 0x7F again, just to be sure.
01011101110000,>>7 to:
00000000101110, then:
& 00000001111111
= 00000000101110
The main difference from the default code is that I mapped the values so that I could mindlessly port code from arduino-"Servo.write()"-style to pololu-"settarget()"-style.
void settarget(unsigned char servo, unsigned int target)
{
target = map(target, 0, 180, 2400, 9500);
My code, up on github, is also copied below:
======================
#include <SoftwareSerial.h>
#define txPin 2
#define rxPin 3
#define TIBIA 25
#define DELAY 150
#define CW 70
#define CCW 105
#define UP 92
#define DOWN 125
// ~~~~~~~~~~~~~~~~~~~~ //
#define A_COX 1
#define A_FEM 2
#define A_TIB 3
#define B_COX 4
#define B_FEM 5
#define B_TIB 6
#define C_COX 7
#define C_FEM 8
#define C_TIB 9
#define D_COX 10
#define D_FEM 11
#define D_TIB 12
#define E_COX 13
#define E_FEM 14
#define E_TIB 15
#define F_COX 16
#define F_FEM 17
#define F_TIB 18
int numtimes = 3;
SoftwareSerial mySerial(rxPin, txPin);
void setup()// run once, when the sketch starts
{
mySerial.begin(9600);
delay(1000);
}
void loop()
{
for (int i=0; i<=4; i++){
walkfwd();
}
for (int j=0; j<=4; j++){
walkbwd();
}
for (int k=0; k<=2; k++){
turnleft();
}
for (int l=0; l<=2; l++){
turnright();
}
}
void tibia() {
settarget(A_TIB, TIBIA);
settarget(B_TIB, TIBIA);
settarget(C_TIB, TIBIA);
settarget(D_TIB, TIBIA);
settarget(E_TIB, TIBIA);
settarget(F_TIB, TIBIA);
}
// ~~~~~~~~~~fwd~~~~~~~~~~ //
void f1() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CCW);
delay(DELAY);
}
void f2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void f3() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CW);
delay(DELAY);
}
void f4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~bwd~~~~~~~~~~~ //
void b1() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CW);
delay(DELAY);
}
void b2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void b3() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CCW);
delay(DELAY);
}
void b4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~left~~~~~~~~~~~ //
void l1() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CW);
delay(DELAY);
}
void l2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void l3() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CCW);
delay(DELAY);
}
void l4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~right~~~~~~~~~~~ //
void r1() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CCW);
delay(DELAY);
}
void r2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void r3() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CW);
delay(DELAY);
}
void r4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~~~~~~~~~~~~ //
void walkbwd() {
tibia();
b1();
b2();
b3();
b4();
}
void walkfwd() {
tibia();
f1();
f2();
f3();
f4();
}
void turnleft() {
tibia();
l1();
l2();
l3();
l4();
}
void turnright() {
tibia();
r1();
r2();
r3();
r4();
}
// ~~~~~~~~~~~~~~~~~~~~ //
//Send a Set Target command to the Maestro.
//Target is in units of quarter microseconds, so the normal range is 4000 to 8000.
void settarget(unsigned char servo, unsigned int target)
{
target = map(target, 0, 180, 2400, 9500);
mySerial.write(0xAA); //start byte
mySerial.write(0x0C) ; //device id
mySerial.write(0x04); //command number
mySerial.write(servo); //servo number
mySerial.write(target & 0x7F);
mySerial.write((target >> 7) & 0x7F);
}
https://github.com/nouyang/18-servo-hexapod/blob/master/pololu_aug17-2012.pde.
Explanation:
See documentation at http://www.pololu.com/docs/0J40/5.e
a. BYTE is a parameter that pecifies the base (format) to us http://www.arduino.cc/en/Serial/Print
b. target is a non-negative integer less than 8192 (it can be written in binary notation with 14 or fewer digits)
e.g. 6000, or in binary: 01011101110000
c. 0x7F is 01111111 in binary, which infinity zeros to the left, so "&"ing (bitwise AND) it masks out all the digits in target (when target is written in binary) except the last 7 digits (only 1 AND 1 == 1. all other combinations == 0)
01011101110000
& 00000001111111
= 00000001110000
d. right shift operator, shifts last seven digits (numbers 7 through 13) in target off into empty space and so now the "new" last seven digits were originally bits #0 to 6 (see color-coded pololu doc). Mask with 0x7F again, just to be sure.
01011101110000,>>7 to:
00000000101110, then:
& 00000001111111
= 00000000101110
The main difference from the default code is that I mapped the values so that I could mindlessly port code from arduino-"Servo.write()"-style to pololu-"settarget()"-style.
void settarget(unsigned char servo, unsigned int target)
{
target = map(target, 0, 180, 2400, 9500);
My code, up on github, is also copied below:
======================
#include <SoftwareSerial.h>
#define txPin 2
#define rxPin 3
#define TIBIA 25
#define DELAY 150
#define CW 70
#define CCW 105
#define UP 92
#define DOWN 125
// ~~~~~~~~~~~~~~~~~~~~ //
#define A_COX 1
#define A_FEM 2
#define A_TIB 3
#define B_COX 4
#define B_FEM 5
#define B_TIB 6
#define C_COX 7
#define C_FEM 8
#define C_TIB 9
#define D_COX 10
#define D_FEM 11
#define D_TIB 12
#define E_COX 13
#define E_FEM 14
#define E_TIB 15
#define F_COX 16
#define F_FEM 17
#define F_TIB 18
int numtimes = 3;
SoftwareSerial mySerial(rxPin, txPin);
void setup()// run once, when the sketch starts
{
mySerial.begin(9600);
delay(1000);
}
void loop()
{
for (int i=0; i<=4; i++){
walkfwd();
}
for (int j=0; j<=4; j++){
walkbwd();
}
for (int k=0; k<=2; k++){
turnleft();
}
for (int l=0; l<=2; l++){
turnright();
}
}
void tibia() {
settarget(A_TIB, TIBIA);
settarget(B_TIB, TIBIA);
settarget(C_TIB, TIBIA);
settarget(D_TIB, TIBIA);
settarget(E_TIB, TIBIA);
settarget(F_TIB, TIBIA);
}
// ~~~~~~~~~~fwd~~~~~~~~~~ //
void f1() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CCW);
delay(DELAY);
}
void f2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void f3() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CW);
delay(DELAY);
}
void f4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~bwd~~~~~~~~~~~ //
void b1() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CW);
delay(DELAY);
}
void b2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void b3() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CCW);
delay(DELAY);
}
void b4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~left~~~~~~~~~~~ //
void l1() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CW);
delay(DELAY);
}
void l2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void l3() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CCW);
delay(DELAY);
}
void l4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~right~~~~~~~~~~~ //
void r1() {
// [COXA] changed
settarget(A_COX, CW);
settarget(C_COX, CW);
settarget(E_COX, CW);
settarget(D_COX, CCW);
settarget(F_COX, CCW);
settarget(B_COX, CCW);
delay(DELAY);
}
void r2() {
// [FEMUR] changed
settarget(A_FEM, DOWN);
settarget(C_FEM, DOWN);
settarget(E_FEM, DOWN);
settarget(D_FEM, UP);
settarget(F_FEM, UP);
settarget(B_FEM, UP);
delay(DELAY);
}
void r3() {
// [COXA] changed
settarget(A_COX, CCW);
settarget(C_COX, CCW);
settarget(E_COX, CCW);
settarget(D_COX, CW);
settarget(F_COX, CW);
settarget(B_COX, CW);
delay(DELAY);
}
void r4() {
// [FEMUR] changed
settarget(A_FEM, UP);
settarget(C_FEM, UP);
settarget(E_FEM, UP);
settarget(D_FEM, DOWN);
settarget(F_FEM, DOWN);
settarget(B_FEM, DOWN );
delay(DELAY);
}
// ~~~~~~~~~~~~~~~~~~~~ //
void walkbwd() {
tibia();
b1();
b2();
b3();
b4();
}
void walkfwd() {
tibia();
f1();
f2();
f3();
f4();
}
void turnleft() {
tibia();
l1();
l2();
l3();
l4();
}
void turnright() {
tibia();
r1();
r2();
r3();
r4();
}
// ~~~~~~~~~~~~~~~~~~~~ //
//Send a Set Target command to the Maestro.
//Target is in units of quarter microseconds, so the normal range is 4000 to 8000.
void settarget(unsigned char servo, unsigned int target)
{
target = map(target, 0, 180, 2400, 9500);
mySerial.write(0xAA); //start byte
mySerial.write(0x0C) ; //device id
mySerial.write(0x04); //command number
mySerial.write(servo); //servo number
mySerial.write(target & 0x7F);
mySerial.write((target >> 7) & 0x7F);
}
Step 13: Further Reading
Congratulations on finishing! Now pose for a picture with your hexapod as it dances! :D
Further Reading
This whole hexapod shenanigans was inspired by youtube: dancing hexapods...
For more hexapod craziness, see my (a bit elderly) gallery here of ones around the internet here: http://orangenarwhals.blogspot.com/2011/07/strange-and-beautiful-hexapods-spider.html.
See also academic papers a reading group I led read here: http://ieee.scripts.mit.edu/urgewiki/index.php?title=S2012_-_Hexapods_and_Other_Cool_Things
An overview of the design process and other things I'd like to implement as of two years ago: http://orangenarwhals.blogspot.com/2011/05/dreaming-of-dancing-hexapods-2007.html
A video explaining the design process in 7 minutes (this instructables goes into the construction but not the design): http://youtu.be/qTh-OGA_LeM
Gaits
Tripod gaits are the simplest. Go out and read more about the different gaits out there. For instance, can you figure out which gait Stompy is using and why?
Forums
There are also many people on the forums, in particular:
pololu e.g. (http://forum.pololu.com/viewtopic.php?f=16&t=6188&p=29520#p29520)
trossenrobotics
lynxmotion
arcbotics e.g. (http://forum.arcbotics.com/viewtopic.php?f=12&t=386)
Hexacon
hexacon2013.mit.edu
On May 4th, 2013, the world's first hexapod conference was held at MIT. If I'm still around MIT in a year or so (I just graduated and am working on my own startup), there will be a second one (or do any of you all want to organize one? Let me know!).
===
May the hexapod revolution commence. Fare thee well.
Further Reading
This whole hexapod shenanigans was inspired by youtube: dancing hexapods...
For more hexapod craziness, see my (a bit elderly) gallery here of ones around the internet here: http://orangenarwhals.blogspot.com/2011/07/strange-and-beautiful-hexapods-spider.html.
See also academic papers a reading group I led read here: http://ieee.scripts.mit.edu/urgewiki/index.php?title=S2012_-_Hexapods_and_Other_Cool_Things
An overview of the design process and other things I'd like to implement as of two years ago: http://orangenarwhals.blogspot.com/2011/05/dreaming-of-dancing-hexapods-2007.html
A video explaining the design process in 7 minutes (this instructables goes into the construction but not the design): http://youtu.be/qTh-OGA_LeM
Gaits
Tripod gaits are the simplest. Go out and read more about the different gaits out there. For instance, can you figure out which gait Stompy is using and why?
Forums
There are also many people on the forums, in particular:
pololu e.g. (http://forum.pololu.com/viewtopic.php?f=16&t=6188&p=29520#p29520)
trossenrobotics
lynxmotion
arcbotics e.g. (http://forum.arcbotics.com/viewtopic.php?f=12&t=386)
Hexacon
hexacon2013.mit.edu
On May 4th, 2013, the world's first hexapod conference was held at MIT. If I'm still around MIT in a year or so (I just graduated and am working on my own startup), there will be a second one (or do any of you all want to organize one? Let me know!).
===
May the hexapod revolution commence. Fare thee well.