Simulinkで16ビットデータを8ビットデータにする方法
言ってる意味が分かりにくいかもしれませんがSimuinkでデータの精度を落とさずに
16ビットデータを8ビットデータにする方法です。というかシリアル通信のアイデアです。
ArduinoとMATLABでシリアル通信しているのですが、Simulinkサポートパッケージの弱点ですね。
Arduinoの仕様でADCは確か10ビットだったと思います。10ビットデータをSimulinkサポートパッケージ
使って送信するにはどうしたらよいかという話です。
RS-232C
まずRS-232Cの仕様ですが、基本的には最大8ビット(2^8-1=255)までしか送れません。
8ビット=1バイトとなりコンピュータ上の単位の一つです。
それともう一つ、8バイトあると漢字以外アルファベット、カタカナすべて網羅できます。
ですからRS-232Cは数値データでなく文字を1文字ずつ送るのには向いているシリアル通信です。
Arduinoで通信したいもの
で、ArduinoとSimulinkを組み合わせる場合、通信したいものって数値データです。
例えばArduinoのADCデータを送ったり、コマンドのPWM%をArduinoに送ったりする使い方です。
Arduinoの仕様上PWM%は8ビットデータですが、ADC出力は10ビットデータとなります。
ですからSimulinkでプログラムを組んだ場合シリアル通信でPWM%を与えるときは問題ありませんが、
ADCのデータをシリアル通信で受信するときに困ってしまいます。
二つの方法
そこで二つの方法があります。
- 10ビットデータを8ビットに無理やりArduinoで変換する方法
- 10ビットデータを上位下位データにわけてArduinoで2回に分けて送信し、受信側で合成する方法
一長一短ですが上の段では10ビット=1024⇒8ビット=256だと分解能が1/4に落ちてしまいます。
下の段の方法ではシリアル通信で1回余分に時間がかかってしまいます。
マルチチャネルの場合は下の段の方法では時間変化の早いものには向かないが高精度、
上の段では分解能が粗いが時間変化の早いものにも有利となります。
若干時間がかかってしまいますが、10ビットデータですが上位、下位の各1バイトデータに分けて順番に
出力している様子がわかります。3、182,3,182・・・とクロックに同期して出力されてます。
実際使うには、どっちが上位でどっちが下位かを分かるようにする工夫が必要ですが
これが基本的なアイデアです。
ちなみに、クロックパルスのエッジ検出をするために初期値として255を設定したため最初の0.5secだけ
値がずれてしまっています。
MATLABで計算すると
Simulinkは時間の概念が入ってしまいますのでMATLABで単純に計算するとこんな作業を
Simulinkは時間領域でやっています。
MATLABコマンドのbin2decやdec2binです。
bin2dec(‘00000011’)は上位8ビット、bin2dec(‘10110110’)は下位8ビットです。
答えがそれぞれ3と8になっています。
簡単に答え合わせすると
256*3+182=950
となりMATLABの答えもSimulinkの答えもあっています。
このアイデアを使ってArduinoのADCデータ分解能を落とさずにシリアル通信したいと思います。
それはまた別の話。
ちなみにMATLAB/Simulinkで遊ぶArduinoでいろいろ連載してます。