【问题标题】:PHP serial port data return from Arduino从Arduino返回PHP串口数据
【发布时间】:2012-10-28 23:53:35
【问题描述】:

我想知道是否有办法通过 PHP 完成读取我的串行端口 - 可行:-)

在练习我的 Arduino 技能时,我开发了一个简单的 LED 开/关草图。它通过在串行监视器中输入 onoff 来工作。

下一步,我整理了一个网页作为GUI界面来点击链接并执行上面的开关功能。这个基于 Web 的 GUI 通过 PHP 工作。 我正在使用PHP SERIAL 类与我的 Arduino 使用的串行端口进行交互。

问题是我需要找到一种从串口获取反馈的方法。使用 Arduino IDE 串行监视器,我可以看到响应每个串行输入的打印消息,并且我需要在我的 PHP 代码中检索相同的反馈。

PHP Serial 类提供了一个 readPort() 函数,但我没有返回我的数据。

更新[2]:

阿杜诺:

const int greenPin = 2;
const int bluePin = 3;
const int redPin = 4;

int currentPin = 0; //current pin to be faded
int brightness = 0; //current brightness level

void setup(){
  Serial.begin(9600);

  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(redPin, OUTPUT);
}

void loop(){
  //if there's any serial data in the buffer, read a byte
  if( Serial.available() > 0 ){
    int inByte = Serial.read();

      //respond only to the values 'r', 'g', 'b', or '0' through '9'
      if(inByte == 'r')
        currentPin = redPin;

      if(inByte == 'g')
        currentPin = greenPin;

      if(inByte == 'b')
        currentPin = bluePin;

      if(inByte >= '0' && inByte <= '9'){
        //map the incoming byte value to the range of the analogRead() command
        brightness = map(inByte, '0', '9', 0, 255);
        //set the current pin to the current brightness:
        analogWrite(currentPin, brightness);
      }

      Serial.print("Current Pin : ");
      Serial.println(currentPin);

      Serial.print("Brightness : ");
      Serial.println(brightness);

  }//close serial check

}

PHP/HTML:

<?php
    require("php_serial.class.php");
// include("php_serial.class.php");

    // Let's start the class
    $serial = new phpSerial();

    // First we must specify the device. This works on both Linux and Windows (if
    // your Linux serial device is /dev/ttyS0 for COM1, etc.)
    $serial->deviceSet("/dev/ttyACM0");

    // Set for 9600-8-N-1 (no flow control)
    $serial->confBaudRate(9600); //Baud rate: 9600
    $serial->confParity("none");  //Parity (this is the "N" in "8-N-1")
    $serial->confCharacterLength(8); //Character length     (this is the "8" in "8-N-1")
    $serial->confStopBits(1);  //Stop bits (this is the "1" in "8-N-1")
    $serial->confFlowControl("none");

    // Then we need to open it
    $serial->deviceOpen();

    // Read data
    $read = $serial->readPort();
print "<pre>";
print_r($read);
print "</pre>";

    // Print out the data
    echo $read;
        // print exec("echo 'r9g9b9' > /dev/ttyACM0");
    print "RESPONSE(1): {$read}<br><br>";

    // If you want to change the configuration, the device must be closed.
    $serial->deviceClose();
?>

<?php
    if( isset($_REQUEST['LED']) )
        response();
?>

<form action='index.php' method='POST'>
    <select id='led' name='LED'>
        <option id='nil'>-</option>
        <option id='red'>RED</option>
        <option id='green'>GREEN</option>
        <option id='blue'>BLUE</option>
        <option id='all'>ALL</option>
    </select>
    <input type='submit' value='SET'>
</form>

<?php
    print "Hi, Earthlings!";

    function response(){
        $CMDString = "";
        $execute   = false;

        if( isset($_REQUEST['LED']) ){
                switch ($_REQUEST['LED']) {
                    case 'RED':
                        $CMDString = 'r9';
                        $execute = true;

        exec("echo 'r9g0b0' > /dev/ttyACM0");

                print "<br>FOUND: {$_REQUEST['LED']}";
                        break;
                    case 'GREEN':
                        $CMDString = 'g9';
                        $execute = true;
                print "<br>FOUND: {$_REQUEST['LED']}";
                        break;
                    case 'BLUE':
                        $CMDString = 'b9';
                        $execute = true;
                print "<br>FOUND: {$_REQUEST['LED']}";
                        break;
                    case 'ALL':
                        $CMDString = 'r9g9b9';
                        $execute = true;
                print "<br>FOUND: {$_REQUEST['LED']}";
                        break;
                    default:
                        print exec("echo 'r0g0b0' > /dev/ttyACM0");
                        $execute = false;
                        break;
                }

                if($execute){
                    print exec("echo '{$CMDString}' > /dev/ttyACM0");
                    print "<br><br>executing: {$CMDString}";
                }
        }
    }
?>

【问题讨论】:

    标签: php serial-port arduino


    【解决方案1】:

    我假设您在 linux 上工作。

    首先设置你的串口:

    stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
    

    那么你就可以使用老式的 fread/fwrite

    $fp =fopen("/dev/ttyACM0", "w+");
    if( !$fp) {
            echo "Error";die();
    }
    
    fwrite($fp, $_SERVER['argv'][1] . 0x00);
    echo fread($fp, 10);
    
    fclose($fp);
    

    你只需要记住一件事。 Arduino 将在每次连接时重新启动。如果你不知道它会让你感到困惑。例如,如果您连接(fopen)并立即发送数据,Arduino 会因为它正在启动而错过它(这需要一两秒)。尝试睡眠,给它一些时间。如果要禁用重启,请在 GRD 到 RST 之间使用 10uF 电容。

    祝你好运

    ps。您可以使用“屏幕”进行故障排除

    screen /dev/ttyACM0 9600
    

    发布关于使用 Arduino http://systemsarchitect.net/connecting-php-with-arduino-via-serial-port-on-linux/ 设置 PHP 的帖子,这里还有一个 http://systemsarchitect.net/arduino-and-php-serial-communication-with-a-protocol/

    【讨论】:

    • 感谢您提供的非常有帮助的 cmets。我已经成功地在我的设置中应用了一个 10uF 电容器。所以我不再需要打开 Arduino 串行监视器。我现在可以使用网络界面来控制我的 RGB-LED 实验。唯一的问题是我仍然没有从串行监视器中的 Aduino 代码 I:E 中得到任何返回语句我有确认语句,如“RED ON”。在我的网络界面中,我没有得到这个非常重要的数据。我成功执行了您的 stty 命令,但没有任何区别。你能再给我一些帮助吗?
    • 您能粘贴您的 Arduino 和 PHP 代码吗?没有它就很难分辨。
    • 嗨 Lukasz,我已经用最新的 PHP/HTML 代码更新了我的问题,并包含了我的 Arduino 草图。 PHP 包括可从我的问题中的链接下载的 PHP_Serial 类。
    • 我看到你只在脚本开头准备好 Arduino 输出。 $read 变量中有什么东西吗?从 Arduino 代码中,我可以理解您必须先发送 2 个字节才能获得任何输出。我不知道你正在使用的图书馆。您可以使用简单的 fopen()、read() 和 wrtie()。
    • 您好 Lukasz,您的持续帮助非常宝贵,非常感谢。我将您的答案标记为正确,但对于我遇到的更多复杂情况,我将不胜感激。您打开和读取端口的策略有效,但只是间歇性的,即:它有时有效,但大多数时候,我没有得到任何输出。当我得到输出时,它是串行端口中的所有内容,而不是最新的。你能提供更多关于这方面的建议吗?另外,您能解释一下“stty ...”命令代码的作用吗?这似乎对我的情况没有帮助。
    【解决方案2】:

    /dev/ttyUSB0 以 root 用户运行,如果您使用 apache 尝试 chown /dev/ttyUSB0 到 apache 或用户已登录。

    $ sudo chown apache2:apache2 /dev/ttyACM0
    OR
    $ sudo chown yourusername:yourusername /dev/ttyACM0
    

    然后再试一次,或者尝试从 ubuntu 注销并以 root 用户身份登录。

    【讨论】:

    【解决方案3】:

    您可能正在尝试读取串行端口上何时没有数据。你需要实现JavaScript代码来调用PHP可以定期读取的代码。

    当你得到数据后,你应该处理它。

    readPort() 对我来说效果很好。如果波特率、奇偶校验等调整得当,那么读取串口应该没有问题。

    这是使用 Arduino 库的示例。前段时间它对我有用:

    <?php
        include "php_serial.class.php";
    
        // Let's start the class
        $serial = new phpSerial();
    
        // First we must specify the device. This works on both Linux and Windows (if
        // your Linux serial device is /dev/ttyS0 for COM1, etc.)
        $serial->deviceSet("/dev/ttyUSB0");
    
        // Set for 9600-8-N-1 (no flow control)
        $serial->confBaudRate(9600); //Baud rate: 9600
        $serial->confParity("none");  //Parity (this is the "N" in "8-N-1")
        $serial->confCharacterLength(8); //Character length     (this is the "8" in "8-N-1")
        $serial->confStopBits(1);  //Stop bits (this is the "1" in "8-N-1")
        $serial->confFlowControl("none");
    
        // Then we need to open it
        $serial->deviceOpen();
    
        // Read data
        $read = $serial->readPort();
    
        // Print out the data
        echo $read;
    
        // If you want to change the configuration, the device must be closed.
        $serial->deviceClose();
    ?>
    

    【讨论】:

    • 我知道波特率是多少,但您介意告诉我什么是奇偶校验以及如何在这种情况下正确配置它吗?
    • @sisko 我已经用一个使用这个库的例子编辑了我的答案。希望你会发现它有用
    • 感谢您的回答和代码示例。我用你的摘录更新了我的代码,但我仍然没有反馈。我用我的 PHP/HTML 脚本更新了我原来的问题。我应该在 3 个地方得到一些反馈,但没有任何反应。我应该指出,我的端口(/dev/ttyACM0)设置为 chmod 777,我实际上在我的 Arduino 草图中调用 Serial.println,这就是为什么我希望在 PHP 中返回一些数据。事实上,每次我使用 Web 界面时,我的 LED 都会成功响应,并且我的 Arduino 串行监视器会打印我的消息
    • 你有什么操作系统,你用的是apache版本/php吗?
    • 操作系统是Linux Ubuntu-12,PHP是5.3.10版本,Apache是​​Apache/2.2.22
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多