Question

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>
Was it helpful?

Solution

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 :)

OTHER TIPS

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.

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top