UART programming

I am writing a UART receiver, why am I getting line 65 instead of line 75 ? I have checked using minicom and there are characters being received, so I suspect it is due to the way I use the read function. Any idea ?

The cpp code is posted below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <unistd.h>			//Used for UART
#include <fcntl.h>			//Used for UART
#include <termios.h>			//Used for UART
 
using namespace std;

int main(int argc, char** argv)
{
	//-------------------------
	//----- 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/ttyUSB1", O_RDONLY | 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 | PARENB | 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);

	//----- CHECK FOR ANY RX BYTES -----
	if (uart0_filestream != -1)
	{
		// Read up to 255 characters from the port if they are there
		unsigned char rx_buffer[256];
		int rx_length = read(uart0_filestream, (void*)rx_buffer, 255);		//Filestream, buffer to store in, number of bytes to read (max)

	    while (rx_length < 255) 
	    {
		if (rx_length < 0)
		{
			//cout << "An error occured (will occur if there are no bytes)" << endl;
		}
		else if (rx_length == 0)
		{
			//cout << "No data waiting" << endl;
		}
		else
		{
			//Bytes received
			rx_buffer[rx_length] = '\0';
			printf("%i bytes read : %s\n", rx_length, rx_buffer);
		}
	    }
	}


	//----- CLOSE THE UART -----
	close(uart0_filestream);
}
Last edited on
Check errno to find out why the read failed.
With the help of perror, I am getting error "Resource temporarily unavailable" if I set O_NDELAY , otherwise no error message is printed out.
Last edited on
If you check the specs of the UART you'll probably find that it takes some small amount of time to set up after you set the options. Put the read in a loop, perhaps with a short delay between calls based on the setup time of UART.
Ok, now I can receive the characters.

I am trying to do an assertion on the rx_buffer against the intended message "HELLO_WORLD!! \r\n"
However, the read() function does not seem to be able to read all the receiving bytes including NULL '\n' and space ' '

Any idea ?

rx_length = 1 rx_buffer =
rx_length = 15 rx_buffer = HELLO_WORLD!!
rx_length = 1 rx_buffer =
ELLO_WORLD!!
rx_length = 15 rx_buffer = HELLO_WORLD!!
rx_length = 1 rx_buffer =
ELLO_WORLD!!
rx_length = 15 rx_buffer = HELLO_WORLD!!
rx_length = 1 rx_buffer =
ELLO_WORLD!!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Credit: http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart

#include <iostream>
#include <unistd.h>			//Used for UART
#include <fcntl.h>			//Used for UART
#include <termios.h>			//Used for UART
#include <assert.h>
#include <string.h>

using namespace std;

int main(int argc, char** argv)
{
	//-------------------------
	//----- 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/ttyUSB0", O_RDONLY | 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 | PARENB | CLOCAL | CREAD;		//<Set baud rate
	//options.c_iflag = INPCK;
	//options.c_cflag |= CS8|PARENB; cfsetispeed(&options, B9600); cfsetospeed(&options, B9600);
	//options.c_cflag &= ~(CRTSCTS|CSTOPB|CSIZE); 
	//options.c_oflag = 0;
	//options.c_lflag = 0;
	tcflush(uart0_filestream, TCIFLUSH);
	tcsetattr(uart0_filestream, TCSANOW, &options);

	// Read up to 255 characters from the port if they are there
	unsigned char rx_buffer[256];
	int rx_length;
	unsigned int num_of_data_errors = 0;
	
	rx_length = read(uart0_filestream, (void*)rx_buffer, 255);  rx_length = 0; // eliminate the first imcomplete received data message

	//----- CHECK FOR ANY RX BYTES -----
	do
	{
		if (rx_length < 0)
		{	perror ("The following error occurred");
			//cout << "An error occured (will occur if there are no bytes)" << endl;
		}
		else if (rx_length == 0)
		{	perror ("The following error occurred");
			//cout << "No data waiting" << endl;
		}
		else
		{
			//Bytes received
			//rx_buffer[rx_length] = '\0';
			cout << "rx_length = " << rx_length << "\trx_buffer = " << rx_buffer;
			//assert(strcmp((const char*)rx_buffer, "HELLO_WORLD!! \r\n")==0);
		}
	}while(rx_length = read(uart0_filestream, (void*)rx_buffer, 255));		//Filestream, buffer to store in, number of bytes to read (max));
	

	//----- CLOSE THE UART -----
	close(uart0_filestream);
}
Last edited on
Are you sure the sending program is actually sending a string that contains both the '\r' and the '\n' characters? Normally when I try to read something like the serial port I will read one byte at a time until I receive the terminating character/s. Trying to insure that the receiver is in sync with the sender can be difficult if you only try to read the buffer once for each message. And if you want to treat the message as a string you must insure that the end of string character is present. I usually insure I have a string by always appending the end of string character to the message.

I would also recommend you break you program up into a few smaller functions. For example I would place the port initialization into it's own function. And you may want to verify that you have all of the parameters correctly initialized. This is normally the configuration that I use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);

    if(fd == -1)
    {
        std::cerr << "ERROR OPENING PORT: " <<  _sys_errlist[errno] << std::endl;
        return(1);
    }

    fcntl(fd, F_SETFL, 0);
    // Store the current settings.
    tcgetattr(fd, &old);
    // Setup place for new settings.
    tcgetattr(fd, &options);
    // Insure not owner of port (CLOCAL) enable reading(CREAD).
    options.c_cflag |= (CLOCAL | CREAD);
    // Set parity, stop bit, bit size (8N1).
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    // Disable hardware flow control.
    options.c_cflag &= ~CRTSCTS;

    // Choose Raw Input Input characters are passed through exactly as
    // they are received, when they are received.
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    // Disable software flow control.
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    // Choose Raw Output, all other option bits in  c_oflag are ignored.
    options.c_oflag &= ~OPOST;

    options.c_cc[VMIN] = 1;
    options.c_cc[VTIME] = 50;


By the way this code is part of a class where the undefined variables are class member variables.

Edit: Here is a fairly good document about using the Serial Port in Linux:
http://www.c-program.com/pdf/serialPort_Programming_c.pdf

And don't forget to checkout the How-to
http://www.tldp.org/HOWTO/pdf/Serial-Programming-HOWTO.pdf
Last edited on
Why is "unsigned char received_character;" treated as pointer ?
I am having the following errors and I am not sure how I would proceed.

UART_rx.cpp: In function ‘int main(int, char**)’:
UART_rx.cpp:80:70: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
if ( (num_of_characters_received < 16) && (&received_character == 'H') ) {

UART_rx.cpp:81:48: error: invalid conversion from ‘unsigned char*’ to ‘unsigned char’ [-fpermissive]
rx_buffer[num_of_characters_received] = &received_character;

UART_rx.cpp:92:51: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
}while(rx_length = read(uart0_filestream, (void*)received_character, 1)); //Filestream, buffer to store in, number of bytes to read (max));


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Credit: http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart

#include <iostream>
#include <unistd.h>			//Used for UART
#include <fcntl.h>			//Used for UART
#include <termios.h>			//Used for UART
#include <assert.h>
#include <string.h>

using namespace std;

int main(int argc, char** argv)
{
	//-------------------------
	//----- 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/ttyUSB0", O_RDONLY | 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 | PARENB | CLOCAL | CREAD;		//<Set baud rate
	//options.c_iflag = INPCK;
	//options.c_cflag |= CS8|PARENB; cfsetispeed(&options, B9600); cfsetospeed(&options, B9600);
	//options.c_cflag &= ~(CRTSCTS|CSTOPB|CSIZE); 
	//options.c_oflag = 0;
	//options.c_lflag = 0;
	tcflush(uart0_filestream, TCIFLUSH);
	tcsetattr(uart0_filestream, TCSANOW, &options);

	// Read up to 16 characters from the port if they are there
	unsigned char rx_buffer[16+1];
	unsigned char received_character;
	int rx_length;
	unsigned int num_of_characters_received = 0;

	//----- CHECK FOR ANY RX BYTES -----
	do
	{
		if (rx_length < 0)
		{	perror ("The following error occurred");
			//cout << "An error occured (will occur if there are no bytes)" << endl;
		}
		else if (rx_length == 0)
		{	perror ("The following error occurred");
			//cout << "No data waiting" << endl;
		}
		else
		{
			//Bytes received
			if ( (num_of_characters_received < 16) && (&received_character == 'H') ) {
			    rx_buffer[num_of_characters_received] = &received_character;
			    cout << "rx_buffer = " << rx_buffer;
			    num_of_characters_received++;
			}
	
			if (num_of_characters_received == 16) {
			    rx_buffer[16] = '\0';
			    assert(strcmp((const char*)rx_buffer, "HELLO_WORLD!! \r\n")==0);
			    num_of_characters_received = 0;
			}
		}
	}while(rx_length = read(uart0_filestream, (void*)received_character, 1));		//Filestream, buffer to store in, number of bytes to read (max));
	

	//----- CLOSE THE UART -----
	close(uart0_filestream);
}
Why is "unsigned char received_character;" treated as pointer ?
UART_rx.cpp: In function ‘int main(int, char**)’:
UART_rx.cpp:80:70: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
if ( (num_of_characters_received < 16) && (&received_character == 'H') ) {

Because you've used the address of operator (&) in front of the variable received_character.


UART_rx.cpp:92:51: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
}while(rx_length = read(uart0_filestream, (void*)received_character, 1)); //Filestream, buffer to store in, number of bytes to read (max));

This is big problem that you should fix as well. By the way if you why are you using an unsigned character for the received_character instead of a signed character? The read() function returns a signed character so why not just use a signed character? If you were using a signed character you wouldn't need to worry about trying to cast the value.

What exactly are you trying to do with this if statement (in English please)?
1
2
3
4
5
6
			//Bytes received
			if ( (num_of_characters_received < 16) && (&received_character == 'H') ) {
			    rx_buffer[num_of_characters_received] = &received_character;
			    cout << "rx_buffer = " << rx_buffer;
			    num_of_characters_received++;
			}


If your string is "HELLO_WORLD\r\n" you would only "receive" one character from your serial port (after you remove that ampersand of course).

Why have you opened the port in a "blocking" mode? I recommend you use a "non-blocking" mode (O_NDELAY).

You should also be careful about using a direct assignment in your flag setups. Instead you should be using bitmasking so you only affect the bits of interest. Also I have found that not using the baud rate helper functions (cfsetispeed and cfsetospeed) can cause problems that tricky to find. Have you studied the links I provided in my last post? Improperly setting up your port is the number one reason for garbled communications, and IMO, your port setup is questionable.

How are you trying to send data to your program? Are you sure the sender is actually sending both the '\r' and the '\n' characters? Normally, when using serial communications, you need to manually add these characters to the stream.

What program are you using to test the communications on the sender side?

This is cpp code to test my FPGA verilog UART transmiter logic.

line 16 seem like carriage return but it is printed as 'a' instead of 'd'

WHY ?


rx_buffer = Hreceived_character = 48
rx_buffer = HEreceived_character = 45
rx_buffer = HELreceived_character = 4c
rx_buffer = HELLreceived_character = 4c
rx_buffer = HELLOreceived_character = 4f
rx_buffer = HELLO_received_character = 5f
rx_buffer = HELLO_Wreceived_character = 57
rx_buffer = HELLO_WOreceived_character = 4f
rx_buffer = HELLO_WORreceived_character = 52
rx_buffer = HELLO_WORLreceived_character = 4c
rx_buffer = HELLO_WORLDreceived_character = 44
rx_buffer = HELLO_WORLD!received_character = 21
rx_buffer = HELLO_WORLD!!received_character = 21
rx_buffer = HELLO_WORLD!! received_character = 20
rx_buffer = HELLO_WORLD!!
received_character = a
rx_buffer = HELLO_WORLD!!

received_character = a
UART_rx: UART_rx.cpp:95: int main(int, char**): Assertion `strcmp((const char*)rx_buffer, "HELLO_WORLD!! \r\n")==0' failed.
Aborted (core dumped)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Credit: http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart
// http://www.cplusplus.com/forum/general/219754/

#include <iostream>
#include <unistd.h>			//Used for UART
#include <fcntl.h>			//Used for UART
#include <termios.h>			//Used for UART
#include <assert.h>
#include <string.h>

using namespace std;

int main(int argc, char** argv)
{
	//-------------------------
	//----- 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/ttyUSB1", O_RDONLY | 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 | PARENB | CLOCAL | CREAD;		//<Set baud rate
	//options.c_iflag = INPCK;
	//options.c_cflag |= CS8|PARENB; cfsetispeed(&options, B9600); cfsetospeed(&options, B9600);
	//options.c_cflag &= ~(CRTSCTS|CSTOPB|CSIZE); 
	//options.c_oflag = 0;
	//options.c_lflag = 0;
	tcflush(uart0_filestream, TCIFLUSH);
	tcsetattr(uart0_filestream, TCSANOW, &options);

	// Read up to 16 characters from the port if they are there
	unsigned char rx_buffer[16+1];
	unsigned char received_character[1+1];
	int rx_length;
	unsigned int num_of_characters_received = 0;
	bool valid_data = false;

	//----- CHECK FOR ANY RX BYTES -----
	while(rx_length = read(uart0_filestream, (void*)received_character, 1)) 	//Filestream, buffer to store in, number of bytes to read (max));    http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_075.htm
	{
		if (rx_length < 0)
		{	perror ("The following error occurred");
			//cout << "An error occured (will occur if there are no bytes)" << endl;
		}
		else if (rx_length == 0)
		{	perror ("The following error occurred");
			//cout << "No data waiting" << endl;
		}
		else
		{
			if ((received_character[0] == 'H')) 
			    valid_data = true;			    

			//Bytes received
			if ( valid_data ) {
			    rx_buffer[num_of_characters_received] = received_character[0];
			    rx_buffer[num_of_characters_received+1] = '\0';
			    cout << "rx_buffer = " << rx_buffer;
			    num_of_characters_received++;
			    //if (num_of_characters_received == 15 || num_of_characters_received == 16)
				printf("received_character = %x\n", received_character[0]);
			}
	
			if (num_of_characters_received == 16) {
			    assert(strcmp((const char*)rx_buffer, "HELLO_WORLD!! \r\n")==0);
			    num_of_characters_received = 0;
			    valid_data = false;
			}
		}
	}
	

	//----- CLOSE THE UART -----
	close(uart0_filestream);
}
line 16 seem like carriage return but it is printed as 'a' instead of 'd'

Well that 'a' is actually 0xa (linefeed) since you're printing the hexadecimal value. The carriage return should be 'd' or 0xd.
So again are you sure your sender is actually sending the linefeed carriage return pair and not just returning one or the other or neither?

What is the length of your string, as reported by strlen(), when you get your assertion failure? It looks like you're missing the print out of the last several characters.

I also recommend you initialize your two strings when you define them:

1
2
	unsigned char rx_buffer[16+1] {0};
	unsigned char received_character[1+1] {0};


Also why is received_character a string.

You really shouldn't need to cast to the void* in your read() function.

Lastly why are you using unsigned char instead of just a char and an array of char?



Topic archived. No new replies allowed.