PHP + Arduino

Hello, everyone

I am doing a project on Arduino. My first step is to have a basic interaction between Arduino and PHP.

However, I met somethink weird in my codes, and I have no idea about what happened.

This is the form used to let a user submit a value. The value can be used to control the color of the LED.

project2.php

<?php $fp =fopen("com5", "w"); fwrite($fp, chr((int)$_GET["value"])); echo $_GET["value"]; sleep(3); flose($fp); ?>

The number shown on the web page is correct, but the led color is wrong and sometimes delayed. So, does it seem that the signal sent from web page to Arduino is very slow?

This is my Arduino code:

const int redPin = 2;
const int bluePin = 3;
const int greenPin = 4;
const byte debugPin = 13;
int usbnumber = 0;

void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(debugPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
if (Serial.available() > 0) {
usbnumber = Serial.read();
}
if (usbnumber > 0) {
digitalWrite(debugPin,HIGH);
if (usbnumber % 3 == 0) {
digitalWrite(redPin,HIGH);
delay(250);
digitalWrite(redPin,LOW);
delay(250);
}
else if (usbnumber % 3 == 1) {
digitalWrite(greenPin,HIGH);
delay(250);
digitalWrite(greenPin,LOW);
delay(250);
}
else {
digitalWrite(bluePin,HIGH);
delay(250);
digitalWrite(bluePin,LOW);
delay(250);
}
usbnumber = -1;
}
}

Can anyone help me find the bugs?

The 'slow' part can be explained by the total delay time of 500 miliseconds after each read, I reckon.
You could remove this by using the same technique used in the Blink Without Delay example.

If I key in 218, the values '2', '1', '8' will be sent to the Arduino.

The Arduino will read 3 values ('2', '1', and '8'). The usbvariable variable will contain 50, 49, and 56 (the ascii equivalent of the characters sent).

if(50 % 3 == 0) as a method for determining whether to turn the red LED on, or not, makes no sense to me. Perhaps it does to you, and you could explain it to me.

I would think that you would want to send 3 values in the range 0 to 255 (as character strings), along with start and stop markers (something like "<128,217,18>"), then read the entire string, and parse that string to get "128", "217", and "18", then convert those strings to integers, and use digitalWrite on PWM pins to set the red, green, and blue LEDs intensity.

Perhaps not.

Could you explain what you were trying to do?

What I want to do now is to let a user to enter a value from PHP. Then, this value can be passed to the Arduino. There is a LED light with three different colors on my breadboard. I want to use the value to control the color of this LED. For example, if value%3==0, then show red light.

Got it.

You need to deal with the fact that the number is being sent as a string of characters, though, not as a single number.

So, how do I make a trasfer?

Besides, my current problem is that no matter which number I enter, the LED light always display green.

Does anyone know why?

The PHP script should be modified to send a start marker, the number as a string, and an end marker:

$fp =fopen("com5", "w");
fwrite($fp, "<");
fwrite($fp, chr((int)$_GET["value"]));
fwrite($fp, ">");
echo $_GET["value"];
sleep(3);
fclose($fp);

The syntax error may be causing some unexpected output on the serial port.

On the Arduino:

bool started = false;
bool ended = false;
int serValue = -1;

void loop()
{
   while(Serial.available() > 0 && !ended)
   {
       char aChar = Serial.read();
       if(aChar == '>')
       {
           started = true;
           ended = false;

           serValue = 0;
       }
       else if(aChar == '>')
       {
           started = false;
           ended = true;
       }
       else
       {
           if(started && aChar >= '0' && aChar <= '9')
           {
               serValue *= 10;
               serValue += aChar - '0';
           }
       }
   }

   // Done processing pending serial data

   if(!started && ended) // Have we got a complete value?
   {
       // Light the LEDs based on serValue
   }
}

This code will read a stream of data like "14><472><23><4", and set serValue to 0, 4, 47, and 472, then allow you to use serValue, then set serValue to 0, 2, and 23, and again allow you to use serValue.

If you had a serial LCD, you could use NewSoftSerial to communicate with it, and echo what is received on the serial port, for debugging purposes.

I met a very very strange problem. The situation is that the LED light will have different display results even though I do not change my code. = ="

Could anyone help me solve this weird situation?

Arduino Code
const int rightLED = 7;
const int centerLED = 8;
const int leftLED = 6;
int usbnumber = 0;

void setup() {
pinMode(rightLED, OUTPUT);
pinMode(centerLED, OUTPUT);
pinMode(leftLED, OUTPUT);
Serial.begin(9600);
}

void loop() {
if (Serial.available() > 0) {
usbnumber = Serial.read();
}
if (usbnumber > 0) {
if (usbnumber % 3 == 0) {
digitalWrite(rightLED,HIGH);
delay(250);
digitalWrite(rightLED,LOW);
delay(0);
}
else if (usbnumber % 3 == 1) {
digitalWrite(leftLED,HIGH);
delay(250);
digitalWrite(leftLED,LOW);
delay(0);
}
else {
digitalWrite(centerLED,HIGH);
delay(250);
digitalWrite(centerLED,LOW);
delay(0);
}
usbnumber = -1;
}
}

PHP code
function test(obj)
{
var url='project2.php?value='+obj.name;
new Image().src = url;
}


project2.php

<?php $fp =fopen("com5", "w"); $i = (int)$_GET["value"] + 48; while (true){ fwrite($fp, chr($i)); sleep(1); } flose($fp); ?>

Hi guys! I seriously need you help! (I've been sitting for six hours straight with this problem. Everything is set up, only problem is, if I send "1" or "0" or anything, the arduino only receives ""

<?php
$x = chr(48);
echo $x;
$fp = fopen("COM5", "w");
fwrite($fp, $x);
sleep(3);
fclose($fp);
echo $x;
?>

I Print the $x so many times to see if the chr() messes up - but it prints out fine in my browser. (In this case 00 apears)

int ledPin = 13;
void setup() {
    pinMode(ledPin, OUTPUT);
    Serial.begin(9600);
}

void loop() {
  while (Serial.available() > 0)
  {
        int x = (int)Serial.read();
           if(x == 48 || x == 0)
           {
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
           }
           if(x == 255)
           {
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
           }
    }
}

With my Arduino, if you look at the code above, the x = 255 all the time (flashes once)

Why don't you just use the characters "0" and "1" like below instead of trying to do conversions? Try this with the serial monior.

int ledPin = 13;
void setup() {
    pinMode(ledPin, OUTPUT);
    Serial.begin(9600);
}

void loop() {
  while (Serial.available() > 0)
  {
        char x = Serial.read();
           if(x == '0') //blink twice
           {
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
           }
           if(x == '1') //blink once
           {
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
           }
    }
}

What is the point of sleeping 3 seconds before closing the file handle (PHP side)? I am wondering if the data isn't actually sent until the file handle is closed...?

You might also want to consider this:

If you haven't seen this thread, it may help:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1266689999/all

Hmm - here's another interesting thread (indeed, googling "arduino php serial" is recommended):

That example shows the "sleeping 3 seconds" before closing as well; I still question that, it seems superfluous to me. Can anyone explain why its used?

I also noted that there seems to be an issue under Windows with reading the serial port - is this still true?

:-?

Hmm - I think I may have answered my question via this thread (where its explained, I think):

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264895784

Basically because of auto-reset? In that thread, this is mentioned:

http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

So - perhaps try disabling auto-reset with the resistor method, remove the call to sleep(3) in the php code, and try again...?

:-?

Thanks guys! - I've visited all that links before (thats where I found the sleep(3) part) - I myself don't know the reason why to put it to sleep for 3 secs

I have found a semi solution, combined with what cr0sh came up with - it might work:

Firstly, I changed the fopen to "w+" ... then I made it to sleep between each step. The auto-reset must be the problem. When it sleeps, the arduino has some time to do his stuff, and then it actually works. But who would want to wait 6 sec to turn off their room lights?...

So I will inform you if cr0sh's solution of removing the auto-reset does not work!

Thanks again guys!

cr0sh, you = awesome!!!!

It works perfectly!
Thanks alot!!!

Glad it worked out for you...

:slight_smile: