Background
I built what I called a "Cloud Scanner" interface for my older but functional HP Laserjet 3055 multi-function office printer some time ago. I built it with a Raspberry Pi and a 2-line Hitachi-compatible LCD and some momentary contact push buttons for navigation. The idea of the device is that I want to be able to easily and rapidly get paper "into the cloud". No turning on a connected computer (waiting for boot-up...ok, I have a Mac so this is not too big a deal for me, but God help you Windows folks), no finding the typically crummy proprietary scanning application, no figuring out how to convert the scan that results into the universal electronic paper (PDF), no fumbling around with a transfer program (email, Google Docs, or the like). No, I just want to walk up, put in my papers to the document feeder, push a button, and have my electronic paper show up in the cloud. One step.I built it and all was well, until...
My wife came to me and said the scanner was not working. She became a fan of my little device and grew to rely on it. She has a vacation rental business and so does a lot of rental agreement processing. She sends paper to her email all the time. So off I go to diagnose. Turns out...corrupt SD RAM card. After some Googling, it seems that many RPi users are having the same problem. Secretly, I kinda knew this. We had a power failure a day or two prior and I don't think it was coincidence. This has happened to me in the past and all I had to do was eject the card, mount it in a Linux machine, and run fsck on the volume. This time...ouch. The card was totally unrecoverable.
This hurt. Of course I did not have a backup. Back to the drawing board...
So this time, I start looking for what the Linux router crowd has been doing for years (with read-only Linux'es and busybox, for example). The only solution I stumbled on, aside from numerous blogs with varying cookbooks to be performed against Raspbarian, is a distro built by NutCom Services Ltd. This post chronicles my experience and gives you a mini how-to if you want to build your own. I use a MacBook for development work, so all instructions will be given in that context.
Re-Baking the Pi
Installing IPE
- You'll need a command prompt. On the Mac, it's terminal.
- Download the Industrial Perennial Environment (IPE) and unzip it.
- Insert your SD card (must be 1GB or greater) and figure out which volume it mounts up as. I used:
$ df -lh
- If there is already a formatted volume on the card (usually there is), unmount it:
$ sudo diskutil umount "/Volumes/NO NAME"
- From the directory where the ipe_r1.img file is located, type (NOTE - /dev/disk2 is where my SD card was located...ymmv and don't blame me if you wipe out something important. This command is destructive and unforgiving!):
$ sudo dd if=ipe_r1.img of=/dev/disk2 bs=1m
- Put the card into the Pi and boot it. Since I did not have a monitor and keyboard hooked up to mine, I used my router to figure out what IP address was given to the Pi. Note - The IPE distro only starts up with TELNET for remote access! It took me a while to figure this out. I had to hook up a monitor and keyboard to learn that sshd was not started (never fear, keep reading). Log into the Pi using root with password root.
$ telnet 192.168.1.122
- A very nice command script was written by NutCom that resizes your SD card volume to the max it can be (defaults to 1GB upon install) and then generates an SSH private key, turns on sshd, resets the root password, and turns off telnet. Run TWICE (there is a reboot in between if memory serves).
$ firstboot $ firstboot
- I am always in the habit (and one of the reasons I gravitate to Debian-based distros - apt rocks) of updating software upon a new install. So this step would be to tell you to run apt-get update and apt-get upgrade. But I ran into problems with this distro. There is a script you can run that will set of the Pi volume for read-write, which you obviously need to do to update software. But what it does not do is change to /boot volume. Therefore, I got the following errors:rm: cannot remove `/boot/bootcode.bin': Read-only file systemdpkg: error processing raspberrypi-bootloader (--configure):subprocess installed post-installation script returned error exit status 1dpkg: dependency problems prevent configuration of libraspberrypi0:libraspberrypi0 depends on raspberrypi-bootloader (= 1.20130617-1); however:Package raspberrypi-bootloader is not configured yet.dpkg: error processing libraspberrypi0 (--configure):dependency problems - leaving unconfigureddpkg: dependency problems prevent configuration of libraspberrypi-dev:libraspberrypi-dev depends on libraspberrypi0 (= 1.20130617-1); however:Package libraspberrypi0 is not configured yet.dpkg: error processing libraspberrypi-dev (--configure):dependency problems - leaving unconfigureddpkg: dependency problems prevent configuration of libraspberrypi-doc:libraspberrypi-doc depends on libraspberrypi0 (= 1.20130617-1); however:Package libraspberrypi0 is not configured yet.dpkg: error processing libraspberrypi-doc (--configure):dependency problems - leaving unconfigureddpkg: dependency problems prevent configuration of libraspberrypi-bin:libraspberrypi-bin depends on libraspberrypi0 (= 1.20130617-1); however:Package libraspberrypi0 is not configured yet.dpkg: error processing libraspberrypi-bin (--configure):dependency problems - leaving unconfigured…Errors were encountered while processing:raspberrypi-bootloaderlibraspberrypi0libraspberrypi-devlibraspberrypi-doclibraspberrypi-binE: Sub-process /usr/bin/dpkg returned an error code (1)
- Set the Pi root volume to read/write.
$ ipe-rw
- Modify the /sbin/ipe-rw file as follows:
#!/bin/sh echo Remounting rootFS for R/W! Use \"ipe-ro\" to lock it again! mount / -o remount,rw mount /boot -o remount,rw
- Modify the /sbin/ipe-ro file as follows:
#!/bin/sh echo Remounting rootFS for R/O! mount / -o remount,ro mount /boot -o remount,ro
- Now update the distro (need to re-execute read-write script):
$ ipe-rw
$ apt-get update $ apt-get upgrade
- Base Pi install, immune to SD card corruption (at least so far for me), is now good to go!
Caveat
When updating the Pi, I encountered a situation that I cannot reproduce where DHCP assigned DNS addressing no longer worked (it did at initial install). It may be that the upgrade process overwrote /etc/resolv.conf and because of the read-only nature of the root volume, it could not get reset. When I manually updated it with my routers' address, everything was fine. I intend to ping NutCom after authoring this to see if they have any experience with this.
Base Packages and Dependencies
The following base software is needed by the Cloud Scanner device:
$ apt-get install sane libsane sane-utils libsane-hpaio
$ apt-get install libtiff-tools imagemagick
$ apt-get install python-dev python-pip
$ pip install RPIO
$ pip install RPLCD
The Hardware
I used a HD44780 compatible LCD display and 4 momentary push button switches for the user interface. I used the onboard power supply on the Pi to power these peripherals, which is just enough (and also contingent on how you are powering the device and what else beside a connection to your scanner you may have plugged into the USB port).
Cloud Scanner Schematic |
The Software
I have put my project on github. Instructions on how to install it are located in the github readme.
There are three options from the main menu: Green button = Scan now, White button = select an email destination, and Blue button = select a paper size. The program will scan from the first scanner it finds (which may be a limitation I realize...it's on my list).
One additional thing you will need to do, since the scan program will put all working files in /tmp, is to expand the size of the tmpfs volume. To do that, edit /etc/default/tmpfs, find the TMP_SIZE parameter, uncomment it, and change it to 200M.
Enhancements
Nothing is ever completely done, is it?
- Add a More> submenu to the black button so more options can be added.
- Add a scanner selector.
- Add an automatic document feeder vs. flatbed option (defaults to ADF but I do have a flatbed-only scanner and it will currently work).
- Add more destination types, like to Dropbox, Google Docs, Amazon S3, ftps, etc.
- Add a duplex assembly option (for double-sided pages).
- Add a web interface to manage the settings.
The Result
For the "enclosure", I was inspired by a project that I saw that used discarded CDs and CD protectors. Since I have plenty of those, I made one myself. It worked pretty well.