1

シリアル接続を介してコンピューターから Arduino UNO と通信するプログラムを C# で作成しようとしています。現時点では、Arduino との接続を確立し、arduino の各ピンを制御するためのいくつかのコントロールを確立する単純なアプリケーションを作成しています。そこから値を読み取るか、それに値を書き込みます。

Arduino との接続を確立し、ピンの値を設定することはできましたが、Arduino は常に私のコマンドに従いたいとは限りません。いくつかのチェック ボックスを設定しました。チェック ボックスをオンにすると LED がオンになり、オフにするとオフになります。問題は、LED がオンまたはオフのままになることがあり、ボックスを数回クリックしてから再度応答するか、回路をリセットする必要があることです...

私はいくつかの障害を見つけようとしていましたが、問題の根本にたどり着くことができませんでした:それは私のアプリですか、それとも Arduino コードですか?

これが私のコードの関連部分です:

private void sendValue(int RW, int _Pin, int Val) //send from my app to serial port
{
    if (CommPort.IsOpen)
    {
        CommPort.WriteLine(RW.ToString() + "," + _Pin.ToString() + ","  + Val.ToString());
    }
}

private void chP9_CheckedChanged(object sender, EventArgs e) //call the sendValue routine
{
    if (chP9.Checked)
    {
            sendValue(1, 9, 255); //('Write', to pin 9, 'On')
    }
    else
    {
        sendValue(1, 9, 0); //('Write', to pin 9, 'Off')
    }
}

これは私の C# コードです。コンマ区切りの文字列をコンパイルして、Arduino が読み取るシリアル ポート経由で送信します。

Arduinoコードは次のとおりです。

int RW;    //0 to read pin, 1 to write to pin
int PN;    //Pin number to read or write
int Val;   //Value to write to pin

void setup() {
  Serial.begin(38400);
}

void loop() {
  ReadIncoming();
  ProcessIncoming(); 
}

void ReadIncoming()
{
  if(Serial.available() > 0)
  {
    RW = Serial.parseInt();
    PN = Serial.parseInt();
    Val = Serial.parseInt();
  }
  while(Serial.available() > 0) //Clear the buffer if any data remains after reading
  {
    Serial.read();
  }
}

void ProcessIncoming()
{
  if(RW == 0)
  {
    pinMode(PN, INPUT);
  }
  else
  {
    pinMode(PN, OUTPUT);
    analogWrite(PN, Val);
  }
}

parseInt は、見つけた最初の整数値を取り出して格納し、コンマを破棄して、何度も何度も繰り返しますが、少し直感に反するようです。

私の問題はここにあると思います:

  while(Serial.available() > 0) //Clear the buffer if any data remains after reading
  {
    Serial.read();
  }

特にこのループでは、アプリケーションは Arduino コードが処理できるよりも速くデータを送信していると思いますが、余分なデータはどうすればよいですか?

私は parseInt を使いたくないのですが、私の指示を正しく読む唯一の方法です。C# からバイト配列を送信し、その配列を Arduino の配列に読み込むにはどうすればよいですか?

私は自分の仮説を指摘し、代替案を検討しましたが、解決策を得ることができませんでした. 皆さんは私にどんな提案がありますか?

4

1 に答える 1

3

なぜそれがまったく機能するのか、私にはそれほど明確ではありません。コマンドをエンコードするよりスマートな方法を検討する必要があります。次の 3 バイトだけが必要です。

    private void sendValue(int RW, int _Pin, int Val) {
        var cmd = new byte[] { (byte)RW, (byte)_Pin, (byte)Val };
        ComPort.Write(cmd, 0, cmd.Length);
    }

次に、Arduino 側でこれらの 3 バイトを読み取る必要があります。

void ReadIncoming() {
    if (Serial.available() >= 3) {
        RW = Serial.read();
        PN = Serial.read();
        Val = Serial.read();
        ProcessIncoming();
    }
}
于 2013-10-05T01:32:07.200 に答える