Programming the Raspberry Pi with Perl; eBook fundraiser (Update)

Well, thanks to all the generous donations, we've reached 71% of our initial target at exactly half-way through the campaign!!

We have decided to set a stretch goal. If we surpass our minimum $2,500 USD and get up to $4,000 USD, we will be adding three new chapters.

Timm will add one on Infrared Remote Control, and another focusing on using MQTT: a machine-to-machine (M2M)/"Internet of Things" connectivity protocol.

I will add a chapter that will step-by-step explain how to read and understand the relevant portions of a datasheet for an Integrated Circuit (IC) or some form of sensor, how to communicate/manipulate and otherwise act on the device's registers in C, the process of converting the working C code into XS, and finally creating a new Perl distribution for the device.

Thank you for all of the support!


Programming the Raspberry Pi with Perl; eBook fundraiser

A few weeks back, it was pointed out to me that Timm Murray was proposing to write an eBook for using Perl on the Raspberry Pi. Due to my extensive work on that platform over the last two-plus years, I had keen interest in the project.

Timm will be writing the bulk of the content using various distributions including my RPi::WiringPi along with all its related distributions, and I will be adding at least one chapter to cover my indoor grow room single-webpage environment controller, as well as performing editing duties and testing of the code.

We've been working together for a couple of weeks now, and today, I'm proud to announce the official launching of the fundraiser for the new book.

Whether you're interested in working on the Raspberry Pi, or just want to donate to a good cause for other Perl hackers, please have a look.


Pi Day!

Yesterday, when I published and wrote a blog about my new RPi::StepperMotor distribution, I didn't even think that the very next day was Pi Day.

So, although nothing significant could be done in the meantime, I updated that dist with a cleanup() method which resets the GPIO pins at the end of your script, and published version 2.3623 of RPi::WiringPi, which is the top-level framework that allows you to safely pull in all of the other RPi:: distribution objects.

Changes include:

  • bumping GPSD::Parse prereq due to having added some convenience methods to it

  • Documentation fixes and updates (all broken links now work!)

  • incorporation of said RPi::StepperMotor distribution

Nothing major, but since most of my personal programming time the last two years has gone into Raspberry Pi work for Perl, thought I'd do at least something :)

byterock, this one's for you...


Controlling a stepper motor with the Raspberry Pi

I live in an extremely remote part of Northern British Columbia, Canada. It is a minimum of an hour to get to the nearest town. We are exceptionally sparsely populated with a vast amount of land right on the second-largest lake in the province.

To that end, we have a wild abundance of wildlife everywhere. Bears, moose, wolves, coyotes, deer etc etc. I set out to set up a series (eight) wildlife cameras using Raspberry Pis (four on my house, the other four each on a separate cabin), all streaming to a central server that I can display on a television set, with all eight camera streams within a single window.

After I accomplished the bulk of that work, I wanted a way to pan and tilt my cameras individually. The tilt part I use a standard servo with the the servo() functionality of the RPi::WiringPi distribution.

For pan, I decided on a 28BYJ-48 gear reduction stepper motor, driven by a ULN2003A motor driver. I then read the datasheet, put some code together, and now we can drive said unit with Perl.

The setup is extremely basic, simply connect 5v+ and Ground to the driver board, along with four GPIO pins (image on my Github).

The new distribution is RPi::StepperMotor, and is very easy to get going with.

To the code. This is pretty well the most basic example we can have. It sets up the object, readies the pins, then swivels 180 degrees clockwise, then back counter-clockwise 180 degrees, essentially on a permanent sweep:

use warnings;
use strict;

use RPi::StepperMotor;

my $sm = RPi::StepperMotor->new(
    pins => [12, 16, 20, 21]

while (1){

NOTE: It is up to the user to unset the pins after they are done. Shortly, this distribution will appear within the RPi::WiringPi framework, so pin cleanup will be done automatically upon crash or program exit if you use that distribution and instantiate a stepper motor object through there. It's already in the repo, doing the full test suite so I should have that up tomorrow.

I've included also a stepper binary for quick command line movement of the motor:

Usage:   stepper <cw|ccw> degrees [speed]

Example: stepper cw 180 [full]

The stepper motor can be driven in "half" speed (ie. we execute all steps per movement) or "full" speed, which skips every second step. Full is half as accurate, but twice as fast. You can set the speed ('half' by default) in the instantiation call:

my $sm = RPi::StepperMotor->new(pins => $pins, speed => 'full');

...or at runtime with the speed() method:


The only other option is the delay we introduce in between each step. This, too can be set in the instantiation call, or at runtime with the delay() method. The default delay is 0.01 seconds.

my $sm = RPi::StepperMotor->new(pins => $pins, delay => 0.2);



Have fun!

Easily back up your Github repositories and/or issues

It's been in the works at the lower-end of my priority list, but after having a bit of a bug-closing weekend, thought I'd tackle getting out an initial release of Github::Backup.

The cloud is a great thing, until the sun evaporates it one way or another. Github, although fantastically reliable, is prone to issues just like any other site on the Internet. I'd go as far to say that even they could be prone to data loss in very rare circumstances.

This distribution, which provides a command-line binary, allows you to quickly and easily back up your repositories and issues to your local machine. The repositories are cloned so all data is retrieved as-is as legitimate Git repos, and the issues are fetched and stored as JSON data. Useful if there was ever a catastrophic issue at Github, or simply for offline perusal of your information.

At a basic level, you need to send in your Github username, API token (see this), a directory to stash the data retrieved, and a flag to signify you want to back up either your repos, issues or both.

github_backup \
    -u stevieb9 \
    -t 003e12e0780025889f8da286d89d144323c20c1ff7 \
    -d /home/steve/github_backup \
    -r \

That'll back up both repos and issues. The structure of the backup directory is as follows:

    - issues/
        - repo1/
            - issue_id_x
            - issue_id_y
        - repo2/
            - issue_id_a
    - repo1/
        - repository data
    - repo2/
        - repository data

Now, most don't like supplying keys/tokens/passwords on the command-line or within a script, so you can stash your Github API token into the GITHUB_TOKEN environment variable, and we'll fetch it from there instead:

github_backup -u stevieb9 -d /home/steve/github_backup -r -i

Full usage for the binary:

Usage: github_backup -u username -t github_api_token -d /backup/directory -r -i


-u | --user     Your Github username
-t | --token    Your Github API token
-d | --dir      The backup directory
-p | --proxy    Optional proxy (
-r | --repos    Back up all of your repositories
-i | --issues   Back up all of your issues
-h | --help     Display this help page

The API is very straightforward as well:

use warnings;
use strict;

use Github::Backup;

# token stashed in GITHUB_TOKEN env var

my $gh = Github::Backup->new(
    api_user => 'stevieb9',
    dir      => '/home/steve/github_backup'

# back up all repos 


# back up all issues


This is one distribution that I've released prior to being happy with my unit test regimen, so that's on the imminent to-do list. There are tests, but as always, there can never be enough. In this case, I, myself am not even happy, so if you run into any issues, please open a ticket, or reply back here.

Going forward, I plan on adding functionality to independently back up all Github data for a user, not just repos and issues. I also plan to test restore operations, but that's not anything I'm considering short-term.

Have fun!


Note: Also posted at Perlmonks.