Intro

In this blog post I will describe how I used the SPI interface of the Raspberry Pi 2 (and Raspberry Pi) to communicate with an Arduino board.

Both the RPi and Arduino are connected to a nRF24L01+ chip to communicate with each other via the SPI interface.

I will describe the practical details of the setup and will also share the sources which were used.

The GPIO usage on the Raspberry Pi 2 is exactly the same as on the Raspberry Pi B(+). In practice it might be that some expansion boards which fit on the Raspberry Pi B do not fit on the RPiB+ or RPi2 because pins 27,28 are right next to pins 25,26.

 

Setup

To use the GPIO pins on the Raspberry Pi 2 I used some (additional) electronic parts. I did the same tests with Raspberry Pi B Rev. 2.0 and Raspberry Pi 2 B.

The most important parts I used:

2x nRF24L01+

1x Raspberry Pi 2 / 1x Raspberry Pi B

1x Arduino UNO R3

2x Capacitor 220uF(*) (for the power to the nRF24L01+ chip)

 

To connect to the nRF24L01+ chip I used a straight 20 pin ribbon cable and for connecting to the GPIO pins of the Raspberry Pi an old IDE40 cable. (Note that if you try this yourself, you should pay attention that you have 40 pin cable without any shorts, a 80-wire / 40 pin cable will most likely have shorts to reduce crosstalk.)


(*) I still had this capacitor laying around, probably 10uF would have been sufficient.


Raspberry Pi (2) GPIO PINs

For both Raspberry Pi's the pins that I use are the same.

P01 : 3.3V : dark orange (*)
P25 : GND : black

P15 : GPIO22 : white (CE)

P19 : MOSI : yellow

P21 : MISO : green

P23 : SCLK : orange (*)

P24 : CSN  : blue


We connect the pins from the RPi(2) to the nRF24L01+ chip. Vcc is 3.3V and for CE we use pin 15 (GPIO22) on the RPi(2). (For the rest we connect the MOSI of the RPi to the MOSI of the nRF24L01+ chip, ... )

In the test setup I used an old IDE40 cable. On both the RPi2 and RPi, pin 1 and 2 are at the edge of the board. Since some pins of the IDE cable are next to the board you will see that the wires on the other side of the IDE cable are inserted in a different position.

(*) It might not be that easy to see the difference between dark orange and orange in the pictures, but the dark orange is the "lonely" cable (7 pins next to the white cable).

 

IDE40 color
RPi(2) function
RPi(2) pinnRF24L01+ pinnRF24L01+ function20-pin color
dark orange3.3V012Vcc / 3.3Vyellow
blackGND251GNDwhite
whiteGPIO22153CEwhite
yellowMOSI196MOSIyellow
greenMISO217MISOgreen
orangeSCLK235SCKorange
blueCSN244CSNblue

 

Raspberry Pi 2 B:

The following table tries to show the relation between the pins on the RPi2 and the pins on the IDE40 cable:

__________________------__________________
403836343230282624222018161412108642
39373533312927252321191715131197531

The "---" in the middle represents the notch in the midlle of the IDE cable (see pictures "RPi2: IDE40 ribbon cable / dupont wires").

 

{gallery} Raspberry Pi 2 IDE40

RPi2B_IDE40.jpg

RPi2: IDE40 ribbon cable

RPi2B_IDE40_dupont.jpg

RPi2: IDE40 ribbon cable / dupont wires

 

Raspberry Pi B:

The following table tries to show the relation between the pins on the RPi and the pins on the IDE40 cable (xx means not used; pins sticking out next to the board):

__________________------__________________
2624222018161412108642xxxxxxxxxxxxxx
252321191715131197531xxxxxxxxxxxxxx

 

 

{gallery} Raspberry Pi IDE40

RPiB_IDE40.jpg

RPi: IDE40 ribbon cable

RPiB_IDE40_dupont.jpg

RPi: IDE40 ribbon cable / dupont wires

nRF24L01+

"Top" view of the nRF24L01+ chip

|__|__|__|__|--
|___________
|||
|||
|||
2468
1357

 

1 : GND

2 : VCC (3.3V)

3 : CE    : white

4 : CSN  : blue

5 : SCK  : orange

6 : MOSI : yellow

7 : MISO : green

8 : IRQ : xx

 

The following table tries to show the relation between the nRF24L01+ pins and the pins on the 20-pin ribbon cable (xx means not used):

________------________
2468xxxxxxxxxxxx
1357xxxxxxxxxxxx

 

{gallery} nRF24L01+

nRF24L01_180.jpg

nRF24L01+: chip

nRF24L01_dupont_180.jpg

nRF24L01+: dupont

 

Software

By default SPI is not enabled on Raspbian to load it during the boot process execute sudo raspi-config then select Advanced and then enable the SPI kernel module.

You can also do sudo modprobe spi-bcm2708.

For both the RPi and Arduino, I used the TMRh20 library available on github (some RPi specific info).

If you download the library and do not follow the installation procedure, then you'll need to do sudo make and sudo make install to install the library.

The modified sources are just to transmit data between RPi and Arduino. By default this Arduino sketch will start in transmit mode, by pressing d it will go in "dump" mode, where it will dump the contents of the data array when it's received.

 

Arduino Sketch:

/*
2015-04-06 : Johan Boeckx - Arduino/RPi(2) nRF24L01+ : Arduino UNO R3 code
  Tested on Arduino UNO R3 and Raspberry Pi B Rev. 2.0 and Raspberry Pi 2 B


TMRh20 2014
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
*/
/** Reliably transmitting large volumes of data with a low signal or in noisy environments
* This example demonstrates data transfer functionality with the use of auto-retry
and auto-reUse functionality enabled. This sketch demonstrates how a user can extend
the auto-retry functionality to any chosen time period, preventing data loss and ensuring
the consistency of data.

This sketh demonstrates use of the writeBlocking() functionality, and extends the standard
retry functionality of the radio. Payloads will be auto-retried until successful or the
extended timeout period is reached.
*/
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
/*************  USER Configuration *****************************/
RF24 radio(7,8);                        // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
unsigned long timeoutPeriod = 3000;     // Set a user-defined timeout period. With auto-retransmit set to (15,15) retransmission will take up to 60ms and as little as 7.5ms with it set to (1,15).
                                        // With a timeout period of 1000, the radio will retry each payload for up to 1 second before giving up on the transmission and starting over
/***************************************************************/
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };   // Radio pipe addresses for the 2 nodes to communicate.
byte data[32] = {"_This is a message via NRF24L+!"};                           //Data buffer
volatile unsigned long counter;
unsigned long rxTimer,startTime, stopTime, payloads = 0;
//bool TX=1,RX=0,role=0, transferInProgress = 0;
bool transferInProgress = 0;
unsigned int TX=1,RX=0,role=1,lastrole=0,SKIP=2,RXPRINT=3,RXDUMP=4;
unsigned int offset=0;
void setup(void) {
  Serial.begin(57600);
  printf_begin();
  radio.begin();                           // Setup and configure rf radio
  radio.setChannel(1);                     // Set the channel
  radio.setPALevel(RF24_PA_HIGH);
  radio.setDataRate(RF24_250KBPS);
  //radio.setDataRate(RF24_2MBPS);
  radio.setAutoAck(1);                     // Ensure autoACK is enabled
  radio.setRetries(2,15);                  // Optionally, increase the delay between retries. Want the number of auto-retries as high as possible (15)
  radio.setCRCLength(RF24_CRC_16);         // Set CRC length to 16-bit to ensure quality of data
  if (role == RX)
  {
    radio.openWritingPipe(pipes[0]);         // Open the default reading and writing pipe
    radio.openReadingPipe(1,pipes[1]);

    radio.startListening();                 // Start listening
  }
  else{
    radio.openWritingPipe(pipes[1]);         // Open the default reading and writing pipe
    radio.openReadingPipe(1,pipes[0]);
    radio.stopListening();
  }
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging

  printf("\n\rRF24/examples/Transfer Rates/\n\r");
  printf("*** PRESS 'T' to begin transmitting to the other node\n\r");

  /*
  randomSeed(analogRead(0));              //Seed for random number generation
  for(int i=0; i<32; i++){
     data[i] = random(255);               //Load the buffer with random data
  }
  */
  radio.powerUp();                        //Power up the radio

}
void showData(void)
{
      printf("Data: ");
      for(int i=0; i<32; i++){
         if(isprint(data[i]))
           printf("%c", data[i]);
         else
           printf(".");
      }
      printf("\n\r");
}
void loop(void){
  if(role == TX){
    delay(500);                                              // Pause for a couple seconds between transfers
    printf("Initiating Extended Timeout Data Transfer\n\r");
    unsigned long cycles = 1000;                              // Change this to a higher or lower number. This is the number of payloads that will be sent.

    unsigned long transferCMD[] = {'H','S',cycles };          // Indicate to the other radio that we are starting, and provide the number of payloads that will be sent
    radio.writeFast(&transferCMD,12);                         // Send the transfer command
    if(radio.txStandBy(timeoutPeriod)){                       // If transfer initiation was successful, do the following

        startTime = millis();                                 // For calculating transfer rate
        boolean timedOut = 0;                                 // Boolean for keeping track of failures

        for(int i=0; i<cycles; i++){                          // Loop through a number of cycles
          data[0] = i;                                        // Change the first byte of the payload for identification
          if(!radio.writeBlocking(&data,32,timeoutPeriod)){   // If retries are failing and the user defined timeout is exceeded
              timedOut = 1;                                   // Indicate failure
              counter = cycles;                               // Set the fail count to maximum
              break;                                          // Break out of the for loop
          }
        }


        stopTime = millis();                                  // Capture the time of completion or failure

       //This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success
       if(timedOut){ radio.txStandBy(); }                     //Partially blocking standby, blocks until success or max retries. FIFO flushed if auto timeout reached
       else{ radio.txStandBy(timeoutPeriod);     }            //Standby, block until FIFO empty (sent) or user specified timeout reached. FIFO flushed if user timeout reached.

   }else{                                      
       Serial.println("Communication not established");       //If unsuccessful initiating transfer, exit and retry later
       counter = cycles+1;
   }
   if (counter <= cycles )
   {
     float rate = cycles * 32 / (stopTime - startTime);         //Display results:

     Serial.print("Transfer complete at "); Serial.print(rate); printf(" KB/s \n\r");
     Serial.print(counter);
     Serial.print(" of ");
     Serial.print(cycles); Serial.println(" Packets Failed to Send");
     //if (counter == 0)
     showData();
   }
   counter = 0;
   Serial.print("------------------------------------------------------------\r\n\r\n");
}

if(role == RX){

  if(!transferInProgress){                       // If a bulk data transfer has not been started
     if(radio.available()){
        //Serial.print("Rx\r\n");
        //Serial.print(".");
        radio.read(&data,32);                    //Read any available payloads for analysis
        if(data[0] == 'H' && data[4] == 'S'){    // If a bulk data transfer command has been received
          payloads = data[8];                    // Read the first two bytes of the unsigned long. Need to read the 3rd and 4th if sending more than 65535 payloads
          payloads |= data[9] << 8;              // This is the number of payloads that will be sent
          counter = 0;                           // Reset the payload counter to 0
          transferInProgress = 1;                // Indicate it has started
          startTime = rxTimer = millis();        // Capture the start time to measure transfer rate and calculate timeouts
        }
     }
  }else{
     if(radio.available()){                     // If in bulk transfer mode, and a payload is available
       //Serial.print("Rx\r\n");
       radio.read(&data,32);                    // Read the payload
       rxTimer = millis();                      // Reset the timeout timer
       counter++;                               // Keep a count of received payloads
     }else
     if(millis() - rxTimer > timeoutPeriod){    // If no data available, check the timeout period
       Serial.println("Transfer Failed");       // If per-payload timeout exceeeded, end the transfer
       transferInProgress = 0;
       //Serial.print("!\r\n");
     }else
     if(counter >= payloads){                   // If the specified number of payloads is reached, transfer is completed
      //Serial.print("!\r\n");
      startTime = millis() - startTime;         // Calculate the total time spent during transfer
      float numBytes = counter*32;              // Calculate the number of bytes transferred
      Serial.print("Rate: ");                   // Print the transfer rate and number of payloads
      Serial.print(numBytes/startTime);
      Serial.println(" KB/s");
      printf("Payload Count: %d (%c)\n\r", counter, (char* )data[1]);
      showData();
      transferInProgress = 0;                   // End the transfer as complete
    }
  }
}
if(role == RXDUMP){
     if(radio.available()){
        radio.read(&data,32);                    //Read any available payloads for analysis
        showData();
     }
}
if(role == RXPRINT){
  if(!transferInProgress){                       // If a bulk data transfer has not been started
     if(radio.available()){
        //Serial.print("Rx\r\n");
        Serial.print(".");
        radio.read(&data,32);                    //Read any available payloads for analysis
        if(data[0] == 'H' && data[4] == 'S'){    // If a bulk data transfer command has been received
          payloads = data[8];                    // Read the first two bytes of the unsigned long. Need to read the 3rd and 4th if sending more than 65535 payloads
          payloads |= data[9] << 8;              // This is the number of payloads that will be sent
          counter = 0;                           // Reset the payload counter to 0
          transferInProgress = 1;                // Indicate it has started
          startTime = rxTimer = millis();        // Capture the start time to measure transfer rate and calculate timeouts
        }
     }
  }else{
     if(radio.available()){                     // If in bulk transfer mode, and a payload is available
       Serial.print(".");
       radio.read(&data,32);                    // Read the payload
       rxTimer = millis();                      // Reset the timeout timer
       counter++;                               // Keep a count of received payloads
     }else
     if(millis() - rxTimer > timeoutPeriod){    // If no data available, check the timeout period
       Serial.println("Transfer Failed");       // If per-payload timeout exceeeded, end the transfer
       transferInProgress = 0;
       Serial.print("!\r\n");
     }else
     if(counter >= payloads){                   // If the specified number of payloads is reached, transfer is completed
      Serial.print("!\r\n");
      startTime = millis() - startTime;         // Calculate the total time spent during transfer
      float numBytes = counter*32;              // Calculate the number of bytes transferred
      Serial.print("Rate: ");                   // Print the transfer rate and number of payloads
      Serial.print(numBytes/startTime);
      Serial.println(" KB/s");
      printf("Payload Count: %d (%c)\n\r", counter, (char* )data[1]);
      showData();
      transferInProgress = 0;                   // End the transfer as complete
      delay(500);
    }
  }
}
if(role == SKIP){
}

  //
  // Change roles
  //
  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    printf("*** SERIAL : %c %d\n\r", c, c);
    if ( c == 'C' && role == SKIP)
    {
      role = lastrole;
      printf("*** CONTINUING PREVIOUS ROLE\n\r");
    }
    else if ( c == 'D' && (role != RXDUMP ))
    {
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[1]);
      radio.startListening();
      printf("*** CHANGING TO RECEIVE DUMP ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
      role = RXDUMP;                // Become the primary receiver (pong back)
    }
    else if ( c == 'T' && (role != TX ))
    {
      printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
      radio.openWritingPipe(pipes[1]);
      radio.openReadingPipe(1,pipes[0]);
      radio.stopListening();
      role = TX;                  // Become the primary transmitter (ping out)
    }
    else if ( c == 'P' && (role != RXPRINT ) )
    {
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[1]);
      radio.startListening();
      printf("*** CHANGING TO RECEIVE PRINT ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
      role = RXPRINT;                // Become the primary receiver (pong back)
    }
    else if ( c == 'R' && (role == RX) )
    {
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[1]);
      radio.startListening();
      printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
      role = RX;                // Become the primary receiver (pong back)
    }
    else if ( c == 'S' && role != SKIP)
    {
      lastrole = role;
      role = SKIP;
      showData();
      printf("*** WAITING -- PRESS 'C' TO CONTINUE\n\r");
    }
    else if ( c == 'M' ){
      offset = 1;
      while ( c != 13 )
      {

        if ( Serial.available() )
        {
          c = Serial.read();
          if ( c != 13 ){
          offset++;
          if (offset>=32)
            offset = 1;
          data[offset] = c;
          printf("*** SERIAL : %c data[%d]=(%c)\n\r", c, offset, data[offset]);
          }
        }
      }
    }
  }
}








 

Raspberry Pi (2) c code:

/*
2015-04-06 : Johan Boeckx - Arduino/RPi(2) nRF24L01+ : Raspberry Pi (2) code
  Tested on Arduino UNO R3 and Raspberry Pi B Rev. 2.0 and Raspberry Pi 2 B

 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.

 03/17/2013 : Charles-Henri Hallard (http://hallard.me)
              Modified to use with Arduipi board http://hallard.me/arduipi
                          Changed to use modified bcm2835 and RF24 library
TMRh20 2014 - Updated to work with optimized RF24 Arduino library

*/

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

using namespace std;
//
// Hardware configuration
// Configure the appropriate pins for your connections

/****************** Raspberry Pi ***********************/

// Radio CE Pin, CSN Pin, SPI Speed
// See http://www.airspayce.com/mikem/bcm2835/group__constants.html#ga63c029bd6500167152db4e57736d0939 and the related enumerations for pin information.

// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);

// NEW: Setup for RPi B+
//RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ);

// Setup for GPIO 15 CE and CE0 CSN with SPI Speed @ 8Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);

// RPi generic:
RF24 radio(22,0);

/*** RPi Alternate ***/
//Note: Specify SPI BUS 0 or 1 instead of CS pin number.
// See http://tmrh20.github.io/RF24/RPi.html for more information on usage

//RPi Alternate, with MRAA
//RF24 radio(15,0);

//RPi Alternate, with SPIDEV - Note: Edit RF24/arch/BBB/spi.cpp and  set 'this->device = "/dev/spidev0.0";;' or as listed in /dev
//RF24 radio(22,0);


/****************** Linux (BBB,x86,etc) ***********************/

// See http://tmrh20.github.io/RF24/pages.html for more information on usage
// See http://iotdk.intel.com/docs/master/mraa/ for more information on MRAA
// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV

// Setup for ARM(Linux) devices like BBB using spidev (default is "/dev/spidev1.0" )
//RF24 radio(115,0);

//BBB Alternate, with mraa
// CE pin = (Header P9, Pin 13) = 59 = 13 + 46
//Note: Specify SPI BUS 0 or 1 instead of CS pin number.
//RF24 radio(59,0);

/********** User Config *********/
// Assign a unique identifier for this node, 0 or 1
// 0 Rx / 1 Tx
bool radioNumber = 0;
unsigned long timeoutPeriod = 3000;     // Set a user-defined timeout period. With auto-retransmit set to (15,15) retransmission will take up to 60ms and as little as 7.5ms with it set to (1,15).

/********************************/

// Radio pipe addresses for the 2 nodes to communicate.
// const uint8_t pipes[][6] = {"1Node","2Node"};
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };   // Radio pipe addresses for the 2 nodes to communicate.
char data[32] = {"_A message from RPi w/ NRF24L+!"};            //Data buffer

void showData(void)
{
      printf("Data: ");
      for(int i=0; i<32; i++){
         if(isprint(data[i]))
           printf("%c", data[i]);
         else
           printf(".");
      }
      printf("\n\r");
}

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

  const int role_rx=0, role_tx=1;
  int role=role_rx;
/********* Role chooser ***********/

  printf("\n ************ Role Setup ***********\n");
  string input = "";
  char myChar = {0};

  cout << "Choose a role: Enter 0 for Rx, 1 for Tx (CTRL+C to exit) \n>";
  getline(cin,input);

  if(input.length() == 1) {
    myChar = input[0];
    if(myChar == '0'){
        cout << "Role: Rx " << endl << endl;
    }else{  cout << "Role: Tx " << endl << endl;
        role = role_tx;
    }
  }
  switch(role) {
      case role_rx :
        radioNumber=0;
        break;

      case role_tx :
        radioNumber=1;
        break;
  }

/***********************************/
  // Setup and configure rf radio
  radio.begin();

  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15);
  // Set the channel
  radio.setChannel(1);
  // Set the data rate
  //radio.setDataRate(RF24_2MBPS);
  radio.setDataRate(RF24_250KBPS);
  //radio.setPALevel(RF24_PA_MAX);
  radio.setPALevel(RF24_PA_MIN);

    if ( !radioNumber )    {
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]);
        memset(&data,'\0',sizeof(data));
        radio.startListening();
    } else {
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1,pipes[0]);
        radio.stopListening();
    }
    // Dump the configuration of the rf unit for debugging
    radio.printDetails();
    printf("Start loop:\n");
    // forever loop
    while (1)
    {
        if (radioNumber) {
            if (radio.writeBlocking(&data,sizeof(data),timeoutPeriod)) {
                printf(".");
            }
            else {
                printf("?");
            }
            fflush(stdout);
            //printf("\n");
        }
        else {
        //
        // Receive each packet, dump it
        //
            if(radio.available()){
                // Read any available payloads for analysis
                radio.read(&data,32);
                // Dump the printable data of the payload
                showData();
                fflush(stdout);
            }
        }
        delay(5);
    } // forever loop

  return 0;
}









 

Raspberry Pi (2) output

Receive mode

When we receive a message, dump the data.

************ Role Setup ***********

Choose a role: Enter 0 for Rx, 1 for Tx (CTRL+C to exit)

>0

Role: Rx

 

================ SPI Configuration ================

CSN Pin       = CE0 (PI Hardware Driven)

CE Pin       = Custom GPIO22

Clock Speed     = 8 Mhz

================ NRF Configuration ================

STATUS         = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0

RX_ADDR_P0-1     = 0xabcdabcd71 0x544d52687c

RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6

TX_ADDR         = 0xabcdabcd71

RX_PW_P0-6     = 0x20 0x20 0x00 0x00 0x00 0x00

EN_AA         = 0x3f

EN_RXADDR     = 0x02

RF_CH         = 0x01

RF_SETUP     = 0x21

CONFIG         = 0x0f

DYNPD/FEATURE     = 0x00 0x00

Data Rate     = 250KBPS

Model         = nRF24L01+

CRC Length     = 16 bits

PA Power     = PA_MIN

Start loop:

Data: H...S...........................

Data: .This is a message via NRF24L+!.

Transmit mode

If the write succeeds write a "." else a "?".

************ Role Setup ***********

Choose a role: Enter 0 for Rx, 1 for Tx (CTRL+C to exit)

>1

Role: Tx

 

================ SPI Configuration ================

CSN Pin       = CE0 (PI Hardware Driven)

CE Pin       = Custom GPIO22

Clock Speed     = 8 Mhz

================ NRF Configuration ================

STATUS         = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0

RX_ADDR_P0-1     = 0x544d52687c 0xabcdabcd71

RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6

TX_ADDR         = 0x544d52687c

RX_PW_P0-6     = 0x20 0x20 0x00 0x00 0x00 0x00

EN_AA         = 0x3f

EN_RXADDR     = 0x03

RF_CH         = 0x01

RF_SETUP     = 0x21

CONFIG         = 0x0e

DYNPD/FEATURE     = 0x00 0x00

Data Rate     = 250KBPS

Model         = nRF24L01+

CRC Length     = 16 bits

PA Power     = PA_MIN

Start loop:

...????................................................................................................................................................................................................................................................................................................^C

Arduino Output

By default the Arduino starts in Transmit mode. When you press "d" it goes to "dump" mode, which means just dump the packet which is received.

STATUS           = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0

RX_ADDR_P0-1     = 0x544d52687c 0xabcdabcd71

RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6

TX_ADDR          = 0x544d52687c

RX_PW_P0-6       = 0x20 0x20 0x00 0x00 0x00 0x00

EN_AA            = 0x3f

EN_RXADDR        = 0x03

RF_CH            = 0x01

RF_SETUP         = 0x25

CONFIG           = 0x0e

DYNPD/FEATURE    = 0x00 0x00

Data Rate        = 250KBPS

Model            = nRF24L01+

CRC Length       = 16 bits

PA Power         = PA_HIGH

 

Transmit mode

The Arduino sketch which was taken as basis, was meant to send a header packet and then x times a payload packet.

When we stop listening on the RPi to the packets coming from the Arduino, we will see errors on the serial output of the Arduino:

Initiating Extended Timeout Data Transfer

Transfer complete at 5.00 KB/s

0 of 1000 Packets Failed to Send

Data: .This is a message via NRF24L+!.

------------------------------------------------------------

 

Initiating Extended Timeout Data Transfer

Communication not established

------------------------------------------------------------

Dump mode

Data: _A message from RPi w/ NRF24L+!.

 

 

Sources

 

Github : https://github.com/TMRh20/RF24

Class documentation : Optimized High Speed NRF24L01+ Driver Class Documenation: Optimized High Speed Driver for nRF24L01(+) 2.4GHz Wireless Tr…

Raspberry Pi info : Optimized High Speed NRF24L01+ Driver Class Documenation: Raspberry Pi

Ethernet library : RF24Ethernet - TCP/IP over RF24Network: RF24Ethernet library: TCP/IP over RF24Network