Serial communication with Web Server (PHP)

I've been playing around with controlling an Atmega1284P (yea a bit overkill, but I had it laying around) over the web using PHP. It "kinda" works. by "kinda" I mean it's stable under certain environments and totally unstable under others.

Environment 1: OS CentOS 6.6 (running as a VirtualBox guest) Apache version: 2.2.15 PHP version: 5.3.3 Result: fairly stable, very rarely do I not get a sensor reading

Environment 2:

OS: CentOS7.1 (tried both a dedicated physical machine and a VirtualBox guest) Apache version: 2.4.6 PHP version: 5.4.16 Result: When I take a reading of my photoresistor, one or both of my two LED's turns off/on. Sometimes I do not get a sensor reading.

Environment 3:

OS:Raspbian Apache version:2.2.22 PHP version:5.4.39 Result: When I take a reading of my photoresistor, one or both of my two LED's turns off/on. Sometimes I do not get a sensor reading.

Hardware configuration (Arduino side of things) Atmega 1284p FTDI USB-Serial Two LED's photoresistor DS1631 I2C temp sensor

My Arduino code:

//temp sensor vars
boolean neg=0;
byte temp=0;
float tempb=0;
// end

byte hybyte=0;
int result=0;
void setup() {
  // put your setup code here, to run once:
DDRD|=B11000000; //setting pins 20 and 21 as outputs
ADMUX=B01000111;//set adc reference and select channel
ADCSRA=B10000110;//enable adc and set prescaler to divide by 64
//temp sensor pins
PORTC |=B11000000;
DDRC |=B11000000;// pc7 as ada and pc6 as sck
//end
Serial.begin(9600);
DS1631startconvert();
}

void loop() {
  // put your main code here, to run repeatedly:
//cal = OSCCAL;
if (Serial.available()){
     int ser = Serial.read();
    
     if (ser == 52){//keyboard key 4 to read the temp sensor
      DS1631readtemp();
      delay(50);
      tempb=(tempb*(9.0/5.0))+32;
      Serial.println(tempb,4);//4 decimal places 
      neg=0;
      temp=0;
     tempb=0;
       }
     else if (ser == 53){//keyboard key 5 to turn on led1
      PORTD |=B01000000;
      delay(50);
    Serial.println("Object1 enabled"); 
       }
     else if(ser == 54){//keyboard key 6 to turn off led1
      PORTD &=~B01000000;
            delay(50);
      Serial.println("Object1 disabled"); 
       }
     else if(ser == 55){//keyboard key 7 to turn led2 on
      PORTD |=B10000000;
            delay(50);
       Serial.println("Object2 enabled"); 
       }
      else if(ser == 56){//keyboard key 8 to tourn led2 off
      PORTD &=~B10000000;
            delay(50);
     Serial.println("Object2 disabled"); 
       }
       else if(ser == 57){//keyboard key 9 to read the photoresistor
            delay(50);
            adcread();
     Serial.println(result); 
       }
}

}

void adcread(){
ADCSRA |= (1 << ADSC);         // start ADC measurement
    while (ADCSRA & (1<

On the webserver side using this code(as well as this person's code for the serial comms: http://www.phpclasses.org/browse/file/17926.html):




Cpannel

Control Panel
Status:
deviceSet("/dev/ttyUSB0"); $serial->confBaudRate(9600); date_default_timezone_set("UTC"); if (isset($_POST['button1'])) { $serial->deviceOpen(); $serial->sendMessage("9"); $read = $serial->readPort(); echo "
" . $read . "
"; $serial->deviceClose(); echo "
" . date("h:i:sa") . "
"; } if (isset($_POST['button2'])) { echo "button2 has been pressed"; } if (isset($_POST['button3'])) { $serial->deviceOpen(); $serial->sendMessage("4"); $read = $serial->readPort(); echo "
" . $read . "
"; $serial->deviceClose(); echo "
" . date("h:i:sa") . "
"; } if (isset($_POST['button4'])) { echo ""; } if (isset($_POST['button5'])) { $serial->deviceOpen(); $serial->sendMessage("5"); $read = $serial->readPort(); echo "
" . $read . "
"; $serial->deviceClose(); echo "
" . date("h:i:sa") . "
"; } if (isset($_POST['button6'])) { $serial->deviceOpen(); $serial->sendMessage("6"); $read = $serial->readPort(); echo "
" . $read . "
"; $serial->deviceClose(); echo "
" . date("h:i:sa") . "
"; } if (isset($_POST['button7'])) { $serial->deviceOpen(); $serial->sendMessage("7"); $read = $serial->readPort(); echo "
" . $read . "
"; $serial->deviceClose(); echo "
" . date("h:i:sa") . "
"; } if (isset($_POST['button8'])) { $serial->deviceOpen(); $serial->sendMessage("8"); $read = $serial->readPort(); echo "
" . $read . "
"; $serial->deviceClose(); echo "
" . date("h:i:sa") . "
"; } ?>

The webpage side of things is a bit on the messy side (was experimenting with other aspects of PHP). If anyone could give me some tips on improving reliability, that would be great!

The current goal is to be able to run it off of of my Raspberry Pi without the current stability issues.

Have you interrogating the arduino from a serial terminal (eg minicom or screen) on your linux host? Doing that will ensure your serial link is working correctly

See also http://www.fritz-hut.com/2012/08/30/php-serialclass-with-arduino-raspberrypi/ for some additional steps you may need to take to get php serial working.

I did just use minicom on the Linux host, and it behaves just fine.

I did add the following lines, but it didn't help at all:

$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");

So it seems the problem is with the phpserial module- I’m not a PHP person so cant really help too much.

I’ve not used any of them but this page Sniff serial port on Linux - Server Fault gives some utilities to monitor serial comms

Just based on the write up I’d try http://sourceforge.net/projects/slsnif/ to try and understand what is going wrong between your PHP module and the arduino.

I’m just learning PHP myself. Making an educated guess, it appears that the more recent versions of php don’t like to play nicely with php_serial.class.php. I also noticed that I don’t have any problems when I hit a button that triggers something simple like an LED but if I select something such as take a reading of my photo resistor things go a bit nuts with my LED randomly getting turned on/off (but again everything is perfectly stable when I tried it under minicom.)

Will have to sniff the serial port to see exactly what’s happening :slight_smile:

Well I did find a work-around to the issue by adding the following lines after the results of the photoresistor and temperature are sent to clear the incoming serial buffer (a delay was also needed):

delay(250);
while(Serial.available())
  Serial.read();

I did try slsnif but got “Failed to open a pty: No such file or directory” Googled it and read that is only supports “legacy” pseudo-terminals. Tried a few others with no luck.

Update: I’ve tried it on my RaspberryPi. For some reason, a response isn’t always displayed such as the reading of my photoresistor. Everything else works ok on it.
Udate2:I did a work-around on that on the php side with a while loop.