NRF24l01+ on MKR1000

Has anyone made this board work whit this RF transceiver?
I’ve tried the example but it doesn’t work. Don’t know how to resolve the problem.

The error I get is this:

In member function 'virtual void MirfHardwareSpiDriver::begin()':
error: 'SPI_2XCLOCK_MASK' was not declared in this scope
SPI.setClockDivider(SPI_2XCLOCK_MASK);
exit status 1

Using this code:

/**
 * A Mirf example to test the latency between two Ardunio.
 *
 * Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 8
 * CSN -> 7
 *
 * Note: To see best case latency comment out all Serial.println
 * statements not displaying the result and load 
 * 'ping_server_interupt' on the server.
 */

#include <SPI.h>
#include <Mirf.h>
#include <Mirf_nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

void setup(){
  Serial.begin(9600);
  /*
   * Setup pins / SPI.
   */
   
  /* To change CE / CSN Pins:
   * 
   * Mirf.csnPin = 9;
   * Mirf.cePin = 7;
   */
  
  Mirf.cePin = 1;
  Mirf.csnPin = 0;
  
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  
  /*
   * Configure reciving address.
   */
   
  Mirf.setRADDR((byte *)"clie1");
  
  /*
   * Set the payload length to sizeof(unsigned long) the
   * return type of millis().
   *
   * NB: payload on client and server must be the same.
   */
   
  Mirf.payload = sizeof(unsigned long);
  
  /*
   * Write channel and payload config then power up reciver.
   */
   
  /*
   * To change channel:
   * 
   * Mirf.channel = 10;
   *
   * NB: Make sure channel is legal in your area.
   */
   
  Mirf.config();
  
  Serial.println("Beginning ... "); 
}

void loop(){
  unsigned long time = millis();
  
  Mirf.setTADDR((byte *)"serv1");
  
  Mirf.send((byte *)&time);
  
  while(Mirf.isSending()){
  }
  Serial.println("Finished sending");
  delay(10);
  while(!Mirf.dataReady()){
    Serial.println("Waiting");
    if ( ( millis() - time ) > 1000 ) {
      Serial.println("Timeout on response from server!");
      return;
    }
  }
  
  Mirf.getData((byte *) &time);
  
  Serial.print("Ping: ");
  Serial.println((millis() - time));
  
  delay(1000);
}

Can anyone hepl me?

I don't know anything about the MKR1000 but I suspect the nRF24s need the same stuff no matter what they are connected to.

I got my nRF24s working on an Uno with this Tutorial

I suggest you use the TMRh20 version of the RF24 library - it solves some problems from the ManiacBug version

The pair of programs in this link may be useful.

...R

@ciaomanuhello,

Were you able to make it work on MKR1000??

Did you get your answer?
I am looking for same answer too.

This newer Simple nRF24L01+ Tutorial may be of interest - but it is for an Uno. However the same approach works for me on a Mega and Leonardo.

…R

I stopped working in this Project. I have discovered that libraries for this chip are made for avr board, so it can't work on arm...

Assuming that the MKR1000 supports SPI it should not be too difficult to create a few functions to read and write the registers on the nRF24.

The following pieces of code may be of interest. They come from a project I have been building on an Attiny and wanted also a compatible system for an Uno.

SPI code without the SPI library

// Very simple SPI code for Atemga 328 / Uno
// the idea is to facilitate an equivalent piece of code for the Attiny84 
// which does not have SPI


#include <Arduino.h>

#define MOSI_PIN 11
#define MISO_PIN 12
#define SCK_PIN 13
#define SS_PIN 10


void R2spiInitialize(byte settings) {
 pinMode(SS_PIN, OUTPUT); // this must come before SPCR is set
 // - took a long time to figure out
 SPCR = settings;
 SPSR = 0b00000000; // bit 0 affects SPI speed
 
 pinMode(MOSI_PIN, OUTPUT);
 pinMode(SCK_PIN, OUTPUT);
 pinMode(MISO_PIN, INPUT);
}


byte R2spiTransfer(byte val) {
 SPDR = val;
 asm volatile("nop"); // small delay  - see SPI.h
 while (!(SPSR & _BV(SPIF))) { // wait

 }
 return SPDR;
}

Code to work with nRF24

// an attempt to write my own nRF24 access functions
// this version uses my SPI functions rather than the standard library

// #includeX "Definitions.h"

byte R2rfStatus;
byte R2rfPayloadLength = 32;
byte writeBytes[4];
byte readBytes[32];

// some function prototypes

byte R2rfResetStatus();

//======================

void R2rfInitialize() {
 R2spiInitialize(0);
 pinMode(CE_PIN, OUTPUT);
 pinMode(CSN_PIN, OUTPUT);
}

//======================

 // basic functions to interface with nRF24
 // 3 are required - read a register, write a register, send a stand-alone command

 // this version with pointers - drawn from TMRh20RF24.cpp
 // this reads one byte
byte R2rfReadRegister(byte reg) {
 byte regCmd = 0x00 + reg;
 byte regVal;
 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( regCmd );
 regVal = R2spiTransfer(0xEE);
 digitalWrite(CSN_PIN, HIGH);
 return regVal;
}

//======================

 // this writes one byte
void R2rfWriteRegister(byte reg, byte regVal) {
 byte regCmd = 0x20 + reg;
 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( regCmd ); 
 R2spiTransfer(regVal);
 digitalWrite(CSN_PIN, HIGH);
}

//======================

 // write 5 address bytes
void R2rfWriteAddress5(byte reg, void* buf) {

 byte* tempBuf = reinterpret_cast <byte*>(buf);
 byte regCmd = 0x20 + reg;
 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( regCmd ); 
 for (byte n = 0; n < 5; n++) {
 R2spiTransfer(tempBuf[n]);
 }
 digitalWrite(CSN_PIN, HIGH);
}


//======================

void R2rfWriteTxPld(void* buf, byte numBytes) {

 byte numBlanks = R2rfPayloadLength - numBytes;
 byte* tempBuf = reinterpret_cast <byte*>(buf);
 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( W_TX_PAYLOAD ); 
 for (byte n = 0; n < numBytes; n++) {
 R2spiTransfer(tempBuf[n]);
 }
 for (byte n = 0; n < numBlanks; n++) {
 R2spiTransfer(0);
 }
 digitalWrite(CSN_PIN, HIGH);
}

//======================

void R2rfWriteAckPld(byte pipe, void* buf, byte numBytes) {

 byte numBlanks = R2rfPayloadLength - numBytes;
 byte* tempBuf = reinterpret_cast <byte*>(buf);
 byte cmd = W_ACK_PAYLOAD + pipe;
 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( cmd ); 
 for (byte n = 0; n < numBytes; n++) {
 R2spiTransfer(tempBuf[n]);
 }
 //~ for (byte n = 0; n < numBlanks; n++) { // think dynamic size works
 //~ R2spiTransfer(0);
 //~ }
 digitalWrite(CSN_PIN, HIGH);
}

//======================

void R2rfReadRxPld(void* buf, byte numBytes) {

 byte* tempBuf = reinterpret_cast <byte*>(buf);
 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( R_RX_PAYLOAD ); 
 for (byte n = 0; n < numBytes; n++) {
 tempBuf[n] = R2spiTransfer(0xFF);
 }
 digitalWrite(CSN_PIN, HIGH);
}

//======================

byte R2rfSingleByteCmd(byte cmd){

 digitalWrite(CSN_PIN, LOW);
 R2rfStatus = R2spiTransfer( cmd );
 digitalWrite(CSN_PIN, HIGH);

}

//======================

void R2rfStartListeningPipe1() {
 // set as Primary Rx
 R2rfWriteRegister(CONFIG, 0b00001111);
 // reset status
 R2rfResetStatus();
 // CE high
 digitalWrite(CE_PIN, HIGH);
 // Flush Tx
 R2rfSingleByteCmd(FLUSH_TX);
 // Flush Rx
 R2rfSingleByteCmd(FLUSH_RX);
}

//======================

byte R2rfDataAvailable() {
 R2rfSingleByteCmd(NOP); // get status
 byte avail = (R2rfStatus & 0b01000000); // register bit will be 1 if data is available
 return (avail > 0);
}

//======================

byte XXR2rfDataAvailable() {
 byte avail = ! (R2rfReadRegister(FIFO_STATUS) & 0b00000001); // register bit will be 1 if RX is empty - invert for avail
 return avail;
}

//======================

byte R2rfResetStatus() {
 // reset status
 R2rfWriteRegister(NRF_STATUS, 0b01110000);
}

If the SPI library works for you then you can use that and modify the second piece of code accordingly.

And I believe you need the definitions of the register names from the TMRh20 RF24 library.

…R

ciaomanuhello: I have discovered that libraries for this chip are made for avr board, so it can't work on arm...

RF24

Optimized fork of nRF24L01 for Arduino & Raspberry Pi/Linux Devices

https://github.com/TMRh20