
シリアル通信で得たデータを二次元配列へ格納するために、
以前では、
if(Serial.available()>120){
for(int k=0;k<8;k++){
for(int l=0;l<15;l++){
//読み込んだ値を配列に代入
matrix[k][l]=Serial.read();
}
}
}
このようなやり方で読み込んだ値を二次元配列に代入していたのですが、
128個以上のデータを扱いたい場合、Serial.availableでは保持できず、困っています。
方法として、
(1)一つずつデータを読み込み、128回ループを繰り返し配列に貯めていく。その後配列を2次元配列に代入する。
(2)一つデータを読みこんだら二次元配列の1行目1列目のドットに格納、もう一つデータを読みこんだら二次元配列の1行目2列目のドットに格納…というように、
読みこんだデータをそのまま二次元配列のそれぞれの場所へ格納していく。
というような二つの方法を思いついたのですが、
(1)の方法では、配列にデータを貯蓄していくコードをこのように↓書いたのですがうまくいかず、
for(int i=0;i<128;i++){
if(Serial.available()>0){
data[128] = Serial.read();
}
}
(2)の方法では、データを二次元配列のそれぞれの場所へ格納していく指定方法が分かりませんでした。
正しい書き方や、良いアイデアをお持ちの方がいましたら、是非御教授お願いします。
No.3ベストアンサー
- 回答日時:
とりあえず、
データ読み込みの方の
> if (Serial.available() > 0) {
これを、
> while (Serial.available() > 0) {
にすれば改善されるかと思います。
現状のコードでは、「1バイト受け取ってデータ更新」→「1画面表示」の繰り返しになっているので、
1ドットずつ表示が順次切り替わっているように見えてしまうわけです。
それを、「受け取り済みのデータをすべて更新」→「1画面表示」するように変えるわけです。
No.2
- 回答日時:
No.1のものです。
参考ページを見ました。この場合、LEDの点灯制御を常時行う必要がありますから、No1の回答の後者の方法じゃないとダメですね。
data[][] へのデータ読み込みは、どういう順番で行けばいいかをまず考えてください。
data[0][0] = Serai.read();
data[0][1] = Serai.read();
…
data[0][13] = Serai.read();
data[0][14] = Serai.read();
data[1][0] = Serai.read();
data[1][1] = Serai.read();
…
data[1][13] = Serai.read();
data[1][14] = Serai.read();
data[2][0] = Serai.read();
…
…
data[7][13] = Serai.read();
data[7][14] = Serai.read();
以上で120個のデータ読み込み完了です。次はまた
data[0][0] = Serai.read();
data[0][1] = Serai.read();
と、最初に戻ることになります。
これを、変数kと変数lを使って
---
data[k][l] = Serai.read();
---
で読み込んでいるわけです。
ではあるデータを読み込んだあと、次の読み込み保存先はどうなるかを考えると、
・l は毎回1足す。(k=0,l=0:data[0][0]の次はk=0,l=1:data[0][1]、k=0,l=1:data[0][1]の次はk=0,l=2:data[0][2]、…のように、lは1増える)
ただし、l=14の次は、15ではなくl=0。14→0にしたときはkを1足す必要がある。(k=0,l=14:data[0][14]の次はk=1,l=0:data[1][0]、k=1,l=14:data[1][14]の次はk=2,l=0:data[2][0]、…のように、lは0に戻る)
・lを14→0にした時は、k に1を足す。(k=0,l=14:data[0][14]の次はk=1,l=0:data[1][0]、k=1,l=14:data[1][14]の次はk=2,l=0:data[2][0] のように、kは1増える)
ただし、k=7の次は、k=8ではなく、最初に戻ってk=0(k=7,l=14:data[7][14]の次は、k=0,l=0:data[0][0])。ここまで来たら120個読み込み完了
ということになります。
これをコードにすると、
---
l++; // lは毎回1足す
if (l == 15) {// ただし、l=14の次は、
l = 0; // 15ではなくl=0に戻す
k++; // そして、lを14→0にした時は、k に1を足す。
if (k == 8) { // ただし、k=7の次は、
k = 0; // 最初に戻ってk=0
// 120のデータを読み終わった。だけど、特別な処理は不要
}
}
}
---
となるわけです。
理解できました。非常に分かりやすいご説明ありがとうございます。
早速試してみましたが、どうやら時間がかかりすぎているようで、映像を出力しているようにみえませんでした。現在このようなコードですが↓一ドットずつ順番に次の明るさに変化していくのが目に見えて分かる感じです。
byte matrix[8][16];
void setup(){
for(int i=2;i<=25;i++){
pinMode(i,OUTPUT);
digitalWrite(i,LOW);
}
Serial.begin(9600);
}
void loop(){
static int k = 0, l = 0;
if (Serial.available() > 0) {
matrix[k][l] = Serial.read();
l++;
if (l == 16) {
l = 0;
k++;
if (k == 8) {
k = 0;
}
}
}
for(int i=2;i<=9;i++){
digitalWrite(i,HIGH);
for(int j=10;j<=25;j++){
digitalWrite(j,LOW);
delayMicroseconds(1+ matrix[i-2][j-10]);
digitalWrite(j,HIGH);
delayMicroseconds(256-matrix[i-2][j-10]);
}
digitalWrite(i,LOW);
}
}
何か良い方法がないでしょうか…。
No.1
- 回答日時:
2通りの方法を挙げておきます。
かならず120個のデータが届くことがわかっており、受取以外になにもする必要がないのであれば、
---
for(int k=0;k<8;k++){
for(int l=0;l<15;l++){
while (Serial.available()== 0) {
;// データがやって来るまで待つ
}
matrix[k][l]=Serial.read();
}
}
---
でいいでしょう。forループの中で、必要なデータが届くまで必要に応じて待つわけです。
データの受信を途中で打ち切るとか、状況によっては、別の処理も行いたい場合は、
---
void loop() {
static int k = 0, l = 0;
if (Serial.available() > 0) {
data[k][l] = Serial.read();
l++;
if (l == 15) {
l = 0;
k++;
if (k == 8) {
k = 0;
// 120のデータを読み終わったので、ここで必要な処理を行う。
}
}
}
}
---
といった書き方もできます。static 変数にすると、次のloop呼び出しでも変数内容が記憶されたままですので、
forループではなく自前の処理として、何番目を読み込んでいるところなのかを管理できるわけです。
回答ありがとうございます。
説明不足で申し訳ありません。
データは0~255の値が常にシリアル通信で送られてきていて、その値を8×15のLEDマトリクスの明るさの値として使用しています。
(このページに近いことを行っています。→ http://kousaku-kousaku.blogspot.jp/2008/08/ardui … )
forループを使用しない配列の指定を初めて見るので、申し訳ありませんが詳細を伺ってもよろしいでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- Microsoft ASP プログラミング関係で質問です。 3 2022/10/11 16:06
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- Perl perlで2次元配列をサブルーチンに値渡しで渡す 5 2022/12/17 18:49
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- Visual Basic(VBA) VBA横データを縦にしたいです 2 2023/08/08 19:38
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
vba クリップボードクリアにつ...
-
画像生成AIのプロンプトの作り...
-
Pythonのエラーメッセージをコ...
-
Geminiフォーム 画像生成で 人...
-
VBAでパワーシェルを実行したい...
-
pip --versionがエラーになる
-
CSVファイルの複数行削除
-
google Colabでmatplotlibの描...
-
数学、プログラミング、物理、...
-
パイソンのソースコードをChatG...
-
Python 3.12.2 か一番最新のパ...
-
HTMLソースが表示のページのも...
-
pythonの実行に関する質問
-
OS入ってる機器のソフト・アプ...
-
Python... 環境設定 初心者です...
-
以下の技能を無料で受講できる...
-
文系のSE志望です。プログラミ...
-
Google ColaboでGUI作成
-
プログラミングを学ぼうと思い...
-
VBSでテキストファイルの2行目...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Perlでのテキスト処理について
-
PerlでInline Cを使った配列の...
-
[arduino]数値の大きなデータを...
-
逆順ソートのやりかた
-
単純なお問い合わせフォーム
-
配列のソートについて質問です。
-
2次元の配列にデータを格納したい
-
Perlの初歩的な質問・・・
-
配列の中に重複文字列があるか...
-
CSVデータ「","」と「,」混在読...
-
配列について
-
<IN>; を単独で使う
-
Visual C++を用いたシリアル通信
-
数十件あるデータを10件だけ表...
-
perlの無名配列の使い方を教え...
-
データの日付でソートをしたい
-
pandasでまとめてインデックス...
-
頻度表の作成(Perl初心者です)
-
要素を削除する最適な方法
-
数字のソート
おすすめ情報