Sniff is a "Scratch-like" programming language that's designed to help Scratchers move gently from Scratch to more conventional languages. They can start writing programs, without having to learn a new language because Sniff is based on Scratch. They learn a little more about variables, compiling, syntax errors (!), and they can have fun controlling real hardware while they're doing it.

Saturday, 19 December 2015

PCA9685 - lots of Servos and LED's with not many wires

We have a fairly predictable cycle of R&D here at Sniff Labs: It starts with us browsing Twitter, AliExpress and Ebay until we spot something cool. Then we get one, write a Sniff Device for it (if necessary), and code up up some demos. We do that for about a month, then push out a "Release". Once a release goes out, we do a blog post for each of the new features, explaining what it does and hopefully inspiring you to take it further...

In the release notes for the last release you'll not that we added support for "pca9685" boards... Then forgot to do the blog post so you've probably no idea what a PCA9685 board is! Well its a chip/board for controlling servos. Now you might say "what's the big deal?". Sniff can already drive servo's pretty easily:

make pulseTime number
when runServo
..set pulseTime to (1+x)*1000
..set servo to on
..wait pulseTime microsecs
..set servo to off
..wait 20 millisecs

This little snippet of code will drive a servo on a digital output pretty well. Just set "x" to be from 0 to 1 and the servo moves.

That's great if you're running one or two servos from an Arduino, but if you're running lots then the timing will probably start to drift, and you'll use a lot of CPU driving outputs when you could be doing more useful work. If you're on a Pi, then the timings will be a mess to start with, and you might want to be cautious of driving 5V servos from a 3.3v Pi. You should also be worried about output currents from the Pi. Finally you're using up output pins that you might need for something else.

The PCA9685  takes care of all of this: it uses i2c (only two wires), and drive 16 outputs with accurate timings. Breakout boards can typically drive an output output with a moderate amount of power, and you can run the outputs at a higher voltage than the control pins.

Connect up power, data and clock on the left and edge, then plug some leds or servos into the channels across the botton. The VCC pin on the left edge should be connected to the power supply that your controller uses (3.3v or 5v typically) while you provide power to drive the outputs with up to 6V from either the V+ pin or the screw terminals. If that's not enough you can connect the outputs on the right of the board to the inputs of the next board, and drive up to 64 boards with 16 servos on each!!! That's 1024 servos...

make i2c device
make pca9685 device
make pwmChannel number
make pwmValue number

Make a device, and we're ready to go. Lets start with some LED's:

#Channels 0-7 (that's how they're labeled on the board!)
#flash LED's
#Brightness goes from 0-1
when start
.make count number
..repeat 8 using  count
...set pwmChannel to count-1
...set pwmValue to (sin of (timer*100+count*10)) *0.5+0.5
...tell pca9685 to "set brightness"

Here the LED's are plugged into the first 8 channels of the board, which are numbered 0-7. Just set the channel, and a value between 0 and 1, then tell the pca968 to send that to the hardware. Here Ive set up a sine wave with an offset so we get a nice ripple effect.

#Channels 8-15 (that's how they're labeled on the board!)
#Move Servos
#Position goes from -1 to 1
#This corresponds to the "safe" 1-2mS pulse
#Your Servo may need or like a larger range
when start
.make count number
..repeat 8 using  count
...set pwmChannel to count+8-1
...set pwmValue to (sin of (timer*100+count*10))
...tell pca9685 to "set servo position"

Doing this with Servo's is just as easy. However the value goes from -1 to +1 and we use the command "set servo position". That's because servo's have some pretty specific timing requirements, so "set servo position" handles all that for you. Depending on your servos you might find that -1 to +1 doesn't give the full range of movement, in which case try increasing the range gradually. A lot of servos need a slightly larger range, but too wide a range of values can damage the servo. The -1 to +1 range is configured to be safe for most hardware, and follows the "standard" behaviour, but try experimenting.


  1. I recently found many useful information in your website especially this blog page. Among the lots of comments on your articles.
    LED Robot In Miami Florida

  2. I love the way how people take interest in technology and i also love this article because it is amazingly written and i also suggest to visit the Professional choice in piano.