Pages: [1]   Go Down
Author Topic: [SOLVED] Serial connection with Arduino + PHP on OpenWrt Router  (Read 4319 times)
0 Members and 1 Guest are viewing this topic.
Indonesia
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to create a PHP web interface to control Arduino Uno via USB interface on TP-Link MR3420 router using OpenWrt firmware

The weird thing is that my PHP script only get reply from arduino after running a python script that communicate with arduino

I'm sure that my PHP script is working since it was able to turn off leds on arduino but get no reply from arduino

Here is my PHP code:

Code:
require("lib/php_serial.class.php");

$serial = new phpSerial;

$serial->deviceSet("/dev/ttyACM0");
$serial->confBaudRate(9600);

$serial->deviceOpen();
$serial->sendMessage($cmd);
sleep(1);
$read = $serial->readPort();
$serial->deviceClose();

Here is my arduino sketch:

Code:
  int numSerial;
  if (Serial.available() > 0)
  {
    char data = Serial.read();
    switch (data)
    {
    case 'l':
      numSerial = incomingSerialNumber();
      if (numSerial >= 0)
      {
        Serial.print("LED Mode: ");
        switch (numSerial)
        {
        case 0:
          ledMode = 0;
          Serial.print("OFF");
          break;
        case 1:
          ledMode = 1;
          Serial.print("TEMP");
          break;
        case 2:
          ledMode = 2;
          Serial.print("KR");
          break;
        }
      }
      else
        Serial.print(ledMode);
      break;
    case 't':
      Serial.print(getTemp());
      break;
    case 's':
      Serial.print(getTemp());
      Serial.print("|");
      Serial.print(getLedMode());
    }
  }

And here is my python code:

Code:
import serial
ser = serial.Serial("/dev/ttyACM0", 9600, timeout=3)
ser.open()
ser.write("t")
print ser.readline()
ser.close()


Please help.
Thanks.
« Last Edit: August 02, 2012, 12:08:04 pm by gutzz » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49365
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
$serial->deviceOpen();
$serial->sendMessage($cmd);
sleep(1);
$read = $serial->readPort();
$serial->deviceClose();
Open the part, resetting the Arduino. Immediately send a message, which will be lost as the Arduino isn't ready to receive serial data yet. Sleep for a second, while the Arduino boots up. See if there is any serial data (there may not be any). Then, close the port, resetting the Arduino again.

Quote
Here is my arduino sketch:
No, that is a small part of the sketch. Useless, as we can't see where or when that is called.
Logged

Indonesia
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Open the part, resetting the Arduino. Immediately send a message, which will be lost as the Arduino isn't ready to receive serial data yet. Sleep for a second, while the Arduino boots up. See if there is any serial data (there may not be any). Then, close the port, resetting the Arduino again.

Still no reply to PHP before executing the python script...

Reboot router > connect Arduino > execute PHP = no reply
Reboot router > connect Arduino > execute python script > execute PHP = got reply from arduino

I forgot to mention that i've uploaded a custom firmware for Atmega8u2 to disable auto reset
http://www.tinkerin.gs/2011/03/arduino-auto-reset-software-fix.html

Here is my full sketch:
Code:
int tempPin = 0;
int ledMode = 1;
int ledArray[] = {
  2, 3, 4, 5, 6, 7};
int count = 0;

void setup()
{
  analogReference(INTERNAL);
  Serial.begin(115200);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop()
{
  if (ledMode == 1)
    ledTemp();
  else if (ledMode == 2)
    ledKnightRider();
  else
  {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
  }
  delay(1);
}

void serialEvent()
{
  incomingSerial();
}

void ledTemp()
{
  float temp = getTemp();
  if (temp > 31)
  {
    arrLed(5);
  }
  else if (temp > 29)
  {
    arrLed(4);
  }
  else if (temp > 27)
  {
    arrLed(3);
  }
  else if (temp > 25)
  {
    arrLed(2);
  }
  else
  {
    arrLed(1);
  }
}

void ledKnightRider()
{
}

void arrLed(int leds)
{
  int idx = 2;
  int offset = 2;

  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);

  for (idx = 2; idx < leds+offset; idx++)
    digitalWrite(idx, HIGH);
}

int getTemp()
{
  int tempC;
  int reading;

  reading = analogRead(tempPin); //LM35
  tempC = reading / 10;
  return tempC;
}

int getLedMode()
{
  return ledMode; 
}

void blinkLed()
{
}

void incomingSerial()
{
  int numSerial;
  if (Serial.available() > 0)
  {
    char data = Serial.read();
    switch (data)
    {
    case 'l':
      numSerial = incomingSerialNumber();
      if (numSerial >= 0)
      {
        Serial.print("LED Mode: ");
        switch (numSerial)
        {
        case 0:
          ledMode = 0;
          Serial.print("OFF");
          break;
        case 1:
          ledMode = 1;
          Serial.print("TEMP");
          break;
        case 2:
          ledMode = 2;
          Serial.print("KR");
          break;
        }
      }
      else
        Serial.print(ledMode);
      break;
    case 't':
      Serial.print(getTemp());
      break;
    case 's':
      Serial.print(getTemp());
      Serial.print("|");
      Serial.print(getLedMode());
    }
  }
}

int incomingSerialNumber()
{
  char num[8];
  unsigned char index=0;
  delay(10);
  while(Serial.available() > 0)
  {
    delay(10);
    num[index++] = Serial.read();
    if(index > 6)
    {
      break;
    }
  }
  num[index]=0;
  if (index > 0)
    return atoi(num);
  else
    return -1;
}

Updated PHP code:
Code:
    $serial = new phpSerial;

    $serial->deviceSet("/dev/ttyACM0");
    $serial->confBaudRate(115200);
 
    $serial->deviceOpen();
    sleep(1);
    $serial->sendMessage($cmd);
    sleep(1);
    $read = $serial->readPort();
    $serial->deviceClose();

Thanks.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49365
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Reboot router > connect Arduino > execute PHP = no reply
Reboot router > connect Arduino > execute python script > execute PHP = got reply from arduino
Then, clearly the python method of opening the serial port is doing something that the PHP method of opening the serial port is not doing. You need to investigate all the options for the phpSerial object, to see what else needs to be set in order to open the serial port correctly.
Logged

Indonesia
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

SOLVED!

Running "stty -F /dev/ttyACM0 raw speed 115200" on every router startup solved my problem smiley-grin
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49365
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
SOLVED!
Yay! I'll bookmark this thread for the next victim that has the same problem.
Logged

Indonesia
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just found the real source of my problem.
In phpSerial class:

$ret = $this->_exec("stty -F " . $this->_device . " " . (int) $rate, $out);

Replace with:

$ret = $this->_exec("stty -F " . $this->_device . " raw speed " . (int) $rate, $out);
Logged

Pages: [1]   Go Up
Jump to: