Last Update: 2017-08-24: updated information

Mustek S400W iScan Air

The Mustek S400W iScan Air aka ion Air Copy [+E-Post Edition] aka Century CPS-A4WF 転写パットリくん A4 Wi-Fiポータブルスキャナー aka HALO Wireless Portable Scanner is a simple document scanner for up to A4 wide documents with up to 40.5 cm length (almost ~9570 vertical pixel for 600 DPI!). Prices range from high (>100 €/$) to very low (30 € incl. VAT) in special sales - like the ion E-Post edition.

Its predecessor is the Mustek S400 iScan docking station for iPads.

It creates its own WIFI network always named DIRECT_<mac>-<model> where <mac> are the last six digits of the scanner's MAC address and the model is AirCopy or iScanAir etc. The ip address is always 192.168.18.33 and the scanner service is listening on port 23. The scanner provides DHCP and allows clients that successfully aquired an IP via DHCP access to the scanning service.

While it is well suited for what it is advertised for - easily scan a document on the go with your tablet or phone (especially if you don't have some kind of 'camera scanner' software or the camera of your tablet / phone has a too low resolution) - the low prices it is sold for warrant a much better usage model. (I did get one for my mom, though ;) Connect it to a server and automatically scan, ocr, pdf, and index documents.

1 The Scanner

1.1 Hardware

Manufacturer: Mustek, sold as:

1.2 Pictures / Data

To open the scanner you need to remove 5 Phillips screws, 4 located beneath the rubber feet, and one beneath the white plug thing in the middle. There is a 6th vicious tri-wing screw beneath the FCC label. Note the smiley drawn with ballpoint pen on mine, some assembly worker knowing the casual hacker will have a nasty surprise here. It's possible to remove it with a thin flat head screwdriver if you are careful.

The scanner is powered by a Zoran Quatro 4310 chip that can run a custom zoran OS or Linux. The memory chip provides 64 MiB RAM.

The battery is fairly large, but not required for the scanner to work. I have not determined yet if calibration settings persist without battery.

It's also interesting to see that the power button is actually two buttons.

UART is on TP26 = receive and TP25 = transmit. Settings are 57600,8,n,1,xon/xoff for putty. The console is non interactive and there is some interesting info while

The device seems to have a unpopulated SD card slot right next to the CPU. There is also an unsoldered USB port, if a keyboard is connected to it, then one can press "a" to abort normal booting and an attempt is made to load the firmware from SD card.

1.3 Software

The original software is very, very simple. You can't do more than take a scan and save it as jpeg or pdf or clean/calibrate the scanner. No OCR, no multi page PDF. Mustek's software is multi language, 3rd party usually not. Unfortunately, the windows version doesn't understand 3rd party hardware model codes. iOS / Android apps do not check the model and work fine.

Appstore: iOS, OS X, Androind, Win8, Win Phone 8
search for iscan air, air copy
Windows: http://www.mustek.com.tw/S400W/S400W.html
ftp://ftp.mustek.com.tw/pub/driver/iScanAir/
Windows: http://www.ionaudio.com/products/details/air-copy
http://www.ionaudio.com/downloads/Air_Copy_for_Windows_7_v1.0.3.zip
Windows: http://www.century.co.jp/support/download/iscanair-win7vx.html
http://www.century.co.jp/support/download/lib/iScanAir_win7_vista_xp.exe

2 Custom Access

2.1 Download

I am providing free source code and applications:

The java version needs a few changes I figured out while implementing the c version. I have to admit that I had not coded C for around a decade before implementing this...

2.3 Specification

Download specification in english or german.

2.3.1 Communication

2.3.2 Legend

<byte>
octet bits
<number>
4 byte, little endian
<mac>
6 characters making up hexadecimal number
<model>
'AirCopy' | 'iScanAir' | ?

2.3.3 Responses

Are usually less than 16 <byte>s (except preview and jpeg data), so a buffer of 16 bytes is enough. Known responses map to ascii strings for the first n <byte> followed by padding (which can be ignored):

devbusy
Device is busy. Generic, so abort action, or try again later (if you want to read status). Shouldn't happen while you wait for a response, only if you are connecting to an already busy device.
battlow
Battery low. Not sure yet if only in idle, or as response on other requests.
nopaper
Device idle. Nothing inserted, thus error for scan, calibrate, clean.
scanready
Paper sensor triggered. Ready to scan, calibrate or clean.
calgo
Device busy, calibration has started.
calibrate
Device busy, calibration finished.
cleango
Device busy, cleaning has started.
cleanend
Device busy, cleaning finished.
dpistd
Resolution set to 300 DPI.
dpifine
Resolution set to 600 DPI.
Note that resolution is sometimes reset to 300 DPI after a successful scan!
scango
Device busy, scanning has started.

Special responses:

previewend
Preview finished.
jpegsize
Jpeg size aka jpeg available.

2.3.4 Commands

Send as <number>s. Waiting after sending a command is recommended. Between 200 ms and 500 ms. Waiting some more after a function finished (cleaning, calibration, scanning) is recommended, too. 500 ms.

20203030: get version
read: {1; 9} <byte>; known response = error
Example: IO0a.032
50006000: get status
wait 200ms
read: known response
70708080: clean (requires status 'scanready')
wait 500ms
read 'cleango'
wait 10s
read 'cleanend'; bad: 'nopaper', 'devbusy', 'battlow'
a000b000: calibrate (requires status 'scanready')
wait 500ms
read 'calgo'
wait 10s
read 'calibrate'; bad: 'nopaper', 'devbusy', 'battlow'
10203040: set DPI 300
wait 200ms
read 'dpistd'
50607080: set DPI 600
wait 200ms
read 'dpifine'
10002000: start scan
wait 200ms
read 'scango'
30304040: send preview data
wait 1s
read n * 1920 <byte> (640 pixel per line, 3 <byte> per pixel: RGB, most likely 1200 lines max) ends on 'previewend' <byte>
wait 1s
c000d000: send jpeg size
wait 200ms
read 'jpegsize' <number>
e000f000: send jpeg data
wait 500ms
read $jpegsize <byte>

Unofficial commands:

40405050: WifiBattery State
~0x287 or 0x284 or so = usb power, ~0x240 = battery full?
30004000: unknown
seems to expect more data
70008000: DevpowerOff
Turns of device

2.3.5 Example

How to get a 300 DPI scan:

  1. open socket
  2. 50006000
  3. if response not 'scanready', abort
  4. 10002000
  5. if response not 'scango', abort
  6. c000d000
  7. if response not 'jpegsize', abort
  8. allocate file for given size
  9. e000f000
  10. read jpeg data

Feedback