====== Scanner Xerox Travel Duplex mit Linux ====== USB: 0x04a7 0x04e2 ===== Kommandos zur Steuerung ===== ==== Papiersensor:==== 0x55, 0x53, 0x42, 0x43, 0xf0, 0x46, 0x7a, 0xd2, 0x18, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0xc5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00 0x55, 0x53, 0x42, 0x43, 0xf0, 0x46, 0x7a, 0xd2, 0x18, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0xc5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00 Abfrage: 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x01, 0x2c, 0x01, 0x2c Ergebnis: mit Blatt: 10 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 f0 00 00 00 00 14 c2 00 ohne Blatt: 10 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ===== Einlesen der Bilddaten ===== Die Bilddaten werden Streifenweise eingelesen bis das Blatt komplett vom Scanner durchgezogen wurde. Abgefragt werden die Daten eines Streifens in Form von 9 Blöcken mit je 65536 Bytes, gefolgt von einem Block mit 32256 Bytes. Anschließend erfolgt die Kontrollabfrage von Papiersensor, Taster usw und der nächste Streifen wird eingelesen. Die Kommandos für das Einlesen der 65536 Byte Blocks eines Streifens fangen an mit: 55 53 42 43 d0 5a 4f d2 00 00 01 00 80 00 10 c3 07 **xx xx** **yy** 00 00 01 00 00 00 00 00 00 00 00 **xx xx** wird von 00 76 ausgehend bei jedem folgenden Aufruf um eins hochgezählt. Die Kommandos für das Einlesen des 32256 Byte Blocks eines Streifens fangen an mit: 55 53 42 43 d0 5a 4f d2 00 7e 00 00 80 00 10 c3 07 **xx xx** **yy** 00 00 00 7e 00 00 00 00 00 00 00 **yy** wechselt nach jedem Streifen zwischen zwei Zahlenreihen. Diese beginnen mit 0x24 und 0xa2, je Streifen wird von yy 4 abgezogen. Es handelt sich dabei um die Ober- und Unterseite des Blattes. Die mit 0x24 startende Zahlenreihe ist die Oberseite. - Kommando zum Abrufen von 65536 Bytes - Abruf in 4 einzelnen Lesevorgängen * 0x00004e00 Byte * 0x00004000 Byte * 0x00004000 Byte * 0x00003200 Byte =65536 Byte Der Abruf der 65536 Bytes erfolgt 9x nacheinander, dann werden einmal 32256 Bytes gelesen: - Kommando zum Abrufen von 32256 Bytes - Abruf in zwei Lesevorgängen * 0x00004e00 Byte * 0x00003000 Byte =32256 Byte In der Summe sind dies also **622.080 Bytes je Streifen**. ===== Auflösungen ===== Der theoretischer Speicherbedarf für ca. A4, beidseitig, RGB24, 300 dpi sollte ungefähr 55.000.000 Bytes betragen. Für eine beidseitig mit 300 dpi gescannte A4 Seite liest der Windows-Treiber 102 solcher Streifen ein. Dies entspricht 63.452.160 Bytes. Bei 600dpi sind es 202 Streifen, entspricht 125.660.160 Bytes. Aus den erhaltenen Daten lässt sich ein Bild "entwickeln", welches 2592 Pixel in der Breite und ungefähr die gewünschte Auflösung in der Höhe hat. Die horizontale Auflösung des Xerox Travel Duplex scheint also konstant nur bei ca. 300 dpi zu liegen. ==== Kommandos zum Ändern der Auflösung ==== === 300 dpi, RGB: === 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x01, 0x2c, **0x01**, **0x2c**, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x80, 0x00, 0x00, 0x98, 0x1c, 0x80, 0x80, 0x80, 0x05, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1d, 0xe0, 0xff, 0x00, 0x1e, 0x60, **0x4c**, 0x20, 0x10, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x10, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 === 600 dpi, RGB: === 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x01, 0x2c, **0x02**, **0x58**, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x80, 0x00, 0x00, 0x98, 0x1c, 0x80, 0x80, 0x80, 0x05, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1d, 0xe0, 0xff, 0x00, 0x1e, 0x60, **0x98**, 0x20, 0x10, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x10, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ==== Datenformat Bilddaten ==== Die empfangenen Daten eines Streifens enthalten die RGB-Daten im Format 2592 x R Byte, gefolgt von 2592 x G Byte, 2592 x B Byte Beim beidseitigen Scan wechselt sich ein Streifen Vorderseite mit einem Streifen Rückseite ab. Die Rückseite muss gespiegelt werden. ==== Compilieren ==== Beim Einsatz auf verschiedenen [[:nanopi_m4|NanoPi M4]] mit verschieden Armbian-Versionen musste der Treiber nicht neu compiliert werden. Die Verwendung auf einem [[:nanopi_neo|NanoPi Neo]] jedoch schon. apt-get install libusb-dev gcc -o driver_xerox-travel-duplex ./lodepng-master/lodepng.c -lusb -lm -lpthread driver_xerox_travel_duplex.c ===== Funktionsweise des Treibers ===== Beim Anstecken des Scanners wird durch eine udev-Regel ein Script aufgerufen, welches den eigentlichen Treiber startet. Dabei wird diesem der Speicherort für die gescannten Dokumente, die gewünschte Auflösung (300 oder 600) und optional der Pfad zu einem Script, welches nach dem Scann jeder Seite aufgerufen wird, übergeben. Der Scanner scannt anschließend jedes eingeführte Blatt doppelseitig ein, schneidet es zu, speichert es als PNG und ruft das übergebene Postprozess-Script auf. Diesem werden der Speicherort (Verzeichnis) der Bilddatei, der Hauptbestandteil deren Namens, die Seitennummer, das Dateiformat und die beim Scannen verwendete Auflösung als Parameter übergeben. In diesem Script kann dann die weitere Bearbeitung, z.B. mit Imagemagick und/oder Tesseract, gestartet werden. Beim Entfernen des Scanners wird der Treiber gestoppt. ==== udev Regel erstellen ==== in /etc/udev/rules.d/ ACTION=="add", ATTRS{idVendor}=="04a7", ATTRS{idProduct}=="04e2", MODE="0664", GROUP="users", OWNER="user", RUN:="/bin/su user -c '/bin/sh /home/user/scannertest/start-xerox_travel_duplex.sh'", OPTIONS="last_rule" udevadm control --reload-rules ==== start-xerox_travel_duplex.sh ==== Konfiguration des Speicherorts der gescannten Bilder und Angabe des Postprozess-Scriptes #!/bin/sh /home/user/scannertest/driver-xerox_travel_duplex/driver-xerox_travel_duplex "/home/user/scannertest/scans/" 300 "/home/user/scannertest/driver-xerox_travel_duplex/postprocess-xerox_travel_duplex.sh" | tee /home/user/scannertest/log.txt ==== postprocess-xerox_travel_duplex.sh ==== Wird nach Beendigung jedes Scanvorganges durch den Treiber aufgerufen und bekommt Pfad, Dateinamen und Auflösung der gespeicherten Bilddatei (ohne Endung .png) übergeben. Es können dann weitere Optimierungen am Bild vorgenommen und die Texterkennung gestartet werden. ==== Anschluss an USB2 des Nanopi M4 ==== Port=32p + 8q + r GPIOp_q q = A=0, B=1, C=2, D=3 ^Pin#^ Assignment^Usage^ Pin#^ Assignment^Usage^ |1| VCC3V3_SYS| 3.3Vout | 2| VDD_5V|+5Vin| |3| I2C2_SDA(3V)| | 4| VDD_5V|+5Vin| |5| I2C2_SCL(3V)| | 6| GND|GNDin| |7| GPIO1_A0(3V)| (32)| 8| GPIO4_C1/I2C3_SCL(3V)|(45)USB1 on/off| |9| GND| GND| 10| GPIO4_C0/I2C3_SDA(3V)|(144) USB2 on/off| |11| GPIO1_A1(3V)|(33)| 12| GPIO1_C2(3V)|(50) | |13| GPIO1_A3(3V)|(35)| 14| GND| | |15| GPIO1_A4(3V)|(36)| 16| GPIO1_C6(3V)|(54) | |17| VCC3V3_SYS| | 18| GPIO1_C7(3V)|(55)| |19| SPI1_TXD/UART4_TX(3V)| | 20| GND| | |21| SPI1_RXD/UART4_RX(3V)| | 22| GPIO1_D0(3V)|(56)| |23| SPI1_CLK(3V)| | 24| SPI1_CSn0(3V)| | |25| GND| | 26| GPIO4_C5/SPDIF_TX(3V)|(149)| |27| I2C2_SDA(1.8V)| | 28| I2C2_SCL(1.8V)| | |29| I2S0_LRCK_RX(1.8V)| | 30| GND| | |31| I2S0_LRCK_TX(1.8V)| | 32| I2S_CLK(1.8V)| | |33| I2S0_SCLK(1.8V)| | 34| GND| | |35| I2S0_SDI0(1.8V)| | 36| I2S0_SDO0(1.8V)| | |37| I2S0_SDI1SDO3(1.8V)| | 38| I2S0_SDI2SDO2(1.8V)| | |39| GND| | 40| I2S0_SDI3SDO1(1.8V)| | echo 33 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio33/direction echo 1 > /sys/class/gpio/gpio33/value Da der Scanner immer angesteckt, aber nicht ständig eingeschalten sein soll wird an einem der USB2-Ports angeschlossen, die vom Nanopi M4 über die Pinleiste oder das SATA-Board erreichbar sind. Das zwischengeschaltete Anschlussboard erlaubt das Ein- und Ausschalten des Scanners über einen GPIO des Nanopi. {{ :eierlegende_wollmilchsau:anschlussboard_top.pdf |}} {{ :eierlegende_wollmilchsau:anschlussboard_bottom.pdf |}}