5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Simulink × M5Stack:Simulink モデルをそのままブチ込んで MATLAB からリモート制御

Last updated at Posted at 2025-12-05

0. はじめに

 自動制御連合講演会 2025 で,Takuya Otani (https://x.com/ta98otani) さんとお話する機会があり,Simulink と M5Stack の連携に関するわたしの困りごとを相談しました.具体的には,以下の 2 点です.

  • M5Stack の LCD にデータを表示させたい.
    (Simulink で実装すると,LCD は漆黒の色のままなので…)
  • リモートで車輪型倒立振子を動かしたい
    (みんなリモートで動かして楽しそう…)

 わたしの方からは Simulink, M5Stack FIRE + Unit Roller485 で動かす方法をお伝えし,逆に Takuya Otani さんにはわたしの困りごとの開発をお願いすることで,個人的にコラボすることとなりました(知らない知識を得られる…ワクワク).

 今回は「リモート指令で車輪型倒立振子を動かしたい」の前段階のお話で,

  MATLAB からのリモート指令で BLDC モータ Unit Roller485 を動かす!

ことを目標とします.そのために,BLE (Bluetooth Low Energy) と呼ばれる「低消費電力」に特化した Bluetooth のプロトコルを利用します.

 LCD の表示については,後日,Takuya Otani (https://x.com/ta98otani) さんが公開されるのではないかと思います.

1. 使用するソフトウェアと機器

1.1 配布するファイル

 ここからダウンロードできます.配布する MATLAB/Simulink のファイルは

  • send_1byte.m
  • send_2bytes.m
  • receive_1byte_R2024b.slx
  • receive_2bytes_R2024b.slx
  • BLE_angle_control_1byte_R2024b.slx
  • BLE_angle_control_2bytes_R2024b.slx

です.また,Application download の Baud rate を 115200 に変更した

  • receive_1byte_R2024b_baudrate115200.slx
  • receive_2bytes_R2024b_baudrate115200.slx
  • BLE_angle_control_1byte_R2024b_baudrate115200.slx
  • BLE_angle_control_2bytes_R2024b_baudrate115200.slx

も置いておきました.

1.2 ソフトウェア

 ソフトウェアは MATLAB R2024b です.使用した Toolbox は

  • MATLAB
  • Simulink
  • Control System Toolbox

です.これに加えてフリーの

  • Simulink Support Package for Arduino Hardware

のインストールが必要です.その際,ESP32 の設定追加も忘れずに!
インストール手順はココで説明しています.

1.3 機器

 まずは,Bluetooth が搭載された M5Stack CORE シリーズ のマイコン.わたしは手持ちの

で動作確認をしました.Arduino だと別途,Bluetooth を用意しなければならないので,M5Stack は便利です!

 また,Unit Roller485 を動かしたい場合は,

をご用意ください(どちらでも可).

1.4 準備

 M5Stack と PC を USB ケーブルで接続し,デバイスマネージャで M5Stack の COM 番号を調べておきます.

image.png

 配布するすべての Simulink モデルは「コンフィギュレーションパラメータ」(もしくは「ハードウェア設定」)で

image.png

のように COM 番号を手動で設定します.なお,M5Stack を使用しますので,Simulink 側でハードウェアボードとして

  • ESP32-WROOM

を選択しています.なお,Application download の Baud rate は必要に応じて 115200 に落としてください

image.png

その他の「コンフィギュレーションパラメータ」は以下を確認してください.

image.png

image.png

 今回の例のように,I2C でやり取りするデータの種類が少なければ,固定ステップサイズを 0.005 秒くらいまで短くできますが,データの種類が多くなってくると,もっと長くしなければなりません.

2. MATLAB からリモート指令を M5Stack に送ってみる

2.1 1 バイトデータの場合

2.1.1 Simulink モデルおよび M ファイル

 Simulink モデル

および M ファイル

send_1byte.m

send_1byte.m
clear

m5 = ble("Arduino");

% UUID の設定
Service        = "fce70352-c544-48f4-9760-7568263b7922";
Characteristic = "b570118e-df2f-4545-9cf9-eff837991f54";

data_c = characteristic(m5, Service, Characteristic);

while 1
    ref = input("ref = ");   % -128 ~ 127 の値を入力
    
    % int8 を uint8 に変換(ビットパターン保持)
    valuesToSend = typecast(int8(ref), 'uint8');
    
    write(data_c, valuesToSend);
end

を作業フォルダに保存しておきます.

 ざっくりとした注意点は以下の通り.

Simulink を実行した後,MATLAB のコマンドウィンドウで以下のように入力することで,周辺にある Bluetooth デバイスを確認することができます.

>> blelist
bluetoothlist を実行して、近くの Bluetooth Classic デバイスを検出してください。
ans =
  4×5 table
    Index       Name          Address        RSSI    Advertisement
    _____    __________    ______________    ____    _____________
      1      ""            "765F38F68068"    -30      1×1 struct  
      2      "Arduino"     "3C8A1FD670AA"    -42      1×1 struct  
      3      ""            "55EFE94FD626"    -66      1×1 struct  
      4      "Quest 3S"    "47FA002D24EE"    -72      1×1 struct 

M5Stack は "Arduino" という名前で認識されますので,M ファイル send_1byte.m では

m5 = ble("Arduino");

と記述しています.もしかしたら

m5 = ble("3C8A1FD670AA");

のようにアドレス指定にしないとうまく認識しないかもw

M ファイル send_1byte.m では,

    ref = input("ref = ");   % -128 ~ 127 の値を入力
    
    % int8 → uint8 に変換(ビットパターン保持)
    valuesToSend = typecast(int8(ref), 'uint8');
    
    write(data_c, valuesToSend);

の部分で,

  • double 型の $\tt ref$ を入力
  • $\tt int8(ref)$ で符号あり 8 ビット整数(1 バイト整数)に変換
  • $\tt typecast(int8(ref), 'uint8')$ で符号なし 8 ビット整数(1 バイト整数)に変換

という順で変換し, MATLAB 関数 $\tt write$ により送信しています.ここで,MATLAB 関数 $\tt write$ で使用できる送信データは uint8(符号なし 8 ビット整数) でなければならないことに注意が必要です.

一方で,Simulink ブロック $\tt BLE\ Receive$ では,int8(符号あり 8 ビット整数) が出力されます.ややこしいですねww

M ファイル send_1byte.m や Simulink モデル receive_1byte_R2024b.slx(あるいは receive_1byte_R2024b_baudrate115200.slx)には 2 種類の 128 ビットの識別子 UUID

  • Service
  • Characteristic

が設定されています.配布するファイルから値を変更する必要はありませんが,これらは

>> char(java.util.UUID.randomUUID())
ans =
    'fce70352-c544-48f4-9760-7568263b7922'
>> char(java.util.UUID.randomUUID())
ans =
    'b570118e-df2f-4545-9cf9-eff837991f54'

のようにして生成しました.

Simulink モデル receive_1byte_R2024b.slx(あるいは receive_1byte_R2024b_baudrate115200.slx)の実行中にデータを受信していないときは,0 を返すような処理をしています.

image.png

2.1.2 実行してみる

 以下の手順で実行してください.

  1. M5Stack と PC を USB ケーブルで接続します.
  2. Simulink モデル receive_1byte_R2024b.slx(あるいは receive_1byte_R2024b_baudrate115200.slx)をエクスターナルモードで実行します(「ハードウェア」のタグで「監視と調整」をクリック).実行が開始されると,M5Stack の LCD は真っ黒になりますが,気にしないでください.
  3. M ファイル send_1byte.m を実行します.動画のように MATLAB のコマンドウィンドウから ref の値を入力すると,Simulink モデルの $\tt Display$ の表示が切り替わることが確認できます.
  4. 終了したい場合は,コマンドウィンドウでキーボード操作「Ctrl + C」により,M ファイルの実行を強制終了してくださいw

 実行した様子の動画を以下に示します.

image.png

スクリーンショットを以下に示します.

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

 M ファイル send_1byte.m では $-128 \sim 127\ (-2^7 \sim 2^7 - 1)$ の int8(符号あり 8 ビット整数)のデータを,$0 \sim 255\ (0 \sim 2^8 - 1)$ の uint8(符号なし 8 ビット整数)に変換してから送信し,M5Stack (Simulink) で受信ていることに注意してください.そのため,

  • $127$ より大きな値を指定すると,$127$ で頭打ちとなる(動画の例では $\tt ref=180$ と指定すると,$\tt Display (ref)$ には $\tt 127$ が表示される)
  • $-128$ より小さな値を指定すると,$-128$ で頭打ちとなる(動画の例では $\tt ref=-180$ と指定すると,$\tt Display (ref)$ には $\tt -128$ が表示される)

という問題があります.つまり,

>> int8(180)
ans =
  int8
   127
>> int8(-180)
ans =
  int8
   -128

ということですね.

2.2 2 バイトデータの場合

 上記のように,1 バイトの送受信データは,$-128 \sim 127\ (-2^7 \sim 2^7 - 1)$ の範囲に制限されます.今回,Roller485 の角度制御をリモート指令で行いたいわけですから,このままでは,目標角を $360^{\circ}$ とか $-360^{\circ}$ に設定できません.この問題を解決するには,送受信データを 2 バイトとすることが考えられます.そうすることで,$-32768 \sim 32767\ (-2^{15} \sim 2^{15} - 1)$ の範囲を扱うことができるようになります.

2.2.1 Simulink モデルおよび M ファイル

 Simulink モデル

および M ファイル

send_2bytes.m

send_2bytes.m
clear

m5 = ble("Arduino");

% UUID の設定
Service        = "fce70352-c544-48f4-9760-7568263b7922";
Characteristic = "b570118e-df2f-4545-9cf9-eff837991f54";

data_c = characteristic(m5, Service, Characteristic);

while 1
    ref = input("ref = ");   % -32768 ~ 32767 の値を入力
    
    % --- int16 を 2 バイトの uint8 に変換(ビットパターン保持)---
    bytesToSend = typecast(int16(ref), 'uint8');  % 1x2 の uint8 ベクトルになる
    
    write(data_c, bytesToSend);
end

を作業フォルダに保存しておきます.

 ざっくりとした注意点は以下の通り.データ変換の詳細については,最下部の付録を参照してください.

残念ながら,int16(2 バイト)データをそのまま送信することはできない(uint8 でしか送信できない)仕様なので,1 バイトずつに分割し,uint8 の 2 次元ベクトルとして送信する必要があります.
そこで,M ファイル send_2bytes.m では,

    ref = input("ref = ");   % -32768 ~ 32767 の値を入力
    
    % --- int16 を 2 バイトの uint8 に変換(ビットパターン保持)---
    bytesToSend = typecast(int16(ref), 'uint8');  % 1x2 の uint8 ベクトルになる
    
    write(data_c, bytesToSend);

の部分で,

  • double 型の $\tt ref$ を入力
  • $\tt int16(ref)$ で符号あり 16 ビット整数(2 バイト整数)に変換
  • $\tt typecast(int16(ref), 'uint8')$ でビットパターンをそのまま 2 バイトに分解する(int16 を「上位バイト + 下位バイト」の 2 つの uint8 に分解する)

という順で変換し,分解した 2 バイトの符号なし 8 ビット整数 (uint8) を MATLAB 関数 $\tt write$ により送信しています.

たとえば,正の値だと

>> ref = 360;
>> int16(ref)
ans =
  int16
   360
>> typecast(int16(ref), 'uint8')
ans =
  1×2  uint8 行ベクトル
   104     1

負の値だと

>> ref = -360;
>> int16(ref)
ans =
  int16
   -360
>> typecast(int16(ref), 'uint8')
ans =
  1×2  uint8 行ベクトル
   152   254

というような感じです.

一方で,Simulink ブロック $\tt BLE\ Receive$ で受信されたデータは,2 バイトの 8 ビット符号あり整数 (int8) として出力されます.さらにややこしいですねww

Simulink ブロック $\tt BLE\ Receive$ から出力された 2 バイトの int8 を元の形式に戻すために,

  • Simulink ブロック ${\tt Data Type Conversion}$ により 2 バイトの uint8 に変換
  • Simulink ブロック ${\tt Byte Unpack}$ により 2 バイトの uint8 を uint18 に変換
  • Simulink ブロック ${\tt Data Type Conversion1}$ により double に変換

image.png

という処理を行っています.

2.2.2 実行してみる

 以下の手順で実行してください.

  1. M5Stack と PC を USB ケーブルで接続します.
  2. Simulink モデル receive_2bytes_R2024b.slx(あるいは receive_2bytes_R2024b_baudrate115200.slx)をエクスターナルモードで実行します(「ハードウェア」のタグで「監視と調整」をクリック).
  3. M ファイル send_2bytes.m を実行します.動画のように MATLAB のコマンドウィンドウから ref の値を入力すると,Simulink モデルの $\tt Display$ の表示が切り替わることが確認できます.
  4. 終了したい場合は,コマンドウィンドウでキーボード操作「Ctrl + C」により,M ファイルの実行を強制終了してくださいww

 実行した様子の動画を以下に示します.

image.png

スナップショットだとこんな感じです.

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

3. Simulink モデル

3.1 Simulink ライブラリ roller485lib のインストール

 後日,Qiita の別記事で使用方法を公開予定ですが,わたしが作成した Unit Roller485 用の Simulink ライブラリ

をインストールします.

image.png

Download ZIP を選択すると,

  • Roller485lib-main.zip

がダウンロードされるので,解凍してできるフォルダ Roller485lib-main(のなかのフォルダ Roller485lib-main)を

  • C:\Users\ユーザ名\Documents\MATLAB

にコピペしてください.ファイル構成は

  • MATLAB
    • Roller485lib-main
      • sample_roller485lib
        <フォルダの中身は省略>
      • slblocks.m
      • README.md
      • roller485.png
      • roller485_matlab_fcn.png
      • roller485lib.slx
      • LICENSE.txt

となります.そして,M ファイル

startup.m
% startup.m

addpath('C:\Users\ユーザ名\Documents\MATLAB\Roller485lib-main')

をフォルダ

  • C:\Users\ユーザ名\Documents\MATLAB

に保存してください.つまり,

  • C:\Users\ユーザ名\Documents\MATLAB\startup.m

としてください.そして,MATLAB を再起動すると,Simulink ライブラリ roller485lib が使用できるようになります.コマンドウィンドウで

>> roller485lib

と入力すると,Simulink ライブラリ roller485lib が開きます.

image.png

このライブラリ自体は R2023a 以上に対応しています.

3.2 Simulink モデル

 Simulink モデル

をダウンロードしてください(R2024b 以上に対応).M ファイルはすでに利用した

です.

3.3 実行してみる

 以下の手順で実行してください.

  1. M5Stack と PC を USB ケーブルで接続します.

  2. Simulink モデル BLE_angle_control_2bytes_R2024b.slx(あるいは BLE_angle_control_2bytes_R2024b_baudrate115200.slx)をスタンドアロンモードで実行します(「ハードウェア」のタグで「ビルド、展開起動」をクリック).M5Stack をバッテリーなど外部から給電しているのであれば,M5Stack にダウンロードが終了したら,USB ケーブルを抜いても大丈夫です.
    image.png

  3. M5Stack の電源を入れたら,5 秒位内に Roller485 の軸の基準位置を決定します.5 秒が経過したら角度の比例制御が始まります.制御が始まったら,手で外乱を与えても,基準位置に戻ろうとすることを確認してください.

  4. M ファイル send_2bytes.m を実行します.動画のように MATLAB のコマンドウィンドウから ref の値を入力すると,Roller485 の軸の角度が目標角に制御されることが確認できます.

  5. 終了したい場合は,コマンドウィンドウでキーボード操作「Ctrl + C」により,M ファイルの実行を強制終了してくださいwww

 実行した様子の動画を以下に示します.

Mac でも動くようですよ!

4. おわりに

 というわけで,Takuya Otani (https://x.com/ta98otani) さんに感謝!

 Roller485 を利用した車輪型倒立振子もリモートで簡単な動作をさせることまではできるようになりました.

1 年前は Simulink で M5Stack や Roller485 をこんな感じで動かせるとは思っていませんでしたが,ずいぶんと進んだような気がする.

ここまでくれば,Bluetooth のボタンやジョイスティックとかでリモート制御ができるかも.

追記

 勉強しているうちに,MATLAB で BLE を使う解説記事があることに気づきましたww
皆さんがお試ししていたのは 2020 年頃なんですね.

ちなみに,今回使用した Sumulink ブロック $\tt BLE\ Receive$ が導入されたのは R2021b からなので,強者たちは恐るべし…

付録

A.1 M モデル send_2bytes.m の信号の流れ

 M モデル send_2bytes.m では,以下のようなデータ変換を行っています.

send_2bytes.m
<>

while 1   % 無限ループ
    ref = input("ref = ");   % -32768 ~ 32767 の値を入力
    
    % --- int16 を 2 バイトの uint8 に変換(ビットパターン保持)---
    bytesToSend = typecast(int16(ref), 'uint8');  % 1x2 の uint8 ベクトルになる
    
    write(data_c, bytesToSend);
end

${\tt int16(ref)}$
double 型の $\tt ref$ を int16 型に変換します.

\begin{align}
{\tt double:}\ 
{\tt ref}
\quad\longrightarrow\quad
{\tt int16:}\ 
{\tt V}_{\tt int16}
\end{align}

${\tt typecast(int16(ref), 'uint8')}$
まず,次式に従って int16 型を uint16 型に変換します ($2^{16} = 65536$).

\begin{align}
{\tt uint16:}\ 
{\tt V}_{\tt uint16} =
\begin{cases}
{\tt V}_{\tt int16} + 65536 & ({\tt V}_{\tt int16} < 0) \\
{\tt V}_{\tt int16}         & ({\tt V}_{\tt int16} \ge 0)
\end{cases}
\end{align}

そして,8 ビット(1 バイト)ごとに分割した uint8 型の

\begin{align}
    {\tt uint8:}&\ [\,\begin{array}{cc}
        {\tt L}_{\tt uint8} & {\tt M}_{\tt uint8}
    \end{array}\,]
    \quad \cdots\cdots\ {\rm Little\ Endian}
\end{align}

の要素(リトルエンディアンの並び)を,次式を満足するように決定します ($2^{8} = 256$).

\begin{align}
{\tt V}_{\tt uint16} = 256 \times {\tt M}_{\tt uint8} + {\tt L}_{\tt uint8}
\end{align}

ただし,

  • 上位ビット ${\tt M}_{\tt uint8}$ (MSB)
  • 下位ビット ${\tt L}_{\tt uint8}$ (LSB)

は $0$ から $255$ までの整数です.

《補足》
ちなみに,さらに

\begin{align}
{\tt int8:}&\ [\,\begin{array}{cc}
        {\tt L}_{\tt int8} & {\tt M}_{\tt int8}
   \end{array}\,]
\end{align}

と変換するには,

\begin{align}
    {\tt L}_{\tt int8} &= \left\{\begin{array}{ll}
        {\tt L}_{\tt uint8}       & ({\tt L}_{\tt uint8} < 128) \\
        {\tt L}_{\tt uint8} - 256 & ({\tt L}_{\tt uint8} \ge 128)
    \end{array}\right.
    \\
    {\tt M}_{\tt int8} &= \left\{\begin{array}{ll}
        {\tt M}_{\tt uint8}       & ({\tt M}_{\tt uint8} < 128) \\
        {\tt M}_{\tt uint8} - 256 & ({\tt M}_{\tt uint8} \ge 128)
    \end{array}\right.
\end{align}

とします.これが,Simulink ブロック ${\tt BLE\ Receive}$ から出力される $\tt Data$ になります.


たとえば,${\tt ref} = 360$ のとき,

\begin{align}
{\tt int16:}\ 
{\tt V}_{\tt int16} = 360 \ge 0
\end{align}

であり,

\begin{align}
{\tt uint16:}\ 
{\tt V}_{\tt uint16} 
&=
{\tt V}_{\tt int16}
= 360 
\end{align}

なので,

\begin{align}
{\tt V}_{\tt uint16} &= 256 \times {\tt M}_{\tt uint8} + {\tt L}_{\tt uint8}
\\
&= 256 \times 1 + 104
\end{align}

です.したがって,

\begin{align}
    {\tt uint8:}&\ [\,\begin{array}{cc}
        {\tt L}_{\tt uint8} & {\tt M}_{\tt uint8}
    \end{array}\,]
    = [\,\begin{array}{cc}
        104 & 1
    \end{array}\,]
\end{align}

が得られます.MATLAB では

>> ref = 360;
>> typecast(int16(ref), 'uint8')
ans =
  1×2  uint8 行ベクトル
   104     1

となります.

ちなみに,

\begin{align}
    {\tt L}_{\tt int8} &= {\tt L}_{\tt uint8} = 104 
        & ({\tt L}_{\tt uint8} = 104 < 128) \\
    {\tt M}_{\tt int8} &= {\tt M}_{\tt uint8} = 1       
        & ({\tt M}_{\tt uint8} = 1 < 128) 
\end{align}

より

\begin{align}
    {\tt int8:}&\ {\tt Data} 
    = [\,\begin{array}{cc}
        {\tt L}_{\tt int8} & {\tt M}_{\tt int8}
    \end{array}\,]
    = [\,\begin{array}{cc}
        104 & 1
    \end{array}\,]
\end{align}

が得られます.MATLAB では

>> ref = 360;
>> typecast(int16(ref), 'int8')
ans =
  1×2  int8 行ベクトル
   104     1

となります.


たとえば,${\tt ref} = -360$ のとき,

\begin{align}
{\tt int16:}\ 
{\tt V}_{\tt int16} = -360 < 0
\end{align}

であり,

\begin{align}
{\tt uint16:}\ 
{\tt V}_{\tt uint16} 
&=
{\tt V}_{\tt int16} + 65536 
\\
&= -360 + 65536 
\\
&= 65176
\end{align}

なので,

\begin{align}
{\tt V}_{\tt uint16} &= 256 \times {\tt M}_{\tt uint8} + {\tt L}_{\tt uint8}
\\
&= 256 \times 254 + 152
\end{align}

です.したがって,

\begin{align}
    {\tt uint8:}&\ [\,\begin{array}{cc}
        {\tt L}_{\tt uint8} & {\tt M}_{\tt uint8}
    \end{array}\,]
    = [\,\begin{array}{cc}
        152 & 254
    \end{array}\,]
\end{align}

が得られます.MATLAB を利用すると,

>> ref = -360;
>> typecast(int16(ref), 'uint8')
ans =
  1×2  uint8 行ベクトル
   152   254

のように結果を確認できます.

ちなみに,

\begin{align}
    {\tt L}_{\tt int8} &= {\tt L}_{\tt uint8} -256 
            = 152 - 256 = -104
        & ({\tt L}_{\tt uint8} = 152 \ge 128) \\
    {\tt M}_{\tt int8} &= {\tt M}_{\tt uint8} -256
            = 254 - 256 = -2    
        & ({\tt M}_{\tt uint8} = 254 \ge 128) 
\end{align}

より

\begin{align}
    {\tt int8:}&\ {\tt Data} 
    = [\,\begin{array}{cc}
        {\tt L}_{\tt int8} & {\tt M}_{\tt int8}
    \end{array}\,]
    = [\,\begin{array}{cc}
        -104 & -2
    \end{array}\,]
\end{align}

が得られます.MATLAB を利用すると,

>> ref = -360
ref =
  -360
>> typecast(int16(ref), 'int8')
ans =
  1×2  int8 行ベクトル
   -104     -2

のように結果を確認できます.


A.2 Simulink モデル receive_2bytes_R2024b.slx の信号の流れ

 Simulink モデル receive_2bytes_R2024b.slx では,以下のようなデータ変換を行っています.

Simulink ブロック ${\tt BLE\ Receive}$ から 2 バイトのリトルエンディアンの $\tt Data$ が

\begin{align}
    {\tt int8:}&\ {\tt Data} = [\,\begin{array}{cc}
        {\tt L}_{\tt int8} & {\tt M}_{\tt int8}
    \end{array}\,]
\end{align}

のように受信されます.Simulink ブロック ${\tt Data\ Type\ Conversion}$ で変換されたデータ

\begin{align}
    {\tt uint8:}&\ [\,\begin{array}{cc}
        {\tt L}_{\tt uint8} & {\tt M}_{\tt uint8}
    \end{array}\,]
\end{align}

の各要素は

\begin{align}
    {\tt L}_{\tt uint8} &= \left\{\begin{array}{ll}
        {\tt L}_{\tt int8} + 256 & ({\tt L}_{\tt int8} < 0) \\
        {\tt L}_{\tt int8}       & ({\tt L}_{\tt int8} \ge 0)
    \end{array}\right.
    \\
    {\tt M}_{\tt uint8} &= \left\{\begin{array}{ll}
        {\tt M}_{\tt int8} + 256 & ({\tt M}_{\tt int8} < 0) \\
        {\tt M}_{\tt int8}       & ({\tt M}_{\tt int8} \ge 0)
    \end{array}\right.
\end{align}

です ($2^8 = 256$).そして,Simulink ブロック ${\tt Byte\ Unpack}$ では,

\begin{align}
    {\tt uint16:}&\ 
    {\tt V}_{\tt uint16} 
    = 256 \times {\tt M}_{\tt uint8} + {\tt L}_{\tt uint8}
\end{align}

と変換した後,

\begin{align}
    {\tt int16:}&\ 
    {\tt V}_{\tt int16} = \left\{\begin{array}{ll}
        {\tt V}_{\tt uint16} - 65536 & ({\tt V}_{\tt uint16} > 32767) \\
        {\tt V}_{\tt uint16}         & ({\tt V}_{\tt uint16} \le 32767)
    \end{array}\right.
\end{align}

と変換しています ($2^{16} = 65536,\ 2^{15} - 1 = 32767$).最終的には,これを double 型に変換して $\tt ref$ を復元しています.

image.png


たとえば,

\begin{align}
    {\tt int8:}&\ {\tt Data} = [\,\begin{array}{cc}
        {\tt L}_{\tt int8} & {\tt M}_{\tt int8}
    \end{array}\,]
    = [\,\begin{array}{cc}
       104 & 1
    \end{array}\,]
\end{align}

のとき,

\begin{align}
    {\tt L}_{\tt uint8} &= {\tt L}_{\tt int8}
    = 104\ &({\tt L}_{\tt int8} \ge 0)
    \\
    {\tt M}_{\tt uint8} &= {\tt M}_{\tt int8}
    = 1\ &({\tt M}_{\tt int8} \ge 0)
\end{align}

と変換されます.そして,

\begin{align}
    {\tt uint16:}\ 
    {\tt V}_{\tt uint16} 
    &= 256 \times {\tt M}_{\tt uint8} + {\tt L}_{\tt uint8}
    \\
    &= 256 \times 1 + 104
    \\
    &= 360 \ (\le 32767)
\end{align}

と変換した後,

\begin{align}
    {\tt int16:}\ 
    {\tt V}_{\tt int16} &= {\tt V}_{\tt uint16}
    = 360
\end{align}

と復元されます.


たとえば,

\begin{align}
    {\tt int8:}&\ {\tt Data} = [\,\begin{array}{cc}
        {\tt L}_{\tt int8} & {\tt M}_{\tt int8}
    \end{array}\,]
    = [\,\begin{array}{cc}
       -104 & -2
    \end{array}\,]
\end{align}

のとき,

\begin{align}
    {\tt L}_{\tt uint8} &= {\tt L}_{\tt int8} + 256
    = -104 + 256 = 152\ &({\tt L}_{\tt int8} < 0)
    \\
    {\tt M}_{\tt uint8} &= {\tt M}_{\tt int8} + 256
    = -2 + 256 = 254\ &({\tt M}_{\tt int8} < 0)
\end{align}

と変換されます.そして,

\begin{align}
    {\tt uint16:}\ 
    {\tt V}_{\tt uint16} 
    &= 256 \times {\tt M}_{\tt uint8} + {\tt L}_{\tt uint8}
    \\
    &= 256 \times 254 + 152
    \\
    &= 65176 \ (> 32767)
\end{align}

と変換した後,

\begin{align}
    {\tt int16:}\ 
    {\tt V}_{\tt int16} &= {\tt V}_{\tt uint16} - 65536
    \\
    &= 65176 - 65536
    \\
    &= -360
\end{align}

と復元されます.

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?