要素数は足りてるはずなのに「行列のインデックスは削除の範囲外です。」のエラーが出る。
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
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
原因がわかる方いらっしゃいましたら、ご教示いただけますと幸いです。
お忙しいところすみませんが、どうぞよろしくお願いいたします。
採用された回答
Atsushi Ueno
2023 年 3 月 29 日
0 投票

12 件のコメント
Atsushi Ueno
2023 年 3 月 29 日
BoardAll(num)= [];
上記はベクトル(配列)の要素を空の値にする意味ではなく、要素そのものを削除しベクトル(配列)の長さを縮めてしまいます。従って長さ8のベクトル(配列)は、上記を4回実行した(可能だった)時点で長さが4に減っており、5回目でとうとう削除する要素が無くなってしまい、当該エラーが出ています。
uenoさま。お忙しいところ、いつも(しかも図つきですごくわかりやすくしていただいて)ありがとうございます!
そういうことなのですね((+_+))
ループの最後に、disp(BoardAll); を追加してブレイクポイント置きながら確認してみたら、確かにおっしゃるとおりのことになっていました。。。
全然気が付いていませんでした。ありがとうございます。
= []; が空に使えないということで、ほかの書き方ありますでしょうか。。
= 0; にしたらdouble型といわれたからダメみたいでした💦
もしご存じであればご教示いただけますと幸いですm(__)m
どうぞよろしくお願いいたします。
Atsushi Ueno
2023 年 3 月 29 日
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
2023 年 3 月 29 日
度々ありがとうございます!
書いていただいている、セル配列の要素を設定する方法の1と2それぞれ当てはめてみて、
BoardAll(num)= [];
と書いていた箇所を、
▼方法1)
BoardAll(num)= {};
と書くと

「左辺と右辺の要素数が異なるため、代入を実行できません。」
となるのですが、左か右の要素が複数あるということなのでしょうか❓
BoardAll(num)= {5};
のように具体的な数値を入れたらエラーが出ませんでした。
▼方法2
BoardAll{num}= [];
と書いたら特にエラーは出ませんでしたが、これで空要素を入れられたということでしょうか…
とりあえずこれで実際のコードにいれて確認してみようと思います。
ありがとうございました( ◠‿◠ )
Atsushi Ueno
2023 年 3 月 29 日
ベクトルや行列と 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]}
Atsushi Ueno
2023 年 3 月 29 日
{[]}と{}は異なります
- {[]}:cell 配列要素の中身が空配列
- {} :空のcell配列
本当に何度も親切に例を書いてくださって、ありがとうございます!
マトラボのヘルプのcell配列の説明は見たものの、書いてる意味がわからなかったり、今自分が悩んでいるのの答えがどこに書いてるのか分からなくて結局ここに質問にきてしまいます(´・_・`)
いただいた例文を眺めていて、とりあえずcell配列の中身をどうにかしたい場合には、{}を使うのは分かった気がするのですが、身につくまでいってないので分からなくなったら見返そうと思います。ありがとうございました。
それですみませんもしご存じであればもう1点ご質問が・・・(*_*;
上記関数内の右辺の部分を、ラズパイ~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
2023 年 3 月 30 日

またまたわかりやすい図を作成していただき、ありがとうございます!
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
2023 年 3 月 31 日
試していないですが:
おそらく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
2023 年 4 月 5 日
uenoさま
お礼おそくなりすみません、
分からなかったので、お返事いただいた内容を周りの人にも見てもらってようやく把握できました💦
いつもお忙しいところありがとうございます。
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で cell 配列 についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)