サーマルプリンタで印刷する: セットアップ編

## 0. 3行まとめ

* Pythonからサーマルプリンタを制御して様々なものを印刷し、業務を改善しました。
* サーマルプリンタ「[MunByn ITPP068USE-BK](https://www.amazon.co.jp/exec/obidos/ASIN/B078TCB8H2/x7edimv35x-22/)」のセットアップには、残念ながらWindows環境が必要でした。（本記事の本題）
* サーマルプリンタの活用方法は想像力次第！

これからの記事については『[目次](https://qiita.com/yuyakato/items/288962fbc39446644668)』をご覧ください。

## 1. 概要

レジのレシートでなじみ深いサーマルプリンタ（感熱紙プリンタ）を活用し、様々な業務の改善を行いました。具体的には:

* カンバンに貼り出すストーリー、タスクの印刷
    * GitHub、GitLabともGoogle Chrome拡張を通じて連携
* ランダムに決定されるランチメンバーのリストの印刷
* 各種メモの印刷

などを行いました。

すべてを1つの記事として書き下すのは辛いので、何本かの記事に分けて投稿する予定です。本記事では、サーマルプリンタのセットアップを中心に書いていきます。

![thermal_printer1.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/12149d51-de5f-5fad-2a14-dd593d775233.jpeg)

## 2. 謝辞

本記事の内容は、[株式会社センスタイムジャパン](https://www.sensetime.jp/)様における業務改善活動に基づいて記述されています。記事としての公開を許諾して頂いた株式会社センスタイムジャパン様に感謝致します。

## 3. 構成

### 3.1. システム構成

本システムで用いた物理デバイス、ソフトウェアの構成は以下の通りです。

* サーマルプリンタ
    * 実際に印刷を行うプリンタです。
    * 今回は「[MunByn ITPP068USE-BK](https://www.amazon.co.jp/exec/obidos/ASIN/B078TCB8H2/x7edimv35x-22/)」を用いました。約11,000円で、とても安価です。（日本製だと4万円ほど）
* Raspberry Pi 3 Model B+
    * サーマルプリンタをネットワークに接続するための中継器として用いました。
    * OSには「Raspbian」を用いました。
* 印刷サービス
    * Pythonで実装された自作サービスです。
    * Web API（HTTPサーバ）として動作しており、画像を送信するとサーマルプリンタから印刷を行います。
* レンダリングサービス
    * Node.js（JavaScript）で実装されたHTMLレンダリングサービスです。
    * Headless Chromeを用いてHTMLから画像への変換を行います。
* Webアプリ
    * React.jsで実装されたHTMLをサーマルプリンタで印刷するためのWebアプリです。
    * 「レンダリングサービス」にてHTMLを画像に変換し、「印刷サービス」で画像をサーマルプリンタに出力します。
* Google Chrome拡張
    * GitHub、GitLabのIssue、Pull Request（Merge Request）をサーマルプリンタで印刷するための拡張です。
    * 「Webアプリ」と同様、「レンダリングサービス」、「印刷サービス」を用いて動作します。
    * Webブラウザ側の拡張として実装されているため、GitHub、GitLabの認証などは気にすることなく、ページに表示されている内容を用いて印刷を行います。

なお、ソフトウェアのソースコードは別途、GitHubにて公開予定です。

### 3.2. 部品リスト

本システムの物理デバイスとして、以下の製品、部品を用いました。

| No | 種別 | メーカ | 型番 | コメント | リンク |
|---:|:---:|:---:|:---:|:---:|:---|:---|
|1|サーマルプリンタ|MunByn|ITPP068USE-BK|約11,000円のリーズナブルなサーマルプリンタ。RS232C、USB、Ethernetの3つのインターフェースに対応。|[Amazon](https://www.amazon.co.jp/exec/obidos/ASIN/B078TCB8H2/x7edimv35x-22/)|
|2|感熱紙|ビジコム|ST808012-5K|80mm幅。5巻で約1,400円。|[Amazon](https://www.amazon.co.jp/exec/obidos/ASIN/B00BFPXX2G/x7edimv35x-22/)|
|3|Raspberry Pi|-|3 Model B+|OSインストール済みmicroSDカード、スイッチ付き電源（便利！）などを含むコンプリートセット。約9,500円。|[Amazon](https://www.amazon.co.jp/exec/obidos/ASIN/B07CRY1JC1/x7edimv35x-22/)|

![thermal_printer2.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/5add5d41-349c-66db-55e8-954abfa3913b.jpeg)

### 3.3. 結線

本システムの物理デバイスは、以下のように結線されています。

* サーマルプリンタ -- （USBケーブル） -- Raspberry Pi
* サーマルプリンタ -- （DC電源ケーブル） -- AC/DCアダプタ -- （AC電源ケーブル） -- 商用電源（AC100V）
* Raspberry Pi -- （Ethernetケーブル） -- スイッチングハブなど
* Raspberry Pi -- （Type-A/Micro-B USBケーブル） -- USB電源 -- 商用電源（AC100V）
* テスト時のみ: Raspberry Pi -- （HDMIケーブル） -- ディスプレイ
* テスト時のみ: Raspberry Pi -- （USB） -- USBキーボード
* テスト時のみ: Raspberry Pi -- （USB） -- USBマウス

## 4. サーマルプリンタのセットアップ

サーマルプリンタを使用するにあたり、事前に以下の設定が必要です。

1. 「仮想COMポート」モードへの変更
2. DIPスイッチの変更

### 4.1. 「仮想COMポート」モードへの変更

使用したサーマルプリンタは、購入時点ではUSBポートが「USBプリンタ」モードに設定されています。PythonからESC/POSで印刷するためには「仮想COMポート」モードに変更する必要があります。

モードの変更に必要なツール「Printer TEST」（`Printer Test.exe`）は、残念ながらWindows版のみ提供されているため、この作業だけはWindows環境で行う必要があります。

「仮想COMポート」モードへの変更についてはユーザマニュアルの9ページに記載があります。具体的な手順は以下の通りです。

1. WindowsマシンにサーマルプリンタをUSBケーブルで接続し、電源を入れる。

    この状態では「デバイスマネージャー」で「不明なデバイス」として認識されます。
    ![screenshot1.png](https://qiita-image-store.s3.amazonaws.com/0/58479/46c43396-cda9-e869-9119-28255f7d8e76.png)

2. 付属のCDからコピー、またはダウンロードした「Printer TEST」を起動する。

3. 「English」ボタンを押下して中国語モードから英語モードに変更する。

    ![screenshot2.png](https://qiita-image-store.s3.amazonaws.com/0/58479/3c41e27f-5820-b21a-4b0c-208a373830ad.png)

4. 「Port Select」で「USB」を、「Printer Type」で「POS-80」をそれぞれ選択する。（おそらくデフォルトのまま）

    ![screenshot3.png](https://qiita-image-store.s3.amazonaws.com/0/58479/d6dcdc63-5ab9-a4fa-0b65-398d2fb6893b.png)

5. 「Content」の「Clear」ボタンを押下する。

6. 「Content」の「HEX」チェックボックスをオンにする。

7. 「Content」のテキストエリアに`1F 1B 1F B8 13 14 01`を入力する。

    ![screenshot4.png](https://qiita-image-store.s3.amazonaws.com/0/58479/2f6762bc-3892-efad-2962-f498f4e6b0ca.png)

8. 「Print」ボタンを押下する。

なお、ユーザマニュアル、ツールが格納されたドライバCDは、以下のページにからダウンロードする事ができます。

* [ITPP068 User Manual(USB+Serial+Ethernet).pdf - pCloud](https://my.pcloud.com/publink/show?code=XZqvKF7Z9tvwB8YepiFDV2EllvQvLFSEpwOk)
* [ITPP068 Driver CD.zip - pCloud](https://my.pcloud.com/publink/show?code=XZ8guX7Z0wJOotq4hch1gscKBYwSJk4UUoNy)

### 4.2. DIPスイッチの変更

サーマルプリンタ底面にあるDIPスイッチを以下のように変更しました。

| No | 設定値 | 意味 | 備考 |
|:---:|:---:|:---|:---|
| 1 | OFF | カッター: 有効 | デフォルトのまま |
| 2 | OFF | ブザー: 無効 | ONからOFFに変更 |
| 3 | OFF | 印刷密度: 軽 | デフォルトのまま |
| 4 | ON | 2バイト文字: 無効 | デフォルトのまま |
| 5 | OFF | 1行あたりの文字数: 48 | デフォルトのまま |
| 6 | OFF | ドロワーと共にカット: 無効 | デフォルトのまま |
| 7 | OFF | 115,200bps | デフォルトのまま |
| 8 | ON | 115,200bps | OFFからONに変更 |

![dip_switch.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/178976dc-27d1-84ab-6d89-b30d5dac5682.jpeg)

### 4.3. セルフテスト

使用したサーマルプリンタでは、以下の手順でセルフテストの用紙を印刷することができます。

1. サーマルプリンタの電源を切る。
2. 「FEED」ボタンを押し続けたまま電源を入れる。
3. 「FEED」ボタンを放す。
4. セルフテスト用紙が印刷される。

実際に印刷されたセルフテスト用紙は以下の通りです。長いので写真3枚に別れています。左側が設定の変更前、右側が設定の変更後です。

![self_test1.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/de74bdfe-75ba-bdc6-4dbc-16930e67856a.jpeg)
![self_test2.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/021034e2-f392-711d-6e90-325f4fa82b0d.jpeg)
![self_test3.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/b6a3dc6a-db2a-d0a4-72e3-84c351a00aa4.jpeg)

### 4.4. 用紙のセット

使用したサーマルプリンタでは、ロール紙は以下のようにセットします。

![paper_setting.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/2abfd88a-1052-a3d9-4181-a3cc4a1c116a.jpeg)

## 5. Pythonからの印刷

詳細な説明は次回以降の記事に示しますが、以下の手順で「Hello World!!!」の文字を印刷することができました。

```text
pi@raspberrypi$ docker pull ubuntu:16.04
16.04: Pulling from library/ubuntu
Digest: sha256:76702ec53c5e7771ba3f2c4f6152c3796c142af2b3cb1a02fce66c697db24f12
Status: Image is up to date for ubuntu:16.04

pi@raspberrypi$ docker run --interactive --tty --rm --device /dev/ttyACM0 ubuntu:16.04 /bin/bash

root@26a8a784fccd:/# ls -l /dev/ttyACM*
crw-rw---- 1 root dialout 166, 0 Oct 25 06:44 /dev/ttyACM0

root@26a8a784fccd:/# apt-get update
root@26a8a784fccd:/# apt-get install --yes --no-install-recommends \
    build-essential \
    libjpeg-dev \
    python3-dev \
    python3-pip \
    python3-setuptools \
    zlib1g-dev

root@26a8a784fccd:/# python3 --version
Python 3.5.2

root@26a8a784fccd:/# pip3 --version
pip 8.1.1 from /usr/lib/python3/dist-packages (python 3.5)

root@26a8a784fccd:/# pip3 install python-escpos==2.2.0
...
Successfully installed Pillow-5.3.0 appdirs-1.4.3 argcomplete-1.9.4 argparse-1.4.0 pyserial-3.4 python-escpos-2.2.0 pyusb-1.0.2 pyyaml-3.13 qrcode-6.0 six-1.11.0

root@26a8a784fccd:/# python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import escpos.printer
>>> printer = escpos.printer.Serial("/dev/ttyACM0")
Serial printer enabled
>>> printer.text("Hello World!!!")
>>> printer.cut()
```

![hello_world.jpg](https://qiita-image-store.s3.amazonaws.com/0/58479/60b8a5b8-95da-7772-8bb7-765411ac182c.jpeg)

## 6. 参考

* [Raspberry Pi 3 Model B(Raspbian)にDockerをインストールする - Qiita](https://qiita.com/yuyakato/items/1cdc7fa511f7767c95ac)
* [ESP/POS プリンタを python-esppos で - Qiita](https://qiita.com/nanbuwks/items/b04467e1dc2b2a5ea059)
* [python-escpos · PyPI](https://pypi.org/project/python-escpos/)