This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

RF TX and RX switching Problem

Hi Team, 

I am working with Nrf24L01 chip with ATMEGA328(ATMEL C code) i made separate TX and RX module it works fine. But i want TX and RX in same module i done coding but it work as only receiver not switched to TX mode.Please find below code and give solution for me. If possible send me sample TXRX code.

/*
 * TxRx_1.c
 *
 * Created: 5/4/2018 2:38:27 PM
 * Author : Mahesh
 */ 



//header files
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include "nRF24L01.h"


//Function declaration
uint8_t GetReg(uint8_t);
uint8_t *WriteToNrf(uint8_t, uint8_t, uint8_t *, uint8_t);
void nrf24L01_init(void);
void nrf24L01_init_tx (void);
void nrf24L01_init_rx (void);
void Initspi(void);
void transmit_payload(uint8_t *);
void receive_payload(void);
void reset(void);



#define dataLen 5
#define W 1
#define R 0
//char data[10];
uint8_t *data;
uint8_t *data2;

int main(void)
{
	char mode;
	char tx_mode,rx_mode;
	Initspi();
	nrf24L01_init();
	
	      unsigned char W_buffer[5];	
		  W_buffer[0]=1;
	      uint8_t str[5]={1,2,3,4,5};		//array contain number
	      
	     // unsigned char W_buffer[5];			//TRANSMISSION
	      
	      int i;
	      for(i=0;i<5;i++)
	      
	      {
		      W_buffer[i]=str[i];		  //sending something data in 0x93;
	      }
   
	while(1)
	{
		if ((PIND & (1<<PIND5))==0)
		mode=tx_mode;
		else
		mode=rx_mode;
	
		if(mode==rx_mode)
		{
		
		reset();
		nrf24L01_init_rx();
		l1:
		receive_payload();	
		
		if((GetReg(STATUS) & (1<<6)) != 0)
		{
			PORTD &= ~(1<<2);
			_delay_us(50);
			
			data=WriteToNrf(R,R_RX_PAYLOAD,data,5);
			if(data[0]==1)
			{
			//mode=tx_mode;
			PORTD &= ~(1<<4);
			_delay_ms(2000);
			PORTD |=(1<<4);	
			}
			
			else
			goto l1;	
		}

		}
		
	else if(mode=tx_mode)
	{
	//reset();
	//_delay_ms(200);
	nrf24L01_init_tx();
	transmit_payload(W_buffer);
	if((GetReg(STATUS) & (1<<5)) != 0)
	{
		PORTD &= ~(1<<4);
		_delay_ms(2000);
		PORTD |=(1<<4);				  //blink led
		//_delay_ms(1000);
		
	}	
	return 0;
	}
		
		}

	}



void Initspi(void)
{
	DDRD |= (1<<4);						//LED
	DDRB|=(1<<PINB5);					 //sck out
	DDRB &= ~(1<<PINB4);				   	 //MISO
	DDRB|=(1<<PINB2);				    //CSN out
	DDRB|=(1<<PIND2);				    //CE out
	DDRB|= (1<<PINB3);                 //MOSI
	//PORTB |=(1<<PINB4);
	PORTB |=(1<<PINB2);			       //CSN high to start with nothing to be sent to RF yet
	PORTD &= ~(1<<PIND2);			   //CE low to start with nothing to sent /receive
	DDRD &= ~(1<<5);			      //switch not yet used
	PORTD |= (1<<5);
	
	PORTD |= (1<<4);
	SPCR|=(1<<SPE)|(1<<MSTR);         // enable spi
	
}


char WriteByteSPI(unsigned char cData)
{
	
	SPDR = cData;				 //Load byte to data register
	while(!(SPSR & (1<<SPIF)));	//wait for transmission complete
	return SPDR;				//return what received from nrf
}


void nrf24L01_init(void)
{
	_delay_ms(100);
	uint8_t val[5];
	
	//EN_AA - (auto-acknowledgments) transmitter gets automatic response from receiver when successfil transmission
	val[0]=0x01;
	WriteToNrf(W, EN_AA, val, 1);				//W=write mode EN_AA=register to write to val=data to write, 1=number of data bytes
	
	val[0]=0x2F;
	WriteToNrf(W, SETUP_RETR, val, 1);         //set up automatic retransmission on fail of AA
	
	val[0]=0x01;
	WriteToNrf(W, EN_RXADDR, val, 1);		    //enable data pipe0 as RX address
	
	//RF address width setup
	val[0]=0x03;
	WriteToNrf(W, SETUP_AW, val, 1);			//5byte Rf address
	
	//RF channel setup 2.4-2,52GHZ
	val[0]=0x01;
	WriteToNrf(W, RF_CH, val, 1);				//2.4GHZ

	//choose power mode and data speed
	val[0]=0x07;								//0b00000111 3rd bit 1=1Mbps,bit 2-1 power mode("11"=-0db ,"00"=-18db)
	WriteToNrf(W, RF_SETUP, val, 1);

	//Payload width setup
	val[0]=dataLen;
	WriteToNrf(W, RX_PW_P0, val, 1);
}

void nrf24L01_init_rx (void)
{
		uint8_t val[5];
			//RX RF address setup
			int i;
			for(i=0; i<5; i++)
			{
				val[i]=0x12;
			}
			WriteToNrf(W, RX_ADDR_P0, val, 5);        //RX_ADDR_P0 giving address to pipe0
			
	//Configure reg setup-now it is time to boot up the nrf and choose if it is receiver or transmitter
	val[0]=0x1F;
	WriteToNrf(W, CONFIG, val, 1);				//0b0001 1110 bit 0="0":Transmitter bit 0="1":Receiver bit 1=power up
	_delay_ms(100);
}

void nrf24L01_init_tx (void)
{
		uint8_t val[5];
		//TX RF address setup
		for(i=0; i<5; i++)
		{
			val[i]=0x12;
		}
		WriteToNrf(W, TX_ADDR, val, 5);
	//Configure reg setup-now it is time to boot up the nrf and choose if it is receiver or transmitter
	val[0]=0x1E;
	WriteToNrf(W, CONFIG, val, 1);				//0b0001 1110 bit 0="0":Transmitter bit 0="1":Receiver bit 1=power up
	_delay_ms(100);
}


uint8_t *WriteToNrf(uint8_t ReadWrite, uint8_t reg, uint8_t *val, uint8_t antVal)
{
	
	//Read or write(W/R), reg=register, *val=array with package, antVal=number of integer in package
	if (ReadWrite == W)
	{
		reg = W_REGISTER + reg;	// add write bit to the register
	}
	
	
	static uint8_t ret[5];
	
	_delay_us(10);
	//CLEARBIT(PORTB, 2);
	PORTB &= ~(1<<2);		//CSN low nrf start listen command
	WriteByteSPI(reg);		//Set nrf to write/read mod of reg
	_delay_us(10);
	
	int i;
	for(i=0; i<antVal; i++)
	{
		if (ReadWrite == R && reg != W_TX_PAYLOAD) //did you want the read registry
		//when writing W_TX_PAYLOAD you cannot add the "W" since it is same level registry
		{
			ret[i]=WriteByteSPI(NOP);				//send dummy bytes to read out the data
			_delay_us(10);
		}
		else
		{
			WriteByteSPI(val[i]);				   //send commands once at a time
			_delay_us(10);
		}
	}
	//SETBIT(PORTB, 2);
	PORTB |= (1<<2);						//CSN high
	
	return ret;								//retun array
}

uint8_t GetReg(uint8_t reg)
{

	_delay_us(10);
	PORTB &= ~(1<<2);    //CSN low nrf start listen command
	//CLEARBIT(PORTB, 2);	//CSN low
	_delay_us(10);
	WriteByteSPI(R_REGISTER + reg);		//R_REGISTER set nrf to read mode reg=this register will read back
	_delay_us(10);
	reg = WriteByteSPI(NOP);			//send dummy byte once to receive the first byte in the reg
	_delay_us(10);
	PORTB |= (1<<2);					//CSN high stop listening
	//SETBIT(PORTB, 2);	//CSN IR_High
	return reg;
}


void receive_payload(void)
{
	
	PORTD |= (1<<2);		//CE high listen for the data
	//SETBIT(PORTB, 1);
	//_delay_ms(1000);
//	PORTD &= ~(1<<2);	   //CE low stop listening
	//CLEARBIT(PORTB, 1);
	//_delay_ms(10);
}


void transmit_payload(uint8_t *W_buff)
{
	WriteToNrf(R, FLUSH_TX, W_buff, 0); //send 0xe1 to flush the old data
	WriteToNrf(R, W_TX_PAYLOAD, W_buff,5);//send the data in W_buff to nrf
	
	_delay_ms(10); 
	PORTD |= (1<<2);	//CE high to transmit the data
	//SETBIT(PORTB, 1);
	_delay_us(20);
	PORTD &= ~(1<<2);	//CE low to stop
	//CLEARBIT(PORTB, 1);
	_delay_ms(10);
}


void reset(void)
{
	_delay_us(10);
	PORTB &= ~(1<<2);//CSN low
	_delay_us(10);
	WriteByteSPI(W_REGISTER + STATUS);	//
	_delay_us(10);
	WriteByteSPI(0b01110000);
	_delay_us(10);
	PORTB |= (1<<2);		//CSN IR_High
}



  • Seems like you have hard coded a lot of variables/configurations, so I won't spend time trying to read your code. Regardless it should be quite straight forward to change mode. Make sure you sett CE = 0 first, so the chip is in Standby mode before you try to change radio mode. Se Figure 4. Radio control state diagram in the product specification.

Related