4

私は Web 制御のローバーに取り組んでおり、シリアル ポートを使用してArduinoと通信しています。fwrite()ASCII 1 または ASCII 2 を使用してシリアルポートに書き込む PHP をいくつか書きました。Arduino はそのポートをリッスンしており、聞いたことに基づいて処理を行います。PHP に何かを送信するように指示すると、Arduino はそれを受信するので、PHP が機能していることはわかっています。Arduinoコードは次のとおりです。

//This listens to the serial port (USB) and does stuff based on what it is hearing.

int motor1Pin = 13; //the first motor's port number
int motor2Pin = 12; //the second motor's port number
int usbnumber = 0; //this variable holds what we are currently reading from serial


void setup() { //call this once at the beginning
    pinMode(motor1Pin, OUTPUT);
    //Tell arduino that the motor pins are going to be outputs
    pinMode(motor2Pin, OUTPUT);
    Serial.begin(9600); //start up serial port
}

void loop() { //main loop
    if (Serial.available() > 0) { //if there is anything on the serial port, read it
        usbnumber = Serial.read(); //store it in the usbnumber variable
    }

    if (usbnumber > 0) { //if we read something
        if (usbnumber = 49){
          delay(1000);
          digitalWrite(motor1Pin, LOW);
          digitalWrite(motor2Pin, LOW); //if we read an ASCII 1, stop
        }

        if (usbnumber = 50){
              delay(1000);
              digitalWrite(motor1Pin, HIGH);
              digitalWrite(motor2Pin, HIGH); //if we read an ASCII 2, drive forward
        }

        usbnumber = 0; //reset
    }
}

したがって、これはかなり簡単なはずです。現在、ASCII 1 または ASCII 2 を送信すると、(ピン 13 で) テストしている LED がオンになり、オンのままになります。しかし、別の ASCII 1 または 2 を送信すると、オフになってからオンに戻ります。目標は、ASCII 1 が最後に送信された場合にのみオンにし、最後に 2 が送信されるまでオンのままにすることです。

編集:ここに私のPHPがあります:

<?php
    $verz="0.0.2";
    $comPort = "com3"; /*change to correct com port */

    if (isset($_POST["rcmd"])) {
        $rcmd = $_POST["rcmd"];
        switch ($rcmd) {
            case Stop:
                $fp =fopen($comPort, "w");
                fwrite($fp, chr(1)); /* this is the number that it will write */
                fclose($fp);


                break;
            case Go:
                $fp =fopen($comPort, "w");
                fwrite($fp, chr(2)); /* this is the number that it will write */
                fclose($fp);
                break;
            default:
                die('???');
        }
    }
?>
<html>
    <head><title>Rover Control</title></head>
    <body>
        <center><h1>Rover Control</h1><b>Version <?php echo $verz; ?></b></center>

        <form method="post" action="<?php echo $PHP_SELF;?>">
            <table border="0">
                <tr>
                    <td></td>
                    <td>

                    </td>
                    <td></td>
                </tr>
                <tr>
                    <td>
                        <input type="submit" value="Stop" name="rcmd"><br/>
                    </td>
                    <td></td>
                    <td>
                        <input type="submit" value="Go" name="rcmd"><br />
                    </td>
                </tr>
                <tr>
                    <td></td>
                    <td><br><br><br><br><br>

                    </td>
                    <td></td>
                </tr>
            </table>
        </form>
    </body>
</html>
4

4 に答える 4

1

C の場合、両方のテストで比較の代わりに代入があるため、両方がであるため、すべての書き込みが毎回行われます。高い警告レベルでコンパイルします ( GCC のように)。これを試して:true-Wall -pedantic


int a = 0;
if ( a == 1 ) printf( "a is not one: %d\n", a );
if ( a = 1 ) printf( "a is one: %d\n", a );

あなたが投稿したPHPコードから(私はここの専門家ではありません)、バイナリ1をcharとして書いているようです。これはASCII 49ではなく、ASCII 1(soh)で、2と同じです。PHP'1'コードでに変更してみてください(または1C コードで。)

PHPでシリアルポートを制御するに関する記事へのリンクがあります-私はグーグルで調べましたが、その品質についてはわかりません-しかし、「com1」に整数を書き込むだけでは十分ではないようです-それは私のドメイン外ですので、頑張ってください:)

于 2009-05-22T18:05:32.580 に答える
1

Nikolai が述べたように、「if」ステートメントで比較 (==) ではなく代入 (=) を行っているようです。

一部の C プログラマーが取り入れている良い習慣は、右辺値を比較の左側に置くことです。これにより、誤って比較演算子の代わりに代入演算子を使用した場合にコンパイラーがエラーを生成します。

if (50 == usbnumber) { // これでいい。
    ...
}

if (50 = usbnumber) { // コンパイラはここでエラーを生成します。
    ...
}

右辺値への割り当ては違法であるため、使用しているコンパイラフラグや警告レベルに関係なく、これは機能します。

2 つの左辺値を比較する必要がある場合、この「セーフティ ネット」は機能しないことを付け加えておきます。

于 2009-05-22T18:16:25.293 に答える
0

私はあなたの答えが他のものを探しているのを見つけました、とにかく私はあなたが持っていたのと同じ問題に直面しました(私は推測します)。

まだ解決していない場合、問題はコードではなく、arduinoボードの自動リセットメカニズムにあると思います。つまり、シリアルポートに新しい接続が設定されるたびに、arduinoボードがリセットされます。これにより、シリアルポートを介してプログラミングするときに新しいファームウェアをロードできます。

これを確認するには、setup()関数でLEDを点滅させてみてください。ページを読み込むたびに点滅する場合は、私の論文を確認できます。

こちらをご覧ください:http ://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

+5VとRESETの間に120オームの抵抗を貼り付けることで解決しました。ボードに新しいファームウェアをアップロードするたびに、忘れずに削除してください。

于 2012-01-02T03:26:58.433 に答える
0

手遅れかもしれませんが、 serial.read()が一度に 1 文字しか読み取れないことが問題だと思います。PC から "49" を送信した場合、usbnumber = serial.read()を呼び出すと、最初のループで "4" が、2 番目のループで "9" が返されます。これらのいずれも条件を満たさないため、何も行われず、usbnumber は 0 にリセットされます。

修正するには、serial.available 条件を次のように変更します。

if (Serial.available() == 2)

次に、次のようにして数値に変換します。

usbnumber = Serial.read() * 10 + Serial.read();

もう 1 つのオプションは、TextFinder ライブラリを使用することです。私は自分の Web サイトhttp://mechariusprojects.com/thunderbolt/?p=60に簡単なチュートリアルを書きました。

メカ

于 2010-12-03T04:18:00.727 に答える