Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
树莓皮/PHP+;Arduino串行通信_Php_Jquery_Ajax_Arduino_Raspberry Pi - Fatal编程技术网

树莓皮/PHP+;Arduino串行通信

树莓皮/PHP+;Arduino串行通信,php,jquery,ajax,arduino,raspberry-pi,Php,Jquery,Ajax,Arduino,Raspberry Pi,我将尝试对项目进行简要总结,然后介绍当前的代码方法 我有一个RPi,都是用最新的Stretch OS设置的 我已经安装了MySQL、PHP、APahce和PhpMyAdmin,并且工作正常 我让它启动到默认(本地托管)网页,并在全屏(亭)模式 数据库已创建,表已填充,查询已就位。。并且网页(饮料菜单)按预期正确显示 我的Arduino UNO通过USB连接到RPI 该网页显示了一系列菜单选项。。每个都有自己的“订单”按钮 单击任何订单按钮时。。我将此按钮数据保存到一个隐藏字段,并使用jQ

我将尝试对项目进行简要总结,然后介绍当前的代码方法

  • 我有一个RPi,都是用最新的Stretch OS设置的
  • 我已经安装了MySQL、PHP、APahce和PhpMyAdmin,并且工作正常
  • 我让它启动到默认(本地托管)网页,并在全屏(亭)模式
  • 数据库已创建,表已填充,查询已就位。。并且网页(饮料菜单)按预期正确显示

  • 我的Arduino UNO通过USB连接到RPI
  • 该网页显示了一系列菜单选项。。每个都有自己的“订单”按钮
  • 单击任何订单按钮时。。我将此按钮数据保存到一个隐藏字段,并使用jQuery提交/发布表单(到表单本身)
  • 在$u POST上,我抓取提交的数据,并通过PHP通过串行通信1发送出去
这就是我目前的处境

  • 因为我的Arduino是通过USB连接到RPi的。我不能用串行监视器调试东西。。。。我还有其他选择吗

  • 当我提交网页时。。我-确实-看到Arduino上的RX/TX指示灯闪烁(使我相信它正在接收串行数据)。。我可以/将在今晚再次连接步进电机,检查其是否正确,并查看ti是否移动到正确的位置

这就是我有点受困的地方。。可以通过一些讨论让我走上正确的道路

所以在Arduino“施展魔法”之后。。它应该向RPi发送确认消息。。说饮料已经喝完了。。我可以回到主菜单等待下一道菜

因为网页已经发布了$_..,并且串行数据已发送到连接的Arduino。。然后我离开页面,显示“请稍候”消息。。。但是由于页面已经在服务器端解析了,我现在需要通过PHP“监听”串行posrt

我想。。我可以使用一些AJAX来调用/加载外部php脚本。。这将只是等待/侦听串行端口。。并将数据返回到AJAX“success”回调

但是我以前从来没有这样做过。。我有点怀疑这是否行得通。。或者这是否是正确的方法

还有关于打开和关闭端口的最佳位置的随机问题。。特别是如果有两个单独的脚本?(即:我可以在一个脚本中打开端口..然后在另一个脚本中访问它吗?或者访问它的文件..需要是打开它的文件吗?)

下面是我当前处理串行端口的发送和等待/侦听的代码段:

[守则]

<?
if ($mode == 'submit') {

    //grab posted data (save to var)
    $drinkRecipe = $_POST['selectedDrink'];

    //set-up com port    
    exec("mode /dev/ttyACM0 BAUD=9600 PARITY=N data=8 stop=1 xon=off");
    //saw this on several RPi posts?  (but not sure of the difference? or why one would be used over the other?)
    //stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

    //open serial port
    $fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write

    //check if open
    if (!$fp) {
        echo "Not open";
        //die();
    } else {
        //if open send data (via PHP) to connected Arduino on serial comm port 1 (ttyACM0)
        fwrite($fp, '<' . $drinkRecipe . '>');


        //arduino takes serial data, parsed it.. does it duty, 
        //and is supposed to reply back via serial to the awaiting (listening) 
        //PHP script executed via AJAX, since the front end needs to display 
        //a 'waiting' type message.. and the callback 'success' will 
        //re-direct back to menu/initial state
        ?>
        <script type="text/JavaScript" language="JavaScript">
            $.ajax({
                //async: false,
                //type: "POST",
                url: "serial_listener.php",

                //define success handler actions
                success: function(response) {
                    //alert("PHP RETURN CHECK: "+response);
                    if($.trim(response) == 'complete'){
                        alert("Drink making is complete... return to main menu");
                        //do redirect here
                    }else{
                        alert("Some value other than 'complete' was returned... look into it!");
                        //not sure what to do? (back to main menu anyways?)
                    }
                },
                //define error handler actions
                error: function(response) {
                    alert("PHP SERIAL READ FAIL: "+ 'Ready State: '+ response.readyState + ' Status: ' + response.status);

                }
            }); 
        </script>       
        <?              

        //close connection
        fclose($fp); //needed? //should this go in the external php script instead now?

    }    

}
最后更新: 我重新编写了一些东西,以使用AJAX调用发送数据。。并等待回应。 AJAX调用执行的外部php脚本是现在打开端口的唯一地方(我不会关闭它)

以下是具有AJAX调用的PHP表单的提交状态:

发送数据的工作时间为100%。。但我看不懂我的回答

if ($mode == 'submit') {

    //grab posted data (save to var)
    $drinkRecipe = $_POST['selectedDrink'];

    ?>  
    <div id="waitingContainer">
        <p>Please wait, your brink is being made.</p>
    </div>

    <script type="text/JavaScript" language="JavaScript">
        console.log("ajax routine hit");

        //var drinkRecipe = "<?php echo $drinkRecipe ?>";
        var drinkRecipe = "<?=$drinkRecipe?>";

        var xhr = $.ajax({
            //async: false,
            type: "POST",
            url: "serial_listener.php",
            //datatype: "html",
            datatype: "text",
            data:({"drinkData":drinkRecipe}),
            //define success handler actions
            success:function(response) {
                //alert("PHP RETURN CHECK: "+response);
                if($.trim(response) == 'complete'){
                    console.log("Drink making is complete... return to main menu");
                    //do redirect here
                }else{
                    console.log("Some value other than 'complete' was returned... look into it!");
                    console.log("RESPONSE SENT WAS: " + response);
                    //not sure what to do? (back to main menu anyways?)
                }
                //kill the request
                xhr.abort();
            },
            //define error handler actions
            error: function(response) {
                console.log("PHP SERIAL READ FAIL: "+ 'Ready State: '+ response.readyState + ' Status: ' + response.status);
                //kill the request
                xhr.abort();
            }
        });     
    </script>
    <?             
}
if($mode=='submit'){
//抓取过账数据(保存到var)
$drinkRecipe=$\u POST['selectedDrink'];
?>  
请等一下,你的悬崖已经被挖出来了

log(“ajax例程命中”); //var drinkRecipe=“”; var drinkRecipe=“”; var xhr=$.ajax({ //async:false, 类型:“POST”, url:“serial_listener.php”, //数据类型:“html”, 数据类型:“文本”, 数据:({“drinkData”:drinkRecipe}), //定义成功处理程序操作 成功:功能(响应){ //警报(“PHP返回检查:+响应”); 如果($.trim(响应)=“完成”){ 日志(“饮料制作完成…返回主菜单”); //请在这里重定向 }否则{ log(“返回了“complete”以外的一些值……请查看它!”); 日志(“发送的响应为:+响应”); //不知道该怎么办?(无论如何回到主菜单?) } //终止请求 xhr.abort(); }, //定义错误处理程序操作 错误:函数(响应){ log(“PHP串行读取失败:“+”就绪状态:“+response.readyState+”状态:“+response.Status”); //终止请求 xhr.abort(); } });
首先,我对覆盆子和Arduino都没有使用Expirence,但我在过去玩过串行通信。 你把事情弄得太复杂了。串行通信不是来自历史频道的奇怪动物——把它当作一个数据层。如果数据来自/进入数据库,你可以轻松地创建所需的前端和后端?现在,以完全相同的方式实现系统,只是使用串行通信代替数据库连接

您的串行侦听器很简单:

  • 创建/配置端口
  • 发送数据
  • 读取数据
  • 关闭端口
因此,整个案例:

前端--post(d)-->serial_listener::COM1::send(d)..COM1::read('OK')-->回复“success”

附言。 有了这些小型控制器…timeout()才是您真正的朋友;)

对于串行通信,我建议使用一些库(例如php_serial.class)


我试着用一段代码来澄清,我试着保持它的简单,只是为了说明整个系统

前端、纯js/html和AJAX请求:

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body onLoad="$('#loading-image').hide();">


<div width="100%" style="text-align: center;">
    <div id="demo">
        <h2>Content: forms/scripts/...</h2>
    </div>
    <div>
        <button type="button"
            onclick="makeSerialCall('serial.php')">order (send AJAX call to php script)
        </button>
    </div>
</div>
<img id='loading-image' src='https://media.tenor.com/images/011ebf9c192d1c9b26f242d526ee24bb/tenor.gif'></img>


<script>
var string = 'data which is collected from content above';

function makeSerialCall(url) {
        $('#loading-image').show();
        $.ajax({
            type: "POST",
            url: url,
            data: string,
            cache: false,
            success: function(response){
                $('#loading-image').hide();
                console.log(JSON.stringify(response['info']));
                //and whatever else you want to do afterwards...
            }
        });
}
</script>
</body>

内容:表格/脚本/。。。
订单(向php脚本发送AJAX调用)
变量字符串='从上述内容收集的数据';
函数makeSerialCall(url){
$(“#加载图像”).show();
$.ajax({
类型:“POST”,
url:url,
数据:
//data sent from AJAX call (works)
$drinkData = $_POST['drinkData'];

//open serial port
$fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write  (works)
//$fp = fopen("/dev/ttyUSB0", "w+"); //w = write w+ = read/write  //tried with USB-TTL cable too.. couldnt even send data)

//check if open
if (!$fp) {
    echo "Not open";
    //die();    
} else {

    if($drinkData != ''){   
        //send drink data
        fwrite($fp, '<' . $drinkData . '>');

        //wait for response
        $chars = "";
        do{
            $char = fread($fp, 1);
            $chars .= $char;
        }while(strlen($char) < 1);
        echo $char;
    }else{
        echo 'drink recipe is empty';
    }   
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body onLoad="$('#loading-image').hide();">


<div width="100%" style="text-align: center;">
    <div id="demo">
        <h2>Content: forms/scripts/...</h2>
    </div>
    <div>
        <button type="button"
            onclick="makeSerialCall('serial.php')">order (send AJAX call to php script)
        </button>
    </div>
</div>
<img id='loading-image' src='https://media.tenor.com/images/011ebf9c192d1c9b26f242d526ee24bb/tenor.gif'></img>


<script>
var string = 'data which is collected from content above';

function makeSerialCall(url) {
        $('#loading-image').show();
        $.ajax({
            type: "POST",
            url: url,
            data: string,
            cache: false,
            success: function(response){
                $('#loading-image').hide();
                console.log(JSON.stringify(response['info']));
                //and whatever else you want to do afterwards...
            }
        });
}
</script>
</body>
<?php
if(!empty($_POST))
  $data = $_POST["data"];

include "php_serial.class.php";

$serial = new phpSerial();
$serial->deviceSet("/dev/ttyUSB0");
$serial->confBaudRate(9600);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");

$serial->deviceOpen();
$serial->sendMessage($data);
$read = $serial->readPort();
$serial->deviceClose();

header('Content-type: application/json');
$response_array['status'] = 'success'; 
$response_array['info'] = 'some additional info:'.$read;   
echo json_encode($response_array);
?>