Vous êtes sur la page 1sur 22

Hexapod

Contents
1 Team Members 2 Mentor 3 Abstract 4 Advantages 5 Design 5.1 Material 6 Code for master slave communication 6.1 Master code 6.2 Slave Code 7 Progress so far 8 Plans ahead 9 Expenses incurred 10 Problems Faced
o o

10.1 Problem 1: Heavy and Weak Bot 10.1.1 Modifications Made: 10.2 Problem 2: High current Requirement 10.2.1 Modifications:

Team Members
Digvijay Maheshwari Prateek Kushwaha Saurabh Kelkar

Mentor
Husain Manasawala

Abstract
Hexapod is a 6 legged locomotive popular among robotics hobbyists. Robot hexapods range from simple one-motor toys to advanced platforms with 12 or more servos. Hexapod is controlled by a micro-controller which drives the servos. Once a simple Hexapod is made it can then be modified to detect obstacles automatically and so on.

Advantages
The robot has Legs and NOT wheels and thus it can be used in terrains that are otherwise not easily reachable. A Hexapod has no specific direction i.e. it can move in any direction.

Design
The center of the Bot will have a hexagon made of acrylic. This part of the Bot will have the power source and the microcontroller. To this will be attached the six legs of the Bot. Each Leg of the Bot will have two motors- one will be attached to the body [from here on referred to as bodymotor] and the other will be attached to the leg piece that will rest on the ground [from here on referred to as legmotor]. Thus each leg will have two degrees of freedom. The material that we used was 4mm acrylic sheet. Note: If you use two different kinds of servos, use the one with the higher torque as the legmotor as itll get the maximum load.

Material
Acrylic Sheets Servo motors [# 12] Battery Micro controller/s General purpose PCB(s).

We used Arduino UNO boards as our microcontrollers. Since we are using 12 servo motors [each servo requires a PWM signal to control and one board has only 6 PWM Pins], we use two Arduinos and using I2C communication between them. Note that a servo motor runs only between the voltage range 4.8-6.0 Volts. If you use a higher voltage as the source you need to step down the voltage to the above range. This we did using IC7805. Since one IC can supply only 1 Amp current we used twelve of them. The current supply of the source needs to be checked as the Bot will need very high current [to the tune of 5-6 Amps]. The driver circuit is as follows:

Once the Bot was ready, the next challenging task was to synchronize different legs of different Arduinos. In the I2C method communication, we have to short the grounds of the two Arduinos, connect the SCL and the SDI pins i.e. Pin Nos. A4 and A5, of the two Arduinos. In this method, one of the microcontrollers becomes the Master and the other one becomes Slave. The Slaves clock is synced to the Masters. Gaits (ways to move) of Hexapod: Alternating tripod: 3 legs on the ground at a time. Quadruped. Crawl: move just one leg at a time. We are using Quadruped method in which at any time at least 4 legs touch the ground.

Code for master slave communication


Master code
#include <Servo.h> #include <Wire.h> #include<String.h> Servo bodymotor[3]; Servo legmotor[3]; int rcvd=-1,inbyte=0,count=0; int angle1,angle2,a1,flag=0; byte x,y; String input=""; void setup() { pinMode(12,OUTPUT); pinMode(13,OUTPUT); bodymotor[0].attach(3);

bodymotor[0].write(90); bodymotor[1].attach(5); bodymotor[1].write(90); bodymotor[2].attach(6); bodymotor[2].write(90); legmotor[0].attach(9); legmotor[0].write(180); legmotor[1].attach(10); legmotor[1].write(180); legmotor[2].attach(11); legmotor[2].write(180); delay(2500); Serial.begin(9600); Wire.begin(); } //---------------------------------------void loop() { while(Serial.available()>1) { if(count==0) { input=""; count++; } if(count==1) { char c=Serial.read(); input+=c; } } if(Serial.available()) { char last=Serial.read(); input+=last; count=0; } if(input=="sit") { sitstand(); delay(50); } else if(input=="twist") { twist(); } else if(input=="move") { newmove(); } else if(input=="turnc") { turn(0); } else if(input=="turna") { turn(1); } else {

reset_bot(500); } delay(500); } //-------------------------------------------void request(int c) { delay(c); Wire.requestFrom(2,1); while(Wire.available()) { rcvd=Wire.receive(); } } //-----------------------------------------------void sending() { rcvd++; byte x; x=byte(rcvd); Wire.beginTransmission(2); Wire.send(x); Wire.endTransmission(); } //-------------------------------------------------void reset_bot(int wait) { bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); legmotor[0].write(180); legmotor[1].write(180); legmotor[2].write(180); delay(wait); } //---------------------------------------------void sitstand() {//2050 Wire.beginTransmission(2); x=byte(50); Wire.send(x); Wire.send(0); Wire.endTransmission(); delay(50); sending(); legmotor[0].write(135); legmotor[1].write(135); legmotor[2].write(135); request(500); sending(); legmotor[0].write(90); legmotor[1].write(90); legmotor[2].write(90); delay(1000); Wire.requestFrom(2,1); Wire.beginTransmission(2); x=byte(4); Wire.send(x); Wire.endTransmission(); legmotor[0].write(180); legmotor[1].write(180);

legmotor[2].write(180); delay(500); rcvd=-1; } //---------------------------------------void move(int a,int b) { Wire.beginTransmission(2); x=byte(a); y=byte(b); Wire.send(a); Wire.endTransmission(); if(b==0) { angle1=110; angle2=70; } else if(b==1) { angle1=70; angle2=110; } legmotor[0].write(130); delay(500); sending();//0 request(500); bodymotor[0].write(angle1); sending();//2 request(500); legmotor[0].write(180); sending();//4 request(500); legmotor[2].write(130); sending();//6 request(500); bodymotor[2].write(angle2); sending();//8 request(500); legmotor[2].write(180); sending();//10 request(500); legmotor[1].write(130); sending();//12 request(500); sending();//14 bodymotor[0].write(90); bodymotor[2].write(90); request(1000); sending();//16 reset_bot(500); rcvd=-1; } //---------------------------------------------------------void turn (byte sense) {//6500 rcvd = 21; byte z; z=byte(20); Wire.beginTransmission(2); Wire.send(z); Serial.println("a sent");

Wire.send(sense); Serial.println("b sent"); Wire.endTransmission(); if(sense==0) { angle1=120; } else if(sense==1) { angle1=60; } delay(500); sending(); legmotor[1].write(130); request(750); sending(); bodymotor[1].write(angle1); request(750); sending(); legmotor[1].write(180); request(750); sending(); legmotor[0].write(130); legmotor[2].write(130); request(750); sending(); bodymotor[0].write(angle1); bodymotor[2].write(angle1); request(750); sending(); legmotor[0].write(180); legmotor[2].write(180); request(750); sending(); bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); delay(1000); rcvd=-1; reset_bot(500); } //------------------------------------------------------void newmove() {//6850 Wire.beginTransmission(2); y=byte(40); x=byte(0); Wire.send(y); Wire.endTransmission(); delay(50); sending(); legmotor[1].write(130); request(500); sending(); bodymotor[1].write(60); request(500); sending(); legmotor[1].write(180); request(500); sending(); legmotor[0].write(130);

request(500); sending(); bodymotor[0].write(85); request(500); sending(); legmotor[0].write(180); delay(800); legmotor[2].write(130); delay(500); bodymotor[2].write(70); delay(500); legmotor[2].write(180); request(500); sending(); request(500); sending(); request(500); sending(); request(500); sending(); rcvd=-1; reset_bot(500); } //------------------------------void twist() {//3650 a1=90; Wire.beginTransmission(2); x=byte(60); Wire.send(x); Wire.send(0); Wire.endTransmission(); delay(50); while(a1<135) { sending(); a1=a1+5; bodymotor[0].write(a1); bodymotor[1].write(a1); bodymotor[2].write(a1); delay(100); rcvd--; } while(a1>45) { sending(); a1=a1-5; bodymotor[0].write(a1); bodymotor[1].write(a1); bodymotor[2].write(a1); delay(100); rcvd--; } while(a1<90) { sending(); a1=a1+5; bodymotor[0].write(a1); bodymotor[1].write(a1); bodymotor[2].write(a1);

delay(100); rcvd--; } rcvd=-1; }

Slave Code
#include <Servo.h> #include <Wire.h> Servo bodymotor[3]; Servo legmotor[3]; int rcvd,a=0,b=0,z=0,angle11,angle12,angle21,angle22,angle01,angle02,a1,a2=90,c ounter=0; byte y; void setup() { Serial.begin(9600); bodymotor[0].attach(3); bodymotor[0].write(90); delay(300); bodymotor[1].attach(5); bodymotor[1].write(90); delay(300); bodymotor[2].attach(6); bodymotor[2].write(90); delay(300); legmotor[0].attach(9); legmotor[0].write(180); delay(300); legmotor[1].attach(10); legmotor[1].write(180); delay(300); legmotor[2].attach(11); legmotor[2].write(180); delay(500); Wire.begin(2); Wire.onReceive(interpret); Wire.onRequest(whattosend); } void loop() { delay(100); } void reset_bot(int wait) { bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); legmotor[0].write(180); legmotor[1].write(180); legmotor[2].write(180); delay(wait); } void whattosend() { int x=rcvd+1; y=byte(x); Wire.send(y);

} void interpret(int howMany) { if(z==0) { while(Wire.available()>0) { a=Wire.receive(); b=Wire.receive(); if(b==0) { angle11=110; angle12=70; angle01=110; angle02=70; a1=120; } if(b==1) { angle01=70; angle02=110; angle01=70; angle02=110; a1=60; } } z=1; } else if(z==1) { while(Wire.available()) { rcvd=Wire.receive(); } if (a==0) { switch(rcvd) { case 0: { legmotor[0].write(130); bodymotor[1].write(90); legmotor[1].write(180); break; } case 2: { bodymotor[0].write(angle01); bodymotor[1].write(90); legmotor[1].write(180); break; } case 4: { legmotor[0].write(180); bodymotor[1].write(90);

legmotor[1].write(180); break; } case 6: { legmotor[1].write(130); break; } case 8: { bodymotor[1].write(angle01); break; } case 10: { legmotor[1].write(180); break; } case 12: { legmotor[2].write(130); break; } case 14: { bodymotor[1].write(90); bodymotor[0].write(90); delay(700); break; } case 16: { reset_bot(500); z=0; break; } default: { Serial.println("Invalid input from Master"); break; } } } if (a==1) { if (rcvd==0) { legmotor[0].write(130); legmotor[2].write(130); } else if (rcvd==2) { bodymotor[0].write(angle11); bodymotor[2].write(angle12); } else if(rcvd==4)

{ legmotor[0].write(180); legmotor[2].write(180); } else if(rcvd==6) { legmotor[1].write(130); } else if(rcvd==8) { bodymotor[0].write(90); bodymotor[2].write(90); } } if (a==2) { switch(rcvd) { case 0: { legmotor[2].write(130); break; } case 2: { bodymotor[2].write(angle21); break; } case 4: { legmotor[2].write(180); break; } case 6: { legmotor[1].write(130); break; } case 8: { bodymotor[1].write(angle22); break; } case 10: { legmotor[1].write(180); delay(500); legmotor[0].write(130); break; } case 12: { bodymotor[2].write(90); bodymotor[1].write(90); delay(700); reset_bot(500);

z=0; break; } default: { Serial.println("Invalid input from Master"); break; } } } if(a==20) { switch(rcvd) { case 22: { legmotor[0].write(130); legmotor[2].write(130); break; } case 24: { bodymotor[0].write(a1); bodymotor[2].write(a1); break; } case 26: { legmotor[0].write(180); legmotor[2].write(180); break; } case 28: { legmotor[1].write(130); break; } case 30: { bodymotor[1].write(a1); break; } case 32: { legmotor[1].write(180); break; } case 34: { bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); delay(1000); reset_bot(500); z=0; break; } default: {

Serial.println("Invalid receipt from master during turn"); break; } } } if(a==40); { switch(rcvd) { case 0: { legmotor[1].write(130); break; } case 2: { bodymotor[1].write(120); break; } case 4: { legmotor[1].write(180); break; } case 6: { legmotor[0].write(130); break; } case 8: { bodymotor[0].write(95); break; } case 10: { legmotor[0].write(180); break; } case 12: { legmotor[2].write(130); break; } case 14: { bodymotor[2].write(110); break; } case 16: { legmotor[2].write(180); break; } case 18: { reset_bot(500); z=0; break; } }

} if(a==50) { switch(rcvd) { case 0: { bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); legmotor[0].write(135); legmotor[1].write(135); legmotor[2].write(135); delay(500); break; } case 2: { bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); legmotor[0].write(90); legmotor[1].write(90); legmotor[2].write(90); delay(750); break; } case 4: { bodymotor[0].write(90); bodymotor[1].write(90); bodymotor[2].write(90); legmotor[0].write(180); legmotor[1].write(180); legmotor[2].write(180); delay(500); z=0; break; } } } if(a==60) { switch(rcvd) { case 0: { if(counter<9) { a2+=5; bodymotor[0].write(a2); bodymotor[1].write(a2); bodymotor[2].write(a2); legmotor[0].write(180); legmotor[1].write(180); legmotor[2].write(180); counter++; } else if(counter<27 && counter>=9) { a2-=5;

bodymotor[0].write(a2); bodymotor[1].write(a2); bodymotor[2].write(a2); legmotor[0].write(180); legmotor[1].write(180); legmotor[2].write(180); counter++; } else if(counter<36 && counter>=27) { a2+=5; bodymotor[0].write(a2); bodymotor[1].write(a2); bodymotor[2].write(a2); legmotor[0].write(180); legmotor[1].write(180); legmotor[2].write(180); counter++; } if(counter==36) { counter=0; a2=90; z=0; } break; } } } } }

Progress so far
The Hexapod is ready. It currently has the codes to Sit and stand up on its own, twist, turn (both clockwise and anticlockwise) about its axis, and move in the forward direction. The Bot accepts the commands from the Serial Monitor. The following are the set of commands: sit - Sit and stand twist - Twist turnc - Turn clockwise turna - Turn anticlockwise move - Move forward

Plans ahead
We plan to make the Bot remote controlled using RF modules. There are also plans to make the power supply on-board once we find a suitably light battery. After the above are

complete, we plan to attach proximity sensors so as to enable the Bot to move on all terrains and adjust according to the height of the ground. After all this is done, well make the robot climb stairs. And probably make it even autonomous sometime.

Expenses incurred

Problems Faced
Problem 1: Heavy and Weak Bot

We earlier made a Bot that looked like this:

The Bot was fine as far as the functioning was concerned. But it was quite heavy and so the motors could not take the load. Also due to too many bends and joints, it was not sturdy and could not stand straight.

Modifications Made:
The Bot was minimized. Bodymotors were attached to the main body itself. One major modification done was in the design of the leg piece so it could lift itself up even when down. The current Bot looks like this:

Problem 2: High current Requirement


Since the Hexapod has 12 Servos, it draws really high current. We tried using different regulators that could give high current. We started with LM-338 Steel Package and ended up blowing up two of them. It did fine when checked with no load on the motors, but failed as soon as it got load. We looked for other regulators as well but we either did not find them or the available ones were too expensive. We also realised that we did not have a source that could supply such high current.

Modifications:
We used 12 7805ICs for our twelve motors, i.e. one separate regulator for each Servo. Since each can supply 1 Amp current, it works good. We currently use two BATTERY ELIMINATORS each having maximum current limit of 5Amps.

Complete with all the connections the Hexapod looks like this:

Video
YouTube Video Link