Arduino serial reading

11,361

Solution 1

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

Solution 2

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.

Share:
11,361
blueintegral
Author by

blueintegral

Computer Engineering Student at Georgia Tech

Updated on June 04, 2022

Comments

  • blueintegral
    blueintegral almost 2 years

    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>
    
  • blueintegral
    blueintegral almost 15 years
    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?
  • Nikolai Fetissov
    Nikolai Fetissov almost 15 years
    Can you log/print somehow what you are receiving? Also post your PHP code - that'll help narrow down the problem.
  • Nikolai Fetissov
    Nikolai Fetissov almost 15 years
    Yes, that works, though for some reason this notation has always felt wrong to me :)
  • blueintegral
    blueintegral almost 15 years
    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,
  • blueintegral
    blueintegral almost 15 years
    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?
  • Dan Moulding
    Dan Moulding almost 15 years
    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".
  • Nikolai Fetissov
    Nikolai Fetissov almost 15 years
    I don't know PHP enough, but try saving it into a variable and printing it on the page after processing the send.
  • blueintegral
    blueintegral almost 15 years
    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.
  • Nikolai Fetissov
    Nikolai Fetissov almost 15 years
    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' ) ?
  • blueintegral
    blueintegral almost 15 years
    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!
  • will-hart
    will-hart over 13 years
    Actually, just re-read your question - its probably worth doing Serial.println(usbnumber) to see what you are getting but it may be as simple as checking if usbnumber == 1 or usbnumber == 2