USART recieve function

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have the USART transmitting data successfully and would like to now recieve data back. Is this the correct approach to filling the recieve[] array with 15 bytes of data? It doesn't seem to be working correctly. Thanks.

for(int i=0;i<15;i++)
{
recieve[i] = usart_recieve();
}

unsigned char usart_recieve(void)
{
while (!(UCSR0A & (1<<RXC0)));
return UDR0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the problem is with your spelling of recieve - its actually spelt 'receive'. 'i' before 'e' except after 'c'.

Seriously though, I can't see any specific logic errors - although you would not normally write code this way for serial comms as you are relying on the fact that you will get 15 characters exactly. In theory this is fine, reality bites and you can have synchronisation problems with the device that is sending, so you would normally store the characters into an array until you get a carriage return char (0x0d) if you expect textual strings or you might look for a start and end token if the data is packetised, for example a nmea string from a GPS receiver. Put it this way, how do you know when the transmitter starts sending something and how do you know you've got the start of it sending? You might get the last half of one transmission and the first half of the next.

I think the 'c' function to get a string terminated by a carriage return is 'gets()'

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dang my bad, that is embarrassing! Thanks for the heads up though!

OK, I get what you are saying and am not sure how to go about it (in code). I am not sure I understand the gets() function either. Do you have any code you can show me or an example of how receiving is usually done?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All of my packets I am receiving start with 0x41 and end with 0x0A.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A few questions...
1. Are 0x41 and 0x0A used anywhere else in the packet? That is, if you are receiving numbers in binary, how do you know it is a start or end character and not just a number. More often than not the protocol is going to be more complicated with binary ( or it can be very simple with fixed size packets ).
2. What are your packet size specs. Do you know that they will always be the same length, a maximum and minimum length, length is the first field of the packet? This sort of information will effect the method you use.
3. What is the priority of receiving the data, and what else needs to be done in the program. This will help decide if polling is appropriate or if an interrupt based solution is required.

Really the above questions need to be answered before you can find the optimal solution, but just assuming a few things here is a basic pseudo code example ( please excuse the Python, C, Pascal, UnrealScript hybrid... ). Okay, packets can be from two to seventeen characters long total ( remembering that each packet has a start and stop character ), so a buffer of fifteen bytes is required as we don't need to save the start or stop. Also reception of the packets is the primary function of the system ( or there are long, regular, time periods between packets in which all our processing can be done ) so a polling solution will work. Under these circumstances something like the following might be workable.

byte buffer[15] # This stores the packet bytes
int length # This stores how many bytes were in the packet

function get_packet():
	while waiting for start:
		if there is new RX data:
			rx_data = UDR # Be sure to read UDR
			if rx_data == 0x41:
				break waiting for start
			end if
		end if
	end while # At this point the start char has been found

	buffer_index = 0

	while waiting for end:
		if there is new RX data:
			rx_data = UDR
			if rx_data == 0x0A: # This is a stop character
				length = buffer_index
				break waiting for end
			else: # This is data to go in the buffer
				buffer[ buffer_index ] = rx_data
				++buffer_index
			end if
		end if

	return # buffer contains the last packet, length contains number of bytes read...

Now obviously this may not be anywhere close to what you need, but it is an example of a way that it could be done. More information is needed as there are more solutions than there are problems.

Martin Jay McKee

As with most things in engineering, the answer is an unabashed, "It depends."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

robtotoreb wrote:
All of my packets I am receiving start with 0x41 and end with 0x0A.

If this is the case i would rather wait till i receive 0x41 and then start saving incoming data in buffer till i receive 0x0A. However you might want to take care of missed frames where you miss detecting start of frame.

Also using interrupt based mode is more appropriate here as you will be waiting for 0x41 to be received.

Dean has written very good tutorial on Interrupt based UART communication here https://www.avrfreaks.net/index.p...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

robtotoreb wrote:
All of my packets I am receiving start with 0x41 and end with 0x0A.

Starts with 'A' and ends with [0x0]A, eh?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.