【发布时间】:2018-09-20 21:53:13
【问题描述】:
我将尝试对项目进行简要总结,然后是当前的代码方法。
- 我有一个安装了最新 Stretch OS 的 RPi。
- 我已经安装了 MySQL、PHP、APahce 和 PhpMyAdmin,并且可以正常工作。
- 我让它启动到默认(本地托管)网页和全屏 (KIOSK) 模式。
- 已创建数据库、已填充表格、已就位查询......并且网页(饮料菜单)按预期正确显示。
- 我的 Arduino UNO 通过 USB 连接到 RPI
- 网页显示了一堆菜单选项。每个选项都有自己的“订购”按钮。
- 点击任何订单按钮时..我将此按钮数据保存到隐藏字段,并使用 jQuery 提交/发布表单(给自己)
- 在 $_POST 之后,我抓取了这个提交的数据,并通过 PHP 通过串行通信 1 将其发送出去。
这就是我现在所在的地方。
因为我的 Arduino 通过 USB 连接到 RPi。我无法使用串行监视器进行调试....这里还有其他选择吗?
当我提交网页时.. 我 - 确实 - 看到 Arduino 上的 RX/TX 灯闪烁(让我相信它正在接收串行数据).. 我可以/将检查它是否正确今晚再次连接步进电机,看看 ti 是否移动到正确的位置......
这是我被卡住/难倒的地方......并且可以通过一些讨论让我走上正确的道路。
所以在 Arduino '施展魔法'之后......它应该向 RPi 发送一条确认消息......说饮料已经完成......我可以回到主饮料菜单等待另一个订单
因为网页已经 $_POSTed.. 并且串行数据发送到连接的 Arduino.. 然后我离开页面显示“请稍候”消息...但是因为该页面已经在服务器上解析一方面,我现在需要如何通过 PHP '收听'串行 posrt。
我想..我可以使用一些 AJAX 来调用/加载外部 php 脚本..它只会等待/侦听串行端口..并将数据返回给 AJAX“成功”回调。
但是因为我以前从未这样做过.. 我有点怀疑这是否可行.. 或者这是否是正确的方法。
还有关于打开和关闭端口的最佳位置的随机问题。特别是如果有 2 个单独的脚本? (即:我可以在一个脚本中打开端口.. 并且仍然在另一个脚本中访问它吗?或者访问它的那个文件.. 需要是打开它的那个吗?)
这是我目前用来处理串口发送和等待/监听的sn-p:
[代码]
<?
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?
}
}
甚至不知道应该进入什么:serial_listener.php 脚本...只是一个while循环或什么?等待数据?或文件结尾什么的? (不确定在串口上使用 fread() 是如何工作的?)
感谢任何尝试解决这个问题的建议。
更新:我不确定我是否没有正确/清楚地解释事情?
但是当页面提交时(向自身).. 即当输出串行数据被发送到连接的(通过 USB 到 RPi)Arduino..
当页面“发布”时,它会将上述数据发送出去......然后显示“请稍候”类型的消息。
此时(据我所知).. 服务器端脚本/解析现已完成...我只剩下一个页面说“请稍候”...
此时没有更多的解析/服务器端任何东西..
这就是为什么我想/提出使用 AJAX 调用外部脚本的原因,该脚本可以坐下来“等待”(监听)串行端口(不清楚如何最好地处理这个......一段时间() 循环还是什么?)...
然后当数据最终返回时......
*
(不知道这个“连续剧”需要多长时间 来自 Arduino 的反馈 .. 因为每种饮料需要不同量的 时间创造)............
*
它将使用 AJAX 'success' 回调函数来更新页面.. 并最终再次将其重定向回主饮料菜单页面.. 重新开始。
我不觉得在 Arduino 上使用 timeout() 或 delay() 不仅是不好的建议(即:永远不要使用 delay() 如果可以帮助它).....但我什至不知道在哪里/为什么这有什么意义吗?
更新:
以及serial_listener.php脚本的内容:(脚本AJAX sn-p调用)
//set-up com port
exec("mode /dev/ttyACM0 BAUD=9600 PARITY=N data=8 stop=1 xon=off");
//open serial port
$fp = fopen("/dev/ttyACM0", "w+"); //w = write w+ = read/write
//check if open
if (!$fp) {
echo "Not open";
//die();
} else {
while(!feof($fp)){
$response = fread($fp, 10);
}
echo $response;
fclose($fp);
}
最终更新:
我重写了一些东西来使用 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>
<?
}
以下是 AJAX 调用执行的 serial_listener.php 脚本的内容:
//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';
}
}
【问题讨论】:
标签: php jquery ajax arduino raspberry-pi