M5 Paper から bluetooth プリンタへ画面出力　備忘録

* この記事には Fortran は出てきません。

# M5 Paper 

知識が無いながらも youtube 動画とネットの記事を見ているうち、欲しくなったので先週の amazon のポイント還元増量の時にポチってみました。正直、使い道が思いつきませんｗ

https://www.switch-science.com/catalog/7359/

電子インク紙と ESP32 マイコンをセットにまとめた中国製品です。M5EPD (M5 Electronic Paper Device ?) という略号でも呼ばれます。M5 Stack という、電子ブロックのように、モジュールを組み合わせてマイコン実験が出来るようになっているシリーズの一つのようです。ESP32 マイコンは WiFi と Bluetooth 機能を内蔵していてとても人気があるようです。

零知識から始めたので、Arduino と Platform IO という二つの開発環境の違いが分かりませんが、Platform IO の方でないと SD card から画像ファイルを読み込むことが出来ませんでした。開発元提供のサンプルも画面表示がなされません。Arduino 環境の方で数時間を無駄にしました。

この他に UIFlow という micro python を使う環境もありますが、まだいじっていません。 

# Phomemo M02S

https://qiita.com/cure_honey/items/72124ff8effddc075e9b

ESC/POS の ラスターグラフィックのみに対応した Bluetooth プリンタです。Bluetooth も USB も仮想シリアル接続されます。

# M5 Paper から Phomemo M02S へ出力

https://twitter.com/curerice2014/status/1499364414113271810

画面のドットを読んでハードコピーを取ります。コンセプト実証だけを目的として、細かいことは気にしないことにします。

プリンタが二値しか取らないので、グレースケールには対応しないことにします。また電子ペーパー面の短辺のドット数が 8 の倍数ではないので、padding などをサボるため適当に切り捨てることにします。

## ソース
SD カードから読み込んだ画像を Bluetooth プリンタへ書き出します。
元としたプログラムは、URL を与えた画像を表示するプログラムです。ここでは、SD card から画像を読むことにして、WiFi 接続の部分を消しました。

https://github.com/m5stack/M5EPD/tree/main/examples/Basics/DISPLAY_URL_JPG

ライブラリのソースをみると canvas.readPixel 関数というものがあったので、これによって画面のドットを読んで、プリンタに送る形式にまとめます。

https://github.com/m5stack/M5EPD/tree/main/src

Bluetooth に関しては、以下のサイトを参考にしました。

https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial/examples/SerialToSerialBTM

```c++
#include <M5EPD.h>
#include "BluetoothSerial.h"

void setup()
{
  M5.begin();

  M5.EPD.SetRotation(90);
  M5.EPD.Clear(true);

  M5EPD_Canvas canvas(&M5.EPD);
  canvas.createCanvas(540, 960);
  canvas.setTextSize(3);
  // canvas.drawJpgUrl("https://m5stack.oss-cn-shenzhen.aliyuncs.com/image/example_pic/flower.jpg");
  //canvas.drawJpgFile(SD, "/flower.jpg");
  //canvas.drawPngFile(SD, "/jsd.png");
  canvas.drawPngFile(SD, "/KZR.png");
  canvas.pushCanvas(0, 0, UPDATE_MODE_GC16);
//e-paper end

// Bluetooth Printer
  // prepare bluetooth  
  BluetoothSerial SerialBT;
  String MACadd = "00:15:83:54:A2:7F";
  uint8_t address[6]  = {0x00, 0x15, 0x83, 0x54, 0xa2, 0x7f};
  String name = "M02S";
  bool connected;
  uint8_t m; 

  SerialBT.begin("M5EPD", true);  // true: master mode
  Serial.println("The device started in master mode, make sure remote BT device is on!");

  // connect(address) is fast (upto 10 secs max), connect(name) is slow (upto 30 secs max) as it needs
  // to resolve name to address first, but it allows to connect to different devices with the same name.
  // Set CoreDebugLevel to Info to view devices bluetooth address and device names
  //connected = SerialBT.connect(name);
  connected = SerialBT.connect(address);
  
  if (connected) {
    Serial.println("Connected Succesfully!");
  } else {
    while(!SerialBT.connected(10000)) {
      Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app."); 
    }
  }
    
  // Phomemo M02S ESC/POS  
  SerialBT.write(0x1e);
  SerialBT.write(0x40); // ESC @ ; reset

  SerialBT.write(0x1f);
  SerialBT.write(0x11);
  SerialBT.write(0x02);
  SerialBT.write(0x04); // US 11 02 04; concentration 01,03,04 thin..thick

  SerialBT.write(0x1d);
  SerialBT.write(0x76); 
  SerialBT.write(0x30);
  SerialBT.write(0x00); // ESC v ' ' mode ; graphic ; mode 00 normal 01double_x 02double_y 03quadruple
  SerialBT.write(0x43); // 536dots = 67byte (43h)
  SerialBT.write(0x00); //  dx / 8 ; 16bit little endian
  SerialBT.write(0xC0); // 960dots (3C0h)
  SerialBT.write(0x03); //  dy     ; 16bit little endian

  for (int iy = 0; iy < 960; iy++) {
    for (int ix = 0; ix < 536; ix += 8) {
      m = 0;
      for (int k = 0; k < 8; k++) {
        m *= 2;
        if ( canvas.readPixel(ix + k, iy) > 0 ) {
           m++;
        };
      }        
      SerialBT.write(m);
     }
  }
  
  Serial.println("Finished");
    // disconnect() may take upto 10 secs max
  if (SerialBT.disconnect()) {
    Serial.println("Disconnected Succesfully!");
  }

  M5.shutdown();
}

void loop()
{
}

//reference: bluetooth
//https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial/examples/SerialToSerialBTM
```

C のビット演算関数が分からないので、算術計算で画像に対応するビット並びを作りました。