SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links

Is this too much code to post on a Forum?

Yes
1
33%
No
2
67%
What's Code?
No votes
0%
By mgopalan
#23648
Hey guys...

I just started playing with my uMIRF units and have spent days getting everything together and double and triple checking everything and I still get squat...

I am using the ADuC814 as my host controller and right now I have one unit set up to transmit 4 bytes and the other unit set to recieve and I get nothing...

Have attached the source code for both the transmitter and reciever below... [color=red]Any[/color] sugestions would be greatly appreciated..

Manoj

[code]________________________________________________________
[size=9]//This is the code for the reciever end of things

#include <ADUC814.H>
#include <stdio.h>
#include <intrins.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>

#define uMIRFCE P3_2
#define uMIRFDR P3_3
#define uMIRFCS P3_4
#define uMIRFCLK P3_5
#define uMIRFDATA P3_7

void recievedata (void);
void delay (void);
void bootuMIRF (void);

void recievedata (void)
{
unsigned char d3,d2,d1,d0;
unsigned char index, input_data;

uMIRFCE = 0; //Turn OFF the reciever front end until you get the data out...

index = uMIRFDATA;
_nop_();_nop_();_nop_();_nop_();_nop_();
input_data = 0x00;
for(index = 0; index < 8; index++)
{
input_data <<= 1;
uMIRFCLK = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
input_data |= uMIRFDATA;
_nop_();_nop_();_nop_();_nop_();_nop_();
uMIRFCLK = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
d0 = input_data;

input_data = 0x00;
for(index = 0; index < 8; index++)
{
input_data <<= 1;
uMIRFCLK = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
input_data |= uMIRFDATA;
_nop_();_nop_();_nop_();_nop_();_nop_();
uMIRFCLK = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
d1 = input_data;

input_data = 0x00;
for(index = 0; index < 8; index++)
{
input_data <<= 1;
uMIRFCLK = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
input_data |= uMIRFDATA;
_nop_();_nop_();_nop_();_nop_();_nop_();
uMIRFCLK = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
d2 = input_data;

input_data = 0x00;
for(index = 0; index < 8; index++)
{
input_data <<= 1;
uMIRFCLK = 1;
_nop_();_nop_();_nop_();_nop_();_nop_();
input_data |= uMIRFDATA;
_nop_();_nop_();_nop_();_nop_();_nop_();
uMIRFCLK = 0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
d3 = input_data;

if (uMIRFDR == 0)
{ TI = 1; printf ("dr line went low.. must have all data\n"); while (!TI);}
else
{ TI = 1; printf ("ohoh dr line dint go low\n"); while (!TI);}

TI = 1; printf ("d0 = 0X%X\n",d0); while (!TI);
TI = 1; printf ("d1 = 0X%X\n",d1); while (!TI);
TI = 1; printf ("d2 = 0X%X\n",d2); while (!TI);
TI = 1; printf ("d3 = 0X%X\n",d3); while (!TI);

uMIRFCE = 1; //Turn ON Recieve on the way out

}

void delay (void)
{
unsigned int i;
for (i = 0;i<100;i++) _nop_(); //this generates roughly a 5 millisecond delay
}

void bootuMIRF (void)
{
unsigned char CONFIGBYTE2,CONFIGBYTE1,CONFIGBYTE0;
unsigned char i;

CONFIGBYTE2 = 0X23;
//0x23 = 00100011
//the first four bits set the width of address in the Shockburst packet
//0 BIT 6 of ADDR WIDTH
//0 BIT 5 of ADDR WIDTH
//1 BIT 4 of ADDR WIDTH 001000 = 8d
//0 BIT 3 of ADDR WIDTH
//0 BIT 2 of ADDR WIDTH
//0 BIT 1 of ADDR WIDTH
//The next 2 bits setup the checksum and chesum size
//1 16 Bit CRC
//1 Enable CRC Checksum

CONFIGBYTE1 = 0X4F;
//0X4F = 01001111
//0 Select only one Channel Recieve
//1 Select ShockBurst Mode
//0 250Kbps Transmission Speed
//The next three bits set the crystal frequency
//0
//1 Select Crystal Frequency as 16 MHz
//1
//The last 2 bits set up the output power of the transmitter
//1
//1 Tranmist power set to 0 dBm

CONFIGBYTE0 = 0x05;
//0X04 = 00000101
//The first 7 bits select the freqneucy channel to use
//0
//0
//0
//0 This select a Channel of 2 which works out to 2402 MHz
//0
//1
//0
//The last bit selects the direction of the setting either transmit or recieve..
//This unit is setup for recieve
//1 RECIEVE MODE

//Note that the higher order bytes for the uMIRF setup have not been written
//We have defaulted these
//With a 8 bit address size, we end with a default address as 11100111 = 0XE7 or 231d
//Even though 40 bits are possible we use only 8.
//The Data width of the data packet has also been defaulted. This default of
//00100000b = 0x20 or 32d
//That is we have a 32 bit packet size.
//This does not include the Address or the Checksum.

//So out transmit packet is

//Preamble... Automatically Sent by the chip under ShockBurst
//Address.... We have an 8 bit address and it is 11100111b 0XE7 or 231d
//Payload.... This is out 32 bits of data to be sent
//CRC........ This is automatically sent andi s set to 16 bit CRC

uMIRFCE = 0;
uMIRFCS = 1;//when you enter boot, set the UMIRF to go into CONFIGURATION Mode
uMIRFDATA = 0; //Init the data line to be an ouput

delay(); //sleep for 5 msec

for (i = 0;i<8;i++)
{
uMIRFDATA = ((CONFIGBYTE2 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
CONFIGBYTE2 <<= 1; // Shift the byte by one bit
}

_nop_();_nop_();_nop_();_nop_();_nop_();

for (i = 0;i<8;i++)
{
uMIRFDATA = ((CONFIGBYTE1 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
CONFIGBYTE1 <<= 1; // Shift the byte by one bit
}

_nop_();_nop_();_nop_();_nop_();_nop_();

for (i = 0;i<8;i++)
{
uMIRFDATA = ((CONFIGBYTE0 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
CONFIGBYTE0 <<= 1; // Shift the byte by one bit
}
_nop_();_nop_();_nop_();_nop_();_nop_();
uMIRFCE = 0;
uMIRFCS = 0; //After configuration is done bring the uMIRF back into Standby MODE

i = uMIRFDATA; //setup the uMIRFDATA line as an input

delay();

TI = 1;
printf ("booted up as reciever\n");
while (!TI);
}

void main (void)
{
unsigned int i;

uMIRFCS = 0;
uMIRFCS = 0; //on power up, set the uMIRF to standby mode
uMIRFCLK = 0; //and pull the clock line low

i = uMIRFDR; //set the output pins from the uMIRF as inputs
i = uMIRFDATA;

TMOD = 0x11; //Set Timer 0 and Timer 1 to 16 bit Timers

TR0 = 0; //
TH0 = 0x00; // Initialize Timer 0 Controls
TL0 = 0x00; //
TF0 = 0; //

TR1 = 0; //
TH1 = 0x00; // Initialize Timer 1 Controls
TL1 = 0x00; //
TF1 = 0; //

SCON = 0x50; //Set Serial port to 9600 baud using Timer 2 as Variable Baud Rate Generator
RCAP2H = 0xFF;
RCAP2L = 0xF9; //St 2.097152 MHZ, this works out to 9532 baud
T2CON = 0x34;

bootuMIRF();//setup uMIRF as a recieveruMIRFCS = 0;
uMIRFCE = 1;//enable the reciever
TI = 1;printf ("enabled reciever\n");while (!TI);

while(1)
{
delay();delay();delay();delay();delay();
delay();delay();delay();delay();delay();//sleep 50 msec
if (uMIRFDR == 1)
{ recievedata(); }
else
{ TI = 1; printf ("no data \n"); while (!TI); }
}
}


//This is the code for the transmitter end of things

#include <ADUC814.H>
#include <stdio.h>
#include <intrins.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>

#define uMIRFCE P3_2
#define uMIRFDR P3_3
#define uMIRFCS P3_4
#define uMIRFCLK P3_5
#define uMIRFDATA P3_7

void transmitdata (void);
void delay (void);
void bootuMIRF (void);

void transmitdata (void)
{
unsigned char data0,data1,data2,data3;
unsigned char rfadd;
unsigned int i;

data0 = 0x00;
data1 = 0x01;
data2 = 0x45;
data3 = 0xAF;
rfadd = 0xE7;

uMIRFCE = 1;
uMIRFDATA = 0; //Init the data line to be an ouput

delay(); //sleep for 5 msec

//first we need to clock in the address of the unit...
//since we defaulted the addredd to 11100111, we need to send this first
for (i = 0;i<8;i++)
{
uMIRFDATA = ((rfadd & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
rfadd <<= 1; // Shift the byte by one bit
}
_nop_();_nop_();_nop_();_nop_();_nop_();
//next we send the 4 bytes of data
for (i = 0;i<8;i++)
{
uMIRFDATA = ((data0 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
data0 <<= 1; // Shift the byte by one bit
}
_nop_();_nop_();_nop_();_nop_();_nop_();

for (i = 0;i<8;i++)
{
uMIRFDATA = ((data1 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
data1 <<= 1; // Shift the byte by one bit
}
_nop_();_nop_();_nop_();_nop_();_nop_();
for (i = 0;i<8;i++)
{
uMIRFDATA = ((data2 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
data2 <<= 1; // Shift the byte by one bit
}
_nop_();_nop_();_nop_();_nop_();_nop_();
for (i = 0;i<8;i++)
{
uMIRFDATA = ((data3 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
data3 <<= 1; // Shift the byte by one bit
}

// after the address and data bytes are clocked in, go ahead and start the transmission

uMIRFCE = 0;
}



void delay (void)
{
unsigned int i;
for (i = 0;i<100;i++) _nop_(); //this generates roughly a 5 millisecond delay
}



void bootuMIRF (void)
{
unsigned char CONFIGBYTE2,CONFIGBYTE1,CONFIGBYTE0;
unsigned char i;

CONFIGBYTE2 = 0X23;
//0x23 = 00100011
//the first four bits set the width of address in the Shockburst packet
//0 BIT 6 of ADDR WIDTH
//0 BIT 5 of ADDR WIDTH
//1 BIT 4 of ADDR WIDTH 001000 = 8d
//0 BIT 3 of ADDR WIDTH
//0 BIT 2 of ADDR WIDTH
//0 BIT 1 of ADDR WIDTH
//The next 2 bits setup the checksum and chesum size
//1 16 Bit CRC
//1 Enable CRC Checksum

CONFIGBYTE1 = 0X4F;
//0X4F = 01001111
//0 Select only one Channel Recieve
//1 Select ShockBurst Mode
//0 250Kbps Transmission Speed
//The next three bits set the crystal frequency
//0
//1 Select Crystal Frequency as 16 MHz
//1
//The last 2 bits set up the output power of the transmitter
//1
//1 Tranmist power set to 0 dBm

CONFIGBYTE0 = 0x04;
//0X04 = 00000100
//The first 7 bits select the freqneucy channel to use
//0
//0
//0
//0 This select a Channel of 2 which works out to 2402 MHz
//0
//1
//0
//The last bit selects the direction of the setting either transmit or recieve..
//This unit is setup for transmit
//0 TRANSMIT MODE

//Note that the higher order bytes for the uMIRF setup have not been written
//We have defaulted these
//With a 8 bit address size, we end with a default address as 11100111 = 0XE7 or 231d
//Even though 40 bits are possible we use only 8.
//The Data width of the data packet has also been defaulted. This default of
//00100000b = 0x20 or 32d
//That is we have a 32 bit packet size.
//This does not include the Address or the Checksum.

//So out transmit packet is

//Preamble... Automatically Sent by the chip under ShockBurst
//Address.... We have an 8 bit address and it is 11100111b 0XE7 or 231d
//Payload.... This is out 32 bits of data to be sent
//CRC........ This is automatically sent and is set to 16 bit CRC

uMIRFCE = 0;
uMIRFCS = 1;//when you enter boot, set the UMIRF to go into CONFIGURATION Mode
uMIRFDATA = 0; //Init the data line to be an ouput

delay(); //sleep for 5 msec

for (i = 0;i<8;i++)
{
uMIRFDATA = ((CONFIGBYTE2 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
CONFIGBYTE2 <<= 1; // Shift the byte by one bit
}
for (i = 0;i<8;i++)
{
uMIRFDATA = ((CONFIGBYTE1 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
CONFIGBYTE1 <<= 1; // Shift the byte by one bit
}
for (i = 0;i<8;i++)
{
uMIRFDATA = ((CONFIGBYTE0 & 0x80) ? 1 : 0); //Mask the highest bit and load it onto the uMIRFDATA line
uMIRFCLK = 1; // Clock the data into the I2C Bus
_nop_();_nop_();_nop_();_nop_();_nop_(); //Delay a little bit
uMIRFCLK = 0; //Bring the Clock low again
CONFIGBYTE0 <<= 1; // Shift the byte by one bit
}

uMIRFCE = 0;
uMIRFCS = 0; //After configuration is done bring the uMIRF back into Standby MODE

i = uMIRFDATA; //setup the uMIRFDATA line as an input

delay();

TI = 1;
printf ("booted up as transmitter\n");
while (!TI);
}

void main (void)
{
unsigned int i;

uMIRFCS = 0;
uMIRFCS = 0; //on power up, set the uMIRF to standby mode
uMIRFCLK = 0; //and pull the clock line low

i = uMIRFDR; //set the output pins from the uMIRF to high impedance
i = uMIRFDATA;

TMOD = 0x11; //Set Timer 0 and Timer 1 to 16 bit Timers

TR0 = 0; //
TH0 = 0x00; // Initialize Timer 0 Controls
TL0 = 0x00; //
TF0 = 0; //

TR1 = 0; //
TH1 = 0x00; // Initialize Timer 1 Controls
TL1 = 0x00; //
TF1 = 0; //

SCON = 0x50; //Set Serial port to 9600 baud using Timer 2 as Variable Baud Rate Generator
RCAP2H = 0xFF;
RCAP2L = 0xF9; //St 2.097152 MHZ, this works out to 9532 baud
T2CON = 0x34;

bootuMIRF();//setup uMIRF as a transmitter
TI = 1;
printf ("booted transmitter\n");
while (!TI);

while(1)
{
delay();delay();delay();delay();delay();
delay();delay();delay();delay();delay();//sleep 50 msec
transmitdata();

TI = 1;printf ("packet sent\n");while (!TI);
}
}
}[/size[/code][/code]
By mgopalan
#23669
ok.. so I went back read EVERY line of the data sheet for the nrf2401A..

Does the following matter?

When the unit powers up , the first thing i need to do is put it in config mode and clock in the config bytes..

now the data sheet says that in Shockburst, I can clock in UP TO 15 bytes of data (120 bits 0 thru 119)

And then in the next page goes ahead and defines bit positions 120 through 143 as TESTING.. so Im assuming that these dont need to be clocked in...

Now at the bottom of page 18, it says again that on power up just once...I need to clock in just the 120 bits of data to set the unit up....

Now in the RF24G code ive looked at off the SFE links, I see only the LAST three bytes being clocked in... (this is what I did in my code too)

so which is the right one to do?

During first time config..do I Clock in

144 bits
120 bits
24 bits

now by the default power up is set to 0 and the unit poweres up in DIRECT MODE (bit 14) so I cant just NOT load in a config byte...plus I know that using a CRC16 and a long non patterned address helps...

Now all of this gets muddled with the fact that in some places it says AFTER config, you can clock in just the LAST BYTE (set the channel and the direction RX or TX) or just the LAST BIT (just set RX or TX)....

Now the code over at PICGUIDE.com has all 15 bytes (120 bits) being loaded in and only the last bit it toggled to go from transmit to recieve and vice verse....

Dammit I need a drink....
MG
By DarioG
#23679
Hi, as far as I know, you can clock in HOW MUCH BITS you feel... Bits are shifted / pushed one at a time, so as to fill all the desired bytes. I.e. if you want to change the 1st 3 registers, just push 24 bits; if you need to write all of the 15 registers, shift in 120 bits.
That's why A FIRST TIME INIT of all 120 should be needed at power up, but , later, only those who are needed to change, will be shifted (for speed reason).

I've only used 2401, not 2401A... but this matter should not have changed!
By mgopalan
#23698
Thanks..

I guess I can assume that if I dont want the address or the data width changed from their defaults, I dont have to load them in at startup...they should just defalt to their power on states...right? (all those bits above 24 are just for the address of channel 0 and channel 1 and their data packet widths)

The nRF2401A should power on default to an 8 bit address 11100111 and a data width of 32 bits or so it claims in the data sheet..

This is what I have assumed so far and no luck.... Im grasping at straws here...

Im planning to try writing in all the bits in this morning to see if I can get it to work any better..

MG
By mgopalan
#23710
Finally got SOMETHING across...

a combination of a bad uMIRF unit and me writing all the data bits across has provided me with success and little hope...

Dont know if I blew the unit or if it was faulty to start with but at least now Im getting a single 2 byte packet across every 300 msec...

a whopping 53 bits per second!!..

its a start..

MG
By DarioG
#23744
Ok MG!
IMO, I'd always write whole Config at start... I'll always want to have MY defaults... !