views:

2782

answers:

2

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 recieve 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>
+1  A: 

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

Nikolai N Fetissov
I changed that and now the led doesn't light up at all. This must mean that it is not reading an ascii 1 or 2 right?
aloishis89
Can you log/print somehow what you are receiving?Also post your PHP code - that'll help narrow down the problem.
Nikolai N Fetissov
If I try to use the serial monitor that is built in to the arduino environment, PHP complains that the com port isn't available for it to write to,
aloishis89
Still nothing. It must be that whatever representation of 1 PHP is sending is not the same as what it is being compared to in the arduino. How can I tell what PHP is sending?
aloishis89
I don't know PHP enough, but try saving it into a variable and printing it on the page after processing the send.
Nikolai N Fetissov
I am just learning PHP also, and I realized that the chr() function takes in an ascii representation of a character and returns that character. So I know that PHP is sending an ascii character now, but my C code is still not seeing it.
aloishis89
I think you are confusing characters with integers here. chr() takes an integer (index in ASCII table) and returns one-character string. How about just doing fwrite( $fp, '1' ) ?
Nikolai N Fetissov
Still no :(. I have tried several combinations of sending just a 1, sending a character 1 (1 in quotes), using the chr() function, and then comparing them in the C code with both a 1 and a 49. I can't really think of anything else to try other than make a table and literally try every combination I can think of!
aloishis89
I updated the answer.
Nikolai N Fetissov
A: 

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.

Dan Moulding
Yes, that works, though for some reason this notation has always felt wrong to me :)
Nikolai N Fetissov
As I said, it's a good habit that *some* C programmers get into :P Some C programmers never get into that habit (even good ones). It definitely takes some getting used to before it no longer feels "wrong".
Dan Moulding