与RPI RS-232通讯 [英] RS-232 communication with RPi

查看:199
本文介绍了与RPI RS-232通讯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个跟进的问题这个原帖:

This is a follow up question to this original post:

树莓派RS-232的麻烦

我所做的更改每公认的答案我的code,终端现在设置为阻止和标准输入。在阅读()现在将按预期,随着第一个读异常(这通常是一些良好的数据混了一些额外的随机符号)我得到的数据的单一线从激光测距仪重新presenting正是我期望看到的。

I made changes to my code per the accepted answer, the terminal is now set up for blocking and canonical input. The read() now works as expected, with the exception of the very first read(which is typically some extra random symbols mixed with some good data) I get single lines of data from the laser range finder representing exactly what I expect to see.

不过,我现在有,如果我做太多的读取,激光测距仪被放入非工作状态的问题,停止沟通,只能通过做一个电源周期进行复位。这已经发生在只有4设备上读取的,我没有能够做到超过8读取。不要紧,如果是读取一次全部或跨区跨多个程序启动。

However, I now have an issue that if I do too many reads, the laser range finder is put into a non-operating state, stops communication, and can only be reset by doing a power cycle. This has happened with as few as 4 reads on the device, and I haven't been able to do more than 8 reads. It doesn't matter if the reads are all at once, or spanned across several program starts.

int main(){
    int uart0_filestream = -1;
    int loop, i, sentBytes;
    int isError, rx_length;
    unsigned char rx_buffer[256];

    uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
    fcntl(uart0_filestream, F_SETFL, 0);

    if(uart0_filestream == -1){
        printf("ERROR: Unable to open UART\n");
        checkError(errno);
        exit(1);
    }

    struct termios options;

    isError = tcgetattr(uart0_filestream, &options);

    if(isError < 0){
        printf("ERROR: tcgetattr failed.\n");
        checkError(errno);
        exit(1);
    }

    //set c ontrol options and baud
    options.c_cflag |= (CLOCAL | CREAD);
    cfsetispeed(&options, B19200);
    cfsetospeed(&options, B19200);

    //set 8 data bits, 1 stop bit, no parity
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    //set input options
    options.c_iflag |= (INPCK | ISTRIP);        //strip parity
    options.c_iflag &= ~(IXON | IXOFF | IXANY); //turn off software flow control

    //set canonical input processing
    options.c_lflag |= (ICANON | ECHO | ECHOE);

    tcflush(uart0_filestream, TCIFLUSH);
    isError = tcsetattr(uart0_filestream, TCSANOW, &options);

    if(isError < 0){
        printf("ERROR: tcsetattr failed.\n");
        checkError(errno);
        exit(1);
    }

    //read() successfully returns expected data, with the exception of the first 
    //read. Reading more than 6-8 times, regardless of same session or restarting
    //program puts LRF in non-working state which requires a power cycle to fix
    for(i=0; i<4;i++ ){
        rx_length = read(uart0_filestream, (void*)rx_buffer, 255);

        if(rx_length < 0){
            printf("ERROR: read() failed.\n");
            checkError(errno);
        }

        if(rx_length > 0){
            printf("rx_lentgh = %i:\t ", rx_length);
            for(loop=0; loop<rx_length; loop++){
                printf("%c", rx_buffer[loop]);
            }
            printf("\n");
        }
    }

    //writing once has no affect, sending command has no affect
    //looping the write, eventually 'something' gets to the LRF
    //but it puts it in the same state as when reading too many
    //times and have to power cycle
    for(i = 0; i<8; i++){
        sentBytes = write(uart0_filestream, "o\n", 2);

        if(sentBytes < 2){
            printf("ERROR: write() failed.\n");
            checkError(errno);
        }   
    }

    close(uart0_filestream);
}

我不相信它是测距仪,因为我可以运行小型机,它会不断地成功地显示输出。

I don't believe it is the range finder, as I can run minicom and it will continuously display the output successfully.

正如我在code的评论中指出,我也有麻烦写任何命令的激光测距仪。每个命令由单个字符,后跟一个新行。一个写没有影响,但循环几次就可以把该设备在相同的状态读取次数过多。

As noted in the comments of my code, I also have trouble writing any commands to the laser range finder. Each command consists of a single character, followed by a new line. One write has no affect, but looping several times can put the device in the same state as reading too many times.

我已阅读 Posix的串行编程指南,并尝试不同的组合我认为可能会影响无论是读或写的,但标记没有成功。

I have read Posix Serial Programming Guide, and tried different combinations of flags that I believe might affect either the reading or writing, but have had no success.

推荐答案

这导致的建议是我的尴尬 - 以为字符串是O / N

This lead suggestion is my embarrassment - thought the string was "o/n".

数据发送量是1短。

// sentBytes = write(uart0_filestream, "o\n", 2);
// if(sentBytes < 2){
sentBytes = write(uart0_filestream, "o\n", 3);
if(sentBytes < 3){


小:不清楚为什么读缓存减少1(sizeof的RX_BUFFER为256)。 阅读()不会追加 \\ 0 而且也没有这个code。 code很好地把传入的数据字节数组。虽然在的printf(%C... 的东西可以,如果做!isgraph(RX_BUFFER [循环])`。


Minor: Unclear why read buffer is reduced by 1 (sizeof rx_buffer is 256). read() is not going to append a \0 and neither does this code. Code nicely treats the incoming data as an array of bytes. Although in printf("%c"... something could be done if !isgraph(rx_buffer[loop])`.

// rx_length = read(uart0_filestream, (void*)rx_buffer, 255)
rx_length = read(uart0_filestream, (void*)rx_buffer, sizeof rx_buffer)

这篇关于与RPI RS-232通讯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆