Well, there are a couple errors in your code.
First, you don’t have a delay(); after moving the servo. So the code rapidly switches between each position, and the servo will never make it to either.
Next, you are forgetting to call getstate() and getpos() after the second servo position. So you are printing the same values twice, and the values will always be related to the first position, never the second.
In getpos() you are combing the posval1 and posval2 into a 16bit number, but your pos variable and function are a byte, so it gets truncated back down to an 8bit. Also, posstate in loop() is declared a byte, when you need it to be a 16bit int. For each of these, you should declare them “unsigned int”, since you are only working with positive numbers.
Then, you need to change the values from 2200 and 400 to 8800 and 1600. The Maestros operate with .25us units, so 1600*.25 is 400us.
To receive the values in getpos() and getstate(), you should check servo.available() with a while statement. Otherwise you may be reading an empty buffer. This is shown below in my version of your code.
I don’t have a Mini Maestro, but I do have a Micro. I changed the servo number to 0 to work with it. I also made a couple minor changes for my own readability.
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3
SoftwareSerial servo = SoftwareSerial(rxPin, txPin);
void setup()
{
// pinMode(rxPin, INPUT);
// digitalWrite(txPin, HIGH); //Writing to a pin before setting it to be an
//output does not actually set the pinstate.
//It instead writes to the pullup register.
// pinMode(txPin, OUTPUT); //You don't need these lines. Software Serial sets these.
Serial.begin(9600);
servo.begin(9600);
delay(100); //Never hurts to put in a short start up delay. Makes sure
//that the Maestro is on before sending serial to it.
move400();
delay(500); //Wait for servo to move to position.
}
byte getstate()
{
byte state;
servo.write(0x93);
while(servo.available() < 1); //Wait for 1 byte to be available in the buffer.
state = servo.read(); //SoftwareSerial::read() is non-blocking in 1.0. If
//there is nothing in the buffer it returns -1.
return state;
}
unsigned int getpos() //The function needs to be an int if you want to return values greater
{ //than 255.
byte posval1;
byte posval2;
unsigned int pos; //Also needs to handle int sized numbers
servo.write(0x90);
servo.write(byte(0));
while(servo.available() < 2); //wait for 2 bytes to be available in the buffer.
posval1 = servo.read();
posval2 = servo.read();
pos = ((posval2 << 8) + posval1); //I only changed this line for my own
//readability, what you had is fine.
return pos;
}
void move2200()
{
servo.write(0x84);
servo.write(byte(0)); //Writing a 0 will give an ambiguous error if you don't cast it.
servo.write(0x60); //These numbers need to make 8800 for a time of 2200us. Units are in .25us
servo.write(0x44);
}
void move400()
{
servo.write(0x84);
servo.write(byte(0));
// servo.write(0x10); //These were the values you had
// servo.write(0x03);
servo.write(0x64);
servo.write(0x0C);
}
void loop()
{
unsigned int posstate; //Again, this variables needs to handle numbers larger than 255.
byte movestate;
move2200();
delay(500); //This lets the servo move to position. You can make it
//shorter and getstate() will return a 1.
movestate = getstate();
posstate = getpos();
Serial.print(" pos1 ");
Serial.print(posstate);
Serial.print("\t\tstate1 "); //The "\t" character is a tab.
Serial.println(movestate); //I changed the output to make it more readable.
move400();
delay(500);
movestate = getstate();
posstate = getpos();
Serial.print(" pos2 ");
Serial.print(posstate);
Serial.print("\t\tstate2 ");
Serial.println(movestate);
}
This is compiled and tested in Arduino 1.0. To work in 0023 and older, you would need to use new software serial instead of software serial. That replacement was made in 1.0.
I get position values of 8000 and 3968. I those are the upper and lower limits set for my Maestro.