Ver. 0.32以降
print関数、println関数、PutChar関数などで文字列を表示する場合に使用する文字のエンコード法(文字と文字コードを対応させる方法)を指定する。
引数にMGLCD_CODE_STRAIGHTを指定すると、8ビットの文字コード(文字コード表を参照)に基づいて文字列を表示する。
引数にMGLCD_CODE_UTF8を指定すると、文字列はUTF-8でエンコードされているものとして文字列を表示する。扱うことができる文字は、文字コード表の7FH(Hは16進数であることを示す記号)以下の文字と、半角カナである。扱うことができない文字は、空白に置き換えられる。
Arduino IDEは、UTF-8で文字を符号化するため、半角カナは1バイトではなく3バイトで表現される。そのためArduino IDEに標準で付いてくるキャラクタLCD用ライブラリのLiquidCrystal使う場合、例えば
lcd.print("カタカナ");
としたのでは、使っているLCDモジュールが半角カナ表示に対応していても、文字列のエンコードが合わないために、文字化けしてしまう。
注1:Arduino IDE 1.6.6で半角カナの文字コードがUTF-8から拡張ASCIIコードに変更され、これ以降のArduino IDEでは、上記のコードで文字化けしなくなった。詳しくはArduino IDE 1.6.6に文字コード関係のバグ?を参照。
注2:LiquidCrystalライブラリの代わりにKanaLiquidCrystalライブラリを使えば、文字化けせずに半角カナを表示する事ができる。
これを回避するためには、まず文字コード表から以下の様に、表示したい文字の文字コードを調べる必要がある。
文字 | 文字コード |
---|---|
カ | B6H |
タ | C0H |
カ | B6H |
ナ | C5H |
そして、文字列はこれらの文字コードを直接指定するように、次のように改める必要がある。
lcd.print("\xb6\xc0\xb6\xc5");
以上のようにすると、半角カナの表示が可能ではあるものの、プログラムに手間が掛かり、ソースリストが読みにくくなる。
MGLCDライブラリを使う場合でも、文字エンコードのモードがMGLCD_CODE_STRAIGHTの場合はLiquidCrystalライブラリを使う場合と同じ問題が発生する。しかしながら、SetCodeMode関数で文字エンコードのモードをMGLCD_CODE_UTF8に切り替えると、UTF-8でエンコードされた半角カナを正しく解釈し、例えば
MGLCD.print("カタカナ");
とすれば、正しくカタカナと表示される。
ただし、MGLCD_CODE_UTF8モードでは、逆に8ビットの文字コードを指定する方法では、正しく文字が表示されない場合がある。
MGLCD.print("\xb6\xc0\xb6\xc5");
とすると、MGLCD_CODE_STRAIGHTモードの場合は正しくカタカナと表示されるのに対して、MGLCD_CODE_UTF8モードの場合は文字化けしてしまう。このような現象はC0H~FFHの範囲の文字コードの文字を含む場合に発生する。(UTF-8ではC0H~FFHは、複数バイト文字の1バイト目として使用されているため)
また、Arduinoに直接LCDをつなぐ場合は、MGLCD_CODE_UTF8を指定すると、コードサイズが若干増えてしまう。これは、UTF-8のデコード用の関数がリンクされるからである。シリアル回線経由でLCDをつないでいる場合は、LCD側のマイコンでデコード処理が行われるので、コードサイズは増えない。
スケッチの起動時にはMGLCD_CODE_STRAIGHTモードになっているが、任意の時点でSetCodeMode関数を呼び出し、文字エンコードのモードを切り替えられる。
文字エンコードの変更に成功すれば0を、失敗すれば負の値を返す。
ArduinoにLCDが直接つながっている場合、引数にMGLCD_CODE_STRAIGHTまたはMGLCD_CODE_UTF8を指定すると、必ず返り値は0となる。
シリアル回線経由でLCDがつながっている場合、回線のエラーにより返り値が負の数になることがある。
#include <MGLCD.h>
MGLCD_serial MGLCD(&Serial,500000);
void setup()
{
while(MGLCD.Reset());
}
void loop()
{
// MGLCD.println("カタカナ")のテスト
MGLCD.ClearScreen();
MGLCD.SetCodeMode(MGLCD_CODE_UTF8);
MGLCD.println("println(\"カタカナ\") ノ テスト ヲ ハジメマス。");
delay(5000);
MGLCD.ClearScreen();
MGLCD.SetCodeMode(MGLCD_CODE_STRAIGHT);
MGLCD.println("MGLCD_CODE_STRAIGHT");
MGLCD.println("カタカナ"); // 文字化けする
MGLCD.SetCodeMode(MGLCD_CODE_UTF8);
MGLCD.println("MGLCD_CODE_UTF8");
MGLCD.println("カタカナ"); // 正しくカタカナと表示する
delay(10000);
// MGLCD.println("\xb6\xc0\xb6\xc5")のテスト
MGLCD.ClearScreen();
MGLCD.SetCodeMode(MGLCD_CODE_UTF8);
MGLCD.println("println(\"\\xb6\\xc0\\xb6\\xc5\") ノ テスト ヲ ハジメマス。");
delay(5000);
MGLCD.ClearScreen();
MGLCD.SetCodeMode(MGLCD_CODE_STRAIGHT);
MGLCD.println("MGLCD_CODE_STRAIGHT");
MGLCD.println("\xb6\xc0\xb6\xc5"); // 正しくカタカナと表示する
MGLCD.SetCodeMode(MGLCD_CODE_UTF8);
MGLCD.println("MGLCD_CODE_UTF8");
MGLCD.println("\xb6\xc0\xb6\xc5"); // 文字化けする
delay(10000);
}