Raspberry Pi USB Flatbed Document Scanner
by ozmacguyver in Circuits > Raspberry Pi
2865 Views, 2 Favorites, 0 Comments
Raspberry Pi USB Flatbed Document Scanner
This is my Raspberry Pi 3 Model B+ Flatbed Document Scanner project. It uses a SANE compatible Canon USB Printer Scanner to create a stand alone document scanner, rather than using software installed on a PC.
The scanned files are saved to the SD Card on the Raspberry Pi, and you simply access them via the local network from any device. I haven't incorporated a direct scan then print function, as it was not part of this project, but having said that, it would not be too hard to get that feature to work, pretty much like a stand alone photocopier.
Full details on my website - http://ozmacguyver.com/projects/index.php/2-canonpiscanner
Supplies
- Raspberry Pi 3 Model B+ (or similar)
- Official 7" Touchscreen (or similar or just a non-touch screen)
- Keyboard
- Mouse
- 12v DC 3A Power Supply
- 12v DC 3A to 5V converter module (ebay is full of them)
- Adafruit 3.7w Class D Amplifier Module and appropriate speakers (laptop or similar) - OR just a set of normal speakers with 3.5mm plug
- USB Scanner (compatible with SANE)
- USB cable
- Hook up Wire
Python Code
As you can see, this is the GUI that you use on a touchscreen
It can be mouse driven and use a non-touch screen also, but how 80's is that?
Here's the code for the GUI (Python code, bash scripts, audio and image files)
https://drive.google.com/file/d/1YJNoiFuf5jd6LuqmRgo8HKtN15SmuxU6/view?usp=sharing
Here's a view of the Python GUI code
<code>from tkinter import * import tkinter as tk import tkinter.font as font import subprocess import os import socket import sys from time import * from time import sleep import time from pydub import AudioSegment from pydub.playback import play import os.path from os import path import pathlib from tkinter import ttk #PROGRESS BAR import tempfile # ------------------------------------------------------------------------------ # RASPBERRY PI CANON SCANNER by OZMACGUYVER 2019 # ------------------------------------------------------------------------------ # SET UP MAIN WINDOW GUI root = tk.Tk() root.configure(bg='#402F2F') # WINDOW TITLE root.title("Cano-Pi-Scanner") # WINDOW SIZE root.geometry("614x1024") # 7" SCREEN MODIFIED # FULL SCREEN - NO TITLE BAR root.wm_attributes('-fullscreen','true') # ------------------------------------------------------------------------------ # SET UP FONT SIZES AND TYPES myFont0 = font.Font(family='Courier', size=6) myFont1 = font.Font(family='Courier', size=8, weight="bold") myFont2 = font.Font(family='Courier', size=12, weight="bold") myFont3 = font.Font(family='Courier', size=4, weight="bold") # ------------------------------------------------------------------------------ # SET UP FOLDER folder = pathlib.Path("/home/pi/CanoPyScannerGUI/scanner") checkFOLDERempty = os.listdir('/home/pi/CanoPyScannerGUI/scanner') # ------------------------------------------------------------------------------ # SETUP SOUND soundERROR = AudioSegment.from_mp3('/home/pi/CanoPyScannerGUI/audio/Beep_Short.mp3') soundGOOD = AudioSegment.from_mp3('/home/pi/CanoPyScannerGUI/audio/complete.mp3') soundCONNECTIONlost = AudioSegment.from_mp3('/home/pi/CanoPyScannerGUI/audio/device-removed.mp3') soundCONNECTIONfound = AudioSegment.from_mp3('/home/pi/CanoPyScannerGUI/audio/device-added.mp3') # SET UP IMAGES LOGO = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/logo.png") BW = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/blacknwhite.png") COLOUR = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/color.png") GREY = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/greyscale.png") USB = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/usb.png") WIFI = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/wifi.png") POWER_OFF = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/poweroff.png") REBOOT = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/reboot.png") TRASH = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/trash.png") FOLDER = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/folder.png") HAPPY = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/happy.png") PUZZLED = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/puzzled.png") ERROR = tk.PhotoImage(file = "/home/pi/CanoPyScannerGUI/images/error.png") # ------------------------------------------------------------------------------ # LOGO iconLOGO = (LOGO) theLabelIMAGE = tk.Label(root, image = iconLOGO, bg='#402F2F') theLabelIMAGE.grid(row=0, column=0, columnspan=2) # ------------------------------------------------------------------------------ # SPACE theLabelEMPTY1 = Label(root, text="", bg='#402F2F') theLabelEMPTY1.grid(row=1, column=1) theLabelEMPTY1 = Label(root, text="", bg='#402F2F') theLabelEMPTY1.grid(row=4, column=1) # ------------------------------------------------------------------------------ # CHECK SCANNER IS CONNECTED/POWERED ON GUI START scannerCONNECTEDinitial = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) # ------------------------------------------------------------------------------ # SET UP BUTTONS # A4 BW 600 DPI. def A4_BW_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS print('A4 600 DPI B&W Scanning......') scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonA4BW600['text'] = 'A4 600 DPI - B&W' os.setuid(os.geteuid()) A4_BW_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/A4_BW.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonA4BW600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonA4BW600 = (BW) iconbuttonA4BW600RESIZE = iconbuttonA4BW600.subsample(2, 2) buttonA4BW600 = Button(text = 'A4 600 DPI - B&W', image = iconbuttonA4BW600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = A4_BW_GO) buttonA4BW600['font'] = myFont2 buttonA4BW600.grid(row=5, column=0) # ------------------------------------------------------------------------------ # A4 COLOUR 300 DPI def A4COLOUR300_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('A4 300 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonA4COLOUR300['text'] = 'A4 300 DPI - COLOUR' os.setuid(os.geteuid()) A4COLOUR300_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/A4_Colour_300.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonA4COLOUR300['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonA4COLOUR300 = (COLOUR) iconbuttonA4COLOUR300RESIZE = iconbuttonA4COLOUR300.subsample(2, 2) buttonA4COLOUR300 = Button(text = 'A4 300 DPI - COLOUR', image = iconbuttonA4COLOUR300RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = A4COLOUR300_GO) buttonA4COLOUR300['font'] = myFont2 buttonA4COLOUR300.grid(row=5, column=1) # ------------------------------------------------------------------------------ # A4 COLOUR 600 DPI def A4COLOUR600_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('A4 600 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: os.setuid(os.geteuid()) buttonRECHECKusb['text'] = 'USB CONNECTED' buttonA4COLOUR600['text'] = 'A4 600 DPI - COLOUR' A4COLOUR600_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/A4_Colour_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonA4COLOUR600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonA4COLOUR600 = (COLOUR) iconbuttonA4COLOUR600RESIZE = iconbuttonA4COLOUR600.subsample(2, 2) buttonA4COLOUR600 = Button(text = 'A4 600 DPI - COLOUR', image = iconbuttonA4COLOUR600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = A4COLOUR600_GO) buttonA4COLOUR600['font'] = myFont2 buttonA4COLOUR600.grid(row=6, column=0) # ------------------------------------------------------------------------------ # A4 GREY 300 DPI def A4GREY300_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('A4 300 DPI GREY Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonA4GREY300['text'] = 'A4 300 DPI - GREY' os.setuid(os.geteuid()) A4GREY300_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/A4_Grey_300.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonA4GREY300['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonA4GREY300 = (GREY) iconbuttonA4GREY300RESIZE = iconbuttonA4GREY300.subsample(2, 2) buttonA4GREY300 = Button(text = 'A4 300 DPI - GREY', image = iconbuttonA4GREY300RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = A4GREY300_GO) buttonA4GREY300['font'] = myFont2 buttonA4GREY300.grid(row=6, column=1) # ------------------------------------------------------------------------------ # A4 GREY 600 DPI def A4GREY600_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('A4 600 DPI GREY Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonA4GREY600['text'] = 'A4 600 DPI - GREY' os.setuid(os.geteuid()) A4GREY600_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/A4_Grey_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonA4GREY600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonA4GREY600 = (GREY) iconbuttonA4GREY600RESIZE = iconbuttonA4GREY600.subsample(2, 2) buttonA4GREY600 = Button(text = 'A4 600 DPI - GREY', image = iconbuttonA4GREY600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = A4GREY600_GO) buttonA4GREY600['font'] = myFont2 buttonA4GREY600.grid(row=7, column=0) # ------------------------------------------------------------------------------ # ID COLOUR 600 DPI def IDCOLOUR600_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('ID 600 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonIDCOLOUR600['text'] = 'ID 600 DPI - COLOUR' os.setuid(os.geteuid()) IDCOLOUR600_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/ID_Colour_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonIDCOLOUR600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonIDCOLOUR600 = (COLOUR) iconbuttonIDCOLOUR600RESIZE = iconbuttonIDCOLOUR600.subsample(2, 2) buttonIDCOLOUR600 = Button(text = 'ID 600 DPI - COLOUR', image = iconbuttonIDCOLOUR600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = IDCOLOUR600_GO) buttonIDCOLOUR600['font'] = myFont2 buttonIDCOLOUR600.grid(row=7, column=1) # ------------------------------------------------------------------------------ # ID GREY 600 DPI def IDGREY600_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('ID 600 DPI GREY Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonIDGREY600['text'] = 'ID 600 DPI - GREY' os.setuid(os.geteuid()) IDGREY600_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/ID_Grey_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonIDGREY600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonIDGREY600 = (GREY) iconbuttonIDGREY600RESIZE = iconbuttonIDGREY600.subsample(2, 2) buttonIDGREY600 = Button(text = 'ID 600 DPI - GREY', image = iconbuttonIDGREY600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = IDGREY600_GO) buttonIDGREY600['font'] = myFont2 buttonIDGREY600.grid(row=8, column=0) # ------------------------------------------------------------------------------ # PHOTO COLOUR 300 DPI def PHOTOCOLOUR300DPI_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('PHOTO 300 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonPHOTOCOLOUR300['text'] = 'PHOTO 300 DPI - COLOUR' os.setuid(os.geteuid()) PHOTOCOLOUR300DPI_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/Photo_Colour_300.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonPHOTOCOLOUR300['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonPHOTOCOLOUR300 = (COLOUR) iconbuttonPHOTOCOLOUR300RESIZE = iconbuttonPHOTOCOLOUR300.subsample(2, 2) buttonPHOTOCOLOUR300 = Button(text = 'PHOTO 300 DPI - COLOUR', image = iconbuttonPHOTOCOLOUR300RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = PHOTOCOLOUR300DPI_GO) buttonPHOTOCOLOUR300['font'] = myFont2 buttonPHOTOCOLOUR300.grid(row=8, column=1) # ------------------------------------------------------------------------------ # PHOTO COLOUR 600 DPI def PHOTOCOLOUR600DPI_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('PHOTO 600 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonPHOTOCOLOUR600['text'] = 'PHOTO 600 DPI - COLOUR' os.setuid(os.geteuid()) PHOTOCOLOUR600DPI_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/Photo_Colour_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonPHOTOCOLOUR600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonPHOTOCOLOUR600 = (COLOUR) iconbuttonPHOTOCOLOUR600RESIZE = iconbuttonPHOTOCOLOUR600.subsample(2, 2) buttonPHOTOCOLOUR600 = Button(text = 'PHOTO 600 DPI - COLOUR', image = iconbuttonPHOTOCOLOUR600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = PHOTOCOLOUR600DPI_GO) buttonPHOTOCOLOUR600['font'] = myFont2 buttonPHOTOCOLOUR600.grid(row=9, column=0) # ------------------------------------------------------------------------------ # PHOTO GREY 300DPI def PHOTOGREY300DPI_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('PHOTO 300 DPI GREY Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonPHOTOGREY300['text'] = 'PHOTO 300 DPI - GREY' os.setuid(os.geteuid()) PHOTOGREY300DPI_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/Photo_Grey_300.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonPHOTOGREY300['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonPHOTOGREY300 = (GREY) iconbuttonPHOTOGREY300RESIZE = iconbuttonPHOTOGREY300.subsample(2, 2) buttonPHOTOGREY300 = Button(text = 'PHOTO 300 DPI - GREY', image = iconbuttonPHOTOGREY300RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = PHOTOGREY300DPI_GO) buttonPHOTOGREY300['font'] = myFont2 buttonPHOTOGREY300.grid(row=9, column=1) # ------------------------------------------------------------------------------ # PHOTO GREY 600DPI def PHOTOGREY600DPI_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('PHOTO 600 DPI GREY Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonPHOTOGREY600['text'] = 'PHOTO 600 DPI - GREY' os.setuid(os.geteuid()) PHOTOGREY600DPI_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/Photo_Grey_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonPHOTOGREY600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonPHOTOGREY600 = (GREY) iconbuttonPHOTOGREY600RESIZE = iconbuttonPHOTOGREY600.subsample(2, 2) buttonPHOTOGREY600 = Button(text = 'PHOTO 600 DPI - GREY', image = iconbuttonPHOTOGREY600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = PHOTOGREY600DPI_GO) buttonPHOTOGREY600['font'] = myFont2 buttonPHOTOGREY600.grid(row=10, column=0) # ------------------------------------------------------------------------------ # PASSPORT 600 DPI def PASSPORT600DPI_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('PASSPORT 600 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonPASSPORT600['text'] = 'PASSPORT 600 DPI - COLOUR' os.setuid(os.geteuid()) PASSPORT600DPI_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/Passport_600.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonPASSPORT600['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonPASSPORT600 = (COLOUR) iconbuttonPASSPORT600RESIZE = iconbuttonPASSPORT600.subsample(2, 2) buttonPASSPORT600 = Button(text = 'PASSPORT 600 DPI - COLOUR', image = iconbuttonPASSPORT600RESIZE, width=280, height=60, anchor='w', compound = LEFT, command = PASSPORT600DPI_GO) buttonPASSPORT600['font'] = myFont2 buttonPASSPORT600.grid(row=10, column=1) # ------------------------------------------------------------------------------ # RECEIPT_BW def RECEIPT_BW_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('RECEIPT 600 DPI B&W Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonRECEIPT_BW['text'] = 'RECEIPT 600 DPI - B&W' os.setuid(os.geteuid()) RECEIPT_BW_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/Receipt_BW.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonRECEIPT_BW['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonRECEIPT_BW = (BW) iconbuttonRECEIPT_BWRESIZE = iconbuttonRECEIPT_BW.subsample(2, 2) buttonRECEIPT_BW = Button(text = 'RECEIPT 600 DPI - B&W', image = iconbuttonRECEIPT_BWRESIZE, width=280, height=60, anchor='w', compound = LEFT, command = RECEIPT_BW_GO) buttonRECEIPT_BW['font'] = myFont2 buttonRECEIPT_BW.grid(row=11, column=0) # ------------------------------------------------------------------------------ # SPACE theLabelEMPTY1 = Label(root, text="", bg='#402F2F') theLabelEMPTY1.grid(row=12, column=1) # ------------------------------------------------------------------------------ # A4_IMAGE_ONLY def A4_IMAGE_ONLY_GO(): # THIS IS THE SCANNING PROCESS OF EVENTS scannerCHECKbeforeSCAN = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) print('IMAGE 600 DPI COLOUR Scanning......') if scannerCHECKbeforeSCAN == 0: buttonRECHECKusb['text'] = 'USB CONNECTED' buttonA4_IMAGE_ONLY['text'] = 'IMAGE 600 DPI - COLOUR' os.setuid(os.geteuid()) A4_IMAGE_ONLY_GO = subprocess.call("sudo /home/pi/CanoPyScannerGUI/A4_Image_only.sh", shell=True) play(soundGOOD) print('Finished') if scannerCHECKbeforeSCAN == 1: buttonRECHECKusb['text'] = 'USB NOT CONNECTED' buttonRECEIPT_BW['text'] = 'NOT CONNECTED' play(soundCONNECTIONlost) iconbuttonA4_IMAGE_ONLY = (COLOUR) iconbuttonA4_IMAGE_ONLYRESIZE = iconbuttonA4_IMAGE_ONLY.subsample(2, 2) buttonA4_IMAGE_ONLY = Button(text = 'IMAGE 600 DPI - COLOUR', image = iconbuttonA4_IMAGE_ONLYRESIZE, width=280, height=60, anchor='w', compound = LEFT, command = A4_IMAGE_ONLY_GO) buttonA4_IMAGE_ONLY['font'] = myFont2 buttonA4_IMAGE_ONLY.grid(row=11, column=1) # FOLDER CHECKING icontheLabelFOLDERfound = (HAPPY) icontheLabelFOLDERfoundRESIZE = icontheLabelFOLDERfound.subsample(1, 1) icontheLabelFOLDERmissing = (ERROR) icontheLabelFOLDERmissingRESIZE = icontheLabelFOLDERmissing.subsample(1, 1) def main(): if folder.exists (): print ("Folder Exists!") theLabelFOLDER = Label(root, text=" Scanned Documents Folder OK", image = icontheLabelFOLDERfoundRESIZE, compound = LEFT, bg='#402F2F', fg='#ffffff') theLabelFOLDER['font'] = myFont2 theLabelFOLDER.grid(row=13, column=0, columnspan=2) else: print ("Folder Missing!") theLabelFOLDER = Label(root, text=" Scanned Documents Folder Missing!", image = icontheLabelFOLDERmissingRESIZE, compound = LEFT, bg='#402F2F', fg='#ff0000') theLabelFOLDER['font'] = myFont2 theLabelFOLDER.grid(row=13, column=0, columnspan=2) # RUNS WHEN THE MAINLOOP (GUI) STARTS if __name__== "__main__": main() # ------------------------------------------------------------------------------ theLabelEMPTY1 = Label(root, text="", bg='#402F2F') theLabelEMPTY1.grid(row=14, column=1) # ------------------------------------------------------------------------------ # IP ADDRESS IP = subprocess.getoutput('hostname -I') icontheLabelIP = (WIFI) theLabelIP = Label(text = " " + IP, fg="white", image = icontheLabelIP, compound = LEFT, bg='#402F2F') theLabelIP['font'] = myFont2 theLabelIP.grid(row=17, column=0, columnspan=2) # ------------------------------------------------------------------------------ # SPACE theLabelEMPTY1 = Label(root, text="", bg='#402F2F') theLabelEMPTY1.grid(row=20, column=0) # ------------------------------------------------------------------------------ # DELETE ALL def DELETEALL_GO(): # THIS IS THE PROCESS OF EVENTS os.setuid(os.geteuid()) if checkFOLDERempty: subprocess.call("sudo /home/pi/CanoPyScannerGUI/Delete_All_Documents.sh", shell=True) buttonDELETEALL['text'] = 'Delete All' play(soundGOOD) print('Finished') else: buttonDELETEALL['text'] = 'Delete All' play(soundGOOD) iconbuttonDELETEALL = (TRASH) buttonDELETEALL = Button(text = 'Delete All', image = iconbuttonDELETEALL, width=280, height=60, compound = LEFT, command = DELETEALL_GO, bg='#DD5B5B') buttonDELETEALL['font'] = myFont2 buttonDELETEALL.grid(row=50, column=1) # ------------------------------------------------------------------------------ # REBOOT def Reboot_GO(): subprocess.call("sudo reboot now", shell=True) iconbuttonREBOOT = (REBOOT) iconbuttonREBOOTRESIZE = iconbuttonREBOOT.subsample(1, 1) buttonREBOOT = Button(text = 'Re-Boot', image = iconbuttonREBOOTRESIZE, width=280, height=60, compound = LEFT, command = Reboot_GO, bg='#767BEC') buttonREBOOT['font'] = myFont2 buttonREBOOT.grid(row=50, column=0) # ------------------------------------------------------------------------------ # POWER OFF def ShutDown_GO(): subprocess.call("sudo shutdown now", shell=True) iconbuttonPOWEROFF = (POWER_OFF) iconbuttonPOWEROFFRESIZE = iconbuttonPOWEROFF.subsample(1, 1) buttonPOWEROFF = Button(text = 'Power Off', image = iconbuttonPOWEROFFRESIZE, width=280, height=60, compound = LEFT, command = ShutDown_GO, bg='#A9F659') buttonPOWEROFF['font'] = myFont2 buttonPOWEROFF.grid(row=51, column=0) # ------------------------------------------------------------------------------ # SCANNER CONNECTED ICON # MANUAL USB RE-PING def RECHECKusbGO(): # RESET BUTTONS BACK TO START UP STATE buttonRECEIPT_BW['text'] = 'RECEIPT 600 DPI - B&W' buttonPASSPORT600['text'] = 'PASSPORT 600 DPI - COLOUR' buttonPHOTOGREY600['text'] = 'PHOTO 600 DPI - GREY' buttonPHOTOGREY300['text'] = 'PHOTO 300 DPI - GREY' buttonPHOTOCOLOUR600['text'] = 'PHOTO 600 DPI - COLOUR' buttonPHOTOCOLOUR300['text'] = 'PHOTO 300 DPI - COLOUR' buttonIDGREY600['text'] = 'ID 600 DPI - GREY' buttonIDCOLOUR600['text'] = 'ID 600 DPI - COLOUR' buttonA4GREY600['text'] = 'A4 600 DPI - GREY' buttonA4GREY300['text'] = 'A4 300 DPI - GREY' buttonA4COLOUR600['text'] = 'A4 600 DPI - COLOUR' buttonA4COLOUR300['text'] = 'A4 300 DPI - COLOUR' buttonA4BW600['text'] = 'A4 600 DPI - B&W' # CHECKING USB CONNECTION os.setuid(os.geteuid()) RECHECKusbGO = subprocess.call("sudo lsusb |grep 04a9:176d", shell=True) if RECHECKusbGO == 0: buttonRECHECKusb['text'] = 'USB RE-CHECK SUCCESSFUL' play(soundCONNECTIONfound) if RECHECKusbGO == 1: buttonRECHECKusb['text'] = 'USB RE-CHECK FAIL' play(soundCONNECTIONlost) if scannerCONNECTEDinitial == 0: iconRECHECKusb = (USB) buttonRECHECKusb = Button(text = "USB CONNECTED", image = iconRECHECKusb, width=280, height=60, compound = LEFT, command = RECHECKusbGO, bg='#938C8C') play(soundCONNECTIONfound) buttonRECHECKusb['font'] = myFont2 buttonRECHECKusb.grid(row=51, column=1) if scannerCONNECTEDinitial == 1: iconRECHECKusb = (USB) buttonRECHECKusb = Button(text = "USB NOT CONNECTED", image = iconRECHECKusb, width=280, height=60, compound = LEFT, command = RECHECKusbGO, bg='#938C8C') play(soundCONNECTIONlost) buttonRECHECKusb['font'] = myFont2 buttonRECHECKusb.grid(row=51, column=1) # ------------------------------------------------------------------------------ root.mainloop()
What is this code that I see?
sudo lsusb | grep 04a9:176d
Basically, you need to check the Scanner is connected when running the Python GUI commands, otherwise, it will just sit there asking to scan a document, but there won't be a response, or the code will terminate.
When you just run the following
sudo lsusb
It will probe the USB Bus, and give you a list of USB devices connected to the USB Bus
The screenshot above shows a list of my devices, mine is the Canon, Inc. PIXMA MG2500 Series
If you take not of the identifier, then add this to the end, it will probe the USB bus, but only look for your Scanner
sudo lsusb | grep 04a9:176d
As per the other screenshot above
A4_BW.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # A4_BW.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Lineart -x 210 -y 297 | pnmtops -imagewidth 11.3 -imageheight 11.7 -nocenter | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
A4_Colour_300.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # A4_Colour_300.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 300 --mode Color -x 210 -y 297 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
A4_Colour_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # A4_Colour_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Color -x 210 -y 297 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
A4_Grey_300.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # A4_Grey_300.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 300 --mode Gray -x 210 -y 297 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
A4_Grey_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # A4_Grey_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Gray -x 210 -y 297 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
A4_Image_only.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Image_${datetime}" #For a normal image (colour or grey scale) scanimage -d 'pixma:04A9176D_EEEA33' --progress --format=tiff --resolution 600 -x 2550 -y 3300 > /home/pi/CanoPyScannerGUI/scanner/$filename.tiff
Delete_All_Documents.sh
#!/bin/bash<br> # DELETE ALL DOCUMENTS FROM SCANNER FOLDER rm /home/pi/CanoPyScannerGUI/scanner/*.pdf rm /home/pi/CanoPyScannerGUI/scanner/*.tiff
ID_Colour_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # ID_Colour_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Color -x 54 -y 85.5 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
ID_Grey_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # ID_Grey_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Gray -x 54 -y 85.5 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
Passport_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # Passport_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Color -x 88 -y 125 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
Photo_Colour_300.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # Photo_Colour_300.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 300 --mode Color -x 104 -y 154 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
Photo_Colour_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # Photo_Colour_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Color -x 104 -y 154 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
Photo_Grey_300.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # Photo_Grey_300.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 300 --mode Gray -x 104 -y 154 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
Photo_Grey_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # Photo_Grey_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Gray -x 104 -y 154 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
ID_Grey_600.sh
#!/bin/bash<br> # Scanning the document, and saving with timestamp datetime="`date '+%Y%m%d%H%M%S'`" filename="Scanned_Document_${datetime}" # ID_Grey_600.sh scanimage -d 'pixma:04A9176D_EEEA33' --progress --resolution 600 --mode Gray -x 80 -y 297 | pnmtops -imageheight 11.7 -imagewidth 8.3 | ps2pdf - /home/pi/CanoPyScannerGUI/scanner/$filename.pdf
start_saned.py
import subprocess subprocess.call("sudo su -s /bin/sh - saned", shell=True)
startup_gui.sh
#!/usr/bin/sh<br>sleep 4 python3 /home/pi/CanoPyScannerGUI/gui.py
Configuring the Raspberry Pi
Boot up the Raspberry Pi, and open a terminal so we can enable SSH
sudo raspi-config
I won't delve into changing users or the initial password. For the purposes of this project, I've left everything stock so it's easier to follow the process
Now we can SSH into the Raspberry Pi, and complete our settings remotely (IP address will differ) ssh
pi@192.168.1.xxx
Add user to SUDOERS group
sudo usermod -aG sudo pi
Make sure you update/upgrade the OS
sudo apt update && sudo apt upgrade
Now we install what we need
sudo apt install python3 python3-tk sudo apt install python-pip sudo apt install python3-pip sudo pip install pydub sudo pip3 install pydub sudo apt install netpbm ghostscript samba sane
Now we copy our folder that contains the python gui, bash scripts, images and audio files from the LOCAL machine to the RASPBERRY PI (I have included my local folder structure and the destination folder structure as an example)
scp -r /home/debianos/projects/CanoPyScannerGUI/ pi@192.168.1.xxx:/home/pi/CanoPyScannerGUI/
Change the permissions of the scanner folder - https://linuxize.com/post/what-does-chmod-777-mea...
chmod 777 /home/pi/CanoPyScannerGUI/scanner
We now need to edit the config.txt file, and add code to make the Official 7" Touchscreen work
cd /boot sudo nano config.txt
Add the following
# LCD SCREEN SIZE (FOR 7") framebuffer_width=614 framebuffer_height=1024 # ROTATES THE LCD ONLY display_rotate=1 # ROTATES THE LCD TOUCH DRIVER TO MATCH THE LCD ROTATION dtoverlay=rpi-ft5406,touchscreen- swapped-x-y=1,touchscreen-inverted-x=1,touchscreen-inverted-y=1
Reboot, and let's check the resolution
sudo reboot now
ssh pi@192.168.1.xxx
fbset -s
Make scripts executable
chmod +x /home/pi/CanoPyScannerGUI/*.sh
Set up a SAMBA share
sudo nano /etc/samba/smb.conf
add this to the end
[scanner] comment = Samba on Ubuntu path = /home/pi/CanoPyScannerGUI/scanner read only = no browsable = yes
Restart the SAMBA service
sudo service smbd restart
Set up a password for the SAMBA share
sudo smbpasswd -a pi
Connect to the SAMBA share from the LOCAL PC
smb://raspberrypi.local/scanner/
Lets now make the GUI Auto start when the OS boots up
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
add this to the end
@sh /home/pi/CanoPyScannerGUI/startup_gui.sh
Remove the rainbow screen
sudo nano /boot/config.txt
add this to the end
disable_splash=1
Remove the text that is displayed under the boot splash screen
sudo nano /usr/share/plymouth/themes/pix/pix.script
Comment out as follows
#message_sprite = Sprite(); #message_sprite.SetPosition(screen_width * 0.1, screen_height * 0.9, 10000); # my_image = Image.Text(text, 1, 1, 1); # message_sprite.SetImage(my_image);
Remove Boot Messages
sudo nano /boot/cmdline.txt
Replace “console=tty1” with “console=tty3” (This redirects boot messages to tty3)
add this to the end
splash quiet plymouth.ignore-serial-consoles logo.nologo vt.global_cursor_default=0
Here are brief explanations.
‘splash’ : enables splash image,
‘quiet’ : disable boot message texts,
‘plymouth.ignore-serial-consoles’ : not sure about this but seems it’s required when use Plymouth,
‘logo.nologo’ : removes Raspberry Pi logo in top left corner,
‘vt.global_cursor_default=0’ : removes blinking cursor.
Replace the default splash screen
sudo cp /usr/share/plymouth/themes/pix/splash.png /home/pi/ sudo cp /home/pi/CanoPyScannerGUI/images/logo.png /usr/share/plymouth/themes/pix/splash.png
We need to now control the Raspberry Pi locally, so grab the mouse and keyboard you plugged in earlier, and navigate as follows:
APPEARANCE PREFERENCES > CHOOSE logo.png from /home/pi/CanoPyScannerGUI/images
SET CENTRED
CHANGE WALLPAPER COLOUR TO DARK
The display will blank out due to power saving mode, we need to disable this
sudo nano /etc/lightdm/lightdm.conf
add to the [SEATS] options
# don't sleep the screen xserver-command=X -s 0 dpms
Now, let's see if it all works!
sudo reboot