树莓皮/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是否移动到正确的位置
<?
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);
?>