Complete Raspberry Pi Image for Internet of Things Project

True Story Follows

So I’m on the grind on a weekend project trying to setup a microcontroller to manage a hundred meters of addressable LED strips in my front yard. In order to restart from where I left off on a previous project where we used a raspberry pi to drive an LED screen, I needed to get my raspberry pi image together to run some of the code I’d written in the past. In doing so, it also seemed like a good time to go ahead and flash the image in anticipation of all possible projects that might evolve from a raspberry pi. This isn’t the first time I’ve been through this rodeo, and I recognized that IoT projects generally had similar needs across the board.

Way Too Long; Did not Read

If you want a blank raspberry pi image that already has a read-only hard drive that will automatically mount a single USB thumbstick, allocate 256 MB for a RAM filesystem, starts a redis-server on startup, has the Go runtime environment installed, has ffmpeg installed, is compatible with an Emlid Navio2, and is intended for a 16 GB micro SD card, you can download the image here: My really cool Raspberry Pi Image that I could give some ridiculous name to in the anchor text that you’d still be forced to click because you know you want this image. It’s going to change your life.

Image Requirements

My projects with a raspberry pi have involved an Emlid Navio2, a Teensy 3.2 microcontroller, point to point streaming, video file input to HDMI output, and sensor logging all generally in line with supporting a blimp autopilot. Given all of those different use cases, commonalities exist that are either must-haves or nice-to-haves. Here’s a union of all of those requirements:

  • Pi needed to be safely shut off to avoid hard drive corruption; my solution was to make the hard drive read-only
  • We want the Pi to have internet when plugged into an ethernet cable or when it’s sharing the connection from a laptop for easy development
  • In the case of applications where we want to communicate between devices, I needed a simple communication mechanism; therefore each image hosts its own Redis server that can be reached by any device in the same network
  • Tons of IoT projects involve video, whether outputting or consuming; therefore ffmpeg was included on the image
  • omxplayer is installed so that the Pi could easily be turned into an entertainment device
  • The device automatically supports exactly 1 USB storage device that’s automatically mounted at startup; read and write capabilities are included (thumb drive does in fact risk corruption during power down, but the tradeoff favors extreme simplicity)
  • Because we can’t write to the (read-only) hard drive during production use, the file system is automatically mounted with an in-memory directory with 256 megabytes of RAM allocated
  • My weapon of choice for the Pi is the Emlid Navio2. So the Pi uses Emlid’s initial image for compatibility. Whether or not you intend to build an autopilot, GPS, accelerometer, gyroscope, and magnetomer can easily become relevant on a number of projects.
  • I like Go, therefore the Go runtime environment was installed on the Pi. This makes integration with C or C++ code simple and helps to mitigate the risks of memory leaks in your terrible, terrible code.
  • We also want to make sure we maximize the available disk space; People probably intentionally shrink their images for compatibility across SD cards, but I went ahead and assumed that you want the luxurious 16 GB and that you’re a big enough baller to afford such a micro SD card

Example Projects

The interesting thing I find about this project is not necessarily what features I was trying to support for my own problems, but mainly how simple it offers development in some completely doable weekend projects. Some thoughts that come to mind:

  • Karaoke machine powered by a raspberry pi
  • Absurdly simple setup movie player (i.e. you want a TV that plays something with an infinite loop that requires no setup)
  • Simple GPS logger (i.e. how many times have you ever had a package stolen from your front doorstep, and you start to wonder how easy it would be to place a GPS device in a fake box you intentionally leave at your doorstep that you could log from your computer to identify the thief as you begin to embrace your dark side; you ponder life and what it means to be a man in this world. Do you die for something? Or do you live for nothing?)
  • Simple baby monitor that’s dramatically cheaper than anything else on the streets
  • Simple intercom system for your home
  • Cheap security camera (just ffmpeg and pipe that output to Amazon. When that unidentifiable burglar breaks into your car, smashes all your windows, and unnecessarily breaks the drawers and lights in your car in search of nonexistent sunglasses, you’ll be able to watch on stored files the following day to point and laugh at how much of an idiot that guy looks).

Installing the Image

Assuming you’re kind of a suave hipster type, you have a Mac. Therefore this assumes you’re using Mac OS X. Download the image above, and from there you can stick an SD card in the hole and run:

diskutil list

From here you should be able to infer which disk is the SD card. Assuming that we isolate “/dev/disk2” to be the Micro SD card, we now run:

diskutil unmountDisk /dev/disk2
sudo newfs_msdos -F 16 /dev/disk2
sudo dd if=~/Downloads/iot_raspberrypi.dmg of=/dev/disk2

This will take a while. But it’s worth it.

Sharing Internet to Your Raspberry Pi

In years past, embarassingly, I’ve gone through the pain of getting out wired ethernet cables and plugging the Pi into my router. This gets annoying because you always need to work in close proximity to your router where you have physical access. Instead, it’s worth buying a thunderbolt to ethernet adapter if you don’t already have one, and then go through the few steps to make your internet shareable to the Pi:

 

Screen Shot 2017-11-11 at 9.07.35 PM

Connect the Pi to your suave, hipster Mac with a thunderbolt to eithernet adapter

Screen Shot 2017-11-11 at 9.07.47 PM

Go to system preferences -> sharing > turn on internet sharing

Screen Shot 2017-11-11 at 9.08.04 PM

Your ethernet port should light up like a Christmas tree. If not, you likely have a hardware or connection problem.

Screen Shot 2017-11-11 at 9.08.14 PM

If you go to system preferences -> network, you should see something like the above for your Thunderbolt internet.

Screen Shot 2017-11-11 at 9.08.27 PM

If you change DHCP to DHCP with manual address, you should be able to find an unused IP address within your network.

 

Now you also want to run:

ifconfig bridge100 | grep inet | grep -v inet6

This will contain output like:

inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255

From the IP address above:

nmap -n -sP 192.168.2.1/24 

Part of the output will contain something with:

nmap scan report for 192.168.2.2

And now you can:

ssh pi@192.168.2.2

With default password “raspberry”.

If “host key verification failed”, delete the line for the above IP address in ~/.ssh/known_hosts

At this point, you can remote into your Raspberry Pi, and using the image provided, you should be able to ping The Google.

Using the Image

  • sudo username is “pi” and password is “password”
  • A Redis Server is up and running serving on the default port 6379
  • ffmpeg and omxplayer are installed so you’re free to go nuts. Just really. Whatever you can think of.
  • If a USB thumbstick is present at startup, the mounted disk will exist at:
    /mnt/usb_stick
    
  • In order to write to the hard drive, you can run the alias:
    write_to_hard_drive
    
  • By default, you cannot write to the hard drive so that you are safe to power the Pi down any time, any place
  • You can write to the in memory filesystem at:
    /mnt/in_memory_filesystem
    
  • So just go nuts:
    echo "I CAN ABSOLUTELY WRITE TO RAM!!!!!" > /mnt/in_memory_filesystem/SOME_ARBITRARY_FILENAME_THAT_WONT_EXIST_WHEN_I_RESTART_THE_MACHINE.txt
    
  • To add a new startup script to the Pi:
    write_to_hard_drive
    sudo vim /etc_org/rc.local
    
  • It’s important to note as well that “/etc_org” must be modified rather than the conventional “/etc” for any changes in the latter directory that you intend; This is a result of the setup for a read-only hard drive
  • You must “sudo reboot -f” rather than a standard “reboot” because I didn’t make everything squeaky clean.

In Conclusion