如何通过Apache网络服务器控制Raspberry Pi的串行GPIO引脚


How to control the serial GPIO pin of Raspberry Pi via an Apache web sever

我想使用Raspberry Pi上运行的Apache服务器,通过GPIO串行端口将数据从Raspberry Pi发送到Arduino Uno。我将RPI的TX引脚连接到3.3 V至5 V电平转换器,并将其输出连接到RX Arduino PIN。

为了将数据从Raspberry Pi发送到Arduino,我使用了以下C程序,我为Raspberry Pi重新编译了该程序,它工作正常。我将可执行代码重命名为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)通过"system"命令处理软件:

<?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开发了一个简单的草图,如果从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。 您可以通过在 httpd.conf 中设置以下内容来将 Apache 配置为以 root 身份运行来快速测试这一点:

User root

由于以root身份运行Web服务器不是一个好主意,因此您需要找出Apache通常在您的系统上运行的用户(可能是www),并授予该用户使用串行端口的权限。 这样的事情可能会起作用:

chown :www /dev/ttyAMA0
chmod g+rw /dev/ttyAMA0

或者,您可能只需要将用户www添加到类似 callout 的组中:

useradd -G callout www

根据您的特定系统进行调整。