I built a 3DOF hexapod utilizing MG90S digital servos and a Torobot servo controller and PS2 handle for offline play. I've managed to perfect my sequences using the included servo sequencer software but now I'm ready to code it. Only problem is I'm totally new to coding. I know some DOS and C++ basics but that's about it.
I've tested both c++ and arduino with the controller and niether bring up error messages when run. So I know I can do arduino. It did come with a few sample files listed below for reference but I have no idea how to decipher it.
Any and all help would be greatly appreciated.
#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;
}
}
}
}
I think you should start with some of the Arduino Basics tutorials.
Basically, you have to learn about two things: C++ and Arduino.
The code you have included looks is the SoftwareServo libary and is designed to work with Arduino, but is not complete by itself. You do not need to understand the library code, just how to interact with the library (see:http://playground.arduino.cc/ComponentLib/Servo).
From the users perspective, Arduino starts running by calling the setup() method, and later calls the loop() method repeatedly. Without at least one of these methods in your code, it will never really do anything of yours.
So, you should add both methods, and then call your SoftwareServo library.
That's actually one of the three example files for moving one leg or so it says. Here's the other two.
This is the PDE file
#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();
}
This the _h file
#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
That's actually one of the three example files for moving one leg or so it says. Here's the other two.
This is the PDE file
This the _h file
We don't need to see the libraries. We need to see your code trying to use the libraries.
Do the basic tutorials, and you will being to understand how to program the Arduino. Without doing that, we really can't help you. No-one here is going to write your code for you. You have to work out how to do that yourself, with our guidance.
The one you really need to understand is the .PDE file (although now, it would be a .INO file. Same thing)
The other ones are the library. When using a library, you do not need to look at the library code, just the interface (that is, the way you call/talk to the library). It's like a bank teller. You tell them want you want, and they give you the result. You have no idea what they actually do behind the glass, and it doesn't matter. But, you know you have to fill in forms, etc. to get the things you want from the bank teller.
But, if you do the basic arduino tutorials, you will start to understand how to use libraries.
Couple more general questions. Could you send me a link to including the libraries at the top of my code. Is the fact that the actual files will be .txt files gonna change the way I include the libraries. Can I use the same library over and over with my action files or do I have to generate one each time I write a new set of commands?
I have been reading the tutorials I'm starting to understand the commands but I'll prolly need a walk through at least to animate one leg. I think once I've figured that out I'll be able to do the rest on completely on my own. And don't worry I'm not asking anyone to write it for me.
Something else I need to mention. In order to do anything at all with the servo controller , I have to go through its software to add to or delete actions from the board. To use the PS2 handle for offline play I have to open and import my files to a screen then download to the board which then gives an action group number that I use to program the action into the handle.
That's the reason I am asking about loading the libraries. I can load up 12 actions to the board, more if I figure out how to change modes. Any way I was hoping to down load all the action groups one by one to get my PS2 handle code then add the libraries last so it doesn't mess with the action group numbers.
Or I could import all the three files to screen and download them but I don't know if it will use the other files if thier on it consecutively as 1 action.
I guess theirs gonna be a lot of experimentation here as to what my controller can actually do. Which actually seems to be a lot from the videos I've seen using the board.
For the Arduino, there is no such thing as an "action" file. The libraries are not .txt files, they are C++ files.
If this is all to do with your Servo Controller, someone with specific knowledge of the control software running on your Torobot will probably have to step in. It looks like it's an Arduino variant, but it is running it's own software on it, which has nothing to do with a normal Arduino.
If i write a "program" to move the Hex forward, that would be considered an action group. My plan is to write several programs to give my hexapod movements like forward, reverse, strafe, turn ETC.
Yes what ever program i write i need to save as a note using notepad which will give it a .txt ending on my file. Thats the only way the software will understand it. The code can be written in any language that offshoots C++, like Arduino for example.
I would like to use Arduino sonce im more comfortable with it. I use it to program my quadcopter.
We will get to all that later after ive started programming.
What i really need to know before starting is about including libraries at the top of my code, and whther i need to write one for each set of movements.
Personally, I would suggest you start with C since it is easier to learn, yet will allow you to do a lot without the complexity of learning C++ from the outset. True, the libraries are written in C++, but you can do a lot of learning with C, plus nailing down the Arduino fundamentals.
What you are calling "action groups" are called functions in C (or methods in C++). You would write one function for each action you want (e.g., forward(), backward(), up(), down(), etc.) You invoke, or call, the functions in the order that accomplishes whatever it is you're trying to do. In the Arduino environment, I would place these functions in the *.ino or .pde file. If you need functionality embodied in a library, simply include the header file (.h) associated with that library in your *.ino file. For example, if you needed something from the Wire library, you would place the following lines near the top of your *.ino file:
#include <Wire.h>
You can then use the facilities of the Wire library in your program.
All right and just to make sure, it's the PDE or INO file that I have to write that actually controls the servos?
In general, yes, especially while you're just getting started. If the program gets very large, it is possible to break it up into other *.cpp files, but for now, just use the *.ino to hold the code you write and use the library features when that makes sense.
BTW, because the Arduino is Open Source, there is a bazillion lines of code already out there for you. Any time you start a new project, Google the basic idea with "Arduino" stuck on the "front", as in:
Ok so the first thing I want to do is include the nessasary Library. In my case it's software.h. Then I want to create objects to command. In Arduino it's written
Servo myservo; if I'm using multiple servos I'll put a number before the ; for each servo used.
Now it says a maximum of 8 servo objects can be created but I would like to move all servos at the same time.
Also pinmode. When I define a pin, it would be the channel my servo is hooked to for example pinmode(18,output)? 18 being the channel the servo is hooked to output would be what I program it to do.
And when I attach I'm attaching a servo to the pin we just turned on?
Ok idid what you said and typed Arduino Hexapod using the sites Google search and I think I need to write a legs movements then then repeat with the next legs. I guess from there they can be strung together?
Ok i want to compile the sample files i have to test the program.
If i open the PDE in arduino (or copy and paste) how do i add the two library files so i can compile it.
I opened a new project and copied and pasted the PDE file then added two tabs and named them software servo.h and the same for the .cpp file then copied and pasted them to thier correct tab but when i hit compile i get an error meassage that says cannot compile no file named servosoftware.h
The code I saw uses the Wire and SoftwareSerial libraries. To use the content of these two libraries only requires that you have the following statements:
#include <Wire.h>
#include <SoftwareSerial.h>
at the top of your .ino (.pde) program. The IDE takes care of the rest.
So when i compile my code and it puts out a sketch, the sketch is what i load on the board. I dont actually have to download the .cpp or .h file to the board. They will all be included in the sketch?