Reputation: 1271
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>
Upvotes: 4
Views: 11553
Reputation: 6777
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.
Upvotes: 0
Reputation: 3831
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
Upvotes: 0
Reputation: 84159
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 :)
Upvotes: 1
Reputation: 220573
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.
Upvotes: 1