Here is my Hexapod :)

Adafruit's tiny microcontroller platform. Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
richarduk
 
Posts: 64
Joined: Tue Nov 05, 2013 4:55 pm

Here is my Hexapod :)

Post by richarduk »

I built my self a 3D printer over Christmas using the k8200 kit. And of cause, first thing to print, some robot stuff. :)

I used the following hexapod 3d files with a little modification.
5v Trinket
2 micro switchs
And three micro servos.

Here is a video :)

So that I don't have to disconnect anything to upload new code I test for LOW on pin #3 (it has a pull up on it) and test for HIGH on pin #4 ( I added a pull down)
Pins 0,1,2 are for the servos.

Hope you like it. :) And thanks to Kitty and Mike for help with the issues I had. :)

And here is the code.

Code: Select all

/*******************************************************************
 
 
 *******************************************************************/
 #include <avr/power.h>
  
#define LEGS_MIDDLE_PIN 0
#define LEGS_MIDDLE_RAISE_RIGHT 1650
#define LEGS_MIDDLE_CENTER 1125
#define LEGS_MIDDLE_RAISE_LEFT 1400

#define LEGS_LEFT_PIN 1
#define LEGS_LEFT_FORWARD 800
#define LEGS_LEFT_CENTER 1350
#define LEGS_LEFT_BACK 1800

#define LEGS_RIGHT_PIN 2

#define LEGS_RIGHT_FORWARD 1700
#define LEGS_RIGHT_CENTER 1200
#define LEGS_RIGHT_BACK 700

#define MOVE_PAUSE 250

#define LEFT_TENTACLE 3
#define RIGHT_TENTACLE 4

static bool Tentacle_Both()
{
    return digitalRead(LEFT_TENTACLE) == LOW && digitalRead(RIGHT_TENTACLE) == HIGH;
}
    
static bool Tentacle_LeftHit()
{
    return digitalRead(LEFT_TENTACLE) == LOW;
}

static bool Tentacle_RightHit()
{
    return digitalRead(RIGHT_TENTACLE) == HIGH;
}

struct Legs
{
    Legs()
    {
        middle = left = right = 0;
    }
    
    void setup()
    {
        pinMode(LEGS_MIDDLE_PIN,OUTPUT);
        pinMode(LEGS_LEFT_PIN,OUTPUT);
        pinMode(LEGS_RIGHT_PIN,OUTPUT);
        
        middle = LEGS_MIDDLE_CENTER;
        right = LEGS_RIGHT_CENTER;
        left = LEGS_LEFT_CENTER;
    }
    
    void ForwardOneStep()
    {
        middle = LEGS_MIDDLE_RAISE_RIGHT;
        delay(MOVE_PAUSE);
        
        right = LEGS_RIGHT_FORWARD;
        left = LEGS_LEFT_BACK;
        delay(MOVE_PAUSE);
        
        middle = LEGS_MIDDLE_RAISE_LEFT;
        delay(MOVE_PAUSE);
        
        right = LEGS_RIGHT_BACK;
        left = LEGS_LEFT_FORWARD;
        delay(MOVE_PAUSE);
        
    }
    
    void BackupRotate180()
    {
        Backup(5);
        // Random left or right.
        if( (millis()&1) == 1)
        {
            RotateCCW(5);
        }
        else
        {
            RotateCW(5);
        }
    }
    
    void BackupRotateCCW()
    {
        Backup(4);
        RotateCCW(3);
    }
    
    void BackupRotateCW()
    {
        Backup(4);
        RotateCW(3);
    }
    
    void Refresh()
    {
        if( middle == 0 )
        {
            return;
        }
        digitalWrite(LEGS_MIDDLE_PIN, HIGH);
        delayMicroseconds(middle);
        digitalWrite(LEGS_MIDDLE_PIN, LOW);
          
        digitalWrite(LEGS_LEFT_PIN, HIGH);
        delayMicroseconds(left);
        digitalWrite(LEGS_LEFT_PIN, LOW);
          
        digitalWrite(LEGS_RIGHT_PIN, HIGH);
        delayMicroseconds(right);
        digitalWrite(LEGS_RIGHT_PIN, LOW);
    }
    
private:

    void Backup(int n)
    {
        while(n--)
        {
            middle = LEGS_MIDDLE_RAISE_LEFT;
            delay(MOVE_PAUSE);
            
            right = LEGS_RIGHT_FORWARD;
            left = LEGS_LEFT_BACK;
            delay(MOVE_PAUSE);
            
             middle = LEGS_MIDDLE_RAISE_RIGHT;
            delay(MOVE_PAUSE);
            
            right = LEGS_RIGHT_BACK;
            left = LEGS_LEFT_FORWARD;
            delay(MOVE_PAUSE);
        };
    }
    
    void  RotateCCW(int n)
    {
        middle = LEGS_MIDDLE_RAISE_LEFT;
        delay(MOVE_PAUSE);
        
        left = LEGS_LEFT_CENTER;
        delay(MOVE_PAUSE);

        while(n--)
        {            
            middle = LEGS_MIDDLE_RAISE_RIGHT;
            delay(MOVE_PAUSE);
            
            right = LEGS_RIGHT_FORWARD;
            delay(MOVE_PAUSE);
            
            middle = LEGS_MIDDLE_RAISE_LEFT;
            delay(MOVE_PAUSE);
            
            right = LEGS_RIGHT_BACK;
            delay(MOVE_PAUSE);
        };
    }

    void  RotateCW(int n)
    {
        middle = LEGS_MIDDLE_RAISE_LEFT;
        delay(MOVE_PAUSE);
        
        left = LEGS_RIGHT_CENTER;            
        delay(MOVE_PAUSE);
            
        while(n--)
        {            
            middle = LEGS_MIDDLE_RAISE_RIGHT;
            delay(MOVE_PAUSE);
            
            left = LEGS_LEFT_BACK;
            delay(MOVE_PAUSE);
            
            middle = LEGS_MIDDLE_RAISE_LEFT;
            delay(MOVE_PAUSE);
            
            left = LEGS_LEFT_FORWARD;
            delay(MOVE_PAUSE);
        };
    }


    uint16_t middle,left,right;
};


Legs OurLegs;

void setup()
{
     if (F_CPU == 16000000)
    {
        clock_prescale_set(clock_div_1);
    }
    
    OurLegs.setup();
    
    pinMode(LEFT_TENTACLE,INPUT);
    pinMode(RIGHT_TENTACLE,INPUT);
     
    // Set up the interrupt that will refresh the servo for us automagically
    OCR0A = 0xAF;            // any number is OK
    TIMSK |= _BV(OCIE0A);    // Turn on the compare interrupt (below!)
}

void loop() 
{
    if( Tentacle_Both() )
    {
        OurLegs.BackupRotate180();
    }
    else if( Tentacle_LeftHit() )
    {
        OurLegs.BackupRotateCCW();
    }
    else if( Tentacle_RightHit() )
    {
        OurLegs.BackupRotateCW();
    }
    else
    {
        OurLegs.ForwardOneStep();
    }
}
 
// We'll take advantage of the built in millis() timer that goes off
// to keep track of time, and refresh the servo every 20 milliseconds
// The SIGNAL(TIMER0_COMPA_vect) function is the interrupt that will be
// Called by the microcontroller every 2 milliseconds
volatile uint8_t counter = 0;
SIGNAL(TIMER0_COMPA_vect)
{
    // this gets called every 1 millisecond on trinket running @ 16MHz
    counter += 1;
    // every 20 milliseconds, refresh the servos!
    if (counter >= 20)
    {
        counter = 0;
        OurLegs.Refresh();
    }
}

User avatar
AnneBarela
Learn User Page
 
Posts: 757
Joined: Sat Mar 24, 2012 8:56 pm

Re: Here is my Hexapod :)

Post by AnneBarela »

Richard, this is way cool! Great work!

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Here is my Hexapod :)

Post by adafruit_support_bill »

Excellent job! Amazing what you can do with these tiny processors :D

User avatar
jw40
 
Posts: 22
Joined: Fri Jun 07, 2013 4:34 pm

Re: Here is my Hexapod :)

Post by jw40 »

No. Freakin'. Way. This is just incredible.

User avatar
richarduk
 
Posts: 64
Joined: Tue Nov 05, 2013 4:55 pm

Re: Here is my Hexapod :)

Post by richarduk »

Cool, just seen the post on the blog. [Massive grin on face] :D

Locked
Please be positive and constructive with your questions and comments.

Return to “Trinket ATTiny, Trinket M0”