Arduinoのシリアル読み取り
-
23-08-2019 - |
質問
私は Web 制御のローバーで作業しており、シリアル ポートを使用してローバーと通信しています。 Arduino. 。私はちょうど使用するいくつかの PHP を書きました fwrite()
そして、ASCII 1 または ASCII 2 をシリアル ポートに書き込みます。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 を送信すると、テストしている LED (ピン 13 上) が点灯し、点灯したままになります。しかし、別の 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>
解決
C の場合は次のとおりです。 割り当て の代わりに 比較 どちらのテストでも、両方とも true
, したがって、すべての書き込みは毎回行われます。高い警告レベルでコンパイルします (例: -Wall -pedantic
GCC では)。これを試して:
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を文字として書いているようです。これはASCII 49ではなく、ASCII 1(soh)であり、2も同様です。に変更してみてください '1'
PHP コード内 (または 1
C コードで。)
ここにいくつかの記事へのリンクがあります PHPによるシリアルポートの制御 - グーグルで調べましたが、その品質についてはわかりませんでした - しかし、「com1」に整数を書き込むだけでは十分ではないようです - それは私の領域外ですので、頑張ってください:)
他のヒント
Nikolai が述べたように、「if」ステートメントでは比較 (==) ではなく代入 (=) を実行しているようです。
一部の C プログラマが身につける良い習慣は、比較演算子の左側に右辺値を配置することです。これにより、誤って比較演算子の代わりに代入演算子を使用した場合にコンパイラがエラーを生成します。
if (50 == usbnumber) { // This is okay. ... } if (50 = usbnumber) { // The compiler will generate an error here. ... }
これは、右辺値への代入が不正であるため、使用しているコンパイラ フラグや警告レベルに関係なく機能します。
2 つの左辺値を比較する必要がある場合、この「セーフティ ネット」は機能しないことを付け加えておきます。
手遅れかもしれませんが、あなたの問題は次のとおりだと思います シリアル.読み取り() 一度に 1 文字だけを読み取ります。パソコンから「49」を送信すると、電話をかけるときに usb番号 = シリアル.読み取り() 最初のループでは「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
メカ
他のものを探していてあなたの答えを見つけました。とにかく、私はあなたが抱えていたのと同じ問題に直面した(おそらく)。
まだ解決していない場合は、問題はコードではなく、Arduino ボード上の自動リセット メカニズムにあると思います。あれは:シリアル ポート上で新しい接続が設定されるたびに、Arduino ボードがリセットされ、シリアル ポート経由でプログラミングするときに新しいファームウェアをロードできるようになります。
これを確認するには、デバイスの LED を点滅させてみてください。 setup()
ページをロードするたびに関数が点滅する場合、これは私の仮説を裏付けています。
ここを見てください: http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection
+5VとRESETの間に120オームの抵抗を接続することで解決しました。新しいファームウェアをボードにアップロードするときは必ず削除してください。