Tag Archives: hexaringapod

I made a video about hexapods.

I made a video about hexapods! yay. I’d estimate it was a full 4 or 5 days working on it, learning final cut pro along the way. It basically covers my journey through 2.007 two years ago, and is meant to be a resource for students in the class.

Note to self: shortcuts: < > ctrl-= alt-w

Meanwhile, I think an instructable a week sounds like an excellent plan for Spring semester senior year.

how to set up arduino + pololu mini maestro (for an 18 servo hexapod)

EDIT 4 Dec 2012:
As of august 2012-ish (I haven’t tried to run hexapod since then, because I ate my pololu controller sometime while dragging my hexapod all around the country this summer >__< Ugh I fail at taking care of expensive electronic things), there are some syntax changes if you’re using the latest version of arduino because newsoftserial is now built into arduino, not a separate library.

This version of the code is also slightly better organized…
https://github.com/nouyang/18-servo-hexapod/blob/master/pololu_aug17-2012.pde

[updated because i saw a link from http://forum.pololu.com/viewtopic.php?f=16&t=6188&p=29520#p29520]

EDIT 18 March 2013:
I made a video about my hexapod.

Also, a diagram to explain what is going on in the August 17th revision of the code:

[updated because I saw a link from hexy forums]

=====

this post because pololu has awesome documentation but dear lord is it long and difficult to wade through when I’m fairly new to this stuff. Also, I finally figured out the sad-servo problem that was plaguing me for a week.

Fig. 1

My current setup: eighteen servos on maestro pins 1-18 (pin 0 left empty), VSRV=VIN jumper has been removed. 8.4V battery pack fed through 5V linear regulator on carrier board. The servo wire with with masking tape comes from PIN2 of the carrier board/arduino setup and is supplying the pololu controller with GND, VIN, and the serial signal. Red and black wires going from breadboard on carrier board to VSRV on maestro.

If all that didn’t make sense…

Steps

a. Hardware
  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>
    #define txPin 2
    NewSoftSerial mySerial(rxPin, txPin);
    void setup(){
    mySerial.begin(9600);
    delay(1000);
    }
  4. we should take a servo female-female wire, put one end on servo male header pins for pin 2 of Arduino.

  5. 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 pic above, the wire-with-masking-tape, with black facing “out” toward the USB port.
  6. Servo power: see pic above, 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)
  7. 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.

the single pin (pololu RX) inside the masking-tape-servo-cable is a sad pin. The cable also falls off often.

I used the jumper originally because I was thinking I would need two batteries (one for VSRV one for VIN) or something otherwise. But hey look, it’s setup to be neater without the jumper, I’m still only dealing with one battery, and my hexapod doesn’t work with the jumper on. u___u

b. Software
[edit 27 Jun 2011 I fixed the many errors in my post, as pointed out on the pololu forums: Pololu maestro and arduino again]

1) newsoftserial should be downloaded from the internet and the folder inside the zip put in (path to where you unzipped arduino)/arduino/libraries/ (e.g. for ubuntu 10.10 via the repository, /usr/share/arduino/libraries)

And the code from http://www.pololu.com/docs/0J40/5.e or from above means:
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

You can see the code I used with Fig. 1 here: https://github.com/nouyang/18-servo-hexapod/blob/036271da7e66b80ff7ea732ea13b7028b43d28ac/pololu_jun17a.pde

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);

Also feel free to compare to original arduino version: https://github.com/nouyang/18-servo-hexapod/blob/master/arduino_may13_2011.pde

Is the CAD?

Great success! I learned CAD. Or rather Amy worked through the point I kept getting stuck on (a particular series of mates for the hexapod leg assembly), and then it was fairly easy sailing from there. Yay πŸ™‚

not sure why it has 5 legs, might’ve hidden one when I screenshot’d

In other news, I didn’t make much headway on the pololu issue where something about my setup using Arduino + Pololu Mini Maestro is off (Dane showed me how to check with the multimeter to verify that the voltage was dropping to zero, aka symptoms of current limiting). I even took twenty minutes to wire everything to the original Arduino Nano (+ 2.007 carrier board) state, and verified that it did sound much… happier (yay the sound of 18 bloodthirsty happy servos =]). But I did read up more on serial and code, which was fun and hurt my head.

new robot brainz: Pololu Mini Maestro + Arduino

[Update, Jun 24 2010]: well now it actually works. see post: http://www.orangenarwhals.com/?p=197

My hardware:
Pololu Mini Maestro (24 ch serial RC controller)
Arduino Nano
1 servo
Some male header pins
A battery
A 2.007 Nano Carrier Board, which gives me easy access to the Arduino pins and a 5V supply
An 8V battery pack
Ubuntu 10.10 on my hp 2140 mini netbook

Steps:
Apply Powerz to Pololu and servos

TX/RX if needed
http://www.pololu.com/docs/0J40/7.c
specifically
http://www.arduino.cc/en/Reference/Board
http:// www.pololu.com/docs/0J40/1.b 

Apply codez
http://forum.pololu.com/viewtopic.php?f=16&t=3944

(put servo on pololu ch 0)

Hexaringapod rotate code

MEETERS  (MITERS end of term showcase) today! ’twas awesome, lots of people came (both MIT students and people from the area and people from artist’s asylum).

Anyway, I fixed the servo horn that a kid broke @ Cambridge Mini Maker Faire (10 minutes), then I scratched my head a lot over rotating my hexapod. In the end, trial and error code and fellow MITERians ftw.

Still KISS code that I’m embarrassed to publish, but I know I’ll find this useful in the future.
I rewrote the coxa in terms of rotating CW or CCW around the body, instead of backward and forward. Backward and forward were useful for the rectangular body, making it clear that moving coxa in the +J direction, “forward”, meant moving CW for servos on the left “half” of the body and CCW for servos on the right half. But now that I have a circular body, it just confused me (I couldn’t figure out how rotating was different walking forward, hah).

I don’t think I can get it to strife left / right with my current setup, where I’m pairing servos with Y splitter cables to get down to 12 channels, the max that the Arduino servo library supports.

(As it turns out, it is entirely possible to get more PWM outputs. David Lawrence, after I spammed everyone on MITERS asking for guidance, informed me that

http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html 

Essentially, because the PWM waveform is output at 1000 Hz, it’s necessary to use the hardware timers, which only connect to a subset of the output pins.  However, servos are quite happy to be driven by a 50 Hz PWM, in which case you can use one timer to control a whole bunch more of the GPIO pins.  The higher frequency is only really necessary for interfacing with analog hardware.  

 )

Vid:

Code:

 #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);
};

and as always, pics:
https://picasaweb.google.com/nancy.ouyang/2007HexapodSpring2011