我将尝试简要介绍该项目,然后介绍当前的代码方法。
这是我目前的位置。
因为我的Arduino通过USB连接到RPi。我无法使用串行监视器调试内容。...我在这里还有其他选择吗?
提交网页时。.–我看到Arduino上的RX / TX指示灯闪烁(使我相信它正在接收串行数据)。.我可以/将检查它是否正确。今晚再次挂上步进电机,看看ti是否移到正确的位置...
这是我被困/绊倒的地方..可以通过一些讨论使我走上正确的道路。
因此,在Arduino“完成其魔力”之后..应该将确认消息发送回RPi ..说饮料已经完成..我可以返回主饮料菜单等待下一个订单>
因为该网页已经$ _POSTed ..并且串行数据已发送到连接的Arduino .. ..然后我离开该页面,显示“请稍候”消息...但是因为该页面已经在服务器上解析事情的另一面,我现在需要如何通过PHP“监听”串行posrt。
我想..我可以使用一些AJAX来调用/加载一个外部php脚本..该脚本将等待/侦听串行端口..并将数据返回给AJAX'success'回调。
但是,因为我以前从未做过..如果这行得通..或者这甚至是正确的方法,我会有点怀疑。
还随机询问打开和关闭端口的最佳位置。特别是如果有2个单独的脚本? (即:我可以在一个脚本中打开该端口..仍然在另一个脚本中访问它吗?还是该文件正在访问它..需要成为打开它的那个文件?)
这是我当前的代码片段,用于处理串行端口的发送和等待/监听:
[代码]
<?
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代码段调用)
//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表单的SUBMIT状态:
数据发送在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';
}
}
答案 0 :(得分:0)
无法发表评论(无声誉) 我对Ajax,jquery,Raspberry Pi或PHP不了解,但是...
如果您拥有this之类的USB串行转TTL设备,则可以使用SoftwareSerial库。在arduino上几个未使用的数字引脚上设置SoftwareSerial,并在那里发送调试信息。
不是答案,而是建议。
*********编辑***********
请考虑一下,Raspberry Pi是否没有串行端口? 如果是这样,则不需要USB转换器。只需在Arduino上设置softwareSerial端口,然后使用该端口连接到Pi。您可以使用USB端口的另一种方式将调试com发送到计算机。
答案 1 :(得分:-1)
首先,我没有Raspberry和Arduino的经验,但过去确实玩过串行通信。 您使事情变得太复杂了。串行通信不是历史通道中的奇特动物-将其作为数据层。您会轻松地创建所需的前端和后端IF数据是否来自/进入数据库?现在,以完全相同的方式实现您的系统,而不是使用串行通信来代替数据库连接。
您的serial_listener很简单:
因此,整个案例:
frontend --post(d)-> serial_listener :: COM1 :: send(d)... COM1 :: read('OK')->回复'success'
PS。 那些小型控制器... 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
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);
?>
这样,您可以在屏幕上显示“正在加载...”图像,直到响应为止。最初呈现的页面一直存在。当然,当串行等没有响应时,您需要进行很多(错误)检查,解决方案等。但是基本系统不是“火箭科学”。