-->
Page 1 of 1

NRF24L01 + SPI

PostPosted: Wed Jun 14, 2017 3:47 pm
by Adamyno
Hi!

With ESP8266 the NRF24L01 scanner not works via SPI bus. There are 2 SPI in ESP. I don't know what is the difference, but I tried all of them. In RF24 library there is a scanner template and it doesn't compile. (Arduino IDE 1.8.3, atest libraries and boards)

There is an other method what Works for me with arduino uno but not with ESP.

Code: Select all#include <SPI.h>

#define CE  D2
#define CSN D8 //ss

// Array to hold Channel data
#define CHANNELS  64
int channel[CHANNELS];

// greyscale mapping
int  line;
char grey[] = " 123456789";

// nRF24L01P registers we need
#define _NRF24_CONFIG      0x00
#define _NRF24_EN_AA       0x01
#define _NRF24_RF_CH       0x05
#define _NRF24_RF_SETUP    0x06
#define _NRF24_RPD         0x09

// get the value of a nRF24L01p register
byte getRegister(byte r)
{
 byte c;
 
digitalWrite(CSN,LOW);
 c = SPI.transfer(r&0x1F);
 c = SPI.transfer(0); 
 digitalWrite(CSN,HIGH);

 return(c);
}

// set the value of a nRF24L01p register
void setRegister(byte r, byte v)
{
 digitalWrite(CSN,LOW);
 SPI.transfer((r&0x1F)|0x20);
 SPI.transfer(v);
 digitalWrite(CSN,HIGH);
}
 
// power up the nRF24L01p chip
void powerUp(void)
{
 setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x02);
 delayMicroseconds(130);
}

// switch nRF24L01p off
void powerDown(void)
{
 setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)&~0x02);
}

// enable RX
void enable(void)
{
   digitalWrite(CE,HIGH);
}

// disable RX
void disable(void)
{
   digitalWrite(CE,LOW);
}

// setup RX-Mode of nRF24L01p
void setRX(void)
{
 setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x01);
 enable();
 delayMicroseconds(130);
}

// scanning channels
void scan(void)
{
 disable();
 for( int j=0; j<64; j++)
 {
   for( int i=0 ; i<CHANNELS ; i++)
   {
     // select a new channel
     setRegister(_NRF24_RF_CH,(128*i)/CHANNELS);
     
     // switch on RX
     setRX();
     
     // wait enough for RX-things to settle
     delayMicroseconds(40);
     
     // this is actually the point where the RPD-flag
     // is set, when CE goes low
     disable();
     
     // read out RPD flag; set to 1 if
     // received power > -64dBm
     if( getRegister(_NRF24_RPD)>0 )   channel[i]++;
   }
 }
}

// outputs channel data as a simple grey map
void outputChannels(void)
{
 int norm = 0;
 
 // find the maximal count in channel array
 for( int i=0 ; i<CHANNELS ; i++)
   if( channel[i]>norm ) norm = channel[i];
   
 // now output the data
 Serial.print('|');
 for( int i=0 ; i<CHANNELS ; i++)
 {
   int pos;
   
   // calculate grey value position
   if( norm!=0 ) pos = (channel[i]*10)/norm;
   else          pos = 0;
   
   // boost low values
   if( pos==0 && channel[i]>0 ) pos++;
   
   // clamp large values
   if( pos>9 ) pos = 9;
 
   // print it out
   Serial.print(grey[pos]);
   channel[i] = 0;
 }
 
 // indicate overall power
 Serial.print("| ");
 Serial.println(norm);
}

// give a visual reference between WLAN-channels and displayed data
void printChannels(void)
{
 // output approximate positions of WLAN-channels
 Serial.println(">      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <");
}

void setup()
{
 Serial.begin(115200);
 
 Serial.println("Starting...");
 Serial.println();

 // Channel Layout
 // 0         1         2         3         4         5         6
 // 0123456789012345678901234567890123456789012345678901234567890123
 //       1 2  3 4  5  6 7 8  9 10 11 12 13  14                     |
 //
 Serial.println("Channel Layout");
 printChannels();
 
 // Setup SPI
 SPI.begin();
 SPI.setFrequency(40000000);
 SPI.setDataMode(SPI_MODE0);
 SPI.setBitOrder(MSBFIRST);
 //SPI.setClockDivider(SPI_CLOCK_DIV4);
 //SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
 
 
 // Activate Chip Enable
 pinMode(CE,OUTPUT);
 disable();
 
 // now start receiver
 powerUp();
 
 // switch off Shockburst
 setRegister(_NRF24_EN_AA,0x0);
 
 // make sure RF-section is set properly
 // - just write default value...
 setRegister(_NRF24_RF_SETUP,0x0F);
 
 // reset line counter
 line = 0;
}

void loop()
{
 // do the scan
 scan();
 yield();
 // output the result
 outputChannels();
 yield();
 
 // output WLAN-channel reference every 12th line
 if( line++>12 )
 {
   printChannels();
 
   
   line = 0;
 }
}


I tried many methods to wake the device. It compiled but not Works. When I move the CSN connector, somtimes prints random data but it is not real. So it Works wit Arduino (with SPI.setClockDivider(SPI_CLOCK_DIV4);) but doesn't Works with ESP.

Maybe the clock freq is not OK. I don't know. Please help. Thank you!

I have NodeMCU and Wemos D1 and standalone ESP-12E modules.