RPI Zero scan button

While I was finishing wireless scanner and printer server I realised that traditional document scanning approach is not so nice from UX point of view.

I really like the way office scanners in multi-functional devices work. Normally if you want to scan you just load stack of paper into and put your email address. Scanner does the rest and in minute you’ll get ready-to-use pdf file in your inbox.

I was thinking about having button attached to RPI Zero which initiates scanning and document upload.

Alternatively it’s possible to program another/one more action, for instance document copy. It’s really up to developer – Raspberry PI provides you endless possibilities!

Let’s build this scan button:

  • It should indicate scanning process right after user hit the button. The problem is the scanner has to be pre-heated to operate and it can take up to 20-30 seconds. User shouldn’t be puzzled by current process.
  • To display current process we need LED. I found yellow LED 3v
  • Scanned document should be placed in shared folder accessible from all popular OS. There are not so many options, hence we have to use Samba(windows files sharing service)
  • Documents older than 1h should be removed from that shared folder
  • Scanned document format – jpg

Prepare environment

First things first – we need python libraries and samba server

sudo apt-get install samba
sudo apt-get install python3-gpiozero python-gpiozero python-pkg-resources

Button script

The script is fairly simple.

It configures LED and Button ports. Then listens to button event. When button is clicked LED blinks to indicate process start and script excecutes scanimage utility which convert output from ppm to jpg format.


<p>from gpiozero import Button, PWMLED
from signal import pause
from time import sleep, strftime
import os;</p>


<p>led = PWMLED(15)
button = Button(23, pull_up=True, hold_repeat=False)</p>

<p>def blink():
  for i in range(20):
    if i % 2 == 0: led.off()
    else: led.value = 0.3

<p>def toggle():
  led.value = 0.3
  ts = strftime("%d-%b-%Y %H.%M.%S.jpg")
  cmd = "scanimage --resolution 150 | convert - jpg:- > '{}/{}'".format(OUT_FOLDER, ts)
  print("Scanning... {}".format(cmd))

<p>button.when_released = toggle</p>



PWMLED is used in this script on purpose. Seems like I bought too powerful led without any specs – lady in the shop ensured me that it’s low current LED. Unfortunately one of GPIO port has died after I left it on for 10 minutes. To avoid burning another GPIO pin I enabled PWM for LED, if you never heard about it read wikipedia. From my experiments I found brightness of 30%(0.3) seems minimum acceptable for me. You might need to connect your led via resistor, depending on it’s current and voltage.

I couldn’t run this script under non-privileged user unfortunately because scanimage command doesn’t detect scanner. I think there were problems with USB device permission but if you care I’m sure it’s possible to fix it.


I forgot to copy other configuration files for samba server, crond and systemd and now I don’t have access to RPI but trust me it used to work :D I’ll put here other configs later on

This blogpost has been written in airplane over Baltic sea on the way to London