ATG_voip’s kimama blog

RaspberryPiやらArduinoやらAndroidやら色々

ESC/POSとは何ぞや

前置き

 現在、私が開発しているものがAndroid端末とThermal Printer(サーマルプリンタ)をBletoothで接続し、レシートを印刷するものである。
今回は、Thermal Printer(サーマルプリンタ)にどのようなデータを送ればレシートが印刷できるのかを、現段階で私が理解した範囲で書く。この記事を読む前に理解していて欲しいことは、この記事の内容は私が英語のマニュアルを機械翻訳するなどして、勘だったり勝手に察したりした内容が書かれていると理解していてほしい。一切の責任を負いません。

 内容が事実と異なったり、分かりにくい箇所があれば一報をお願いいたします。
 
最終更新日(2017.2/20)

「ESC/POS」とは

私が調べた範囲だと以下のような事らしい

  • 開発したのはエプソン(EPSON)
  • シリアル通信により印刷するプリンタなどはこの規格が搭載されている事が多い
  • レシート用紙に印刷する文字のフォント・大きさ・言語などなどを設定する事ができるコマンド,制御コード(命令のようなもの)らしい
  • 「ESC/POS」以外にも、「ESC/P」、「ESC/P-R」がある。

今回使用するThermal Printer

製品:Koolertron 58mm Mini Portable Bluetooth 4.0 Wireless Receipt Thermal Printer, Compatible With Apple And AndroidKoolertron 58mm Mini Portable Bluetooth 4.0 Wireless Receipt Thermal Printer, Compatible With Apple And Android : Koolertron.com
特徴1:ESC/POSの互換性あり
特徴2:スマホタブレットBluetooth接続し、印刷が可能
特徴3:デモアプリ同梱

「ESC/POS」で頻繁に使うコマンド

[ESC ! n]コマンド

内容:文字の大きさや太さ、アンダーラインなどの設定コマンド
フォーマット:

ASCII ESC ! n
Hex(16進数) 1B 21 n
Decimal(10進数) 27 33 n

nの値による設定:
f:id:ATG_voip:20161101105425p:plain

例:fontB、強調、アンダーラインの文字を印刷する場合
fontB = (0000 0001), 強調 = (0000 1000) , アンダーライン = (1000 0000)
n = (0000 0001) + (0000 1000) + (1000 0000) = (1000 1001)
2進 = (1000 1001)
16進 = (89)
コマンド(16進数/Hex):「1B 21 89」

AndroidProject.java(bluetooth関連の部分は省略)

public class MainActivity extends AppCompatActivity implements Runnable, View.OnClickListener {
    //[ESC ! n] Select print mode (s)
    byte  Character_font_A   = 0x00;
    byte  Character_font_B   = 0x01;
    byte  font_Emphasized    = 0x08;
    byte  font_Double_height = 0x10;
    byte  font_Double_width  = 0x20;
    byte  font_Underline     = (byte)0x80;
    private Button printButton;
    private OutputStream mOutput_Printer=null; // bluetooth出力ストリーム

    @Override
    public void onCreate(Bundle savedInstanceState){
        printButton= (Button)findViewById(R.id.printButton);
        printButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v){
       if(v.equals(printButton)) {
         // フォントの設定(font setting)
         // [ESC ! n]
         byte  Character_font[] = {0x1B, 0x21, 0x00}; // DefaultとしてfontAを設定する
         Character_font[2] |= Character_font_B; // fontBを設定
         Character_font[2] |= font_Emphasized;  // 強調を設定
         Character_font[2] |= font_Underline;   // アンダーラインを設定(線幅を指定しないと印字されない)
         mOutput_Printer.write(Character_font);
       }
    }
}

[ESC a n]コマンド

内容:印字する文字を左寄せ、中央寄せ、右寄せに設定する
フォーマット:

ASCII ESC a n
Hex(16進数) 1B 61 n
Decimal(10進数) 27 97 n

nの値による設定:

n 寄せ側
0,48 左寄せ
1,49 中央寄せ
2,50 右寄せ

[ESC t n ]コマンド

内容:印字する文字コードの設定?
フォーマット:

n 文字コード
0 PC437 USA Standard Europe
1 katakana
2 PC850 Multilingua;l

...etc

注意:
「katakana」ですが、ここで指定して使用できる文字はANK文字コードとなります.
ANK文字コードとは
・使える文字はアルファベット,数字,カタカナ(半角)のみです.
表→
ANK文字コード表


例:「アイウエオ」を印字してみる
AndroidProject.java(bluetooth関連の部分は省略)

public class MainActivity extends AppCompatActivity implements Runnable, View.OnClickListener {    private Button printButton;
    private OutputStream mOutput_Printer=null; // bluetooth出力ストリーム

    @Override
    public void onCreate(Bundle savedInstanceState){
        printButton= (Button)findViewById(R.id.printButton);
        printButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v){
       if(v.equals(printButton)) {
     String aiueo="アイウエオ"; 
         // フォントの設定(font setting)
         // [ESC ! n] フォント設定
         byte  Character_font[] = {0x1B, 0x21, 0x00}; // DefaultとしてfontAを設定
         mOutput_Printer.write(Character_font);
         // [ESC a n] 文字配置位置
         byte  Textposition_Left[]   = {0x1B, 0x61, 0x00};
         mOutput_Printer.write(Textposition_Left); //印字位置を左寄せに設定

         byte cmd[] = {0x1B, 0x74, 0x01}; // [ESC t 1]コマンド
         mOutput_Printer.write(cmd);           //印字文字(言語?)を「katakana」ANK文字コードに設定
         
         mOutput_Printer.write("------katakana------".getBytes()); 
         byte  aiueo[] = {(byte)0xB1, (byte)0xB2, (byte)0xB3,(byte)0xB4,(byte)0xB5};   //ANK文字コード
         mOutput_Printer.write("\n".getBytes());
         mOutput_Printer.write(aiueo);
         mOutput_Printer.write("\n".getBytes());
         }
    }
}
ESC/POSで困ること

ESC/POSコマンドから日本語が印字できない事もないが,半角カタカナしか印字できない.
この問題への回避策として,レシートを文字として印刷するのではなく,画像として印刷する手法がある.
画像の印刷はESC/POSコマンドには無い(?)ようだ.しかし,プリンタの製造会社によっては画像を印刷するためのコマンドを用意しているかもしれない.また,対応する制御コマンドによっては画像の印刷も可能である(各自,自分が持っているプリンタのマニュアルを確認してみると良いかも).
画像の印刷が可能な制御コードとして,STAR (LINE)コマンドがあるらしい.私が使用しているサーマルプリンタはESC/POSコマンドだけでなく,STARコマンドによる操作も可能のようだが,上手く行かない.

bitmap画像を印刷することで日本語を印刷した例(参考サイト)として,以下に載せる.
blogs.yahoo.co.jp