代码之家  ›  专栏  ›  技术社区  ›  thenetimp

串行端口读取与PHP怪异

  •  1
  • thenetimp  · 技术社区  · 12 年前

    我已经用PHP编写了一个项目。我需要从串行端口读取数据。我希望保持从串行端口以与项目其他部分相同的语言读取数据的能力。

    我找到了一个很多人似乎都有问题的班级。php_serial.class.php基于示例,这是我为它编写的测试。使用RFID读卡器作为串行输入。

    #!/usr/bin/php
    <?php
    
    // Include the class to read the serial line.
    include ("php_serial.class.php");
    
    // Let's start the class
    $serial = new phpSerial;
    
    $serial->deviceSet("/dev/ttyAMA0");
    $serial->confBaudRate(9600);
    $serial->confParity("none");
    $serial->confCharacterLength(8);
    $serial->confStopBits(1);
    // We can change the baud rate, parity, length, stop bits, flow control
    #$serial->confFlowControl("none");
    
    // Check if we can open the serial line.  Otherwise die.
    if(!$serial->deviceOpen()) die("unable to open device");
    
    stream_set_timeout($serial->_dHandle, 10);
    
    $rfid_key = FALSE;
    
    // Start the loop to keep checking the
    while(!$rfid_key)
    {
        $read = $serial->readPort();
    
        // Array to store eachvalue of the RFID tag
        $ascii_read  = array();
    
        for($i = 0; $i < strlen($read); $i++)
        {
            $ascii_read[] = ord($read[$i]);
            if(count($ascii_read) == 14 && $ascii_read[0] == 2 && $ascii_read[13] == 3)
            {
                $rfid_key = implode("", $ascii_read);
                break;
            }
        }
    
        // If the key is empty then sleep for 1 second.
        if(!$rfid_key)
        {
            sleep(1);
        }
    }
    
    print_r($rfid_key);
    print "\n\n";
    

    如果我运行脚本,它将等待输入,如果我在天线上闪烁RFID标签,它就会失败。

    然后我决定看看它是否是php,所以我写了一个python脚本。

    import serial
    serialport = serial.Serial("/dev/ttyAMA0", 9600, timeout=0.5)
    response = serialport.readlines(None)
    print response
    

    如果我把标签放在天线上,运行脚本,然后把标签拿走,我会得到它在该时间段内读取的标签实例的数量。告诉我RFID阅读器可以与RaspberryPi配合使用。

    现在是非常奇怪的部分。如果我在执行完python代码后返回并执行php代码,那么它就可以工作了。这让我相信,这与Python中完成的串行端口实例化有关,当php代码在之后执行时,它会一直保留下来。然后,我去掉python代码,只实例化串行端口并退出,正如预期的那样,php代码就可以工作了。

    所以,我的问题是。WTF是python在做php代码没有做的事情吗?我不是串行总线的专家,对atm也很困惑。

    1 回复  |  直到 12 年前
        1
  •  2
  •   thenetimp    12 年前

    好的,我找到了解决方案。问题不在于php脚本,而在于为/dev/ttyAMA010设置的选项

    经过大量研究,我发现运行命令 /bin/stty -F /dev/ttyAMA010 给我看了串行线路的当前状态。在一次新的启动后运行它,我得到了这个作为输出。

    speed 9600 baud; line = 0;
    -brkint -imaxbel
    

    然后运行python脚本,看看有什么不同。

    speed 9600 baud; line = 0;
    min = 0; time = 0;
    -brkint -icrnl -imaxbel
    -opost
    -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
    

    然后,我系统地包含了每个配置选项,并刷新了我的页面,直到它起作用。最后,我发现我需要两个选项才能让php串行脚本正常工作。

    stty -F /dev/ttyAMA0 -isig
    stty -F /dev/ttyAMA0 -icanon