Controlling the Raspberry Pi camera from C

I wanted to be able to stop and start the camera driven by events instead of just calling raspivid to record for a preset time.

My code is really just a simple wrapper around raspivid using the SIGUSR1 option to stop the video under program control rather than after a preset time.

The example main() function starts the video, sleeps for five seconds and then stops it.  For demo purposes I included the options for black and white inverted video.  To record with the normal raspivid defaults you just call startVideo with an empty options string:

startVideo(“filename.h264”, “”);

Obviously you can put any of the normal raspivid options in the string – but you should avoid -t, -n, -o, and -s as the code fills those in for you.  If you want to enable preview/monitoring then make the obvious change to remove the -n (no preview) option.

Save code as, say, video.c and compile with gcc -o video video.c

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static pid_t pid = 0;

void startVideo(char *filename, char *options) {
    if ((pid = fork()) == 0) {
        char **cmd;

        // count tokens in options string
        int count = 0;
        char *copy;
        copy = strdup(options);
        if (strtok(copy, " \t") != NULL) {
            count = 1;
            while (strtok(NULL, " \t") != NULL)
                count++;
        }

        cmd = malloc((count + 8) * sizeof(char **));
        free(copy);

        // if any tokens in options, 
        // copy them to cmd starting at positon[1]
        if (count) {
            int i;
            copy = strdup(options);
            cmd[1] = strtok(copy, " \t");
            for (i = 2; i <= count; i++)
                cmd[i] = strtok(NULL, " \t");
        }

        // add default options
        cmd[0] = "raspivid"; // executable name
        cmd[count + 1] = "-n"; // no preview
        cmd[count + 2] = "-t"; // default time (overridden by -s)
                               // but needed for clean exit
        cmd[count + 3] = "10"; // 10 millisecond (minimum) time for -t
        cmd[count + 4] = "-s"; // enable USR1 signal to stop recording
        cmd[count + 5] = "-o"; // output file specifer
        cmd[count + 6] = filename;
        cmd[count + 7] = (char *)0; // terminator
        execv("/usr/bin/raspivid", cmd);
    }
}

void stopVideo(void) {
    if (pid) {
        kill(pid, 10); // seems to stop with two signals separated
                       // by 1 second if started with -t 10 parameter
        sleep(1);
        kill(pid, 10);
    }
}

int main(int argc, char **argv) {
    printf("Recording video for 5 secs...");
    // example options give an upside-down black and white video
    startVideo("temp.h264", "-cfx 128:128 -rot 180"); 
    fflush(stdout);
    sleep(5);
    stopVideo();
    printf("\nVideo stopped - exiting in 2 secs.\n");
    sleep(2);
    return 0;
}

Flash Rubik Cube Simulator

Snapshot of Flash Rubik Cube Simulator

Above is a snapshot image.  Here’s the real thing.

It works for any size of cube from 2 x 2 x 2 up to 11 x 11 x 11.  Actually, 11 is an arbitrary limit – the same code would work for any size of cube.  Use the little + and – buttons up in the top left hand corner to select the size of the cube.

Turning a face or slicing a layer is pretty intuitive – just click somewhere on the cube, hold down the mouse button and drag.

Turning the whole cube around is the same but you have to double-click, hold the mouse button down on the second click and then drag.

There’s a bug in the turning of the whole cube which causes the orientation to jump occasionally.  I think I can fix it by using quaternions to do the whole-cube rotation, but with the demise of Flash I’m thinking this would be a good project to migrate to HTML5 – and then I could patch in the quaternion stuff at the same time.

You can also use the keyboard to turn layers (there’s a sort of agreed way of doing this among speed-cubers, and the simulation mostly uses the agreed keys),

The Minimum Attack Problem

Place five queens on a chess board so that every square on the board is attacked.  It’s an old and famous problem; there are lots of solutions and it’s pretty easy to find one.  Try it for yourself and see!

Now try using just three queens and two rooks.  Not so easy this time; the solution is unique if you ignore trivial rotations and reflections of the whole board.  What about other attacking forces? Four queens and two pawns maybe?

The image above is a snapshot of my solver.  Click here to go to the solver itself. I wrote it over ten years ago when Java applets were flavor of the month.  Most modern computers and tablets don’t have Java available by default and most tablets won’t let you install Java at all; you can still install Java as a free plug-in in most PC browsers though.