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