Custom servo usage in Firmata

If you only have a hammer, everything looks like a nail. And my biggest hammer for now is Firmata.

I was looking at an Ignite 2015 presentation, MOB324, where a kind of radar using a distance reader was demonstrated. And at the same time I was checking out the same usage of a distance reader and a servo as part of am Arduino controlled car.

So I tried to do the same using Firmata. And it’s pretty easy, with a little twist.

But first we look at the servo part using the Arduino Servo.h library.

This is part 7 of a serie of blogs about device communication between Arduino, RaspberryPi etc:

  • Part 1: Using I2C to connect two Arduino Nano’s
  • Part 2: Using I2C between RPi Master and Arduino Slave
  • Part 3: Use Bluetooth between Win 10 UWP and Arduino
  • Part 4: Add virtual Arduino ports to your UWP app
  • Part 5: Custom Firmata function called by Windows 10 IoT Core
  • Part 6: Better long running custom Firmata functions
  • Part 7: Custom servo usage in Firmata
  • Part 8: Using NRF24L01+ modules between arduino’s
  • Part 9: Cheap Arduino mesh using RF24 radio modules

The servo.h is not that difficult to use. Here is the almost standard example on how to attach the servo and put it in a certain position (x degrees):

#include <Servo.h>

Servo myServo; // create servo object to control a servo

int pos = 0; // variable to store the servo position

void setup()
{
myServo.attach(9); // attaches the servo on pin 9
}

void loop()
{
// goes from 0 degrees to 180 degrees in steps
for (pos = 0; pos <= 180; pos += 1)
{ // in steps of 1 degree
// tell servo to go to position in variable ‘pos’
myServo.write(pos);  
// waits 15ms for the servo to reach the position
delay(15);                      
}

// goes from 180 degrees to 0 degrees in steps
for (pos = 180; pos >= 0; pos -= 1)
{
// tell servo to go to position in variable ‘pos’
myServo.write(pos);             
// waits 15ms for the servo to reach the position
delay(15);                      
}
}

Note: check your board type to figure out which port you will have to use. More indept info is available at the servo.h site.

So having executed this example succesfully, I was thinking that using a servo inside a custom Firmata function would be pretty easy.

So I wrote that custom function which would be called inside the regular loop function. And each time it was executed, I would step up or down the servo. I just used the Attach and the Write function, that should do the job?

Well, in the end, nothing happened. Not a single movement.

Time to do some research 🙂 And when I was checking the standard Firmata library, it was there: in plain sight!

The Firmata library already makes use of the Servo.h library. And it already contains a function to attach:

  • void attachServo(byte pin, int minPulse, int maxPulse)

So finally I came up with the following code with both a function for setup and a function which is called in the overall loop:


void setup()
{
  ...
  setupServo();
}

void loop()
{
  ...
  moveServo();
}

// Will be changed by the Firmata function call (see Part 6)
bool isMoving = false; 
bool countingUp = true;
int degree = 10;

void setupServo()
{
  attachServo(9, 544, 2400);
}
void moveServo()
{
  if(!isMoving)
  {
    return;
  }

  servos[servoPinMap[9]].write(degree);
  delay(15);

  if (countingUp)
  {
    if (degree < 170)
    {
      degree = degree + 5;
    }
    else
    {
      countingUp = false;
    }
  }
  else
  {
    if (degree > 10)
    {
      degree = degree - 5;
    }
    else
    {
      countingUp = true;
    }
  }
}

This code does use the standard Firmata support for servo’s. And it works just as expected, I am happy. And this way other commands are still executed by Firmata while the servo is turning at the same time.

WP_20160126_15_13_15_Rich_LI

So now I have my own radar 🙂

Radar

For the distance sensor, I stumbled over the NewPing.h library. Reading a value is pretty easy:

#include <NewPing.h>

#define TRIG_PIN A0
#define ECHO_PIN A1
#define MAX_DISTANCE 500

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);

...
int distance = sonar.ping_cm();
delay(30);
...

And reading the value should be much faster and more accurate. Seems ok.

 

 

Advertenties