HELP receive data Usart

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

 

 

Hello, i want to receive my data in correct order but i dont know how to do.

i'm sending data from atmega8 to atmega644.

i read the adc in atmgea 8 and then send via usar to atmega644, when i seend the data i do a CRC. i send buffer_cmd_enviar[x,y,crc>>8,crc] and i want to receive in the same order. Now the problem is in the receive part at atmega644, how can i do to receive the correct order?

 

 this is the code at atmega8

#include <avr/interrupt.h>
#include <stdio.h>
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <util/delay.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALER (((F_CPU) / (USART_BAUDRATE * 16UL))-1)

void initADC(void)
{
	ADMUX |=(1<<REFS0); /* Utiliza VCC como Ref */
	ADCSRA |=(1<<ADEN)|(1<<ADLAR)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2); /* ADEN enable do ADC, 128 Prescaler*/
	

}

uint16_t read_adc(uint8_t ch)
{	
	
	//ch &= 0b00000111; // escolhe o canal
	ADMUX = (ADMUX & 0xF8)|(ch&7);
	ADCSRA|=(1<<ADSC); //Inicia conversao
	while(!(ADCSRA&(1<<ADSC))); //espera pelo fim da conversao
	return(ADC);
	
}

void initUSART(void)
{
	
	UBRRH=(BAUD_PRESCALER>>8);
	UBRRL= BAUD_PRESCALER; //valor relativo ao baud rate de 9600
	UCSRA=0x00;
	UCSRB=(1<<RXEN)|(1<<TXEN); // hablita transmissao e recepcao 
	UCSRC=(1<<URSEL)|(1<<USBS)|(3<<UCSZ0); // 2 stops bit, 8 bit data

}


unsigned char receiveusart(void)
{
	while(!(UCSRA&(1<<RXC)));
	return UDR;
	
}

void send_usart ( uint8_t data)
{

	while((UCSRA & (1<<UDRE))==0);
	UDR = data;
}



//VARIAVEL GLOBAL PARA GUARDAR O VALOR DO CRC
uint16_t m_crc;


void crc_clear()
{
	m_crc = 0;
}

void crc_update( uint8_t data )
{
	int i;
	m_crc = m_crc ^ ((uint16_t)data << 8);
	for (i=0; i<8; i++)
	{
		if (m_crc & 0x8000)
		m_crc = (m_crc << 1) ^ 0x1021;
		else
		m_crc <<= 1;
	}
}

uint16_t crc_get()
{
	return m_crc;
}

void send_buffer(uint8_t x, uint8_t y){
	
	int i;
	//Calculo do CRC
	crc_clear();
	crc_update(x);
	crc_update(y);
	uint16_t crc = crc_get();

	//Preparar o dados para enviar
	uint8_t buffer_cmd_enviar[4];
	buffer_cmd_enviar[0] = x;
	buffer_cmd_enviar[1] = y;
	buffer_cmd_enviar[2] = crc>>8;
	buffer_cmd_enviar[3] = crc;


	for(i=0;i<4;i++){
		
		send_usart(buffer_cmd_enviar[i]);
		//_delay_ms(1000);
	}
	
}

int main(void)
{
	
	int x,y;
	initUSART();
	initADC();
	
    while (1) 
    { 
		
		x = (uint8_t)(read_adc(1)>>2);
		_delay_ms(1);
		
		y = (uint8_t)(read_adc(0)>>2);
		_delay_ms(1);
		send_buffer(x,y);
		
 		
		

	}

}

i check direct to pc and i receive always the correct order X, Y , CRC>>8, CRC

But when i receive in the atempa 644 and send to pc, sometimes they change the place.

this is the code.



//VARIAVEL GLOBAL PARA GUARDAR O VALOR DO CRC
uint16_t m_crc;

//FUNCOES PARA CALCULO DO CRC
void crc_clear()
{
    m_crc = 0;
}

void crc_update( uint8_t data )
{
    int i;
    m_crc = m_crc ^ ((uint16_t)data << 8);
    for (i=0; i<8; i++)
    {
        if (m_crc & 0x8000)
            m_crc = (m_crc << 1) ^ 0x1021;
        else
            m_crc <<= 1;
    }
}

uint16_t crc_get()
{
    return m_crc;
}

void send_command(uint8_t address, uint8_t cmd, uint8_t valor){
	
	int i;
	//Calculo do CRC
	crc_clear();
    crc_update(address);
    crc_update(cmd);
    crc_update(valor);
    uint16_t crc = crc_get();

    //Preparar o dados para enviar
    uint8_t buffer_cmd_enviar[5];
    buffer_cmd_enviar[0] = address;
    buffer_cmd_enviar[1] = cmd;
    buffer_cmd_enviar[2] = valor;
    buffer_cmd_enviar[3] = crc>>8;
    buffer_cmd_enviar[4] = crc;


	for(i=0;i<5;i++){
   
    send_usart0(buffer_cmd_enviar[i]);
	}
    
}


	
int main(void)
{
	initusart1();
	initusart0();
	uint8_t  x,y;
	uint8_t receve_joystick[4];



	while (1)
	{
	
 
		for(int i=0; i<4; i++){
		receve_joystick[i] = receiveusart1();
		}
		
		x=0;
		y=0;
		
		x=receve_joystick[0];

		
			send_command(0x80,MIXEDLR,x);
			
			y = receve_joystick[1];
			
			send_command(0x80,MIXEDFB,y);// 127 - Full Forward, 64 Stop, 0- full backward
		   _delay_ms(1000);
   		}
			  
		

	
}

i know the problem is here:

for(int i=0; i<4; i++){
		receve_joystick[i] = receiveusart1();
		}

sometimes the receve_joystick[0]=x and other is y or crc>>8 or crc

someone can show me an example or something like that to receive in the correct order?

best regards

Eduardo

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

docasbb wrote:
sometimes they change the place

You need to be more clear - what, exactly, do you mean by "change the place" ?

 

Do you really mean that you sometimes receive in a different order??

 

Or do you just mean that you miss some characters completely?

 

I strongly suspect the latter!

 

In which case, think about how you tell that any given byte is supposed to  be an X rather than a Y or a CRC byte ...

 

You need some means to synchronise your receiver - so that it knows where a message begins ...

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

check out S.N.A.P protocol, here: http://www.hth.com/snap/

they have examples for AVR too!

 

Jim

 

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

And look at how other things provide "synchronisation" - eg, AT Commands; NMEA (for GPS data); Intel Hex format; CSV; S-Records; etc, etc, ...

 

EDIT

 

Recent thread in which many protocols were mentioned: http://www.avrfreaks.net/forum/p...

Last Edited: Tue. Oct 31, 2017 - 12:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

when i receive the data in pc, its show 80 0D 7A 92 DB where 80 its the adress, 0D the comand, 7A is the y and 92, DB are crc>>8 and CRC, after that show 80 0C C4 E7 FF, 80 0D 45 55 67, 80 0C 80 EF BF, 80 0D 7A 92 DB, 80 0C C4 E7 FF, 80 0D 45 55 67, 80 0C 80 EF BF....

My output from atmega8 is 80 7A C4 45 where, x = 80 and Y = 7A

So if you can see, they alternte the x and y in the correct order of my output from amtega8, but i want to put only de 80 and 7A in the correct place 

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

docasbb wrote:
So if you can see

No, I'm afraid I can't!

 

It might help if you used the 'Add code' button to tabulate your sequence; eg,

80 0C C4 E7 FF, 
80 0D 45 55 67, 
80 0C 80 EF BF, 
80 0D 7A 92 DB, 
80 0C C4 E7 FF, 
80 0D 45 55 67, 
80 0C 80 EF BF....

See: http://www.avrfreaks.net/comment...

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

Can i do the crc on the receiver side, and check if the values are the same? if they are, i use the values, if not i discard the valeu

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

Yes - that is the whole point of a CRC (or a checksum) !!

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

ok, im doing this on the receiver side 

uint16_t receive_buffer(uint8_t x, uint8_t y){
	
	//int i;
	//Calculo do CRC
	crc_clear1();
	crc_update1(x);
	crc_update1(y);
	
	
}

while (1)
	{
	
 	
		for(int i=0; i<4; i++){
		receve_joystick[i] = receiveusart1();
		}
		
				
		x=receve_joystick[0];
		y=receve_joystick[1];
		receive_buffer(x,y);
		uint16_t crc1 = crc_get1();
			if (crc1>>8 == receve_joystick[2]){
			if (crc1 == receve_joystick[3]){
			send_command(0x80,MIXEDLR,x);
			send_command(0x80,MIXEDFB,y);}}
			
			

but the program its stuck, any sugestion?

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

docasbb wrote:
 the program its stuck, 

What, exactly, does that mean?

 

any sugestion

Please try to remember that we cannot see what you're doing, or what's appearing on your screen, or what's happening on your bench - and we cannot read your mind.

 

We rely totally on what you provide in your posts.

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

Sorry, 

when i run this program and if the crc don't match the program they show me the crc>>8 value.

if i put a delay on transmiter and if i press the reste button, if the crc match, the program run smothly.

uint16_t receive_buffer(uint8_t x, uint8_t y){
	
	//int i;
	//Calculo do CRC
	crc_clear1();
	crc_update1(x);
	crc_update1(y);
	
	
}

while (1)
	{
	
 	
		for(int i=0; i<4; i++){
		receve_joystick[i] = receiveusart1();
		}
		
				
		x=receve_joystick[0];
		y=receve_joystick[1];
		receive_buffer(x,y);
		uint16_t crc1 = crc_get1();
		
		send_usart0(crc1>>8);
		
			if (crc1>>8 == receve_joystick[2]){
			send_command(0x80,MIXEDLR,x);
			send_command(0x80,MIXEDFB,y);}
			
			

this is show when crc dont match

63
63
63
63
63
63
...

when the crc are the same

C4
80 0D 80 DC 8E
80 0C 7A A1 EA
C4
80 0D 80 DC 8E
80 0C 7A A1 EA
C4
....

But i only catch this value when i press resete button to adjust the timing.

how can i do it in other way?

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

Your indentation is all over the place!

 

This makes your code unpleasant to read.

 

Note that using TAB characters is not reliable; therefore, do not use TAB characters - use only spaces.  This will ensure that your layout is preserved whatever it is viewed on.

 

Any decent code editor will have an option so that it will insert the appropriate number of spaces when you press the TAB button on your keyboard.

 

See the 2nd half of this post: http://www.avrfreaks.net/comment...

 

I think you might also benefit from drawing a flowchart of how you want your code to work ...