Arduino串口读取

发布于 2024-07-21 05:30:32 字数 3593 浏览 4 评论 0原文

我正在开发一个网络控制的流动站,并使用串行端口与 Arduino 进行通信。 我编写了一些仅使用 fwrite() 并将 ASCII 1 或 ASCII 2 写入串行端口的 PHP。 Arduino 正在监听该端口并根据它听到的内容执行操作。 我知道我的 PHP 正在工作,因为每当我告诉它发送东西时,Arduino 都会收到它。 这是 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>

I am working on a web controlled rover and am using a serial port to communicate with an Arduino. I wrote some PHP that just uses fwrite() and writes an ASCII 1 or an ASCII 2 to the serial port. The Arduino is listening to that port and does stuff based on what it hears. I know my PHP is working, because whenever I tell it to send stuff, the Arduino does receive it. Here is the Arduino code:

//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
    }
}

So this should be fairly straight forward. Right now, when I send either an ASCII 1 or an ASCII 2, the LED I am testing with (on pin 13) turns on and stays on. But, if I send another ASCII 1 or 2, it turns off and then turns back on. The goal is to have it turn on only if an ASCII 1 was the last thing sent and to stay on until a 2 was the last thing sent.

Edit: Here's my 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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

却一份温柔 2024-07-28 05:30:32

如果是 C,那么在两个测试中您都会进行赋值,而不是比较,因此两者都是true,因此每次都会完成所有写入。 使用高警告级别进行编译(如 GCC 中的 -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写为字符,这不是ASCII 49,而是ASCII 1(所以),与2相同。尝试将其更改为PHP 代码中的 '1'(或 C 代码中的 1)。

这是关于 用 PHP 控制串口 - 我用谷歌搜索,不知道它的质量 - 但看起来仅仅将一个整数写入“ com1” - 这超出了我的领域,祝你好运:)

If it's C then you have assignment instead of comparison in both tests, so both are true, so all writes are done every time. Compile with high warning level (like -Wall -pedantic in GCC). Try this:


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

From PHP code you posted (I'm not an expert here) it looks that you are writing binary 1 as a char, which is not ASCII 49, but ASCII 1 (soh), same for 2. Try changing it to '1' in PHP code (or 1 in C code.)

Here's a link to some article on Controlling the Serial Port with PHP - I googled, no idea of its quality - but doesn't look like it's enough to just write an integer into "com1" - that's out of my domain, so good luck :)

开始看清了 2024-07-28 05:30:32

正如尼古拉提到的,看起来你在“if”语句中进行赋值(=)而不是比较(==)。

一些 C 程序员养成的一个好习惯是将右值放在比较的左侧,这样,如果您不小心使用赋值运算符而不是比较运算符,编译器就会生成错误:

if (50 == usbnumber) {   // This is okay.
    ...
}

if (50 = usbnumber) {    // The compiler will generate an error here.
    ...
}

无论什么编译器,这都有效您正在使用的标志或警告级别,因为分配给右值是非法的。

我应该补充一点,如果您需要比较两个左值,则此“安全网”不起作用。

As Nikolai mentioned, it looks like you are doing assignment (=) rather than comparison (==) in your "if" statements.

A good habit that some C programmers get into is to put rvalues on the left-hand side of comparisons, so that the compiler will generate an error if you accidentally use the assignment operator instead of the comparison operator:

if (50 == usbnumber) {   // This is okay.
    ...
}

if (50 = usbnumber) {    // The compiler will generate an error here.
    ...
}

This works, regardless of what compiler flags or warning level you are using since assigning to an rvalue is illegal.

I should add that this "safety net" doesn't work if you need to compare two lvalues.

万人眼中万个我 2024-07-28 05:30:32

可能为时已晚,但我认为您的问题是 serial.read() 一次只能读取一个字符。 如果您从 PC 发送“49”,则当您调用 usbnumber = serial.read() 时,您将在第一个循环中获得“4”,在第二个循环中获得“9”。 这些都不满足条件,因此不执行任何操作,并且 usbnumber 重置为 0。

要修复此问题,您可以将serial.available 条件更改为

if (Serial.available() == 2)

,然后执行类似以下操作以转换为数字:

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

另一个选择是使用 TextFinder库 - 我在我的网站 http://mechariusprojects.com/thunderbolt/?p 上编写了一个简短的教程=60

机甲

May be too late, but I think your problem is that serial.read() only reads one character at a time. If you send "49" from the PC, when you call usbnumber = serial.read() you would be getting "4" the first loop and "9" the second loop. None of these satisfy the conditions so nothing is done and usbnumber is reset to 0.

To fix, you can either change serial.available condition to be

if (Serial.available() == 2)

and then do something like the following to convert to a number:

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

Another option is to use the TextFinder library - I've written a brief tutorial at my website http://mechariusprojects.com/thunderbolt/?p=60

Mech

梦罢 2024-07-28 05:30:32

我发现你的答案正在寻找其他东西,无论如何我刚刚遇到(我猜)你遇到的同样的问题。

如果你还没有解决它,我认为问题不是你的代码,而是arduino板上的自动重置机制。
也就是说:每次在串行端口上建立新连接时,arduino 板都会重置,这允许在通过串行端口对其进行编程时加载新固件。

要验证这一点,请尝试在 setup() 函数中闪烁 LED,如果每次加载页面时 LED 都会闪烁,这证实了我的论点。

看看这里:http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

我通过在 +5V 和 RESET 之间粘贴 120 欧姆电阻来解决。 请记住每次您想要将新固件上传到主板时将其删除。

I found your answer looking for other stuff, anyways I just faced (I guess) the same problem you had.

In case you haven't already solved it, I think the problems is not your code, but the auto-reset mechanism on the arduino board.
That is: each time a new connection is set up on the serial port, the arduino board is reset, this allowing a new firmware to be loaded when programming it via the serial port.

To verify this, try blinking a LED in your setup() function, if it blinks each time you load the page, this confirms my thesis.

Have a look here: http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

I solved by sticking the 120 Ohm resistor between +5V and RESET. Just remember to remove it every time you want to upload a new firmware to your board.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文