SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By Sam
#2290
Can anyone tell me if there is a problem with the following code? I have been having a lot of trouble getting the RF-24G modules to work. I finally resorted to the following minimalist code. It is based directly on the sample code from Sparkfun. My understanding is that I should get random noise on RX_DR when this code is running, but on my DSO, I get nothing. The controller is a PIC16F877 at 3.3 volts. The only connections to the RF-24G are gound, power and the following described in the defines below. The compiler is from Hi-Tech.

I would appreciate any help.

Thanks in advance.
Sam

#include "mxapi.h"
#include "mxapi.c"

#define RX_CE RC2
#define RX_CS RC3
#define RX_CLK1 RC4
#define RX_DATA RC1
#define RX_DR RC0

void configure_receiver(void);

void main()
{

delay_ms(100);

configure_receiver();

while(TRUE);
}

void configure_receiver(void)
{
unsigned char i;
unsigned char config_setup;

PORTC = 0b00000000;
TRISC = 0b00000001;

RX_CE = 0; RX_CS = 1;

config_setup = 0b00000101;

for(i = 0 ; i < 8 ; i++)
{
RX_DATA = ((config_setup & 0x80) >> 7);
RX_CLK1 = 1;
RX_CLK1 = 0;
config_setup <<= 1;
}

RX_CE = 0; RX_CS = 0;

PORTC = 0b00000000;
TRISC = 0b00000011;

RX_CE = 1; RX_CS = 0;
}
By Guest
#2301
I don't know the Hytech compiler. But did you try turning off its optimizing options?

I can imagine that:

RX_CLK1 = 1;
RX_CLK1 = 0;

will be optimized by leaving out the first of these lines (your compiler thinks that it gives the same end result). Then, nothing happens because RX_CLK is not toggled. Check with an oscilloscope, and/or check the de-assembled object code.

Hope this helps?
By Sam
#2305
Anonymous wrote:I don't know the Hytech compiler. But did you try turning off its optimizing options?

I can imagine that:

RX_CLK1 = 1;
RX_CLK1 = 0;

will be optimized by leaving out the first of these lines (your compiler thinks that it gives the same end result). Then, nothing happens because RX_CLK is not toggled. Check with an oscilloscope, and/or check the de-assembled object code.

Hope this helps?
Thanks for the response. Just to make absolutely sure, I checked the assembled code to confirm that the pin is being toggled. Also, I am using a 4mHz oscillator so there is a minimum 1us delay between high and low transistions.
Any other thoughts?
Sam
By Guest
#2319
check the cs / ce pin signals? with an oscilloscope?

- Marco
User avatar
By sparky
#2329
I'm pretty sure the PIC may be the problem. The 16F877 certainly does not like to run down at 3.3V. It's spec'd down to only 4V. You may get it to run just fine, or it may be finnicky. Only way to tell is with an o-scope, and even then, there's no way to tell if it will work from day to day (temperature changes, etc).

I've also seen some compilers (CC5X I think does this) stick a sleep command at the end of main.

I don't quite follow your configure_receiver routine. I'm bad at reading other people's code so bare with me:
Code: Select all
config_setup = 0b00000101; 

for(i = 0 ; i < 8 ; i++) 
{ 
RX_DATA = ((config_setup & 0x80) >> 7); 
RX_CLK1 = 1; 
RX_CLK1 = 0; 
config_setup <<= 1; 
} 
Why are setting config_setup to something right before you force bit 7 to 1 and everything else to 0? And then you assign an 8 bit value to a pin? I have no idea what that will do.

Let me know what I'm missing,
-Nathan
By Guest
#2347
sparky wrote:I'm pretty sure the PIC may be the problem. The 16F877 certainly does not like to run down at 3.3V. It's spec'd down to only 4V. You may get it to run just fine, or it may be finnicky. Only way to tell is with an o-scope, and even then, there's no way to tell if it will work from day to day (temperature changes, etc).
You are right the spec sheet does specify 4V. I have been running another 877 project at 3.2 so I never checked + it bootloaded correctly. Upon testing on the scope with a bench supply, I was able to get the correct signals down to 3V with the 877. Just to be sure, I set up a board with the 16F628 which specifies that it works down to 3V. Again, no trigger on DR1.
I don't quite follow your configure_receiver routine. I'm bad at reading other people's code so bare with me:
Code: Select all
config_setup = 0b00000101; 

for(i = 0 ; i < 8 ; i++) 
{ 
RX_DATA = ((config_setup & 0x80) >> 7); 
RX_CLK1 = 1; 
RX_CLK1 = 0; 
config_setup <<= 1; 
} 
Why are setting config_setup to something right before you force bit 7 to 1 and everything else to 0? And then you assign an 8 bit value to a pin? I have no idea what that will do.
config_setup & 0x80 forces bits 0-6 to zero but does not force bit 7 to zero. If bit 7 of config_setup is one, it remains 1 (1 & 1 = 1). If bit 7 of config_setup is zero it remains zero (0 & 1 = 0). The resulting bit (zero or one) is shifted down to the 0 bit by the function >>7. Only bit zero is read and masked into the port register. As result, if bit 7 of config_setup is zero RX_DATA is set to zero and if not it is set to one. I have check the output for RX_DATA and CLK on the scope simultanously and it looks fine.

My test is to wait for DR1 to change, because I am assuming that with the default set up I there should be enough noise to trigger DR1 once in a while. So far, no change in DR1. Maybe this is not a good test. If it is though, and I can get this working, than the above code would provide a very simple test for anyone to use to make sure they have configured their board properly for the RF-24. In addition, the code is written such that it except for the delays, it should compile on all PIC compilers.

Again, I would appreciate any help.
By Sam
#2348
I should note that I do see lots (I mean lots!) of pulses on the DATA using the above code. And I see no pulses on DATA when I simply power the RF-24 -- not tied to the microcontroller. But if I am getting data, why does DR1 not register anything?
User avatar
By sparky
#2349
Don't take this personally - but I really don't see why you are doing something in 4 steps that needs to be only 1.

Why not just use the example code?:
Code: Select all
temp = config_setup;

for(i = 0 ; i < 8 ; i++) 
{ 
     RX_DATA = temp.7;   //((config_setup & 0x80) >> 7); 

     RX_CLK1 = 1; 
     RX_CLK1 = 0; 

     temp <<= 1; 
} 
That way we know exactly what bit is being output to RX_DATA.

So you've got your oscope telling you that DR1 is toggling, but the PIC is not working. I've never used the Hi-Tech compiler so I don't know what statements work with your compiler. My guess is the compiler is doing something screwy with the tris assigment:

TRISC = 0b000000001;

So that the PORTC.0 is never getting set to an input, or the define at the top of your code is not working correctly. Try looking at the generated ASM or using:

TRISC = 0x01; //Or whatever the Hi-Tech hex assignment is

instead of the binary format. I remember some motorola compilers that would happily compile
x = 0b.0000.1101;
and very happily (and to my never ending frustration) cut off everything after the second period - without any compile errors!

Keep us updated.

-Nathan
By Sam
#2354
sparky wrote:Don't take this personally - but I really don't see why you are doing something in 4 steps that needs to be only 1.

Why not just use the example code?:
Code: Select all
temp = config_setup;

for(i = 0 ; i < 8 ; i++) 
{ 
     RX_DATA = temp.7;   //((config_setup & 0x80) >> 7); 

     RX_CLK1 = 1; 
     RX_CLK1 = 0; 

     temp <<= 1; 
} 
That way we know exactly what bit is being output to RX_DATA.
Hi-Tech C has its pros and cons. It does not support statements like temp.7 unless you write supporting statements for them yourself such as creating a bit field in a structure - something like this may actually be going on in your compiler. What I like about Hi-Tech C is that it implements full ISO/ANSI C. Code written for the Hi-Tech compiler should be portable to any other ANSI C compiler.
So you've got your oscope telling you that DR1 is toggling, but the PIC is not working.
Actually DR1 is not toggling. In fact, the problem is that DR1 is doing nothing (from what I could see on the scope), though DATA is rapidly sending pulses. This is what seems so strange to me. In fact, if I remember, I believe that CLK was also toggling, yet the PIC was doing nothing and in an infinite loop. It was as if, the RF-24 was receiving data and attempting to clock it into the PIC all by itself, yet I never saw DR1 change.
I've never used the Hi-Tech compiler so I don't know what statements work with your compiler. My guess is the compiler is doing something screwy with the tris assigment:

TRISC = 0b000000001;

So that the PORTC.0 is never getting set to an input, or the define at the top of your code is not working correctly. Try looking at the generated ASM or using:

TRISC = 0x01; //Or whatever the Hi-Tech hex assignment is

instead of the binary format. I remember some motorola compilers that would happily compile
x = 0b.0000.1101;
and very happily (and to my never ending frustration) cut off everything after the second period - without any compile errors!
I am pretty sure the registers are being set correctly. I have never had any trouble before. I normally set registers in Hex, but I was faithfully trying to copy your working example. I can certainly see how being able to set periods after every nibble is convenient -- especially when you are dealing with larger numbers! Again, Hi Tech C does not support these methods.

Again, I really appreciate the help. I know you are busy, but would there be any chance you could compile my code for one of your processors and see if DR1 toggles? It is basically your code verbatim with the two changes you noted in bit representation. As I said, if I can get this code to work consistantly, it might be a nice test jig for the RF-24.

Thanks,
Sam
By Zman
#2360
hey, Sam

do you have the .asm output from your .c code ?
if you post it, it will be easier to trace the bug
User avatar
By sparky
#2364
Actually DR1 is not toggling. In fact, the problem is that DR1 is doing nothing (from what I could see on the scope), though DATA is rapidly sending pulses. This is what seems so strange to me. In fact, if I remember, I believe that CLK was also toggling, yet the PIC was doing nothing and in an infinite loop. It was as if, the RF-24 was receiving data and attempting to clock it into the PIC all by itself, yet I never saw DR1 change.
Sorry, I need to read closer. I skimmed your extra post and saw something was toggling. DATA will toggle as it can be both an output and an input. BUT - CLK should NEVER toggle. That is an input only.

You are really going to have to check your hardware on this one...

I forget what the default state is of the TX/RX bit. If the nrf2401 powers up in TX mode, you'll never see the DR1 line go high until you correctly get control of the data and clk lines and get the correct configuration data in there.

-Nathan
By Sam
#2373
Sorry, I need to read closer. I skimmed your extra post and saw something was toggling. DATA will toggle as it can be both an output and an input. BUT - CLK should NEVER toggle. That is an input only.
Upon further inspection, I noticed that when I reset the PIC, CLK sends out a series of 800us pulses prior to sending the correct 8 clock pulses - though this should not matter. Of more interest is that as soon as the I clock in the config_setup, the DATA line begins transmitting a whole mess of 2.3us pulses. I am not sure what that is all about.
You are really going to have to check your hardware on this one...
I think you must be right, but I am not sure what it could be since I have tried with two set ups using both the F877 and F628. I did add a few more capacitors to no avail.
I forget what the default state is of the TX/RX bit. If the nrf2401 powers up in TX mode, you'll never see the DR1 line go high until you correctly get control of the data and clk lines and get the correct configuration data in there.
It powers up in transmit mode, and I believe that I am correctly clocking the config byte for receive mode. It does appear to respond that something has been clocked in with all the pulses that appear on DATA as I mentioned above.

Thanks again for all the help. I think I am going to put this on hold for a bit. For the meantime, I will stick with coding my own preamble, sync, crc though, unfortunately, I don't think I can match the 1mbps. Which leads me to a question about the RFM RF products and about smt soldering, which I will post separtely.
Thanks again.