質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

解決済

【Arduino】 ネストされた構造体変数へ意図しない代入がされる

yuusakuri
yuusakuri

総合スコア6

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

2回答

0リアクション

0クリップ

325閲覧

投稿2022/08/29 14:05

編集2022/08/29 14:11

前提

ArduinoとM5StickCを使っています。ターミナルとはBluetooth接続です。
ターミナルからのコマンドを解析し、設定を付与した上で処理するプログラムを書いています。問題があるのはコマンドを解析するプログラムです。

実現したいこと

ターミナルから受け取った文字列をスペースによって分割し、予め定義してある構造体に入れるようプログラムしたいです。
しかし、for文内のコメントの箇所にて構造体変数に意図しない代入がされます。
ターミナルからst 1111111と送信すると、構造体変数のコマンド名の部分には最終的に、stが入って欲しいのですが、パラメータ値の1111111が代入されます。
パラメータは、コマンド名 -パラメータ名 パラメータ値でも、コマンド名 7桁の数字でも、両方で動作してほしいので、少々回りくどい書き方のプログラムです。

該当のソースコード

arduino

#include <M5StickC.h> #include <BluetoothSerial.h> #include "utility/MPU6886.h" #define logout SerialBT.println(__LINE__) // BT BluetoothSerial SerialBT; uint64_t chipid; char chipname[256] = "m5hoge"; // flags byte commandStatusCode = 0; // パラメータ名, パラメータ値を持ちます struct m5CommandParam { String name, value; }; // コマンド名とパラメータセット(パラメータ名, パラメータ値)を持ちます struct m5Command { String name; struct m5CommandParam params[20]; int paramsCount = 0; }; // コマンドを解析し、引数のm5Commandに解析されたコマンドのデータをセットします。 void parseCommand(String receivedString, struct m5Command *parsedCommand) { int splitedReceivedStringCount = 0; String splitedReceivedString[20]; receivedString.trim(); if (receivedString.length() < 0) { // 受け取ったコマンドが空だった場合 commandStatusCode = 1; return; } while (receivedString.length() > 0) { int spaceIndex = receivedString.indexOf(' '); splitedReceivedStringCount++; if (spaceIndex == -1) // No space found { splitedReceivedString[splitedReceivedStringCount - 1] = receivedString; break; } else { splitedReceivedString[splitedReceivedStringCount - 1] = receivedString.substring(0, spaceIndex); receivedString = receivedString.substring(spaceIndex + 1); } } if (useShortCommand) { bool is7digit = splitedReceivedString[1].length() == 7; if (!is7digit) { SerialBT.println("!is7digit"); commandStatusCode = 2; return; } splitedReceivedStringCount++; splitedReceivedString[splitedReceivedStringCount - 1] = "-Delay"; splitedReceivedString[splitedReceivedStringCount++] = splitedReceivedString[1].substring(0, 3); splitedReceivedString[splitedReceivedStringCount++] = "-ShouldGetAccelAdc"; splitedReceivedString[splitedReceivedStringCount++] = splitedReceivedString[1][3]; splitedReceivedString[splitedReceivedStringCount++] = "-Afs"; splitedReceivedString[splitedReceivedStringCount++] = splitedReceivedString[1][4]; splitedReceivedString[splitedReceivedStringCount++] = "-ShouldGetGyroAdc"; splitedReceivedString[splitedReceivedStringCount++] = splitedReceivedString[1][5]; splitedReceivedString[splitedReceivedStringCount++] = "-Gfs"; splitedReceivedString[splitedReceivedStringCount++] = splitedReceivedString[1][6]; } // 空白によって区切られた文字列をm5Commandに変換する parsedCommand->name = splitedReceivedString[0]; // この時点でparsedCommand->nameは'st' // todo: debug SerialBT.printf("Debug: Line: '"); logout; SerialBT.printf("parsedCommand.name: '"); SerialBT.print(parsedCommand->name); SerialBT.printf("'"); SerialBT.println(""); for (int i = 1; i < splitedReceivedStringCount; i++) { // todo: debug SerialBT.printf("Debug: Line: '"); logout; SerialBT.printf("i: '"); SerialBT.print(i); SerialBT.printf("', "); SerialBT.printf("parsedCommand.name: '"); SerialBT.print(parsedCommand->name);//ここではstと出力される SerialBT.printf("'"); SerialBT.println(""); bool isParamName = splitedReceivedString[i][0] == '-'; if (isParamName) { parsedCommand->paramsCount++; parsedCommand->params[parsedCommand->paramsCount - 1].name = splitedReceivedString[i]; } else { parsedCommand->params[parsedCommand->paramsCount - 1].value = splitedReceivedString[i]; //問題のか所。この行を消すとparsedCommand->nameは'st'のままだが、残すとi:1の際にparsedCommand->nameが1111111となる。 } } // todo: debug SerialBT.printf("Debug: Line: '"); logout; SerialBT.printf("parsedCommand.name: '"); SerialBT.print(parsedCommand->name); // ここで1111111と出力されるが、stと出力されるのを想定している。 SerialBT.printf("'"); SerialBT.println(""); SerialBT.printf("parsedCommand.paramsCount: '"); SerialBT.print((String)parsedCommand->paramsCount); SerialBT.printf("'"); SerialBT.println(""); } // シリアルから送られてきたコマンドを実行する void executeCommandFromSerial() { if (SerialBT.available() > 0) { // バッファにデータがある場合 receivedFromTerminal = SerialBT.readStringUntil('\r'); // ターミナルから送信された文字列をCRの手前まで取得 SerialBT.println(receivedFromTerminal); if (receivedFromTerminal.isEmpty()) { SerialBT.println("isEmpty"); // todo: remove commandStatusCode = 1; return; } // コマンドを解析する struct m5Command parsedCommand; parseCommand(receivedFromTerminal, &parsedCommand); } } void setup() { // M5 M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.fillScreen(BLACK); M5.Lcd.printf("Bluetooth: %s\n", chipname); sensorInit(); //BT chipid = ESP.getEfuseMac(); SerialBT.begin(chipname); SerialBT.setTimeout(10 * 1000); } void loop() { executeCommandFromSerial(); }

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

nac_tnk

2022/08/31 00:54

実際の所、 SerialBT.print((String)parsedCommand->paramsCount); は幾つだったの?

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。