Data corruption(ATmega128RFA1) Zigduino Board

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

In ZigduinoRadio example there is a pattern of data corruption. E.g my data packet is " MY PACKET CORRUPT WHY?". In my point of view corruption in data occur due to surrounding environment and medium.

But if i RESET(by pressing reset button) reciever every time before sending data there is no corruption in packet.Is there is any circuit issue?

And I read all about RESET on p. 180 of the Atmega128RFA1 datasheet but i do not find any authentic relation between them.

A pattern look like that.
Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PAMY PAMY PAMY PAMY
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKET CORRUPT WHY?
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Rx: MY PACKETMY PACKETMY P
LQI: 255, RSSI: -72 dBm, ED: -69dBm

Transmitter Code

#include 
void setup()
{
  ZigduinoRadio.begin(11);
  Serial.begin(9600);

  ZigduinoRadio.attachError(errHandle);
  ZigduinoRadio.attachTxDone(onXmitDone);
}

void loop()
{
  char c[] = "MY PACKET CORRUPT WHY";
  int i;
  if (Serial.available())
  {
    i=0;
    ZigduinoRadio.beginTransmission();
    Serial.println();
    Serial.print("Tx: ");
    while(c[i]!='\0')
    {
      Serial.write(c[i]);
      ZigduinoRadio.write(c[i++]);
    }
    Serial.println();
    ZigduinoRadio.endTransmission();
    Serial.read();
  }

  if (ZigduinoRadio.available())
  {
    Serial.println();
    Serial.print("Rx: ");

    while(ZigduinoRadio.available())
      Serial.write(ZigduinoRadio.read());

    Serial.println();
    Serial.print("LQI: ");
    Serial.print(ZigduinoRadio.getLqi(), 10);
    Serial.print(", RSSI: ");
    Serial.print(ZigduinoRadio.getLastRssi(), 10);
    Serial.print(" dBm, ED: ");
    Serial.print(ZigduinoRadio.getLastEd(), 10);
    Serial.println("dBm");
  }

  delay(100);
}

void errHandle(radio_error_t err)
{
  Serial.println();
  Serial.print("Error: ");
  Serial.print((uint8_t)err, 10);
  Serial.println();
}

void onXmitDone(radio_tx_done_t x)
{
  Serial.println();
  Serial.print("TxDone: ");
  Serial.print((uint8_t)x, 10);
  Serial.println();
}

Receiver Code

#include 

void setup()
{
  ZigduinoRadio.begin(11);
  Serial.begin(9600);

  ZigduinoRadio.attachError(errHandle);
  ZigduinoRadio.attachTxDone(onXmitDone);
}

void loop()
{
  if (Serial.available())
  {
    ZigduinoRadio.beginTransmission();

    Serial.println();
    Serial.print("Tx: ");

    while(Serial.available())
    {
      char c = Serial.read();
      Serial.write(c);
      ZigduinoRadio.write(c);
    }

    Serial.println();

    ZigduinoRadio.endTransmission();
  }

  if (ZigduinoRadio.available())
  {
    Serial.println();
    Serial.print("Rx: ");

    while(ZigduinoRadio.available())
      Serial.write(ZigduinoRadio.read());

    Serial.println();
    Serial.print("LQI: ");
    Serial.print(ZigduinoRadio.getLqi(), 10);
    Serial.print(", RSSI: ");
    Serial.print(ZigduinoRadio.getLastRssi(), 10);
    Serial.print(" dBm, ED: ");
    Serial.print(ZigduinoRadio.getLastEd(), 10);
    Serial.println("dBm");
  }

  delay(100);
}

void errHandle(radio_error_t err)
{
  Serial.println();
  Serial.print("Error: ");
  Serial.print((uint8_t)err, 10);
  Serial.println();
}

void onXmitDone(radio_tx_done_t x)
{
  Serial.println();
  Serial.print("TxDone: ");
  Serial.print((uint8_t)x, 10);
  Serial.println();
}

From Idea To Invention

Last Edited: Fri. Oct 16, 2015 - 02:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is the CRC of the received frame Ok? If yes,
then the pattern that you see, is forced at the
transmitter site due to a race condition. That
means that you write to TX while it is sending
another frame. I do not know the implementation of the
Zigduino-Core library, but most likely your sketch
should check if the transmitter is not busy.

But please use the code tags for posting code, the
plain text it is really hard to read, especially because
you use some dangerous unbraced-one-line blocks for if()
and while() statements.

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

thankyou uracolix for your reply

Actually i am new to forum discussion. Next time i will use the code tags and about dangerous unbraced-one-line blocks it was an example which i little modify to find data corruption.

Question is if this is race condition then why when i press RESET button of reciever every time before transmitting data there is no corruption in data packet.
Is there is any circuit issue?

From Idea To Invention

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

>Is there is any circuit issue?
Definitely not ;-) This effect for sure
(at confidence level 100%) comes from the software.

Do you wait for the TxDone event before you send the next frame?

At first you could modify your code so, that each button press triggers a frame send, so you are definitely slow enough not to run into that race condition.

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

After Frank reply on "zigduino-radio/issues/" i try revsion 20 result no success but changes of r20 create a map of his library. After 8 hours fighting problem solved.

In ISR funtion

void radio_receive_frame(void)
{
    uint8_t len, lqi, crc_fail;

    crc_fail = trx_bit_read(SR_RX_CRC_VALID) ? 0 : 1;
    len = trx_frame_read(radiostatus.rxframe, radiostatus.rxframesz, &lqi);
    len &= ~0x80;

    radiostatus.rxframe = usr_radio_receive_frame(len, radiostatus.rxframe,
                                                  lqi, crc_fail);
}

Problem in last line its make me angry(i am just joking) but why funtion call like that.

changes what i made was in last line

void radio_receive_frame(void)
{
    uint8_t len, lqi, crc_fail;

    crc_fail = trx_bit_read(SR_RX_CRC_VALID) ? 0 : 1;
    len = trx_frame_read(radiostatus.rxframe, radiostatus.rxframesz, &lqi);
    len &= ~0x80;
    usr_radio_receive_frame(len, radiostatus.rxframe,lqi, crc_fail);
    //radiostatus.rxframe = 
}

From Idea To Invention

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

Congrats for tracking down the issue to this point.

Could you check, what the function usr_radio_receive_frame() returns in the Zigduino package?

This uracoli-code works in many other applications, assuming, that the usr-callback-function returns a valid receive buffer pointer. With your patch you stay forever with the same buffer, what might be Ok, if you have no data bursts to handle (e.g. if the data arrives faster then you can process in the moment).

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

Quote:
Could you check, what the function usr_radio_receive_frame() returns in the Zigduino package?

inline uint8_t * usr_radio_receive_frame(uint8_t len, uint8_t *frm, uint8_t lqi, uint8_t crc_fail)
{
    if (user_radio_receive_frame) return user_radio_receive_frame(len, frm, lqi, crc_fail);
	else return frm;
}

Quote:

This uracoli-code works in many other applications, assuming, that the usr-callback-function returns a valid receive buffer pointer. With your patch you stay forever with the same buffer, what might be Ok, if you have no data bursts to handle (e.g. if the data arrives faster then you can process in the moment).

Will you explain it more?

From Idea To Invention

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
inline uint8_t * usr_radio_receive_frame(uint8_t len, uint8_t *frm, uint8_t lqi, uint8_t crc_fail)
{
    if (user_radio_receive_frame)
    {
        return user_radio_receive_frame(len, frm, 
                                        lqi, crc_fail);
    }
    else
    {
        return frm;
    }
}

I reformated the code a bit to make it more obvious. If there is a function assigned to the function pointer "user_radio_receive_frame" the assigned function is called. If not the frame buffer is returned. The assigned function needs to return a buffer. Have a look at the function that is assigned to user_radio_receive_frame.

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

uracolix wrote:

...
I reformated the code a bit to make it more obvious. If there is a function assigned to the function pointer "user_radio_receive_frame" the assigned function is called. If not the frame buffer is returned. The assigned function needs to return a buffer. Have a look at the function that is assigned to user_radio_receive_frame.

Hello uracolix,

Sorry for late response.

Yesterday by chance i found your reply during reading of Jörg Wunsch discussion to learn UHF designing

https://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=103298&start=0

https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=94891&start=20#724170

tiny230 Documentation [url]"http://www.sax.de/~joerg/tiny230/"[/url].

"Back to point" today i start debugging according to your hint with same line.

radiostatus.rxframe = usr_radio_receive_frame(len, radiostatus.rxframe,lqi, crc_fail);

After some struggle may be this time i trace the exact issue.Function that is assigned to user_radio_receive_frame

uint8_t* cZigduinoRadio::onReceiveFrame(uint8_t len, uint8_t* frm, uint8_t lqi, uint8_t crc_fail)
{
	lastLqi = lqi;
	if (hasAttachedRxEvent == 0)
	{
		// no event handler, so write it into the FIFO
		
		if (len >= 8)
		{
			// frame header exists
			// copy only payload
			
			for (uint8_t i = 7; i < len - 2; i++)
			{
				uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE;
				if (j != rxRingBufferTail)
				{
					// push into FIFO
					rxRingBuffer[rxRingBufferHead] = frm[i];
					//Serial.print( frm[i]);
					rxRingBufferHead = j;	
				}
				else
				{
                    
					// FIFO full
					break;
				}
			}
		}
		else
		{
			// frame header does not exist
			// copy everything
			
			for (uint8_t i = 0; i < len; i++)
			{
				uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE;
				if (j != rxRingBufferTail)
				{
					// push into FIFO
					rxRingBuffer[rxRingBufferHead] = frm[i];
					rxRingBufferHead = j;
				}
				else
				{
					// FIFO full
					break;
				}
			}
		}
		return (uint8_t*)rxRingBuffer;
	}
	else
	{
		// user event is attached so call it
		return zrEventReceiveFrame(len, frm, lqi, crc_fail);
	}
}

I think so problem with this line

return (uint8_t*)rxRingBuffer;

changes what i made was

return frm;

Common thing in both times of debugging i have a flu :?. Thanks i am waitng for your reply and i think so it's enough for today.

From Idea To Invention

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

sorry, my bad, r22 committed

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

Thanks frank.

From Idea To Invention

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

I also can't see, what is returned in case of:
>
> // FIFO full
> break;
>
As far as I see, the function returns with a undefined value and
the next received frame will be copied to that address.

@Frank, could you post what the patch r22 does.

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

uracolix wrote:
I also can't see, what is returned in case of:
>
> // FIFO full
> break;
>

for (uint8_t i = 0; i < len; i++) 
         { 
            uint16_t j = ((uint16_t)((uint16_t)rxRingBufferHead + 1)) % ZR_FIFO_SIZE; 
            if (j != rxRingBufferTail) 
            { 
               // push into FIFO 
               rxRingBuffer[rxRingBufferHead] = frm[i]; 
               rxRingBufferHead = j; 
            } 
            else 
            { 
               // FIFO full 
               break; 
            } 
         } 

I thinks so it just to break the for loop on "condition"

j == rxRingBufferTail

and in that case

return (uint8_t*)frm; //According to rev22

will be the returned value.

From Idea To Invention

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

Ok, now I see it, the return of frm is reasonable in this case,
because in fact it drops the frame that can't be processed.