Program Resource

開発者向け各種コード、アルゴリズム、リソース情報ライブラリ もしくはねふぁの覚え書き

キャラクターLCDやドットマトリクス等の半角カタカナをサポートしているデバイスでカタカナを出力する際、Arduinoのスケッチにそのまま半角カタカナで記述しても文字化けするため、エスケープコードで16進数を書く必要がある。

lcd.print("\xba\xdd\xc6\xc1\xca");

ArduinoのスケッチはユニコードになっているがLCDキャラクターディスプレイはShift-JISのためそのままでは扱えない為である。スケッチのinoファイルをShift-JISで作成し、Arduino IDEで開いてビルド・書き込みも可能だが、Arduino IDE上の表示では豆腐文字になるし、上書きするとデータが壊れる為実用的ではない。

そこで、1602の半角カタカナのみの対応であるが、簡易的にユニコードをShift-JISに変換する関数を作成した。

char jpconv[64];
char* jp(char *text) {
	char *cur = &jpconv[0], *chk = text;
	while (*chk != 0) {
		if ((*chk & 0xff) == 0xef && (*(chk+1) & 0xbc) == 0xbc) {
			*cur = (*++chk & 0x02) << 5;
			*cur++ = *++chk + *cur;
		} else
			*cur++ = *chk;
		chk++;
	}
	*cur = 0;
	return jpconv;
}

このコードで半角カタカナが実行時ユニコードからShift-JISに変換される。使い方としては、例えば1602キャラクターディスプレイにカタカナを表示する場合の例は以下になる。文字列を jp() で囲むだけ。

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

char jpconv[64];
char* jp(char *text) {
	char *cur = &jpconv[0], *chk = text;
	while (*chk != 0) {
		if ((*chk & 0xff) == 0xef && (*(chk+1) & 0xbc) == 0xbc) {
			*cur = (*++chk & 0x02) << 5;
			*cur++ = *++chk + *cur;
		} else
			*cur++ = *chk;
		chk++;
	}
	*cur = 0;
	return jpconv;
}

void setup() {
	lcd.begin(16, 2);
	lcd.clear();
	lcd.setCursor(0,0);
	lcd.print(jp("カンタンニホンゴ"));
}

void loop() {
}

カタカナは下記コードの範囲に対応。句読点濁点括弧などすべて半角で入力する事。Windowsであれば文字入力後 Ctrl + O で半角になる。

スケッチの簡単な解説。1602のLCD等はASCIIコードで文字列を扱っており、1文字1バイトで0~255の数字で文字を指定する。上記カタカナは0xa1~0xdfの範囲である。

Arduinoのスケッチはユニコードで文字を扱う為、半角英数はASCIIコードと同じだが半角カタカナは3バイト構成となっている。以下の様な表になる。

文字ユニコードASCII
ef bd a1a1
ef bd a2a2
ef bd a3a3
ef bd a4a4
ef bd a5a5
ef bd a6a6
ef bd a7a7
ef bd a8a8
ef bd a9a9
ef bd aaaa
・・・
ソef bd bfbf
ef be 80c0
ef be 81c1
ef be 82c2
・・・
ef be 9bdb
ef be 9cdc
ef be 9ddd
ef be 9ede
ef be 9fdf

カタカナはefで始まり、bdが続く場合3バイト目がそのままASCIIコード。beが続く場合は3バイト目に0x40を足した数がASCIIコードなる。

処理としては、一文字ずつ調べて行って0xefでなければそのままコピー、0xefなら次のバイトを見て0xbdであればその次をそのままコピー、0xbeならその次に0x40を足してコピーして変換した文字列を作成する。その処理をコンパクトにまとめたのが上記関数になる。

コメントを残す

メールアドレスが公開されることはありません。


*

CAPTCHA