Arduinoでセントロニクスプリンター

[以前調べたプリントサーバ](https://qiita.com/yamori813/items/25968cf66f031a7a1c75)をいじってみました。当初部品取りにしようかと思ったのですが、IPが話せるので、そのまま使うことにしました。

"print server hack"で画像検索すると以下のページが見つかりました。

https://blog.rhysgoodwin.com/hardware/print-server-power-control-hack/

この方が参考にしたサイトは無くなっていますが、インターネットアーカイブで確認できます。

要はIPで制御できる8ビットの出力ポートとして使っているようです。

Mini2はlprが使えるので、lprのサンプルコードを捜して見ました。PHPで書かれたコードが見つかりました。

https://github.com/Craswer/PhpNetworkLprPrinter

もちろんlprはBSD由来なので、OSを設定しても出来ますが、面倒なのでこのコードで試しました。

lprは元々はプリンターが接続されたホストにデータを転送して、プリントするための仕組みでした。

上のHackのページはポートが515ではないので、lprではなかったのかも知れません。

ロジックICでだけでも8ビットを拾い出す事はできますが、より柔軟に対応できるようにArduinoを使うことにしました。

8ビットの頃のインターフェースなのでarmなどは大げさすぎます。

PHPのコードをIPアドレスなどを書き換えて、Mini2に送ってArduinoで受けてみます。すでに誰かやってそうな話ですが、見つからなかったので自分でArudinoのコードを書きました。

開発はFreeBSD上のPlatformIOでやりました。

```c
/*
 * Centronics Printer Emulator
 * Copyright (c) 2024  Hiroki Mori.  All rights reserved.
 */

void setup() {
    // Data Strobe - 1
    pinMode( 2, INPUT );
    // Acknowledge - 10
    pinMode( A4, OUTPUT );
    // Busy - 11
    pinMode( A3, OUTPUT );
    // Paper End - 12
    pinMode( A2, OUTPUT );
    // Selest - 13 
    pinMode( A1, OUTPUT );
    // Error - 32
    pinMode( A0, OUTPUT );

    // Data PD3-PD7, PB0-PB2
    pinMode( 3, INPUT );
    pinMode( 4, INPUT );
    pinMode( 5, INPUT );
    pinMode( 6, INPUT );
    pinMode( 7, INPUT );
    pinMode( 8, INPUT );
    pinMode( 9, INPUT );
    pinMode( 10, INPUT );

    digitalWrite( A0, HIGH );
    digitalWrite( A1, HIGH );
    digitalWrite( A2, LOW );
    digitalWrite( A3, LOW );
    digitalWrite( A4, HIGH );

    attachInterrupt(digitalPinToInterrupt(2), strobe, RISING );

    Serial.begin( 115200 );
    Serial.println("start");
}

void loop() {
}

void strobe() {

    // Get Data
    int ch = (PIND >> 3) | ((PINB & 7) << 5);
    char c = char(ch);
    digitalWrite( A4, LOW );
    digitalWrite( A4, HIGH );
    Serial.print(c);
}
```

![IMG_20240407_090458.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/12d8a85b-d6c5-619a-663a-bdfca43e8c06.jpeg)

コネクタはアンフェノール36ピンですが、片側は手持ちであった50ピンのコネクタを付けました。結線はコードのコメント通りで抵抗は入れずに直接つなぎました。

demo.phpを実行して受け取ってみます。

```
% php demo.php
<h1>PhpNetworkLprPrinter example</h1><h3>Debug</h3><pre>Array
(
    [0] => Array
        (
            [message] => Connecting... Host: 10.0.1.200, Port: 515
            [time] => 1712449282
            [type] => message
        )

    [1] => Array
        (
            [message] => Print any waiting job...
            [time] => 1712449282
            [type] => message
        )

    [2] => Array
        (
            [message] => Connecting... Host: 10.0.1.200, Port: 515
            [time] => 1712449282
            [type] => message
        )

    [3] => Array
        (
            [message] => Starting printer...
            [time] => 1712449282
            [type] => message
        )

    [4] => Array
        (
            [message] => Setting cfA control String
            [time] => 1712449282
            [type] => message
        )

    [5] => Array
        (
            [message] => Sending control file...
            [time] => 1712449282
            [type] => message
        )

    [6] => Array
        (
            [message] => Sending data...
            [time] => 1712449282
            [type] => message
        )

    [7] => Array
        (
            [message] => Data received!!!
            [time] => 1712449282
            [type] => message
        )

)
</pre>
```

```
% pio device monitor -b 115200
--- Terminal on /dev/cuaU0 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
start
Hello world!
```

なんか勘違いしていたのか手こずりました。タイミングが微妙でちょっといじると動かなくなる可能性があるかもしれません。

lprはlpdプロトコルを使用していて、RFC1179で定義されてます。PHPのコードをざっくり見るとコントロールデータと本体データを送っていて、本体データがプリンターに渡されるようです。

これをベースにI2Cの液晶を付けて表示などもできると思います。