Help with advice on selecting RF transceiver.

pmd34

Joined Feb 22, 2014
527
Im afraid i could not seem to find my original receiver code.. it seemed to be missing the initialisation of the RF chip.
I will enclose a little more complicated (im afraid) program that i made later on.
This basically transferred data from the USB port (picked up on the ATMEGA USART) to the RF chip (on the ATMEGA SPI) and sent it to another RF module. And collected any received RF data (signaled with the interrupt) back to the USB. I used quite a few data "packet" bytes so I could read out information as a string of ascii characters to help easily spot what information was going back and forth. I also dont use loops in the data transmition, at some point I had found that they can actually ran rather slowly and it could make a mess of the USART data transmission timing. I hope it makes some sense!!
USB to RF.PNG
 

Attachments

djsfantasi

Joined Apr 11, 2010
9,156
I may be totally off-base here, so I’m declaring that up front. It’s because I’m used to controlling servos with an Arduino. Or an Arduino with a servo shield. Or serial comms to a stand-alone controller. I’ve used all methods.

Having said that, it’s my understanding that once you output position of your servo to a PWM pin on the AtMega328, the μP maintains the servo position without having to refresh the signal every 20mS (50Hz).

This reduces the strain of communicating, as you only have to output changes in position. And perhaps you don’t need to send every change, but only those larger than some experimentally defined threshold. Perhaps you could use the Arduino Servo library in your code.

I used the last option (stand-alone servo controller) to control 11 servos over a 9600bps link. If you could use this type of controller, I used an SSC-32 from Robotshop.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
hi hex,
I will dig out those TX and RX files and post later.
E

EDIT:
Added the Base station code, the *.txt is the *.bas [ this site will not accept *.bas extensions]
Also the *.asm that Oshonsoft produces, its a mix of Basic code with the ASM code included.
thanks I'll let you know if I have any questions about it. once I get it solved for my appplication i'll post the code back and any notes I have in case anyone else might need similar help and comes across this thread.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
I may be totally off-base here, so I’m declaring that up front. It’s because I’m used to controlling servos with an Arduino. Or an Arduino with a servo shield. Or serial comms to a stand-alone controller. I’ve used all methods.

Having said that, it’s my understanding that once you output position of your servo to a PWM pin on the AtMega328, the μP maintains the servo position without having to refresh the signal every 20mS (50Hz).

This reduces the strain of communicating, as you only have to output changes in position. And perhaps you don’t need to send every change, but only those larger than some experimentally defined threshold. Perhaps you could use the Arduino Servo library in your code.

I used the last option (stand-alone servo controller) to control 11 servos over a 9600bps link. If you could use this type of controller, I used an SSC-32 from Robotshop.
I'm not actually using the PWM pins. I have a timer setup to turn output pins on for a given duration and then turn them off when a compare is made. I am trying to control 5 servos off of the microcontroller without any type of PWM driver.

so my code in a nutshell functions as follows.

ADC on micro 1
reads 1st channel
an identifying byte for that channel gets transmitted via uart
followed by conversion result as 1 byte
a timer setup for approx 4ms halts the program
then the program selects the next channel
and repeats through the remaining 4 adc channels I am using
repeats forever.

2nd microcontroller
receives 1st byte (Identifying byte)
selects 1st output pin
sets up 2 timers (1 for a 4ms delay and another for the pulse duration)
loads 2nd byte into compare register of pulse duration timer
compare match then disables that output
1st timer keeps program halted until 4ms has elapsed
then it repeats through the next 4 packets of data the same way
to give me the 20ms required between the pulses for my servos

I am using 2 atmega328ps and all my code is written in assembly which i've been learning as I go. If you want I can post those 2 programs.
I use SPI to program my controllers with an avr dragon through avr studio 7 but I haven't written any code yet to actually use the controller to manage or program any peripheral devices with SPI so I am really going to need to understand that protocol. I have a vague understanding of how the protocol works.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
hi hex,
I will dig out those TX and RX files and post later.
E

EDIT:
Added the Base station code, the *.txt is the *.bas [ this site will not accept *.bas extensions]
Also the *.asm that Oshonsoft produces, its a mix of Basic code with the ASM code included.
I looked at your ASM code.....and it is well beyond my current level of comprehesion. This is the first time I have ever tried to program anything and I look at your code and immediately I am lost. In hindsight I choose a project that is alot more intense than I thought it was going to be and I have a long row to hoe with very little time left. I am going to do my best to figure out the coding but I will most likely be asking some questions about the NRF register usage in a couple of days once I get my unit and start modifying my program. I do appreciate the help though.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
We learned the basics of programming using an 8051 chip with assembly. We were told that we cannot use "arduino" if we were to use microcontrollers for our projects. Once our abstracts were submitted we are no longer allowed to change or alter our project. The main reason why we aren't to use arduino is because we needed to understand the hardware within the controller and how to access it directly rather than through predefine libraries.....I think I can get it going, hopefully in time. My program works in so far its just getting a wireless interface connected to communicate between the 2 controllers. Besides I am a rather stubborn type of guy and don't really want to take the easy path. I know I could program my controllers with arduino and just show them some one elses assembly code but I refuse to do that. I'd rather fail trying than pass by cheating or taking an easy path I guess. I should have my NRF chips tomorrow and I'll get started.
 

djsfantasi

Joined Apr 11, 2010
9,156
We learned the basics of programming using an 8051 chip with assembly. We were told that we cannot use "arduino" if we were to use microcontrollers for our projects. Once our abstracts were submitted we are no longer allowed to change or alter our project. The main reason why we aren't to use arduino is because we needed to understand the hardware within the controller and how to access it directly rather than through predefine libraries.....I think I can get it going, hopefully in time. My program works in so far its just getting a wireless interface connected to communicate between the 2 controllers. Besides I am a rather stubborn type of guy and don't really want to take the easy path. I know I could program my controllers with arduino and just show them some one elses assembly code but I refuse to do that. I'd rather fail trying than pass by cheating or taking an easy path I guess. I should have my NRF chips tomorrow and I'll get started.
Excellent presentation of your constraints. You’ve got a good attitude.

Have you done serial comms before. Both devices need to be configured exactly the same. Is there a possibility that there is a slight difference?
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
Not really, but I understand the concept. With my 2 controllers I get good communication between them with a wire connecting tx to rx (i'm only sending 1 way with no need for anything else). I understand atleast with my atmega328p how to setup the frame and baud rates correctly. hopefully I can apply the same settings to the NRF24. I'm reading the tutorial that was linked to earlier in this thread and I feel a little bit more at ease. I am starting to understand how this will work and formulating a game plan for modifying my code in my mind right now. the SPI protocol doesn't seem very difficult and how the chip will interact with my controller is also appearing pretty straight forward so far. I think I'll be in good shape, expect some road blocks of course (mainly with learning the NRFs registers) but maybe after a day or 2 playing around with it I believe it will come together.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
Excellent presentation of your constraints. You’ve got a good attitude.

Have you done serial comms before. Both devices need to be configured exactly the same. Is there a possibility that there is a slight difference?
Initially my problem was that I selected a transceiver that couldn't support my data rate. I was ignorant of the fact and only looked that it could handle the baud rate. it took me a while to figure out what was going wrong with it. Thats why I came here and asked for suggestions. Thankfully there is a very helpful community here and I believe i'm on the right track now.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
finished looking over the tutorial and reviewing my micros data sheet. it seems as though my micro has a master SPI mode which will allow me to use some of the USART hardware when communicating with the NRF. This is good for me as I won't need to change a ton of stuff when it comes to sending and receiving my data. I find some of the NRF requirements to be a little funky though, I'll have to read the datasheet for it and re-read that tutorial. I'm a little confused as to why I need to send dummy packets to the NRF when for example I want to read out some data. Not completely understanding it yet, it seems like it needs me to pass it 1 byte of garbage for each byte I expect to get back from it... at any rate it doesn't appear to be as elusive of a process as I thought i would be. Thanks.
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
when configuring the NRF
I need to pull CSN low
then send the instruction to the device in this case the write instruction to a particular register
Can I send the data for the instruction immediately afterwards or does there need to be a delay.

And between writing to different registers I need to bring CSN high then low again right? I can't just send another instruction byte after the last data byte for the last instruction that I sent right?
 

pmd34

Joined Feb 22, 2014
527
Hi Hex,

Right on all counts... it seems you can send data "intermediately" after setting the CSN pin. But you need to "clock" the CNS pin after one set of data and before the next. eg:

#define SPI_En cbi (PORTD, PD5); // Enable CSN line on RF chip (SPI enable)
#define SPI_Dis sbi (PORTD, PD5);

#define SPI_Clock cbi (PORTD, PD5); sbi (PORTD, PD5); cbi (PORTD, PD5); // Clock the SPI - Disable - then enable

SPI_En; // Use "chip select" to select the RF chip for SPI programming

SPDR=0+32; // 32 + to write to the registry command
while (!(SPSR & (1<<SPIF))) // Wait for SPI data to be sent
;
SPDR=RFRxConfig; // Set registry value re-configure into RX unit (LSB=1)
while (!(SPSR & (1<<SPIF)))
;
SPI_Clock; ...........
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
Thanks, that is what I thought. using this device has balooned my program significantly. One more thing that I am confused about though is the pipe address....if I am doing a R_RX_Payload instruction do I need to pass the pipe address next or how does that work. I'm not using multiple modules just the one.
 

pmd34

Joined Feb 22, 2014
527
As far as I remember and see from my code, you set up the addresses when you initialise the chips:
//---------------------------------------------
SPI_Clock;
SPDR=10+32; // Address of THIS Unit when Recieving (address data pipe 0)
while (!(SPSR & (1<<SPIF)))
;
SPDR=TXAddress[3];
while (!(SPSR & (1<<SPIF)))
;
SPDR=TXAddress[2];
while (!(SPSR & (1<<SPIF)))
;
SPDR=TXAddress[1];
while (!(SPSR & (1<<SPIF)))
;
SPDR=TXAddress[0];
while (!(SPSR & (1<<SPIF)))
;
//---------------------------------------------
SPI_Clock;
SPDR=16+32; // Address of Recieving Unit this one is transmitting to
while (!(SPSR & (1<<SPIF)))
;
SPDR=RXAddress[3];
while (!(SPSR & (1<<SPIF)))
;
SPDR=RXAddress[2];
while (!(SPSR & (1<<SPIF)))
;
SPDR=RXAddress[1];
while (!(SPSR & (1<<SPIF)))
;
SPDR=RXAddress[0];
while (!(SPSR & (1<<SPIF)))
;
//---------------------------------------------

So when you send data you just fill up the transmitter "payload" Then signal the chip to send (with the CE line).
 

Thread Starter

hexluthor

Joined Feb 25, 2019
27
Are you familiar with AVR assembly? That is what I am writing my code in. I don't really understand what is happening in your code. I am trying to make sense of it but I am just not seeing it right.

here is the function I have as part of my initialization where I am setting up a transmitter for pipe 0

cbi PORTD, 3 ; drops CSN low
ldi r16, 0x22 ; value of nrf24l01 instruction to write into rx address register
ldi r17, 0x01 ; value of address pipe 0
call Tx_Empty_Poll ; subroutine make sure that nothing is currently in the TX buffer of atmega328p
sts UDR0, r16 ; loading RX adress register of nrf24l01 into TX buffer of atmega328p (should move to shift register and transmit ; immediately)
call Tx_Read_Poll ; subroutine to read out my rx buffer (clear the buffer, since sending the the 1st instruction will return status register
sts UDR0, r17 ; loading value for adress pipe 0 into buffer which should be transmitted immediately
sbi PORTD, 3 ; Sets CSN high again
call Tx_Read_Poll ; clear buffer again

this is obviously not everything I am trying to setup in my initialization just the setup for the data pipe on this device which will be acting as the transmitting device.

On another circuit which is built nearly identical which will be acting as a receiver for data. I have the same initialization routine for the data pipe. in other words they are both setup in their respective address registers as data pipe 0.

when I transmit then I think I won't need to adjust that address register right? The only thing I would need to do is load data into the buffer of my microcontroller and send the instruction byte to load the TX_payload then pass the NRF24 my data for that payload and it will automagically send out a transmission that can be read on another device with the same data pipe setup?

If you are familiar with AVR assembly I could post my entire code but it may be a bit boring to look at. I am getting my circuit board in later this after noon and plan on testing everything out then I am sure I have made mistakes and will need to figure some more things out. but the data pipe is just confusing to me.
 

ericgibbs

Joined Jan 29, 2010
18,766
hi hex,
When you are ready post your AVR coding, I will try it in my Oshonsoft AVR simulator, it may help you with debugging.
E
 
Top