WIP IRL Random Number Generator web service that physically shakes a box with dice using a Raspberry Pi, then snaps a photo which is analyzed for a result and sent back to the user.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


IRL Random Number Generator web service that physically shakes a box with dice in it using a Raspberry Pi, then snaps a photo which is analyzed for a result and sent back to the user.


  • Server/client synchronization.
  • Client work queueing.
  • Shake box.
  • Take photo.
  • Analyze image.

Hardware requirements

  • Raspberry Pi, I'm using a Model B but any model with a camera module and wireless should work.
  • Camera Module
  • Dice, any will do as long as they're white with black dots.

Getting started

Start off by creating a config.mk file with the following values filled in:

PIUSER = <username of user in Raspberry Pi>
PIADDR = <ip address of Raspberry Pi>
SERVUSER = <username of user in server>
SERVADDR = <ip address of server>


Besides the hardware, you'll need openssl, Go + dep for building the project, and NATS running on a server. NATS is used to communicate between the server (running on a server) and the client (running on a Raspberry Pi.) Once you have openssl on your build machine, you can generate a self-signed cert with make cert. This generates cert.pem and key.pem which will be pushed to the server and client.

You can build the project for the Raspberry Pi with make arm. And assuming your server is running Linux on an amd64 architecture, you can build for that with make amd64. Once built, deploy with make deploy. This last command uses scp to copy the files over to the two devices. This can be configured using the contents of the config.mk file you created.

make amd64 deploy

Setting up the server

On your server, install gnatsd with the command below:

go get github.com/nats-io/gnatsd

After deploying your code, you can start up the NATS server and application server with the following commands:

cd ~/diceshaker
gnatsd --tls --tlscert cert.pem --tlskey key.pem
./diceshaker -role server

The last command will bind to port 8080 on localhost and listen to HTTP requests. Going to / will trigger a roll event. By default it'll know how to look up the certificate files but all of this can be configured:

$ ./diceshaker -help
Usage of ./diceshaker:
  -certfile string
        Path to certificate file (default "cert.pem")
  -connect string
        NATS server URL (default "nats://localhost:4222")
  -keyfile string
        Path to key file (default "key.pem")
  -listen string
        Host and port for HTTP requests (default ":8080")
  -role string
        Is this a server or a client?
        Controls whether a client verifies the server's certificate chain and host name

Setting up the client (Raspberry Pi)

sudo systemctl enable ssh
sudo apt-get update && sudo apt-get upgrade
sudo raspi-config

This will enable ssh on startup, do a system update, and start the configuration manager. Once started, arrow down to "Interface Options", find the "Camera" setting, and when asked to enable it, select "<Yes>". You'll now be prompted to reboot, which you should do. After the reboot you can test things out by running raspistill -o img.jpg. If all worked you should get a popup ui window with a preview of the camera's image. It'll take a photo in five seconds.

After deploying your code, you can start the client with the following commands:

cd ~/diceshaker
./diceshaker -role client -connect nats://<NATSSERVERHOST>:4222


If you'd like to add the server and client programs as services managed by systemd, you can use a script included with this project to generate the configuration. The target systemd will generate the service files using this configuration found in config.mk but you can also generate your own. The deploy-systemd target will push the files to the remote machines.

make systemd deploy-systemd

Or see ./gensystemd --help for additional help with generating them manually.