0

私のバックグラウンドはCではなく(Real Studioにあります-VBに似ています)、低レベルの文字列処理に慣れていないため、コンマ区切りの文字列を分割するのに本当に苦労しています。

シリアル経由でArduinoに文字列を送信しています。これらの文字列は、特定の形式のコマンドです。例えば:

@20,2000,5!
@10,423,0!

「@」は新しいコマンドを示すヘッダーであり、「!」コマンドの終了を示す終了フッターです。'@'の後の最初の整数はコマンドIDであり、残りの整数はデータです(データとして渡される整数の数は、0〜10の整数のどこでもかまいません)。

コマンド(「@」と「!」を取り除いたもの)を取得し、処理するコマンドがあるときに呼び出される関数を呼び出すスケッチを作成しましたhandleCommand()。問題は、このコマンドを分割して処理する方法が本当にわからないことです。

スケッチコードは次のとおりです。

String command; // a string to hold the incoming command
boolean commandReceived = false; // whether the command has been received in full

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // main loop
  handleCommand();
}

void serialEvent(){
  while (Serial.available()) {
  // all we do is construct the incoming command to be handled in the main loop

    // get the incoming byte from the serial stream
    char incomingByte = (char)Serial.read();

    if (incomingByte == '!')
    {
       // marks the end of a command
       commandReceived = true;
       return;
    }
    else if (incomingByte == '@')
    {
       // marks the start of a new command
       command = "";
       commandReceived = false;
       return;
    }
    else
    {
      command += incomingByte;
      return;
    }

  }
}

void handleCommand() {

  if (!commandReceived) return; // no command to handle

  // variables to hold the command id and the command data
  int id;
  int data[9];

  // NOT SURE WHAT TO DO HERE!!

  // flag that we've handled the command 
  commandReceived = false;
}

私のPCがArduinoに文字列「@20,2000,5!」を送信するとします。command私のスケッチは「20,2000,5」を含むString変数(と呼ばれる)で終わり、commandRecievedブール変数はTrueに設定されているため、handleCommand()関数が呼び出されます。

(現在は役に立たない)関数でやりたいことhandleCommand()は、20をと呼ばれる変数に割り当てid、2000と5をと呼ばれる整数の配列に割り当てることdataです。data[0] = 2000data[1] = 5

私は読んだことがstrtok()ありますatoi()が、率直に言って、それらとポインターの概念について頭を悩ませることはできません。私のArduinoスケッチも最適化できると確信しています。

4

2 に答える 2

7

ArduinoコアStringタイプを使用しているためstrtok、他のstring.h機能は適切ではありません。代わりに標準のCnullで終了する文字列を使用するようにコードを変更できStringますが、Arduinoを使用すると、ポインターを使用せずにこれを実行できることに注意してください。

StringタイプはあなたindexOfとを与えsubstringます。

@とが削除された文字列を想定すると、!コマンドと引数を見つけると次のようになります。

// given: String command
int data[MAX_ARGS];
int numArgs = 0;

int beginIdx = 0;
int idx = command.indexOf(",");

String arg;
char charBuffer[16];

while (idx != -1)
{
    arg = command.substring(beginIdx, idx);
    arg.toCharArray(charBuffer, 16);

    // add error handling for atoi:
    data[numArgs++] = atoi(charBuffer);
    beginIdx = idx + 1;
    idx = command.indexOf(",", beginIdx);
}

data[numArgs++] = command.substring(beginIdx);

dataこれにより、のコマンド番号を含む配列内のコマンド全体が得られますがdata[0]、引数のみをに含めるように指定した場合もありますdata。ただし、必要な変更は軽微です。

于 2012-08-11T15:58:47.833 に答える
-1

動作しているようですが、バグがある可能性があります:

#include<stdio.h>
#include <string.h>

int main(){
char string[]="20,2000,5";
int a,b,c;
sscanf(string,"%i,%i,%i",&a,&b,&c);
printf("%i %i %i\n",a,b,c);
a=b=c=0;
a=atoi(strtok(string,","));
b=atoi(strtok(0,","));
c=atoi(strtok(0,","));
printf("%i %i %i\n",a,b,c);

return 0;
}
于 2012-08-11T15:54:41.007 に答える