[Luigi's home] [Luigi's FreeBSD] [last updated: 2008.12.30]

FreeBSD Support of the Epson DX/CX multifunction printer-scanner

WARNING: most scanner in the DX/CX series work well with the sane-epson backend which is part of the graphics/sane-backends ports. However, more recent devices in the SX/NX series either require a different backend or are not supported at all. In particular, the SX/NX100 is not supported; the SX/NX400 requires the sane-epkowa backend for which a port is available below.

The Epson CX and DX series is a range of low cost multifunction inkjet printer-scanner devices (some of them also include a card reader) supported by the SANE project for the scanner part, and by CUPS for the printer part.

They work pretty well in FreeBSD in all the three functions. The necessary kernel changes have been integrated in FreeBSD 6.x and higher in fall 2007 and later (as time goes, we need to add USB ids for the various devices). The information below details the things that I did to have the device fully operational.

Supported devices

Because new models come out very quickly I prefer to give an individual listing of those that I actually tried, or for which could collect detailed feedback. Note that american/Uk versions of the same devices are often named CX- instead of DX-, and the number may change. The following is a list updated to Dec.2008:
ModelUSB IDWorksComments
DX-38000x04b8 0x0818Yesno card reader, need to patch the USB ID into uscanner.c
DX-50500x04b8 0x082bYessame as DX-5000
DX-60000x04b8 0x082eYessame as DX-6050
DX-74000x04b8 0x0838Yessame as DX-7450
DX-84500x04b8 0x0839Yes 
SX/NX4000x04b8 0x084aNONeeds the sane-epkowa backend
SX/NX1000x04b8 ????NONot supported at all


The scanner part of the device can be controlled through the SANE package, which provides an appropriate backend and a couple of frontents (scanimage, which is for the command-line; and xscanimage, graphics). Additionally, I would suggest to install graphics/tesseract, a recently released OCR already available as a FreeBSD port which seems to perform well.

SANE accesses devices through a number of backends, which talk to the scanner using a variety of techniques. For our purposes, the dialogue has to occur over USB, and so there is either direct access through the "uscanner" device, or "indirect" access (issuing usb commands with libusb) through the "ugen" device.

Because the DX-5050 is a multi-function device (i.e. it has multiple "interfaces", in USB terminology) the "ugen" method might not be applicable (ugen might not attach because the printer and card reader interfaces will attach to the respective drivers). As a consequence, we need to patch the kernel to let the "uscanner" driver recognise the scanner and properly attach the interface. This is done in the following steps:

With these small changes, the device attaches as "uscanner", "ulpt" and "umass" - one for each interface.

SANE configuration

Because the device is usb, the entry is created dynamically, and you need to make sure that device permissions are correct for your use. This step is critical - if the device is not accessible, the various frontends will not be able to access it. One way to achieve this is to put the following entry in /etc/usbd.conf

device "usb scanner for sane"
        devname "uscanner[0-9]+"
        attach "/usr/sbin/chown yourname:wheel /dev/${DEVNAME}"
(probably you can do something smarter e.g. by reading permissions on /dev/console or /dev/ttyv for the active session, etc.).

In FreeBSD 7.0 and above usbd is deprecated and replaced by devd, the configuration then goes into /etc/devd.conf

attach 10 {     # "usb scanner for sane"
        device-name "uscanner[0-9]+";
        action "/usr/sbin/chown yourname:wheel /dev/$device-name";

Having done this, and assuming you have installed the two SANE ports (graphics/sane-backends and graphics/sane-frontends), the next thing to do is to tell the "epson" backend where the scanner is. This is done by adding the following line to /usr/local/etc/sane.d/epson.conf:

usb /dev/uscanner0

This should be enough to have the scanner working - you can test it e.g. with "xscanimage".

If for some reason the epson backend does not work for you, (e.g. because you have one of the newer models such as the SX/NX400) you can try an alternate backend called epkowa. The source for the Epkowa backend can be found at the Avasys download page, which lets you download the most recent version of the driver (2.15.0 as of this writing). However this version does not work on FreeBSD as of this writing. A working port of a former version (2.11.0) is available below.

To install epkowa you need to do the following:

At this point all the sane frontends should be able to access the scanner using either 'epson' or 'epkowa' as a backend (xscanimage will present a dialog box to choose the driver).


OCR is not an integral part of scanner support but certainly one convenient option to have. I had poor experience in the past with OCR packages under FreeBSD, but apparently the situation has changed now. There is an interesting OCR review covering some packages freely available under linux, which seem to suggest tesseract as one of the best performing and promising command-line OCR; and ocropus, which also has a GUI and format conversion tools.

I have only tried tesseract as there is a FreeBSD port already, available as graphics/tesseract. In order to try it, you should provide a grayscale scan with sufficient resolution, e.g. 300dpi (or 600dpi if you are using a small font).
You also need ImageMagick to do the format conversion, as tesseract only reads TIF files.
Another useful tool to have is the unpaper program, available as a port (graphics/unpaper) which can automatically remove some of the artifacts usually appearing in scanned text pages, including background noise and rotated pages. The only thing i miss in "unscanner" is some way to improve contrast - even if you can set the black and white threshold used for internal feature extraction (e.g. below i use 0.5 (i.e. 128) for black, 0.8 (i.e. approx 200) for white because my scanner does not give a lot of contrast), i would like the same range to be stretched to 0..255 in the output.

A sample test could be done as follows:

scanimage --mode gray --resolution 300 > /tmp/img.pnm
unpaper -b 0.5 -w 0.8 -l single /tmp/img.pnm /tmp/img1.pnm
convert /tmp/img1.pnm /tmp/img.tif
tesseract /tmp/img.tif /tmp/data_out -l ita # change ita to your language
This produces a text file /tmp/data_out.txt with the conversion results. I was definitely impressed with the results.


For the printer part, as long as you have "device ulpt" in your kernel, the device will be recognised as an usb printer. Don't forget that, same as for the scanner, the device entry must have the correct owner. Unless the print subsystem runs as root, you probably need to put something like the following into /etc/usbd.conf

device "usb printer for cups"
        devname "ulpt[0-9]+"
        attach "/usr/sbin/chown cups:cups /dev/${DEVNAME}"
Then you need some suitable print subsystem and backend. As a print subsystem, CUPS (print/cups-base) is probably a good choice - once installed, you can easily configure it through the web interface at http://localhost:631/.

The backend for CUPS is provided as part of print/gutenprint. Remember, when you configure it, to enable the CUPS drivers.

Once you have installed the backend, you can configure the printer and select one of the following and as PPD file:

The name of the base directory may change depending on the version and the language you want (the ppd is a text file with menu entries and links to files, commands etc. to be used as filters). According to various sources on the net, the CX5000 (US market) and DX5000 DX5050 (european market) are the same thing, with marginal differences in print speed.

Configuring the card reader

The printer comes with a card reader (CompactFlash and SD/XD slots) and an USB connector for printing directly from the camera. The CF/SD slots are simply seen as "umass" devices, so just inserting a card in the slot (one at a time) will make it appear as /dev/da0.