要素数は足りてるはず​なのに「行列のインデ​ックスは削除の範囲外​です。」のエラーが出​る。

MATLABのApp Designerを使用しています。
i2cボードの変数の配列と、アドレス情報の配列を作成していて、アドレス情報をボードに入れようとしています。
以下のコードで、forループで4回目までは入っていくのですが、5回目(num = 5)の時に、
BoardAll(num)= [];の部分で、
「行列のインデックスは削除の範囲外です。」
のエラーが出ます。
BoardAll(num)の要素数はnumelで8個となっているので、5回目のループでエラーになる理由がわかりませんでした😓
properties (Access = private)
abc1,
abc2,
def1,
def2,
def3,
ghi1,
ghi2,
ghi3,
end
▼コールバック関数内
BoardAll = {app.abc1,app.abc2,app.def1,app.def2,app.def3,app.ghi1,app.ghi2,app.ghi3};
PrepI2c = {'0x10','0x11','0x12','0x40','0x41','0x42','0x60','0x61'};
for num = 1:numel(BoardAll)
BoardAll(num)= [];
BoardAll(num) = PrepI2c(num);
disp(BoardAll(num));
end
原因がわかる方いらっしゃいましたら、ご教示いただけますと幸いです。
お忙しいところすみませんが、どうぞよろしくお願いいたします。

 Réponse acceptée

Atsushi Ueno
Atsushi Ueno le 29 Mar 2023

0 votes

12 commentaires

Atsushi Ueno
Atsushi Ueno le 29 Mar 2023
BoardAll(num)= [];
上記はベクトル(配列)の要素を空の値にする意味ではなく、要素そのものを削除しベクトル(配列)の長さを縮めてしまいます。従って長さ8のベクトル(配列)は、上記を4回実行した(可能だった)時点で長さが4に減っており、5回目でとうとう削除する要素が無くなってしまい、当該エラーが出ています。
mayu
mayu le 29 Mar 2023
Modifié(e) : mayu le 29 Mar 2023
uenoさま。お忙しいところ、いつも(しかも図つきですごくわかりやすくしていただいて)ありがとうございます!
そういうことなのですね((+_+))
ループの最後に、disp(BoardAll); を追加してブレイクポイント置きながら確認してみたら、確かにおっしゃるとおりのことになっていました。。。
全然気が付いていませんでした。ありがとうございます。
= []; が空に使えないということで、ほかの書き方ありますでしょうか。。
= 0; にしたらdouble型といわれたからダメみたいでした💦
もしご存じであればご教示いただけますと幸いですm(__)m
どうぞよろしくお願いいたします。
Atsushi Ueno
Atsushi Ueno le 29 Mar 2023
cell 配列の値にアクセスするには括弧()ではなく中括弧{}で括ります。
BoardAll = {1,2,3,4,5,6,7,8} % 例
BoardAll = 1×8 cell array
{[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]}
BoardAll(3) = {999} % セル配列の要素を設定する方法1
BoardAll = 1×8 cell array
{[1]} {[2]} {[999]} {[4]} {[5]} {[6]} {[7]} {[8]}
BoardAll{3} = 999.999 % セル配列の要素を設定する方法2
BoardAll = 1×8 cell array
{[1]} {[2]} {[999.9990]} {[4]} {[5]} {[6]} {[7]} {[8]}
mayu
mayu le 29 Mar 2023
度々ありがとうございます!
書いていただいている、セル配列の要素を設定する方法の1と2それぞれ当てはめてみて、
BoardAll(num)= [];
と書いていた箇所を、
▼方法1)
BoardAll(num)= {};
と書くと
「左辺と右辺の要素数が異なるため、代入を実行できません。」
となるのですが、左か右の要素が複数あるということなのでしょうか❓
BoardAll(num)= {5};
のように具体的な数値を入れたらエラーが出ませんでした。
▼方法2
BoardAll{num}= [];
と書いたら特にエラーは出ませんでしたが、これで空要素を入れられたということでしょうか…
とりあえずこれで実際のコードにいれて確認してみようと思います。
ありがとうございました( ◠‿◠ )
Atsushi Ueno
Atsushi Ueno le 29 Mar 2023
ベクトルや行列と cell 配列の「要素自体の削除方法」は同じです。
cell 配列については、下記の両方とも「削除する」と説明しているので混乱しますね。
  • cell 配列の要素自体を削除して cell 配列の長さを縮める
  • cell 配列の要素の中身を空にする(cell 配列の長さは変わらない)
BoardAll = {1,2,3,4,5,6,7,8}; num = 3;
BoardAll(num) = {[]} % ▼方法1)cell 配列の要素を空配列に設定する。BoardAll(num) = {} は次元が合わないのでNG
BoardAll = 1×8 cell array
{[1]} {[2]} {0×0 double} {[4]} {[5]} {[6]} {[7]} {[8]}
BoardAll{num} = [] % ▼方法2)cell 配列の要素を空配列にする
BoardAll = 1×8 cell array
{[1]} {[2]} {0×0 double} {[4]} {[5]} {[6]} {[7]} {[8]}
BoardAll(num) = [] % ▼方法3)cell 配列の要素自体を削除する
BoardAll = 1×7 cell array
{[1]} {[2]} {[4]} {[5]} {[6]} {[7]} {[8]}
BoardAll = {1,2,3,4,5,6,7,8}; num = 3;
BoardAll{num} = {} % ▼番外編)cell 配列の要素の中身を cell 配列にする(cell 配列の入れ子)
BoardAll = 1×8 cell array
{[1]} {[2]} {0×0 cell} {[4]} {[5]} {[6]} {[7]} {[8]}
整理して考えると一見簡単に思えるのですが、大規模なプログラムの中で複雑な構造の cell 配列が出てくると、まずはそのデータ構造を調べる必要があります。私も7年前に発狂しています。
Atsushi Ueno
Atsushi Ueno le 29 Mar 2023
{[]}{}は異なります
  • {[]}:cell 配列要素の中身が空配列
  • {} :空のcell配列
mayu
mayu le 30 Mar 2023
Modifié(e) : mayu le 30 Mar 2023
本当に何度も親切に例を書いてくださって、ありがとうございます!
マトラボのヘルプのcell配列の説明は見たものの、書いてる意味がわからなかったり、今自分が悩んでいるのの答えがどこに書いてるのか分からなくて結局ここに質問にきてしまいます(´・_・`)
いただいた例文を眺めていて、とりあえずcell配列の中身をどうにかしたい場合には、{}を使うのは分かった気がするのですが、身につくまでいってないので分からなくなったら見返そうと思います。ありがとうございました。
それですみませんもしご存じであればもう1点ご質問が・・・(*_*;
mayu
mayu le 30 Mar 2023
Modifié(e) : mayu le 30 Mar 2023
上記関数内の右辺の部分を、ラズパイ~i2c通信の情報に置き換えたいと思って以下のように書いてみたのですが、
BoardAll(num) = i2cdev(app.rpi,'i2c-1',PrepI2c(num));
のエラーが出たので、
BoardAll(num) = i2cdev(app.rpi,'i2c-1',char(PrepI2c(num)));
と書き換えて実行したら
とでたので
BoardAll{num} = i2cdev(app.rpi,'i2c-1',char(PrepI2c(num)));
と書き換えて実行したら、エラーは出ないのですが、
ブレイクポイントを置いてBoardAllの中身を確認したら、
なんか結局うまく入りませんでした。
配列にボードの情報を入れるのは無理なのかなと思ったのですが、可能な方法はありますでしょうか。(意味がわかりますでしょうか。。。)
もし可能であればご教示いただけますと幸いですm(__)m
お忙しい中たびたびお手数をおかけいたしますが、どうぞよろしくお願いいたします。
Atsushi Ueno
Atsushi Ueno le 30 Mar 2023
mayu
mayu le 31 Mar 2023
Modifié(e) : mayu le 31 Mar 2023
またまたわかりやすい図を作成していただき、ありがとうございます!
cell配列が型限らずなんでも入れられるのと、配列にくくられてるのと中身の取り出せる図のところ、とても分かりやすかったです。
その感じでBoardAll{num}で配列の中身にアクセスして、i2cdevの中身の情報も入れたいと思って
i2cdev(app.rpi,'i2c-1',char(PrepI2c(num)));
の中身を見たら
となっているのですが、これも入れられるのでしょうか❓
BoardAll{num} = i2cdev(app.rpi,'i2c-1',char(PrepI2c(num)));
の場合でてきた
だとちゃんと入ってないみたいで、この後実行している、writeRegisterのところで未定義エラーになります。
i2cdevで出てきたものは、BusとAddressで複数個の要素が入ってるから配列なのでしょうか。
普通の数値や文字と違うみたいですが、同じように扱えるのでしょうか。
どう扱ったらいいのかとか、どう質問したらいいのか分からな食て困っています(´Д`)
Atsushi Ueno
Atsushi Ueno le 31 Mar 2023
試していないですが:
おそらくI2C経由で接続するデバイスを示すオブジェクトを重複させる事が出来ないのだと思います。ですからプログラムの作りとしても、アドレスを配列として持っておき、都度オブジェクトを生成してはアクセスする形に変える必要がるのではないかと思います。
PrepI2c = {'0x10','0x11','0x12','0x40','0x41','0x42','0x60','0x61'};
for num = 1:numel(BoardAll)
i2cdevice = i2cdev(mypi,'i2c-1',PrepI2c{num}); % i2cdeviceは保存しない
output2 = readRegister(i2cdevice,0)
end
mayu
mayu le 5 Avr 2023
uenoさま
お礼おそくなりすみません、
分からなかったので、お返事いただいた内容を周りの人にも見てもらってようやく把握できました💦
いつもお忙しいところありがとうございます。

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur アプリの作成 dans Centre d'aide et File Exchange

Produits

Version

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!