I am using the RS-232 lines on my Pi to communicate with a laser range finder. I have tested the communication between the two using minicom at a baud rate of 19200(because that is the baud rate of the LRF and can't be changed), and it works fine. Although writing down to the LRF any commands(which consists of a single character and pressing 'enter') can take several attempts to take affect, communication in both directions works great.
However, when I start programming in C code to read and write with the RS-232, it half works. Here is the code I am using:
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
//SETUP UART0
int main(){
int uart0_filestream = -1;
int loop;
int i;
int isError=1, rx_length;
unsigned char rx_buffer[256];
useconds_t micro=3000;
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
if(uart0_filestream == -1)
printf("ERROR: Unable to open UART\n\n");
else
printf("UART open\n\n");
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR | ICRNL;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
p_tx_buffer = &tx_buffer[0];
*p_tx_buffer++ = 'o';
*p_tx_buffer++ = '\n';
/*
if(uart0_filestream != -1){
for(i = 0; i<100; i++){
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0]));
if(count < 0)
printf("\n\nERROR: No bytes written\n\n");
else
printf("%i bytes written: %s\n", (p_tx_buffer - &tx_buffer[0]), tx_buffer);
}
}
*/
if(uart0_filestream != -1){
for(i=0; i<50; ){
rx_length = read(uart0_filestream, (void*)rx_buffer, 255);
if(rx_length > 0){
printf("rx_lentgh = %i:\t ", rx_length);
for(loop=0; loop<30; loop++){
//check for NULL and new line for easier readability
if(rx_buffer[loop] == NULL)
rx_buffer[loop] = '$';
if(rx_buffer[loop] == '\n')
rx_buffer[loop] = '%';
printf("%c", rx_buffer[loop]);
}
printf("\n");
i++;
}
}
}
close(uart0_filestream);
}
When I try to read from the device, it always returns an error. I started looping to see if continually reading gave different results. Of the 100 tries, typically 4-5 return data, all the rest [i]rx_length[/i] comes back -1. The data returned should look like:
COUNTS:0000
where the number depends on the distance the LRF is measuring. But instead, I get output like this:
rx_lentgh = 16: jRþ$COUNTS:0000%$$$$$$$$$$$$
rx_lentgh = 8: %$COUNTSTS:0000%$$$$$$$$$$$$
rx_lentgh = 16: :0142%%$COUNTS:0$$$$$$$$$$$$
rx_lentgh = 8: 000%%$COCOUNTS:0$$$$$$$$$$$$
rx_lentgh = 16: UNTS:0142%%$COUN$$$$$$$$$$$$
rx_lentgh = 24: TS:0142%%$COUNTS:0000%%$$$$$
rx_lentgh = 8: COUNTS:0%$COUNTS:0000%%$$$$$
rx_lentgh = 16: 142%%$COUNTS:000:0000%%$$$$$
rx_lentgh = 16: 0%%$COUNTS:0142%:0000%%$$$$$
rx_lentgh = 8: %$COUNTSTS:0142%:0000%%$$$$$
rx_lentgh = 8: :0000%%$TS:0142%:0000%%$$$$$
rx_lentgh = 8: COUNTS:0TS:0142%:0000%%$$$$$
rx_lentgh = 24: 142%%$COUNTS:0142%%$COUN$$$$
rx_lentgh = 8: TS:0000%UNTS:0142%%$COUN$$$$
rx_lentgh = 16: %$COUNTS:0000%%$2%%$COUN$$$$
rx_lentgh = 8: COUNTS:0:0000%%$2%%$COUN$$$$
rx_lentgh = 16: 142%%$COUNTS:0002%%$COUN$$$$
rx_lentgh = 8: 0%%$COUNUNTS:0002%%$COUN$$$$
rx_lentgh = 16: TS:0142%%$COUNTS2%%$COUN$$$$
rx_lentgh = 8: :0000%%$%$COUNTS2%%$COUN$$$$
rx_lentgh = 16: COUNTS:0142%%$CO2%%$COUN$$$$
rx_lentgh = 8: UNTS:000142%%$CO2%%$COUN$$$$
rx_lentgh = 24: 0%%$COUNTS:0142%%$COUNTS$$$$
rx_lentgh = 16: :0000%%$COUNTS:0%$COUNTS$$$$
rx_lentgh = 24: 142%%$COUNTS:0142%%$COUN$$$$
rx_lentgh = 8: TS:0000%UNTS:0142%%$COUN$$$$
rx_lentgh = 16: %$COUNTS:0142%%$2%%$COUN$$$$
**The above is edited in my code for readability. A NULL character is replaced with '$' and a '\n' is replaced with '%'
You can see that every time it gets data, it at least gets part of a good read, and occasionally the whole thing. But there is a lot of junk in there. You can see in my code I have filtered out all reads that returned in an error. It would probably take over 1000 reads to get this many "good" reads. I really think it has to do with timing, but even if it was timing, wouldn't shouldn't I still be getting [i]some[/i] data back?
Writing has the same issue. A single write does nothing. Looping the write code 100 times may end up getting the code down to the LRF, but the LRF pretty much doesn't work at all after running that code and I haven't to cut power to get it to work and view data in minicom again.
The LRF has can send packets at 200Hz or 10Hz, depending on the mode. All data retrieved above was done with the LRF sending packets at 200Hz.
Any help at all would be greatly appreciated! I have been working on this for several weeks between my other classes and work.