GithubHelp home page GithubHelp logo

raspberryy / emulated_usb_printer Goto Github PK

View Code? Open in Web Editor NEW
75.0 7.0 14.0 339 KB

Using a Raspberry Pi Zero to emulate a USB-Printer

License: GNU General Public License v3.0

Makefile 19.05% C 80.95%
usb printer emulator raspberry-pi-zero gprinter dwc2

emulated_usb_printer's Introduction

Emulating a USB Printer

The Emulated USB Printer is based on the Linux USB Gadget API. It allows the emulation of a USB 2.0 High Speed Printer using only a bus-powered Raspberry Pi Zero!

As the USB Gadget API allows us to set low level USB attributes, we expect that using this method anyone can emulate almost any printer... BUT more complex/modern printers often include scanning or copying functions. Besides that, they offer more Interfaces in addition to the USB. You might run into more challenges trying to emulate those printers because either the emulated USB interface does not fit the driver's needs or you will need a more complex firmware running on the Raspberry Pi Zero to be able to respond to the Host's requests.

Purpose

The main goal behind this program is to offer a solution for transferring data from devices without any interface except the USB interface for printing. Instead of connecting the USB printer to print the reports and later scanning them to somehow store them electronically, you can now use a cheap Raspberry Pi Zero which is able to receive all print jobs and store them electronically without wasting paper and time.

Because the reports are now stored either raw as print jobs or converted as PDFs you will no longer need to run any text detection algorithms to hope finding at least somewhat correct letters or even words on potentially terribly scanned reports. Of course this will always require customized code to extract the needed data from the provided reports!

Even if you don't need to or already can extract the data of a system you can use this solution to trigger arbitrarily complex processes. The Pi might receive the report and:

  • send a mail
  • save it to a shared folder
  • analyze print job and reports
  • store the data in a SQL database
  • trigger an ERP process
  • activate electronics using the Pi's GPIO pins
  • ...

Requirements

  • Raspberry Pi Zero W
    • Alternatives: Raspberry Pi Zero, Raspberry Pi 4 Model B
  • USB Micro B to USB A Cable
    • Alternatives: USB Dongle Adapter (Example), USB Mirco B to needed USB Port Adapter
  • Micro SD card
  • Micro SD card Reader
  • WiFi Connection to Pi

Note that to use the Raspberry Pi 4 Model B different power and USB cables might be needed.

Installation

  1. Install Raspberry Pi OS onto the Micro SD card (Latest tested version: Linux raspberrypi 5.4.83+ armv6l)
  2. Change settings in files on Mirco SD card
    • Add dtoverlay=dwc2,dr_mode=peripheral to the end of config.txt
    • Add new and empty file to boot called SSH to auto enable SSH
    • Add wifi settings in wpa_supplicant.conf (Tutorial)
  3. Plug in SD card and connect Raspberry Pi to PC using USB Cable. Make sure you are using the USB "OTG" Port which is closer to the mini HDMI port.
  4. Connect to Pi using SSH
  5. Change default password, update the Pi, ..., add any stuff you might need!
  6. Find g_printer device descriptor
    • Add g_printer module by running modprobe g_printer
    • Find the device descriptor in /dev/ (E.g. /dev/g_printer or /dev/g_printer0)
    • Unload g_printer module by running rmmod g_printer and rmmod usb_f_printer
  7. Optional: Install GhostPDL (Latest tested version: GhostPDL 9.53.3)
    • Download source here
    • Build GhostPDL
    • Confirm path/to/yourghostpdl/bin/gpdl at least shows the help message gpdl -h
    • Remember path to gpdl
  8. Build emulatedprinter
    • Clone this repository to wherever you want
    • Edit printer.c
      • Change your device descriptor in PRINTER_FILE
      • Change path to gpdl in GPDL_BIN_FILE (optional)
      • Change sDEVICE method for gpdl in GDPL_SDEVICE_METHOD (optional)
      • Change file extension for files created through GPDL in GPDL_FILE_EXTENSION (optional)
      • Change folder for received print jobs in FILE_OUTPUT_PATH (optional)
    • Build printer.c by running make build
  9. Check printer status
    • Add g_printer module by running modprobe g_printer
    • Run emulatedprinter -get_status and confirm Printer is Selected, Paper is Loaded and Printer OK.
    • If your status differs from the one above, use emulatedprinter -needed_option to set the correct status
    • Unload modules using (make stop) or (rmmod g_printer and rmmod usb_f_printer)

Emulate the Printer

Before you can start emulating your printer you will need to find out some information about your exact printer model. This includes the manufacturer, the model and the IEEE1284/PNP string. These are the minimum requirements for Microsoft Windows to load the correct driver.

Manufacturer & Model:
Typically you already know this. Manufacturer might be something like HP, Brother, Xerox, ... and Model might be DeskJet, DocuPrint, ... Now you will need look up both the vendorID and the productID assigned be the USB-IF. You will find multiple lists online listing both vendorIDs and productIDs. Here is an example.

IEEE1284 / PNP string:
This is where it will get a little trickier. The IEEE1284 string is send by your printer to your PC whenever you are connecting the printer to your PC. You need to use a USB traffic analyzer to capture the string. The USBlyzer Team offers a great solution called USBlyzer. You will need to start the traffic analyzer, capture hot-plugged devices and then connect your printer. During the enumeration the printer will send the PNP string. When you are already here, you can confirm that you looked up the correct vendorID and productID. Just search through the descriptors. You can find a more detailed description here

Once you have the requiered data you can load the g_printer module: modprobe g_printer idVendor=0x1234 idProduct=0x1234 pnp_string="MFG:;CMD:;CLS:PRINTER;" where idVendor, idProduct and pnp_string have your values. You can find all parameters including a great explanation here. If you want to, you can now add the modprobe command to run at boot time.

If you choose to emulate a different printer than your own, you might run into problems getting the information about your exact device. Luckily there is an awesome website called www.openprinting.org where you will find ~ 4000 (!) printers listed together with their IEEE1284 string. You can find a aggregated list of these PNP string here. Once you have a printer that fits your needs and has a pnp string, you can simply use the same online list as before to get the vendorID and productID. As before load the g_printer module and confirm that your PC recognizes the Pi correctly as the printer you selected.

Now simply call emulatedprinter -read_data to capture all print jobs and save them to the folder you specified earlier.


NOTE

To help others, it would awesome to start collecting vendor ids, device ids and PNP string here in this project. All working combinations for emulating a printer will be added to the Makefile and can be called using make start[Model].


Acknowledgements

This program is made possible due to the work of David Brownell and Craig W. Nadler who added the USB printer gadget to the Linux USB Gadget API. Here you can find a good explanation of how the g_printer module can be used! We also used these examples as a basis for this program.

emulated_usb_printer's People

Contributors

raspberryy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

emulated_usb_printer's Issues

Everything for g_printer should be right, but windows doesn't see the printer correctly

So I am trying to emulate the printer Epson Stylus CX5200 and I have the modprobe g_printer command below.

sudo modprobe g_printer idVendor=0x04B8 idProduct=0x0808 bcdDevice=0x0100 iManufacturer="" iProduct="" iSerialNumber="" iPNPstring="MFG:EPSON;MDL:Stylus CX5200;CMD:ESCPL2,BDC,D4;C LASS:PRINTER;DESCRIPTION:PRINTER;DESCRIPTION:EPSON Stylus CX5200;"

When I run this, it appears in Windows as USB Printing Support.
image
It does show the printer under Device functions, but that is as far as I got.
I'm quite new to this so sorry if it isn't formatted correctly.

Sony Printer, ACL conversion and Windows problem

Hello!
I'm emulating a Sony printer: up-dr80md
I think i found the correct parameters:

modprobe g_printer idVendor=0x054C idProduct=0x3C3 bcdDevice=0x0108 iManufacturer="SONY" iProduct="UP-DR80MD" iSerialNumber="00000000" iPNPstring="MFG:SONY;MDL:UP-DR80MD;DES:Sony UP-DR80MD;CMD:SPJL-DS,SPDL-DS;CLS:PRINTER;SCDIV:0010;SCSYV:02011000;SCSNO:f4?-------------;SCSYS:0000003800010000000100;SCMDS:00000000000000000000;SCPRS:0000;SCSES:0000;SCWTS:0000;SCJBS:0000;SCSYE:00;SCMDE:0A08;SCMCE:00;SCJBI:0000000000000000;SCSYI:0A300E566DCC00004000E92D012D00;SCSVI:000000000000;SCMNI:000000000000;SCCAI:00000000000000;SCGAI:0000;SCGSI:00;SCMDI:1100FF;"

The OS correctly see the printer ad load the driver but now I have 2 problems:

  1. In Windows when I start a print, the driver sends a message about missing paper, probably he except a message from the printer about the paper load.
  2. Switching to Linux, no problem, I can send a file to the printer and get the PCL file, but the conversion to pdf is not working, it always exports the same wrong page.
    should I change some conversion parameter?

the biggest issue it's the point 2
Here the PCL file and the conversion in pdf https://we.tl/t-aOGS8YLUV0

Unable to start emulated printing

Hello,

I followed the instructions on a pi zero 2 w and then on a pi zero w, but I get the error message:

[!] Error -1 opening /dev/g_printer
[*] Printer status
Printer is Selected
Paper is Out
Printer OK

Similar to:
sudo ./emulatedprinter -read_data
[!] Error -1 opening /dev/g_printer
[] Printer status
Printer is Selected
Paper is Out
Printer OK
[
] Start reading printjobs
[!] Error -1 opening /dev/g_printer

I see g_printer0 under my /dev

my printer.c has

#define PRINTER_FILE "/dev/g_printer0"
#define BUF_SIZE 512
#define PRINTJOB_FILE_EXTENSION "pcl"
#define GPDL_BIN_FILE "/home/default/Downloads/ghostpdl-10.2.1/bin/gpdl"
#define GPDL_SDEVICE_METHOD "pdfwrite"
#define GPDL_FILE_EXTENSION "pdf"

My os is:
Linux HPLaserJet 6.1.0-rpi7-rpi-v6 #1 Raspbian 1:6.1.63-1+rpt1 (2023-11-24) armv6l GNU/Linux

Can you help me figuring out what am I missing?

Raspberry Pi Zero W - Error opening /dev/g_printer0

Hey there,
first of all, let me thank you for this project, it is just the right thing I need right now.
However, I'm unable to make it work. I'm using Raspberry Pi Zero W with the lastest image of RPi OS Lite. After running ./emulatedprinter -get_status I get an error of "-1 opening /dev/g_printer0", although it is visible in /dev/. Any idea what I can do with it? Thanks.

Troubles printing data

Hello,

First of all, thank you for your projects, it helps me a lot moving forward on my project.
Now, i'm having some issus printing data from my computer to the raspberry.
So, i've well followed the tutorial and my computer recognize the rasperry as a printer (in my case, i'm emulating a HP laserjet P1005).
When i launch the printing, the file goes to the printing queue and then nothing happens....I just receive the following characters : 12345x @pjl ENTER LANGUAGE=ACL (seems to be an hp command).
While testing this, did you have to send some kind of acknowledgment to the computer to start the printing?

Thank you in advance for your help.

Capturing PNP string

Hello nice project!
Is It possibile to have a detailed procedure how ti capture the PNP string of a own printer?
Thanks

Emulated Printer Working, Output Not So Sure

I have followed all of the steps within this guide and have a printer emulated and working, that is to say, it's storing data in the "printjob" directory, however, I'm not sure as to what printer language the printer is outputting. It should be outputting ESC/POS but it certainly does not look like it is based upon the contents of the files.

I know within the "modprobe" command, there is a parameter called "iPNPString" which details the printer, and within that parameter, there is the "CMD:" option, which in all intentions, looks like the type of output the printer can accept. Even with removing this option/parameter, or setting it to "TXT01", the output file still looks encoded in some respect.

Using the GhostPDL to get output in PDF format isn't generating any meaningful files, just the same encoded file within the PDF.

The question is, how can I simply get the raw output destined for the printer into a file and if that cannot be done, does anyone know what printer language the attached file is in.

Kind Regards
James
2023-12-04-11-29-53.txt

Project details . . . Please?

Greetings @Raspberryy !

First, thanks to David Brownell and Craig W. Nadler for the work on this great project!

Next, I have a use case for this project that would involve several different models of printers. I will be adding each of them to the list of printers in the makefile as my first contribution to this project.

I have been able to make it mostly work by following Craig's original documentation. I was happy to find this GitHub topic and it looks like it has the answers I need.

I am new to GitHub and cannot seem to find details such as the version of Linux distro used successfully, and any other installed pieces.

What say you?

Peace . . . Vince

Raspberry Pi 4 - Problems with accessing /dev/g_printer0

On a Raspberry Pi 4B, I have used this code and have the USB-OTG port correctly configured to emulate an Epson TM-T88V printer. The host machine recognises the Raspberry Pi as the Epson printer.

Unfortunately, I have hit a problem.

I have the code running in /home/pi/software, and the compiled program has chown root:root on it.

If I use:

fd[0].fd = open(PRINTER_FILE, O_RDWR);

I get an error - cannot open /dev/g_printer0 (it shows in the /dev directory though)

If I change this to:
fd[0].fd = open(PRINTER_FILE, O_RDONLY);

or do a CHMOD 777 on /dev/g_printer0, the code opens the device successfully.

However, I get errors when polling the device - errno = 2 (No such file or directory)

Any ideas - could it be a cabling issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.