当前位置: 首页 > 知识库问答 >
问题:

通过PHP从Windows上的Arduino串口读取数据。数据不匹配串行监视器输出

庾才
2023-03-14

我从Arduino Uno发送到串行端口的数据可以在Arduino串行监视器中完全按照预期查看,但在我的WAMP环境中通过serproxy从PHP读取数据时,我会得到一些缺失或额外的字符(例如,通常是一个看起来像黑钻石内部的问号的字符)。

我在网上发现了类似的问题,但所有的答案都不够。解决方案通常只针对Linux,或者只是解决了让Windows从串行端口读取(而不是写入)所需的许多挑战的一部分。

我尝试了以下方法来让PHP简单地读取任何串行数据:

>

  • 我首先尝试了建议的php_serial类,但很快发现它只允许在Windows上编写,而对于另一个堆栈溢出问题(从Arduino到php的串行通信)的答案建议只为代码的Linux部分替换代码,而不是Windows。

    在串行通信与PHP在Windows上的文章也提到有限的Windowsphp_serial类的容量,并建议一个替代的串行扩展(也提到了这里和这里),但这不会加载到我的WAMP环境与PHP 5.4.12 VC9构建时,我使用正确的匹配扩展版本,将扩展添加到正确的php.ini,并重新启动服务器。遵循所有步骤后,我收到了一个“模块win_serial没有编译成PHP”。如果其他人有这个问题,请让我知道,因为我愿意再次调查这个问题。

    最后,我尝试使用一个名为serproxy的程序,该程序将网络套接字重定向到串行端口和从串行端口重定向。我在Arduino的GND和RESET引脚上添加了一个10uF电容器,以防止在新的串行连接上重置,正如从Arduino返回的PHP串行端口数据中提到的那样。

    所以现在,我让我的Arduino通过USB电缆向我的计算机发送数据,只要我监控Arduino串行监视器中的数据,一切看起来都应该如此。当我在PHP中呼应相同的数据时,我开始看到额外或丢失的数据以及流。所以发送文本“AOK AOK AOK”有时会变成“好吗?当在我的PHP脚本中回响时,Pz[R"或类似的东西。

    我试图从PHPsocket_read()获取干净的串行数据的事情:

    >

  • 各种mb_convert_编码(如“ASCII”或“utf-8”)乱七八糟

    设置串行数据的奇偶校验。我尝试设置它为"偶数"在服务器代理配置和DOS(运行命令的模式COM4: BAUD=9600 PARITY=E数据=8停止=1 XON=关闭TO=on和收到一个有效的响应/输出,该命令工作的预期)

    在PHP代码和serproxy配置中,验证波特率设置为9600

    尝试简单的修剪和/或正则表达式来过滤噪声,但它没有帮助,因为一些正常的字母数字字符也随机混合在输出中

    修改了php中TCP/IP的一些示例套接字代码。net,我有一个PHP脚本,通过serproxy从串行端口写入2048位数据。每隔10秒,通过jQuery从另一个页面调用该页面,并将回显的内容加载到我主页上的内容中。

    我的最终目标是发送一个1或0的流到我的PHP脚本中,以指示a应该切换它的背景颜色。我更愿意确定那些1或0不仅仅是随机地在额外的字符中回响,而是真正来自序列流本身。

    有人知道serproxy是否是我在PHP中看到的添加或删除不需要的数据的原因吗?

    串行监视器显示正确数据的事实向我表明,这是PHP接收或解析数据的方式。

    我想不出还有什么可以查的了。也许另一双眼睛会发现一些我忽略或做错的事情。

    请参阅下面我的代码,了解以下具体示例:

    电视连续剧html

    <!DOCTYPE html>
    <head>
    </head>
    <body>
        <div id="serial" name="serial" class="serial"></div>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
        <script src="js/main.js"></script>
    </body>
    </html>
    

    serial_output.php

    <?php
    
    // Set service port to 5334 for serproxy
    $service_port = 5334;
    
    // Using localhost address
    $address = '127.0.0.1';
    
    /* Create a TCP/IP socket. */
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    
    if ($socket === false) {
        echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
    } 
    
    // Attempting to connect to '$address' on port '$service_port'...";
    $result = socket_connect($socket, $address, $service_port);
    
    if ($result === false) {
        echo "socket_connect() failed.\nReason: ($result) " .     socket_strerror(socket_last_error($socket)) . "\n";
    }
    
    // Read 2048 bits of data from socket and convert encoding to ASCII
    $out = mb_convert_encoding(socket_read($socket, 2048), 'ASCII'); 
    
    // Filter out anything that is not "AOK"
    if(preg_match("/AOK/", $out)){
        echo 1;
    } else {
        // Else output raw data so we can see what was actaully sent
        echo $out;
    }
    
    // Closing socket...
    socket_close($socket);
    
    ?>
    

    main.js

    // Set #serial background color to red when receiving a "1" 
    function setBgColor(){
        var serial = $('#serial');  
    
        // Set #serial background color to red when receiving a "1"
        if($('#serial').html() == "1") {
            serial.css('background-color','red');
        } else {
            // Set #serial background to white if we did not receive a "1"
            serial.css('background-color', 'white');
        }
    }
    
    var intervalId = window.setInterval(function(){
        $('#serial').load('serial_output.php');
    
        setBgColor();
    }, 100);
    

    arduino_系列。伊诺

    #include <avr/pgmspace.h>
    
    void setup() {
      // Initialize serial and wait for port to open:
      // Currently I have parity on my serial port set to "EVEN" hence SERIAL_8E1
      Serial.begin(9600, SERIAL_8E1);
    } 
    
    void loop() {
       Serial.println("AOK");
    }
    
  • 共有1个答案

    穆俊杰
    2023-03-14

    所以我运行了你的代码,我的Arduino和加速计也有同样的问题。我找到了三种方法来缓解这个问题。

    首先是根据你的预期来错误检查你的数据。如果数据与您期望的不匹配,只需丢弃它。如果你每秒获得10倍的数据,我想你可以承受失去一些。[顺便说一句:服务器代理在10分钟内就会崩溃,所以它对我的用处有限]。

    第二,延迟Arduino端的数据。显然,数据丢失是有关Arduinos和串行端口的“已知问题”。此人在martinmelchior的网站。be有一些代码来延迟从Ardunio发送的数据流;

    `void slowSerialPrint(char text[]) {
      for ( int i ; i < strlen(text) ; i ++ ) {
        Serial.print(text[i]);
        delay(5);
      }
    } `
    

    向下滚动至“但不要太快…”找到那个片段。

    最后,你可以尝试许多其他人正在做的事情,买一个便宜的无线路由器,用它作为你自己便宜的wi-fi屏蔽。奇怪的是,上面链接的网站是做什么的!

    同样值得注意的是,路由器在5V时的最大电流消耗为185mA(OpenWrt启动),在18dBm的无线网络下的平均电流消耗为100mA,而在没有无线网络的情况下为80mA。因此,路由器的平均功耗为0.5W,非常低。

    另外,谢谢你发布的代码,我正在寻找一种方法来做你正在做的事情,所以我实现了你的代码,撞上了同一面墙,通过在javascript中放慢Arduino的输出并丢弃脏数据来解决我的问题,然后分支进入其他选择。

    tl;医生:我认为没有简单的解决办法。

     类似资料:
    • 我试图做一些非常简单的东西,按钮计数器,有一个按钮在我的HTML-php当我点击它我发送数据'按'到我的arduino和它使led闪烁,到目前为止,还不错,但然后我想发送信号,当我在arduino中按下按钮,我想让我的php读取字符串"点击次数: N"的串行端口,N是从arduio的推送计数。 这里的问题是,在arduino串行我可以看到他字符串,一切正常,但在PHP我做

    • 问题内容: 我有一个Java程序,必须读取Arduino发送的信息。我从这里获取了Java代码。现在,我不太了解它是如何工作的,但是我尝试对其进行修改,并且得到了以下信息: 我创建一个对象串行COM口,我需要在主程序,然后我使用和当我需要它。 效果很好,Arduino获取数据并将其显示在LCD显示屏中。问题是。程序运行时,它会不断从串行端口读取数据(大约每40毫秒一次),但这并不意味着Arduin

    • 我想做的是从我用Arudino制作的转速表电路中读取连续的数据流,然后将其输入处理;我已经使用下面的代码成功完成了: 我不确定如何处理数据,以便每当检测到某个值时,处理中都会发生事件。 编辑:有人建议关闭,所以我的问题是调用是一个阻塞调用,这意味着中的指令指针将保持在。指针将调用和,但永远不会到达启动串行端口的线路 建议的解决方案是将这些行移动到的顶部,并将作为的最后一行。我尝试了这个(我下面的代

    • 我已经用java编写了一段代码来与我的Arduino板通信。它工作得很好。我还可以使用串行监视器与Arduino板通信。 但是,当我试图打开串行监视器时,java程序正在运行(监听连接到电子板的端口,端口32),它没有说, 串行端口“COM 32”已在使用中。尝试退出任何可能正在使用它的程序 这是完整的信息(为了完整起见) 是的,我知道,这是我的java程序,它正在使用端口。但这是否意味着我不能同

    • 我有一个BotBoarduino(一个带有一些额外功能的Duemilanove),我试图使用Perl脚本与之通信。如果我从Arduino IDE打开串行监控器,我可以毫无问题地发送和接收数据。在此之后,我的Perl脚本可以毫无问题地进行通信。但是,如果Arduino断开连接,然后重新连接到PC,则Arduino似乎不会监听从我的Perl脚本发送的命令,直到再次打开Serial Monitor。 我

    • 问题内容: 我想知道是否有一种方法可以通过PHP读取我的串行端口-可行:-) 在练习Arduino技能时,我开发了一个简单的LED ON / OFF草图。通过在串行监视器中 打开 或 关闭 它可以工作。 下一步,我整理了一个网页,充当GUI界面,以单击链接并执行上面的打开和关闭功能。该基于Web的GUI可通过PHP使用。我正在使用PHP SERIAL 类与Arduino使用的串行端口进行交互。 问