Servo16

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.

Screen Shot 2013-12-22 at 12.15.23 PM

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

Advertisements

One comment

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

Comments welcome

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s