NRF24L01 on atMega328p, RC-car

Hi! I want to control a rc car using 2 atmega328p and a h-bridge (SN754410). I'm new using the NRF24L01 and can't find the reason why I don't get a signal between the modules. I suppose it's on my code but I lack the experience to find the problem.
I have two C codes, the first one for the transmitter and the second one for the receiver. Any help would be much appreciated!

Transmitter Code:

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "nrf24.h"

#define JOYSTICK_X PC0     // Analog input pin for joystick X axis
#define JOYSTICK_Y PC1     // Analog input pin for joystick Y axis
#define JOYSTICK_SW PB0
volatile uint8_t switch_pressed = 0;
#define PWM_MAX 255       // Maximum PWM duty cycle value
#define JOYSTICK_MAX 1023 // Maximum joystick reading value

void setup_adc() {
  DDRC |= (0 << PC0) | (0 << PC1) | (0 << PC2)| (0 << PC3)| (0 << PC4) | (0 << PC5);

  ADMUX |= (0 << REFS1) | (1 << REFS0) |(0 << ADLAR) |
           (0 << MUX3)  | (0 << MUX2)  | (0 << MUX1) | (0 << MUX0);  // set reference voltage to AVCC
  
  ADCSRA |= (1 << ADEN) | (1 << ADSC) | (0 << ADATE) |
            (0 << ADIF) | (0 << ADIE) |
            (1 << ADPS2)| (0 << ADPS1)| (0 << ADPS0); // set prescaler to 64
}

void spi_init(void) {
    // Set MOSI, SCK, and SS as output pins
    DDRB |= (1 << PB3) | (1 << PB5) | (0 << PB4);
    // Enable SPI, set as master, and set clock rate to F_CPU/16
    SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPR0);
    DDRD |= (1 << PD0) | (1 << PD1) | (1 << PD3) |(0 << PD4) | (1 << PD5) ;
}

uint8_t send_data[5];

int main(void){

  setup_interrupt();
  sei();

  setup_pwm();
  setup_adc();
  setup();
 
 nrf24_init();       // initialize hardware
    _delay_ms(50);

    /* Set TX address for transmitter module */
    uint8_t tx_addr[] = {0x11, 0x22, 0x33, 0x44, 0x55};
    nrf24_tx_address(tx_addr);

    /* Start transmission from transmitter module */
    
    nrf24_powerUpTx();  
   nrf24_writeRegister(RF_CH, 2);
    nrf24_writeRegister(RX_PW_P0, 4);
    nrf24_writeRegister(RF_SETUP, RF_SETUP_RF_DR_2000 | RF_SETUP_RF_PWR_0);
    nrf24_writeRegister(CONFIG, (1 << EN_CRC)|(0<<CRCO)|(0 << PRIM_RX));
    while(1){
      
      uint16_t x_val = analogRead(JOYSTICK_X); // Read X axis value
      uint16_t y_val = analogRead(JOYSTICK_Y); // Read Y axis value  
      OCR1A = x_val/4;
      OCR1B = y_val/4;

      if (switch_pressed){
        switch_pressed = 0;
        send_data[4]= 1;
      }
      else{
        send_data[4] = 0;
      }

      
      send_data[0] = OCR1A & 0xFF;
      send_data[1] = (OCR1A >> 8) & 0xFF;
      send_data[2] = OCR1B & 0xFF;
      send_data[3] = (OCR1B >> 8) & 0xFF;
     
     nrf24_ce_set(0);
      TX_POWERUP;
      nrf24_ce_set(0);
      spi_transfer( W_TX_PAYLOAD );
      for (i= 0; i<5; i++){
        spi_transfer(send_data[i]);
      }
      nrf24_csn_set(1);
      nrf24_ce_set(1);
      _delay_us(10);
     nrf24_rxFifoEmpty();
     }
    return 0;
}

Receiver Code

#define H_BRIDGE_PIN1 PB1 // PWM output pin for H bridge input 1
#define H_BRIDGE_PIN2 PB2 // PWM output pin for H bridge input 2

#define PWM_MAX 255       // Maximum PWM duty cycle value
#define JOYSTICK_MAX 1023 // Maximum joystick reading value
volatile uint8_t switch_pressed = 0;
#define H_1A PC2          // Define H bridge input DET VAR PB6 INNAN
#define H_2A PC3          // Define H bridge input 
#define H_3A PC4          // Define H bridge input DET VAR PD3 
#define H_4A PC5          // Define H bridge input 

int main(void){  
  
  setup_interrupt();
  sei();
  spi_init();
  setup_pwm();
  setup_adc();
  setup();

  nrf24_init();
  _delay_ms(50);
  // Set RF frequency to 2.402 GHz
  nrf24_writeRegister(RF_CH, 2);

  // Set up receive payload size and RF data rate
  nrf24_writeRegister(RX_PW_P0, 5);
  // Set data rate to 2 Mbps and power level to lowest
  nrf24_writeRegister(RF_SETUP, RF_SETUP_RF_DR_2000 | RF_SETUP_RF_PWR_0);


// Set module to receive mode
    nrf24_writeRegister(CONFIG, (1 << EN_CRC) | (0 << CRCO) | (1 << PRIM_RX));

    // Set the receive address for data pipe 0
    nrf24_writeAddress(RX_ADDR_P0, rx_addr, sizeof(rx_addr));
 
 uint8_t rx_addr[] = {0x55, 0x44, 0x33, 0x22, 0x11};
  nrf24_rx_address(rx_addr);
   nrf24_powerUpRx();

while (nrf24_isSending()) // jag hade innan dataReady()
    {

          nrf24_getData(received_data);
        
        
        /* Extract the received values of OCR1A and OCR1B from the buffer */
        uint16_t ocr1a = received_data[0] | (received_data[1]  << 8 );
        uint16_t ocr1b = received_data[2]  | (received_data[3] << 8 );
        uint16_t x_val = ocr1a*4;
        uint16_t y_val = ocr1b*4;
        uint8_t switch_status = received_data[4];

analogWrite(H_BRIDGE_PIN1,2*ocr1b ); 
      analogWrite(H_BRIDGE_PIN2,2*ocr1a); 
      if (x_val > JOYSTICK_MAX/2){
        PORTC = (1 << H_1A) | (0 << H_4A) |
                (0 << H_2A) | (1 << H_3A);
      }
      else{
        PORTC = (1 << H_1A) | (0 << H_4A) |
                (0 << H_2A) | (1 << H_3A);
      }        
  return 0;
}

You should start with Robin's tutorials first. Have a look here:

Try SimpleTx and SimpleRx to get going. Also run the CheckConnection sketch in post #30 first.

Here are tips that I found while getting my rf24 radios to work:

If you read and, closely, follow Robin2's simple rf24 tutorial you should be able to get them working. That tutorial sure helped me. The code in the examples has been proven to work many many times. If it does not work for you, there is likely a hardware problem.

Run the CheckConnection.ino (look in reply #30 in the tutorial) to verify the physical wiring between the radio module and its processor (Arduino). This is especially useful when running the example code from the tutorial if all you see is “Data received” repeating much more quickly than packets are being sent then there is a problem - most likely theArduino is not communicating properly with its nRF24.

Make sure the rf24 power supply can provide enough current. This is especially true for the high power (external antenna) modules. I use homemade adapters like these. They are powered by 5V and have a 3.3V regulator on the board. Robin2 also has suggested trying with a 2 AA cell battery pack.

If using the high powered radios make sure to separate them by a few meters. They may not work too close together. Try the lower power settings.

Reset the radios by cycling power to them after uploading new code. I have found that to help. They do not reset with the Arduino.

Sending too often can also cause a problem. Trying to send every time through a fast loop may not work. Slow down to 1 to 5 packets per second to test.

Switch to 1MB data rate to catch the not so well cloned clones.
radio.setDataRate( RF24_1MBPS );

Also for some clones, change TMRh20's RF24.cpp line 44
_SPI.setClockDivider(SPI_CLOCK_DIV2);
Into
_SPI.setClockDivider(SPI_CLOCK_DIV4);

Have a look at the common problems page.

The arduinoinfo Wiki.

The Last Minute Engineers rf24 page.

Thank you for the fast answer! I am using only the atmega328 and VSCode and I see that “Robin2” uses Arduino, I see that many functions are only available for Arduino but is there a large difference in the process otherwise?
Thanks!

I have no experience whit VSCode so cannot answer that question.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.