Now that I have the servo shield working I went ahead and created my first OSX app to control the servos from my desk top.
It’s a very simple app. There’s a slider for each of the 16 servos. Changing the sliders causes commands to be sent to the selected serial port. On the Arduino you run the following sketch:
[Note: Servo16 has changed quite a bit so the sketch below is well out of date.]
// include needed librarys
#include
#include <Adafruit_PWMServoDriver.h>
// create the servo driver instance
// change 0x40 to match your servo shield if necessary
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);
void setup()
{
// init serial port coms
Serial.begin(9600);
// init Adafruit's driver and set pulse frequency
pwm.begin();
pwm.setPWMFreq(50);
// tell Servo16 app that we are ready for commands
Serial.println("Servo16 Ready!");
}
// helper function that uses angles rather than pulse ticks
void setAngle( int channel, int angle )
{
// 4096 ticks is 20,000 us (50Hz)
// Angle 0 is 500 us
// angle 180 is 2,500 us
long ticks = ((500L + (2000L*angle)/180L)*4096L)/20000L;
// update the servo channel with the new pusle
pwm.setPWM(channel, 0, ticks);
}
// returns substring of str from pos till delim
String parseTill( char delim, int *pos, String str )
{
int len = str.length();
int index = *pos;
String p = "";
while ( index {
char ch = str.charAt(index++);
if( ch == delim)
{
break;
}
p += ch;
}
*pos = index;
return p;
}
// parse command and execute
void execute( String str )
{
// format {:....}
int pos = 0;
String action = parseTill(':', &pos, str);
if( action == "s" )
{
//format {s::}
String servo = parseTill(':', &pos, str);
String angle = parseTill(':', &pos, str);
setAngle(servo.toInt(), angle.toInt());
}
}
// main loop
void loop()
{
// serialEvent() does all the work
}
String cmd = NULL; // used to store incomming command
// called after every loop() to handle serial coms
void serialEvent()
{
while (Serial.available())
{
char ch = (char)Serial.read();
if(cmd)
{
if( ch =='}')
{
execute(cmd);
// wait for new command
cmd = NULL;
}
else
{
cmd += ch;
}
}
else
{
if( ch == '{' )
{
// start of new command
cmd = "";
}
}
}
}
The sketch parses the serial input for commands and executes them. For now there is only one command : {s:<servo-index>:<new-angle>}
Here it is in action:
You can get all the code at https://github.com/solderspot/Servo16

Pretty cool! Leave it to you to write a tool to control it. Good idea.
LikeLike