如何通过 Apache Web 服务器控制 Raspberry Pi 的串行 GPIO 引脚
Posted
技术标签:
【中文标题】如何通过 Apache Web 服务器控制 Raspberry Pi 的串行 GPIO 引脚【英文标题】:How to control the serial GPIO pin of Raspberry Pi via an Apache web sever 【发布时间】:2015-03-08 17:38:07 【问题描述】:我想使用运行在 Raspberry Pi 上的 Apache 服务器通过 GPIO 串行端口将数据从 Raspberry Pi 发送到 Arduino Uno。我将 RPI 的 TX 引脚连接到 3.3 V 至 5 V 电平转换器,并将其输出连接到 RX Arduino PIN。
为了将数据从 Raspberry Pi 发送到 Arduino,我使用了为 Raspberry Pi 重新编译的以下 C 程序,它工作正常。我重命名了可执行代码SendUART
。
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
#include <string.h>
main(int argc,char **argv)
//----- TX BYTES -----
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
int lx;
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
//CONFIGURE THE UART
//The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input (Use for ASCII comms where you want to auto correct end of line characters - don't use for bianry comms!)
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B9600 | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
p_tx_buffer = &tx_buffer[0];
strcpy(tx_buffer, argv[1]);
lx=strlen(tx_buffer);
if (uart0_filestream != -1)
int count = write(uart0_filestream, &tx_buffer[0], 10); //Filestream, bytes to write, number of bytes to write
if (count < 0)
printf("UART TX error\n");
//----- CLOSE THE UART -----
close(uart0_filestream);
然后我使用php脚本(test.php)通过“系统”命令来处理软件:
<?php
$mes = "0123456789";
$retval = 0;
$last_line = 0;
echo($mes);
$SndMsg = "/var/www/SendUART " . $mes;
$last_line = system($SndMsg, $retval);
echo $last_line
?>
我通过命令行执行了它:
php -f test.php
Arduino 正确接收了字符串(我为 Arduino 开发了一个简单的sketch,如果从 Rx 引脚接收到所有字符,它会打开板载 LED)。
然后我通过 Apache Web 服务器调用 PHP 脚本,在地址栏中写: http://192.168.1.103/test.php
其中 192.168.1.103 是 Raspberry Pi 的 IP 地址,test.php
是 PHP 脚本。当然test.php
和SenUART程序都存放在同一个文件夹/var/www/下,但是浏览器显示如下错误:
0123456789错误 - 无法打开 UART。确保它没有被其他应用程序使用
我该如何解决这个问题?
【问题讨论】:
UART 是否被启用为串行控制台?你用的是树莓派吗? raspberry-projects.com/pi/pi-operating-systems/raspbian/… UART 已启用。我正在使用树莓派。 您必须禁用 UART 用作串行控制台。查看之前发布的链接。 【参考方案1】:运行您的网络服务器的用户可能无法访问 UART。您可以通过在httpd.conf
中设置以下内容,将 Apache 配置为以 root 身份运行来快速测试:
User root
由于以 root 身份运行网络服务器不是一个好主意,因此您需要找出 Apache 通常在您的系统上运行的用户身份(可能是 www
)并授予该用户使用串行端口的权限。这样的事情可能会奏效:
chown :www /dev/ttyAMA0
chmod g+rw /dev/ttyAMA0
或者,您可能只需将用户 www
添加到像 callout
这样的组:
useradd -G callout www
根据您的特定系统进行调整。
【讨论】:
亲爱的菲利普,太棒了!有用!!非常感谢!以上是关于如何通过 Apache Web 服务器控制 Raspberry Pi 的串行 GPIO 引脚的主要内容,如果未能解决你的问题,请参考以下文章
Apache基础服务之Web访问控制(身份验证虚拟目录虚拟主机)