Arduino(C言語)区切り文字付きの文字列の解析(シリアルインターフェイスを介した入力)
ここで答えが見つかりませんでした:/
シリアルインターフェイス(Serial.read())を介してarduinoに、コンマで区切られた3つの数値の単純な文字列を送信したいと思います。これらの3つの数値は、0〜255の範囲にすることができます。
例えば。 255,255,255
0,0,0
1,20,100
90,200,3
Arduinoに送信されたこの文字列を3つの整数(r、g、bとしましょう)に解析する必要があります。
だから私が100、50、30を送るとき、arduinoはそれを
int r = 100
int g = 50
int b = 30
私はたくさんのコードを試しましたが、どれもうまくいきませんでした。主な問題は、文字列(文字の束)を整数に変換することです。区切り文字の目的でstrtok_rが存在することを理解しましたが、それで終わりです。
提案をありがとう:)
あなたが実際に尋ねた質問に答えるために、文字列オブジェクトは非常に強力であり、あなたが尋ねたことを正確に行うことができます。入力から直接解析ルールを制限すると、コードの柔軟性が低下し、再利用性が低下し、少し複雑になります。
文字列には、indexOf()と呼ばれるメソッドがあり、特定の文字の文字列の文字配列でインデックスを検索できます。文字が見つからない場合、メソッドは-1を返します。 2番目のパラメーターを関数呼び出しに追加して、検索の開始点を示すことができます。あなたの場合、区切り文字はコンマなので、次のように呼び出します。
int commaIndex = myString.indexOf(',');
// Search for the next comma just after the first
int secondCommaIndex = myString.indexOf(',', commaIndex + 1);
次に、そのインデックスを使用して、Stringクラスのsubstring()メソッドを使用してサブストリングを作成できます。これは、特定の開始インデックスで始まり、2番目のインデックス(または、何も指定されていない場合はファイルの最後)の直前で終わる新しい文字列を返します。したがって、次のようなものを入力します。
String firstValue = myString.substring(0, commaIndex);
String secondValue = myString.substring(commaIndex + 1, secondCommaIndex);
String thirdValue = myString.substring(secondCommaIndex + 1); // To the end of the string
最後に、整数値は、Stringクラスの文書化されていないメソッドtoInt()を使用して取得できます。
int r = firstValue.toInt();
int g = secondValue.toInt();
int b = thirdValue.toInt();
Stringオブジェクトとそのさまざまなメソッドの詳細については、 Arduinoのドキュメント を参照してください。
sscanf
を使用します。
const char *str = "1,20,100"; // assume this string is result read from serial
int r, g, b;
if (sscanf(str, "%d,%d,%d", &r, &g, &b) == 3) {
// do something with r, g, b
}
文字列のストリームを解析する場合は、ここに私のコードを使用しますex:255,255,255 0,0,0 1,20,100 90,200,3
コンマ区切り文字列の解析関数
これは素晴らしい!
"thirdvalue = 0"に関する最後のコメントは、@ dsnettletonによって最も支持された応答で与えられたコードから当てはまります。ただし、「lastIndexOf( '、');」を使用する代わりに、@ dsnettletonがcommaIndex + 1に対して正しく行ったように、コードは「secondCommaIndex」に「+1」を追加するだけです(+1がない場合は、おそらくその人のタイプミスです)。
ここに更新されたコードがあります
int commaIndex = myString.indexOf(',');
int secondCommaIndex = myString.indexOf(',', commaIndex+1);
String firstValue = myString.substring(0, commaIndex);
String secondValue = myString.substring(commaIndex+1, secondCommaIndex);
String thirdValue = myString.substring(secondCommaIndex+1); //To the end of the string
例)
MyString = "1,2,3"の場合
注:INDEXと文字列のLENGTHを混同しないでください。文字列の長さは5です。StringindexOfは0から始まるため、最後のインデックスは4です。
ちょうど理由
String thirdValue = myString.substring(secondCommaIndex);
.toInt()を使用すると0が返されます。これは、thirdValue = "、3"であり、 "3"ではなく、toInt()を台無しにするためです。
ps。申し訳ありませんがすべての手順を書き出していますが、メカとして、特に過去7年間コンサルティングに携わってきた誰かにコードを教えてもらいたい場合があります。今後ともよろしくお願いいたします。私のような人をたくさん助けてくれます!
最も簡単なのは、このタスクを実行するためにparseInt()
を使用することだと思います。
void loop(){
if (Serial.available() > 0){
int r = Serial.parseInt();
int g = Serial.parseInt();
int b = Serial.parseInt();
}
}
トリックを行います。
データを読み取るには、次のようなことをしたいと思います。
String serialDataIn;
String data[3];
int counter;
int inbyte;
void setup(){
Serial.begin(9600);
counter = 0;
serialDataIn = String("");
}
void loop()
{
if(serial.available){
inbyte = Serial.read();
if(inbyte >= '0' & inbyte <= '9')
serialDataIn += inbyte;
if (inbyte == ','){ // Handle delimiter
data[counter] = String(serialDataIn);
serialDataIn = String("");
counter = counter + 1;
}
if(inbyte == '\r'){ // end of line
handle end of line a do something with data
}
}
}
次に、atoi()を使用してデータを整数に変換し、使用します。
文字列で区切られたn番号の場合
int end;
while((end=str.indexOf(","))!=-1){
String num = str.substring(0,end);
str= asc.substring(end+1,str.length());
Serial.println(num);
}