Atmega328p-pu and NRF24L01 problem

Hi guys,
i’m trying to send data from a breadboard arduino (an atmega328p-pu with internal 8Mhz oscillator) to a raspberry using NRF24L01 modules. I’m using the TMRh20 RF24 lib.
I used Arduino isp to flash the bootloader on the blank atmega, then configured the Arduino IDE to program directly (using the cp2102 usb board) on the atmega using internal oscillator.
The classic blink led example is working, so i assume that this “first” part is done well.

All the connections seems ok because the printDetails show correct information on both sides. i connected VCC-AVCC and GND-GND on the atmega, directly without caps.

nrf24 ------- atmega328
GND —> GND
VCC —> VCC
CE ----> PB1
CSN ----> PB2
SCK -----> PB5
MOSI —> PB3
MISO → PB4
take from http://forum.arduino.cc/index.php?topic=262307.0
I used the GettingStarted_CallResponse example, modified.

#include <JeeLib.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <OneWire.h>
#include <DallasTemperature.h>
 
int led = 13;
int relay=7;
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Setup for low power waiting

// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 10 
RF24 radio(9,10);

byte addresses[2] = {0xF0F0F0F0E1LL,0x7365727631LL};      

byte counter = 1;                                                                                                        

const int max_payload_size = 512;
char payload[512+1]; // +1 to allow room for a terminating NULL char
char floatBuffer[20];
 
void setup(){
  
  Serial.begin(9600);
  printf_begin();
  Serial.println("***Starting\n\r");


  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(15,15);                 // Smallest time between retries, max no. of retries
  radio.setPayloadSize(1);               
  radio.setPALevel(RF24_PA_LOW);
  radio.setChannel(70);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  radio.openReadingPipe(1,0x7365727631LL);
  radio.setCRCLength(RF24_CRC_16);
  radio.powerUp();
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging
  
    
}

 
void loop(void) {

 delay(1000);
/****************** Ping Out Role ***************************/
  //sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura
  delay(100);
  float temperature = 12;//sensors.getTempCByIndex(0);
  sendData(dtostrf(temperature,2,1,floatBuffer));
  delay(100);
  Sleepy::loseSomeTime(2000);  // Try again later
    //Sleepy::powerDown();
   

}

void sendData( char *value) {
  
  uint8_t gotByte; 
  sprintf(payload, "%s", value);
  Serial.print(payload);
  unsigned long time = millis();
  bool ok = radio.write( payload, strlen(payload));
  if (ok)
  {
    if(!radio.available()){                             // If nothing in the buffer, we got an ack but it is blank
            printf("Got blank response. round-trip delay: %lu ms\n\r",millis()-time);
        }
        else
        {
            while(radio.available() ){                      // If an ack with payload was received
                radio.read( &gotByte, 1 );                  // Read it, and display the response time
                printf("Got response %d, round-trip delay: %lu ms\n\r",gotByte,millis()-time);
                counter++;                                  // Increment the counter variable
            }
        }
        Serial.print(" send ok\n\r");
  }
  else
    Serial.print(" send failed\n\r");
}

This is the output from the atmega side
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xf0f0f0f0e1 0x7365727631
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xf0f0f0f0e1
RX_PW_P0-6 =0x01 0x01 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR =0x02
RF_CH = 0x46
RF_SETUP =0x03
CONFIG = 0x0e
DYNPD/FEATURE = 0x3f 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW

Output:
12.0 send failed

I’m powering all of this with 3.3V.
The only extra components i put is a 100uf cap between VCC and GND, without results.

Am i missing something?

Thanks!!
Yuri

I'm missing the receiver-part that is supposed to send the acknowledges.

You’re right: i thinked that this was not important because send failed means that the transmission failed (radio.write). So, i suppose the problem is on arduino side…i’m wrong?
Anyway, the receiver-part is a raspberry B, running the gettingstarted-callresponse for raspi (little bit changed). Also in this part, the printDetails show correct information

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x7365727631 0xf0f0f0f0e1
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x7365727631
RX_PW_P0-6 =0x01 0x01 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR =0x02
RF_CH = 0x46
RF_SETUP =0x03
CONFIG = 0x0e
DYNPD/FEATURE = 0x3f 0x06
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW

also the address seems correct, can you confirm?
This is how the nrf module is connected to raspy (http://hack.lenotta.com/wp-content/uploads/2013/10/Raspischeme.png)

This is the raspi code:

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <RF24/RF24.h>

using namespace std;
RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t addresses[2] = {0xF0F0F0F0E1LL,0x7365727631LL};
//const uint64_t addresses[][6] = { 0xF0F0F0F0E1LL, 0x7365727631LL };
const int max_payload_size = 512;
char payload[max_payload_size+1]; // +1 to allow room for a terminating NULL char

int main(int argc, char** argv){

  radio.begin();
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.enableAckPayload();               // Allow optional ack payloads
  radio.setRetries(15,15);                 // Smallest time between retries, max no. of retries
  radio.setPayloadSize(1);                // Here we are sending 1-byte payloads to test the call-response speed
//  radio.enableDynamicPayloads();
  radio.setPALevel(RF24_PA_LOW); 
  radio.setChannel(70);
  radio.openWritingPipe(addresses[1]);
  radio.openReadingPipe(1,addresses[0]);
  radio.setCRCLength(RF24_CRC_16);
  radio.powerUp();
  radio.printDetails();
  radio.startListening();

while (1){
        delay(100);
	//cout<<"\nCheck data..2";
	
	if ( radio.available() )
	{
		cout<<"\nDisponibili";
		uint8_t len;
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
		len = radio.getDynamicPayloadSize();
        if (len<max_payload_size) {
    	  radio.read( payload, radio.getDynamicPayloadSize() );
  	  // Put a zero at the end to terminate string
	  payload[len] = 0;
  	  // Spew it
          cout<<"\nTemp: " << payload; 
			done=true;
        } else {
          cout<<"0;0;ERROR=Receive error. Too large payload\n"; 
          done=true;
        }
		delay(100);
      }
	  uint8_t pipeNo,resp;
	  
	  double temp;
	  temp=atof(payload);
		if (temp>=22) {
			resp=0;
		}
		else{
			resp=1;
		}
		radio.writeAckPayload(pipeNo,&resp, 1 );   // This can be commented out to send empty payloads.	  
   
   }
   delay(1000);
} //while 1
} //main

Do you have any ideas?
Thanks

I would use dynamicPayloads on both sides and I believe if you want to use ack-Payloads you have to.

You should have a long and intensive look at the nRF24L01+ datasheet. The workings of transmissions, acks and all that stuff are described quite clear.

For a ShockBurst transmission you need the receiving part. So if your first test was stand-alone, everything works as expected.

I have not run the nRF24L01+ attached to my Raspi, so I can not be of much help on that side, but a one second delay between checks of the radio?

Where is the outupt on the Raspi?

I’ll try to change the dynamic payloads as you suggested and i’ll report back to you.
I’ll try also with classic arduino (i have an arduino 2009, pretty sure that this configuration and this same code worked some years ago)
There is no output on the raspy, other that the radio.printDetails() i posted above. Seems that no data is received because the cout<<"\nDisponibili"; (translate: “data avaiable”) after the if ( radio.available() ) is always skipped…so data is never received (or never sended?)

From page 63 of the datasheet:

If ACK packet payload is activated, ACK packets have dynamic payload lengths and the Dynamic Payload Length feature should be enabled for pipe 0 on the PTX and PRX. This is to ensure that they receive the ACK packets with payloads.

just for infos, the problem was a wrong wiring in the raspberry part :) Now trasmission works well!!!