WRX micro:bitを車両で使う その20 アスキーコード16進数から数値10進数への変換

micro:bit, OBD2, 社外部品・DIY

前回、車両に接続したELM327へOBD2ポートに対しての情報取得命令(010C:エンジン回転数)をmicro:bitから送信し、その答えとなる返信をLCDパネルに表示出来る事は確認しました。実際の返信内容にはエンジン回転数以外の情報も含まれるのですが、繰り返しの取得でもmicro:bitのバッファー内で毎回同じ位置に入る事も確認出来たので、必要な部分のみ抜き出して利用出来そうです。ただし返信内容は16進数のアスキーコード(文字)なので、これを最終的には10進数の数値に変換する必要があります。

スポンサーリンク

ELM327からの返信

ELM327へエンジン回転数の情報取得命令の送信を行うと、ELM327はOBD2ポートからエンジン回転数を取得します。その後は答えを返信してきますが、エンジン回転数の場合は16進数で2バイトを答えとして返信してきます。ELM327のデータシート(リンク先はpdf・32ページ目)に記載されている例では「1A」と「F8」の2つ(2バイト)となっていて、ここからOBD2の規格で示される計算式で計算を行うと10進数の正しいエンジン回転数になります。

ただし「1A」と「F8」はターミナルアプリやLCDパネルで文字として表示された状態で、実際にELM327から返信されるデータはその文字を表す16進数のアスキーコードです。従って「1A」は「31 41」、「F8」は「46 38」というデータになっています。

ここまで書くとプログラム内で正しいエンジン回転数を得るのは非常に面倒な事が分かります。31や41をそれぞれ数値として1とAに変換した上で十の位、一の位として組み合わせる必要があります。さらに組み合わされた「1A」は16進数なので、これを10進数にしなければなりません。

この辺りはFA用PLCを使用した時にも理解が大変でした。今回はこれをmicro:bitで実現します。

micro:bitでの文字と数値

幸いな事にMicrosot MakeCodeではブロックで文字と数値を使い分ける事が出来ます。また高度なブロック内にある「文字列」には文字列を数値に変換したり、逆に数値を文字列に変換するブロックなどもあるので、PLCの時ほどプログラムに悩む事はないかもしれません。

変数では「文字列」の一番上にある「” ”」ブロックを使用すると、変数内に文字列も使用出来ます。とても便利なのですが、文字と数値の区別が分かり難くなってしまう事もあります。入力欄に「” ”」があると文字、何も無いと数値です。

上記ではその中で利用出来そうな「文字列を数値に変換する」、「数値を文字列に変換する」、「文字コード~の文字」という3つのブロックを試してみました。しかし残念な事に「文字列を数値に変換する」では文字0~9までしか変換されず、文字A~Fのみでは「NaN」となってしまいます。また「数値を文字列に変換する」も数値0~9までしか変換されず、入力欄自体も数値A~F(16進数)は入力出来ません。さらに「文字コード~の文字」では16進数ではなく10進数文字コードで認識されます。「46」は16進数文字コードで「F」ですが、micro:bitでは10進数文字コードで「.(ドット)」になってしまいます。

結局の所、Microsot MakeCodeのブロック上では10進数でしか文字や数値を利用出来ない様子なので、やはり一筋縄ではいきません。

ブロックで16進数を扱う

前回の記事でELM327からの返信は「シリアル通信 文字列を読み取る」で受信しています。従ってELM327から返信される16進数のアスキーコードは、micro:bitには既に文字列で認識されています。ここではバッファー内に記憶された文字列から必要な部分のみ(今回はエンジン回転数)を抜き出した場合を仮定します。

Microsot MakeCodeで開く

上記のプログラムの「最初に」で2桁の16進数を表す文字列を「F8」とし、それぞれを変数(文字_~桁目)に入れています。「ずっと」では文字から数値への変換と同時に16進数から10進数にも変換していますが、先の通り「文字列を数値に変換する」では文字0~9までしか変換出来ません。苦肉の策で文字A~Fは個別に数値10~15を変数(数値_~桁目)へ入れています。意外だったのは変数(文字_~桁目)内の文字が0~9以内の範囲内であるかを見る大小比較で、文字のままでも行えたことです。

数値に変換後の変数「数値_2桁目」に16を掛けた上で、変数「数値_1桁目」に加えると、文字で2桁16進数とした「F8」は数値の10進数「248」としてLEDに表示されます。

その他

Microsot MakeCodeで開く

上記は配列を使用して文字で表される2桁16進数の各桁の文字が、配列のどの位置にあるかで0~15の数値に変換しています。「最初だけ」で文字の2桁16進数を「D4」にしていますが、文字Dは配列で13番目、文字4は4番目です(配列や文字の先頭は「0」番目である事に注意)。変数の「16進数2桁目」、「16進数1桁目」にはそれぞれ数値で13と4が入ります。従って13に16を掛けて4を足すと、文字で16進数「D4」は数値の10進数「212」になります。

変換の方法は色々あり、出来るだけ分かり易く且つプログラムの簡単(少ない容量)な方法が良いのですが、配列のブロックは配列数が多くなると巨大になってしまって見難いです。ただしJavaScriptにすると最初のプログラム(上記上側)よりは少なく済んでいて、桁数が増えても対応し易いプログラム(上記下側)です。

とりあえずmicro:bitでも文字で表される2桁16進数から数値の10進数への変換は可能になりました。本来の目的であるエンジン回転数ではさらにもう1つあり、その後の計算も残っています。次回は実際にエンジン回転数を得る為のプログラムを考える予定です。

「micro:bit」関連記事

以下は「micro:bit」タグの記事一覧です(投稿順)。現在の記事とこれ以降に投稿した記事も含みます。

その他

FA用PLCとELM327を使用した「OBD2」関連の記事は以下の記事から始まります。

注記

    • このブログ内で書いている内容はあくまで私の利用する製品(アプリ含む)や機器での場合です。他メーカーの製品や機器をはじめ、同じメーカーの製品・機器であってもバージョン違い等の場合もあるので、記事内容の保証や責任を負う事は出来ません。
    • 記事内で紹介している製品や、その他の類似製品を購入・利用する場合はそのメーカーや購入先で仕様等を確認し、自己判断と自己責任の下で利用して下さい。
    • 記事内で公開しているmicro:bit用プログラムは自由に利用・改変して頂いて構いません。ただし不具合やバグもありますので、プログラムを利用した際の故障や事故等についての保証や責任を負う事は出来ません。自己判断と自己責任の下で利用して下さい。
    • micro:bit製品やプログラミング、その他記事内容について個別の問合せや依頼を頂いても回答する事は出来ませんので、予め御了承下さい。
    • BBC micro:bitは、micro:bit教育財団の登録商標です。その他のブランド名または製品名は各所有者の商標です。