Please teach me how to code my 3DOF hexapod

Hexapod Robots

Please teach me how to code my 3DOF hexapod

Postby Duhjoker » Tue Aug 04, 2015 7:15 am

I've built a 3DOF Hexapod utilizing MG90s digital servos and a Torobot 32channel servo controller with PS2 handle for offline play. So far I've perfected my sequences using the included software sequencer but now Im ready to learn how to code it. So far I've tested C++ and Arduino in it to see if it would use the code and it has no problem reading it without putting errors up so either one as long as the file is saved as a .txt.

I know some C++ basics and a good bit of DOS but this will be my first program.

Here's the C++ file "servo software.c++ for a reference.

Code: Select all
 #include <SoftwareServo.h>

SoftwareServo *SoftwareServo::first;

#define NO_ANGLE (0xff)

SoftwareServo::SoftwareServo() : pin(0),angle(NO_ANGLE),pulse0(0),min16(34),max16(150),next(0)
{}

void SoftwareServo::setMinimumPulse(uint16_t t)
{
min16 = t/16;
}

void SoftwareServo::setMaximumPulse(uint16_t t)
{
max16 = t/16;
}

uint8_t SoftwareServo::attach(int pinArg)
{
pin = pinArg;
angle = NO_ANGLE;
pulse0 = 0;
next = first;
first = this;
digitalWrite(pin,0);
pinMode(pin,OUTPUT);
return 1;
}

void SoftwareServo::detach()
{
for ( SoftwareServo **p = &first; *p != 0; p = &((*p)->next) ) {
if ( *p == this) {
*p = this->next;
this->next = 0;
return;
}
}
}

void SoftwareServo::write(int angleArg)
{
if ( angleArg < 0) angleArg = 0;
if ( angleArg > 180) angleArg = 180;
angle = angleArg;
// bleh, have to use longs to prevent overflow, could be tricky if always a 16MHz clock, but not true
// That 64L on the end is the TCNT0 prescaler, it will need to change if the clock's prescaler changes,
// but then there will likely be an overflow problem, so it will have to be handled by a human.
pulse0 = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/64L;
}

uint8_t SoftwareServo::read()
{
return angle;
}

uint8_t SoftwareServo::attached()
{
for ( SoftwareServo *p = first; p != 0; p = p->next ) {
if ( p == this) return 1;
}
return 0;
}

void SoftwareServo::refresh()
{
uint8_t count = 0, i = 0;
uint16_t base = 0;
SoftwareServo *p;
static unsigned long lastRefresh = 0;
unsigned long m = millis();

// if we haven't wrapped millis, and 20ms have not passed, then don't do anything
if ( m >= lastRefresh && m < lastRefresh + 20) return;
lastRefresh = m;

for ( p = first; p != 0; p = p->next ) if ( p->pulse0) count++;
if ( count == 0) return;

// gather all the SoftwareServos in an array
SoftwareServo *s[count];
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) s[i++] = p;

// bubblesort the SoftwareServos by pulse time, ascending order
for(;;) {
uint8_t moved = 0;
for ( i = 1; i < count; i++) {
if ( s[i]->pulse0 < s[i-1]->pulse0) {
SoftwareServo *t = s[i];
s[i] = s[i-1];
s[i-1] = t;
moved = 1;
}
}
if ( !moved) break;
}

// turn on all the pins
// Note the timing error here... when you have many SoftwareServos going, the
// ones at the front will get a pulse that is a few microseconds too long.
// Figure about 4uS/SoftwareServo after them. This could be compensated, but I feel
// it is within the margin of error of software SoftwareServos that could catch
// an extra interrupt handler at any time.
for ( i = 0; i < count; i++) digitalWrite( s[i]->pin, 1);

uint8_t start = TCNT0;
uint8_t now = start;
uint8_t last = now;

// Now wait for each pin's time in turn..
for ( i = 0; i < count; i++) {
uint16_t go = start + s[i]->pulse0;

// loop until we reach or pass 'go' time
for (;;) {
now = TCNT0;
if ( now < last) base += 256;
last = now;

if ( base+now > go) {
digitalWrite( s[i]->pin,0);
break;
}
}
}
Duhjoker
 
Posts: 6
Joined: Fri Jul 31, 2015 8:17 am

Re: Please teach me how to code my 3DOF hexapod

Postby Duhjoker » Sun Aug 09, 2015 3:37 am

All right guys I listed the wrong file for you to help i think. Here is a copy of my PDE file.

Code: Select all
  #include <SoftwareServo.h>

SoftwareServo servo1;
SoftwareServo servo2;

void setup()
{
pinMode(13,OUTPUT);
servo1.attach(2);
servo1.setMaximumPulse(2200);
servo2.attach(4);
servo2.setMaximumPulse(2200);
Serial.begin(9600);
Serial.print("Ready");
}

void loop()
{
static int value = 0;
static char CurrentServo = 0;

if ( Serial.available()) {
char ch = Serial.read();
switch(ch) {
case 'A':
servo1.attach(2);
CurrentServo='A';
digitalWrite(13,LOW);
break;
case 'B':
servo2.attach(4);
CurrentServo='B';
digitalWrite(13,HIGH);
break;
case '0' ... '9':
value=(ch-'0')*20;
if (CurrentServo=='A')
{
servo1.write(value);
}
else if (CurrentServo=='B')
{
servo2.write(value);
}
break;
}
}
SoftwareServo::refresh();


I have a sequence i want to code but am having trouble understanding the Code.

I know i need to include the library softwareservo.h. Then i need set my servo objects with softwareservo servo1;. Im moving 18 servos at once so i would continue til i get to 18.

In set up i need pinmode or open my servo channels. Im having trouble understanding what the integer number after attach refers to exactly. Is it the number of the servo i want to control? Like servo1 gets attached to pin 13
Duhjoker
 
Posts: 6
Joined: Fri Jul 31, 2015 8:17 am

Re: Please teach me how to code my 3DOF hexapod

Postby Duhjoker » Sun Aug 09, 2015 3:40 am

Also could some one look at my .cpp & .h files to tell me if they are complete to run 18 servos or what ever? Heres the .h file.....

Code: Select all
   #ifndef SoftwareServo_h
#define SoftwareServo_h

#include <WProgram.h>
#include <inttypes.h>

class SoftwareServo
{
private:
uint8_t pin;
uint8_t angle; // in degrees
uint16_t pulse0; // pulse width in TCNT0 counts
uint8_t min16; // minimum pulse, 16uS units (default is 34)
uint8_t max16; // maximum pulse, 16uS units, 0-4ms range (default is 150)
class SoftwareServo *next;
static SoftwareServo* first;
public:
SoftwareServo();
uint8_t attach(int); // attach to a pin, sets pinMode, returns 0 on failure, won't
// position the servo until a subsequent write() happens
void detach();
void write(int); // specify the angle in degrees, 0 to 180
uint8_t read();
uint8_t attached();
void setMinimumPulse(uint16_t); // pulse length for 0 degrees in microseconds, 540uS default
void setMaximumPulse(uint16_t); // pulse length for 180 degrees in microseconds, 2400uS default
static void refresh(); // must be called at least every 50ms or so to keep servo alive
// you can call more often, it won't happen more than once every 20ms
};

#endif   
Duhjoker
 
Posts: 6
Joined: Fri Jul 31, 2015 8:17 am

Re: Please teach me how to code my 3DOF hexapod

Postby Matt Denton » Sun Aug 09, 2015 4:00 pm

Sorry but I don't know anything about the code generator you are using, so can't offer any help. There must be a forum for Nuke that covers this, or someone else trying to do what you are asking?
Matt Denton
AKA: Winchy_Matt

micromagic systems ltd
Matt Denton
Site Admin
 
Posts: 1622
Joined: Tue May 20, 2008 9:15 pm
Location: Winchester UK


Return to Hexapods

Who is online

Users browsing this forum: No registered users and 2 guests

cron