2016-04-15 15 views
0

私はゲーム「Assetto Corsa」から車の速度でArduino Servoを作動させようとしていました。私は共有メモリを使用してゲームからライブデータを抽出し、シリアルポート経由でArduinoに送信しようとしています。文字列から情報を抽出する

私はまだサーボの車の実際の速度を表現することはできませんでしたが、なぜそれなら不思議です。私はかなり問題がArduinoコードから来ると確信しています、私は車の速度を抽出することができますが、私はそれを正しく使用する方法がわかりません。多分あなたは助けることができますか?

これは、Arduinoのコードの抜粋です:

char inData[8];  
char inChar; // Where to store the character read 
byte index = 0; // Index into array; where to store the character 
int angle = 0; 
int newAngle = 0; 
int MaxChars = sizeof(inData); 
char ch; 


     while (Serial.available()) 
     { 
     char ch = Serial.read(); 
     Serial.write(ch); 
     if (index < MaxChars && isDigit(ch)) 
     { 
      inData[index++] = ch; 
     } 
     else 
     { 
      inData[index] = 0; 
      newAngle = atoi(inData); 
      Serial.write(newAngle); 
      if (newAngle > 0 && newAngle < 180) 
      { 
      if (newAngle < angle) 
       for (; angle > newAngle; angle -= 1) 
       { 
       myServo.write(angle); 
       } 
      else 
       for (; angle < newAngle; angle += 1) 
       { 
       myServo.write(angle); 
       } 
      } 
      index = 0; 
      angle = newAngle; 
      delay(1000); 
     } 
     } 

そして、これは私がゲームから情報を抽出し、アルドゥイーノに送信するために使用していたコードです:

while (true) 
{ 

    snprintf(Data, sizeof(Data)-1, "%3.3f", pf->speedKmh); 

    SP->WriteData(Data, sizeof(Data));    

    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 

    int readResult = SP->ReadData(inData, sizeof(inData)); 

     printf("\t Bytes read: %i\n",readResult); 

     for (int i = 0; i < sizeof(inData); i++) 
     { 
      printf("%i", inData[i]); 
      inData[i] = 0; 
     } 
} 

Output screenshot1

からのエコーのスクリーンショットです。
Serial.write(NewAngle); 

私は車の速度を黄色で概説しました。私の質問は:Arduino Servoで使用するために受け取ったデータからこの速度をどのように抽出するのですか?

ありがとうございました!

---------- ---------- UPDATE

それは働きます!どうもありがとう、これは私が変更したものです:

snprintf(Data, sizeof(Data)-1, "%3.3f", (int)(pf->speedKmh)*1.0); 

スピードをintにキャストし、1.0倍しました。それはトリックをしたようだ! 「それがなぜ機能しないのかわからない、何かを変える、それがなぜ機能するのかわからない」という別のケースです。

+0

'inData'の内容は何ですか? newAngleのタイプと価値は何ですか?期待される出力は何ですか(実際の出力をイメージとしてテキストとしてコピーして貼り付けてください)。 –

+0

@JoachimPileborg 'inData'は何を受け取るのですか ' WriteData' 送信します。これに使用されるライブラリは、[ここ](http://playground.arduino.cc/Interfacing/CPPWindows)にあります。 Arduinoコードの変数宣言を含めるために投稿を編集しました。 テキスト出力を取得する方法が不明なので、スクリーンショットを撮ったのです:/ – Frazic

+0

データを抽出するために使用した共有メモリライブラリ[ここ](http://www.assettocorsa.net/forum) /index.php?threads/shared-memory-reference-31-03-2016.3352/) – Frazic

答えて

2

主な問題は、これらの短い「メッセージ」(単なる数字)にはフレーミングがないことです。 2つのシステムの時間が同期していないため、遅延またはスリープはフレーミングとみなされません。

数字の間に改行を入れて、ある数字の終わりと次の数字の始まりを知ることができます。 2つのシステムで '\ n'の違いを注意してください... (char)10または(char)13を明示的に送信して、受信者の同じバイトを監視することができます。キャラクターがドロップされた場合、フレーミングによってメッセージの境界に再同期することができます。これにより、Arduino側のdelayを取り除くこともできます。これは非常に良いことです。

潜在的な問題はここにある:

if (index < MaxChars&& isDigit(ch)) 
{ 
    inData[index++] = ch; 
} 
else 
{ 
    inData[index] = 0; 

あなたはNUL終端のための1つ以上のcharを追加するためのテストがindex < MaxChars-1する必要があります。

受信したバイトをxboxにプリントするときは、配列要素の間に区切り文字を入れてください。printf("%i,",inData[i])見ている数字は、2と3、23、または238です。

私はマイナーチェンジを提案します:浮動小数点値を送信していますが、受信した文字列を(非数字で停止した後に)atoiの整数に変換しています。次回のループでは、あなたがまだ読んでいない文字を取得します。あなたは整数として値を送るかもしれません:(int)(speed*100.0)。これにより、2つの他の問題も回避されます。%f3.3は、速度< 100.0(Arduinoはこれらを検索しません)のときにスペースで埋められます。速度の小数部分が切り捨てられます。

+0

index OPはゼロターミネータを読み取ろうとしていないので、MaxCharsはOKと思われます。ちょうど数字を読み取っていて、引用した最後の行にターミネータを追加しています。 –

+0

フレーミングに関しては、あなたが正しいです。私はさらに進んで、数字を '<' and '>'文字の間に入れて、枠に入れられていないものは無視します。 –

+0

こんにちは!答えをありがとう!私はすべてを理解していませんでしたが、少し助けてくれます^^。スピードを表す数字だけを保持するためにArduinoに到着したら、文字列を「分解する」方法についてのヒントはありますか? – Frazic

関連する問題