Arduino串口读取
我正在开发一个网络控制的流动站,并使用串行端口与 Arduino 进行通信。 我编写了一些仅使用 fwrite()
并将 ASCII 1 或 ASCII 2 写入串行端口的 PHP。 Arduino 正在监听该端口并根据它听到的内容执行操作。 我知道我的 PHP 正在工作,因为每当我告诉它发送东西时,Arduino 都会收到它。 这是 Arduino 代码:
//This listens to the serial port (USB) and does stuff based on what it is hearing.
int motor1Pin = 13; //the first motor's port number
int motor2Pin = 12; //the second motor's port number
int usbnumber = 0; //this variable holds what we are currently reading from serial
void setup() { //call this once at the beginning
pinMode(motor1Pin, OUTPUT);
//Tell arduino that the motor pins are going to be outputs
pinMode(motor2Pin, OUTPUT);
Serial.begin(9600); //start up serial port
}
void loop() { //main loop
if (Serial.available() > 0) { //if there is anything on the serial port, read it
usbnumber = Serial.read(); //store it in the usbnumber variable
}
if (usbnumber > 0) { //if we read something
if (usbnumber = 49){
delay(1000);
digitalWrite(motor1Pin, LOW);
digitalWrite(motor2Pin, LOW); //if we read an ASCII 1, stop
}
if (usbnumber = 50){
delay(1000);
digitalWrite(motor1Pin, HIGH);
digitalWrite(motor2Pin, HIGH); //if we read an ASCII 2, drive forward
}
usbnumber = 0; //reset
}
}
所以这应该是相当简单的。 现在,当我发送 ASCII 1 或 ASCII 2 时,我正在测试的 LED(引脚 13)会亮起并保持亮起状态。 但是,如果我发送另一个 ASCII 1 或 2,它会关闭然后重新打开。 目标是仅当最后发送的是 ASCII 1 时才打开它,并保持打开状态直到最后发送的是 2。
编辑:这是我的 PHP:
<?php
$verz="0.0.2";
$comPort = "com3"; /*change to correct com port */
if (isset($_POST["rcmd"])) {
$rcmd = $_POST["rcmd"];
switch ($rcmd) {
case Stop:
$fp =fopen($comPort, "w");
fwrite($fp, chr(1)); /* this is the number that it will write */
fclose($fp);
break;
case Go:
$fp =fopen($comPort, "w");
fwrite($fp, chr(2)); /* this is the number that it will write */
fclose($fp);
break;
default:
die('???');
}
}
?>
<html>
<head><title>Rover Control</title></head>
<body>
<center><h1>Rover Control</h1><b>Version <?php echo $verz; ?></b></center>
<form method="post" action="<?php echo $PHP_SELF;?>">
<table border="0">
<tr>
<td></td>
<td>
</td>
<td></td>
</tr>
<tr>
<td>
<input type="submit" value="Stop" name="rcmd"><br/>
</td>
<td></td>
<td>
<input type="submit" value="Go" name="rcmd"><br />
</td>
</tr>
<tr>
<td></td>
<td><br><br><br><br><br>
</td>
<td></td>
</tr>
</table>
</form>
</body>
</html>
I am working on a web controlled rover and am using a serial port to communicate with an Arduino. I wrote some PHP that just uses fwrite()
and writes an ASCII 1 or an ASCII 2 to the serial port. The Arduino is listening to that port and does stuff based on what it hears. I know my PHP is working, because whenever I tell it to send stuff, the Arduino does receive it. Here is the Arduino code:
//This listens to the serial port (USB) and does stuff based on what it is hearing.
int motor1Pin = 13; //the first motor's port number
int motor2Pin = 12; //the second motor's port number
int usbnumber = 0; //this variable holds what we are currently reading from serial
void setup() { //call this once at the beginning
pinMode(motor1Pin, OUTPUT);
//Tell arduino that the motor pins are going to be outputs
pinMode(motor2Pin, OUTPUT);
Serial.begin(9600); //start up serial port
}
void loop() { //main loop
if (Serial.available() > 0) { //if there is anything on the serial port, read it
usbnumber = Serial.read(); //store it in the usbnumber variable
}
if (usbnumber > 0) { //if we read something
if (usbnumber = 49){
delay(1000);
digitalWrite(motor1Pin, LOW);
digitalWrite(motor2Pin, LOW); //if we read an ASCII 1, stop
}
if (usbnumber = 50){
delay(1000);
digitalWrite(motor1Pin, HIGH);
digitalWrite(motor2Pin, HIGH); //if we read an ASCII 2, drive forward
}
usbnumber = 0; //reset
}
}
So this should be fairly straight forward. Right now, when I send either an ASCII 1 or an ASCII 2, the LED I am testing with (on pin 13) turns on and stays on. But, if I send another ASCII 1 or 2, it turns off and then turns back on. The goal is to have it turn on only if an ASCII 1 was the last thing sent and to stay on until a 2 was the last thing sent.
Edit: Here's my PHP:
<?php
$verz="0.0.2";
$comPort = "com3"; /*change to correct com port */
if (isset($_POST["rcmd"])) {
$rcmd = $_POST["rcmd"];
switch ($rcmd) {
case Stop:
$fp =fopen($comPort, "w");
fwrite($fp, chr(1)); /* this is the number that it will write */
fclose($fp);
break;
case Go:
$fp =fopen($comPort, "w");
fwrite($fp, chr(2)); /* this is the number that it will write */
fclose($fp);
break;
default:
die('???');
}
}
?>
<html>
<head><title>Rover Control</title></head>
<body>
<center><h1>Rover Control</h1><b>Version <?php echo $verz; ?></b></center>
<form method="post" action="<?php echo $PHP_SELF;?>">
<table border="0">
<tr>
<td></td>
<td>
</td>
<td></td>
</tr>
<tr>
<td>
<input type="submit" value="Stop" name="rcmd"><br/>
</td>
<td></td>
<td>
<input type="submit" value="Go" name="rcmd"><br />
</td>
</tr>
<tr>
<td></td>
<td><br><br><br><br><br>
</td>
<td></td>
</tr>
</table>
</form>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果是 C,那么在两个测试中您都会进行赋值,而不是比较,因此两者都是
true
,因此每次都会完成所有写入。 使用高警告级别进行编译(如 GCC 中的-Wall -pedantic
)。 试试这个:从您发布的PHP代码(我不是这里的专家)看来您正在将二进制1写为字符,这不是ASCII 49,而是ASCII 1(所以),与2相同。尝试将其更改为PHP 代码中的
'1'
(或 C 代码中的1
)。这是关于 用 PHP 控制串口 - 我用谷歌搜索,不知道它的质量 - 但看起来仅仅将一个整数写入“ com1” - 这超出了我的领域,祝你好运:)
If it's C then you have assignment instead of comparison in both tests, so both are
true
, so all writes are done every time. Compile with high warning level (like-Wall -pedantic
in GCC). Try this:From PHP code you posted (I'm not an expert here) it looks that you are writing binary 1 as a char, which is not ASCII 49, but ASCII 1 (soh), same for 2. Try changing it to
'1'
in PHP code (or1
in C code.)Here's a link to some article on Controlling the Serial Port with PHP - I googled, no idea of its quality - but doesn't look like it's enough to just write an integer into "com1" - that's out of my domain, so good luck :)
正如尼古拉提到的,看起来你在“if”语句中进行赋值(=)而不是比较(==)。
一些 C 程序员养成的一个好习惯是将右值放在比较的左侧,这样,如果您不小心使用赋值运算符而不是比较运算符,编译器就会生成错误:
无论什么编译器,这都有效您正在使用的标志或警告级别,因为分配给右值是非法的。
我应该补充一点,如果您需要比较两个左值,则此“安全网”不起作用。
As Nikolai mentioned, it looks like you are doing assignment (=) rather than comparison (==) in your "if" statements.
A good habit that some C programmers get into is to put rvalues on the left-hand side of comparisons, so that the compiler will generate an error if you accidentally use the assignment operator instead of the comparison operator:
This works, regardless of what compiler flags or warning level you are using since assigning to an rvalue is illegal.
I should add that this "safety net" doesn't work if you need to compare two lvalues.
可能为时已晚,但我认为您的问题是 serial.read() 一次只能读取一个字符。 如果您从 PC 发送“49”,则当您调用 usbnumber = serial.read() 时,您将在第一个循环中获得“4”,在第二个循环中获得“9”。 这些都不满足条件,因此不执行任何操作,并且 usbnumber 重置为 0。
要修复此问题,您可以将serial.available 条件更改为
,然后执行类似以下操作以转换为数字:
另一个选择是使用 TextFinder库 - 我在我的网站 http://mechariusprojects.com/thunderbolt/?p 上编写了一个简短的教程=60
机甲
May be too late, but I think your problem is that serial.read() only reads one character at a time. If you send "49" from the PC, when you call usbnumber = serial.read() you would be getting "4" the first loop and "9" the second loop. None of these satisfy the conditions so nothing is done and usbnumber is reset to 0.
To fix, you can either change serial.available condition to be
and then do something like the following to convert to a number:
Another option is to use the TextFinder library - I've written a brief tutorial at my website http://mechariusprojects.com/thunderbolt/?p=60
Mech
我发现你的答案正在寻找其他东西,无论如何我刚刚遇到(我猜)你遇到的同样的问题。
如果你还没有解决它,我认为问题不是你的代码,而是arduino板上的自动重置机制。
也就是说:每次在串行端口上建立新连接时,arduino 板都会重置,这允许在通过串行端口对其进行编程时加载新固件。
要验证这一点,请尝试在
setup()
函数中闪烁 LED,如果每次加载页面时 LED 都会闪烁,这证实了我的论点。看看这里:http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection
我通过在 +5V 和 RESET 之间粘贴 120 欧姆电阻来解决。 请记住每次您想要将新固件上传到主板时将其删除。
I found your answer looking for other stuff, anyways I just faced (I guess) the same problem you had.
In case you haven't already solved it, I think the problems is not your code, but the auto-reset mechanism on the arduino board.
That is: each time a new connection is set up on the serial port, the arduino board is reset, this allowing a new firmware to be loaded when programming it via the serial port.
To verify this, try blinking a LED in your
setup()
function, if it blinks each time you load the page, this confirms my thesis.Have a look here: http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection
I solved by sticking the 120 Ohm resistor between +5V and RESET. Just remember to remove it every time you want to upload a new firmware to your board.