Go Down

Topic: Poor Man's 2.4 GHz Scanner (Read 84897 times) previous topic - next topic

jengil

Hey thanks for making such a great tool - When i try to run this code i see a Series of M or Rs across the channels with no color - I really was unsure how to interpret it or if it is working correctly.  Any help would be appreciated if this code still works on the current Arduino platform.  Thanks again

cpixip

Thanks for your comments. The colors were added in the inital example just for marking the different 2.4GHz component seen. Of course there are no colors available in the terminal prg of the Arduino IDE.

The amount of power in each channel is displayed in ASCII grey scale. This is an old technique from the time when lineprinters were the primary output of mainframe computers. Have a try on your favorite search engine to find out more (here's one link which came up http://paulbourke.net/dataformats/asciiart/).

There is no reason why the code should not work with current Arduinos as the code uses only standards. I have however no way of testing the UNO or newer devices - I do not own any of these.

In case you have doubts, try any of the newer RF24-libraries. Most of them feature a scanner example based on my old code. These libraries are pretty much up-to-date.

In any case - have fun!

RonH1212

The Poor Man's 2.4 GHz Scanner work great on my UNO, but it will not work on the Mega2560.
I changed the following in the program #define CE 53

Where do I make the changes for CSN 48,  MOSI 51, MISO 50,  SCK 52    ?
Any help would be great
Ron

assadollahi

really great work and very inspiring. i'm thinking about using wifi signals for indoor positioning.
as i understand, your design is not actually a wifi transmitter but really more like a listener and
is not able to communicate via standard wifi.
i could imagine that this is actually a bonus since probably the power consumption is less compared
to a fully fledged wifi connector such as sparkfun's wifly.

do you have any thoughts / tips /caveat about using your setup for indoor positioning? for example,
the network activity (if that correlates with the power on different bands, i don't know) should certainly
not be used, but actually the network strenght of the different routers around.
also, we possibly would need to find out about temporary signals and stationary signals (wifii routers
are pretty stationary and continous, bluetooth may move or be off, microwaves don't move but are
on and off at unpredictable times).

finally: would it make sense to use two such scanners on either end of the bot so that one could have
a "stereo" view on the singals? or are these wave lengths / the sample rate of the device not suitable?
sorry, i'm a newbie on all of this, but to use wifi signals as a reference for sensor fusing is really tempting.

findftp

Hello,

Very nice scanner! I really would like to use it.
I want to use the nrf24L01 in combination with a 2.4Ghz camera and want to see the free zone to set the channel.
I have two breakout board which both do not seem to work with the code.
I hooked them up on an Arduino mini pro and an Arduino uno to see if that was the problem.
I'm sorry for the long paste, but they both show something like:
(look at the end of the output, it finally produces something, but it is very little)
What am I doing wrong?


Starting Poor Man's Wireless 2.4GHz Scanner ...

Channel Layout
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|  *****-W*                                                      | 3
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|              ::::WW+++::    :+++:++++                          | 4
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
>      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0
|                                                                | 0

cpixip

- the nrf24 might not working properly. You might check this by creating some 2.4GHz traffic close to the nrf24. Put it in close vincinity of your WLAN (make sure it's on ;). Putting the nrf24 in the vincinity of a microwave (but don't put it into the microwave!!!) and switching that on for a few seconds should give you also a strong signal.

cpixip

do you have any thoughts / tips /caveat about using your setup for indoor positioning?
this is not a very precise 2.4GHz scanner as the nrf24 delivers only a single bit, "signal strength above threshold" (or not). You won't be able to use it for such a purpose. Other chips have a better output of reception strength, you might google around for these. This tiny hack is just good to spot channels of low activity, nothing more... :smiley-cool:

rayshobby

#22
Dec 31, 2014, 05:37 am Last Edit: Dec 31, 2014, 05:38 am by rayshobby
Here is a blog post about implementing the poor man's 2.4G scanner using the RFToy:
http://weatherhelge.wordpress.com/2014/12/31/2-4ghz-scanner-using-rftoy/
the built-in OLED screen that comes with the RFToy is quite handy for display.
DIY electronics project at http://rayshobby.net

Divyeshpro

Hello Guys,

I still did not understand how this grey scale waterfall display works. I mean what does the numbers beside each line represent on the display?  Can some one give quick explanation of code?

its kind of urgent as I am using this test in my project.

Thanks....

mactsk

Hi what is the meaning of the numbers on the right side? at first it seems the strength of the signal, but i am unsure.

Jardal

Here is clone with LCD1602a:
http://blog.riyas.org/2014/06/a-simple-24ghz-spectrum-analyser-arduino-lcd-shield.html

And here is code for communication density analysis. It is possible to show live spectrum (SW_MODE = 0), but packets are very short and for exploration of communication density is needed statical display rather with data collection over some time.

-64dB threshold is good for this case. Just place device for some time (half hour or so) near powered-off wifi-AP to check communication density at AP place. Then leave device (for half hour or so) at place from where you will connect to AP (AP still powered off). From both diagrams you can explore free channels right for your AP. If your AP is within one room, then you can make only one measurement.

Used Arduino Pro Micro 3.3V/8MHz, NRF module powered from Arduino VCC, Arduino and LCD1602a(5V) powered from RAW (3.7V Li-ion battery LIR2032 + TP4056 charger module hacked to 30mA charge current). Power consumption about 20mA (without backlight).

Compiler: Arduino 1.6.7
Code: [Select]

 /* A simple 2.4GHZ spectrum analyser with nrf24l01,character lcd and an arduino
  * 
  * http://blog.riyas.org/2014/06/a-simple-24ghz-spectrum-analyser-arduino-lcd-shield.html
  *
  * Connect the nrf module to the spi pins (10,11,12,13)  and A1 (for CE) and an lcd to pin 8,9,4,5,6,7
  */

/*
 *  exact wifi channells map to 16 bars: (0), 1...13, (hole), 14
 */
 
 #include <SPI.h> 
 #include <LiquidCrystal.h> 
 // The LCD is conected to pins RS-8, EN-9, D4-4, D5-5, D6-6, D7-7, RW-GND, VO-GND 
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 
 byte minibars[8][8]; 
 //credits to Poor Man's Wireless 2.4GHz Scanner 
 // credits to all others 
 // uses an nRF24L01p connected to an Arduino 
 //   
 // Cables are: 
 //   CS    -> 10 
 //   MOSI   -> 11 
 //   MISO   -> 12 
 //   SCK   -> 13 
 // and CE    -> A1 
 // 
 // Modified from original code: March 2011 by Rolf Henkel 
 // 
 #define CE A1 
 // Array to hold Channel data 
 #define CHANNELS 94 
 int channel[CHANNELS]; 
 // 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 
 //SoftSPI<SOFT_SPI_MISO_PIN, SOFT_SPI_MOSI_PIN, SOFT_SPI_SCK_PIN, SPI_MODE> spi; 
 
byte CH_LEVEL[16]; 

byte scan_time = 255;  // minimum 130 for system + 40 for AGC - sensitivity to packet density (cca 250us per packet)

byte SW_MODE = 1; // 0 = live wifi scanner   1 = spectrum occupy
byte SCAN_COUNT = 32; // No of scans per one display - sensitivity to density
                      // SCAN_COUNT * 5 (MHz in ordinary channel) <256
byte DISP_ZOOM = 1;  // ZOOM level 0=1, 1=2, 2=4, 3=8, 4=16, 5=32 ...
                     // full "strength" to 15 levels, but some saturation wanted

void LCDdemo(){   // Built the characters for bars. 
  for (byte j=0; j<=7; j++)   
  { 
   for (byte i=0; i<=7; i++) 
   { 
    if (i<=j) 
    { minibars[j][7-i] = B01110;}   
    else 
    { minibars[j][7-i] = 0;} 
   } 
  }   
  for (byte i=0; i<=7;i++) 
  { 
   lcd.createChar(i, minibars[i]); 
  } 
  lcd.begin(16, 2);     
  for (byte j=0; j<=7;j++) 
  { 
   lcd.setCursor(j, 0); 
   lcd.write(j); 
   lcd.setCursor(j, 1); 
   lcd.write(7);   
  } 
}


byte getRegister(byte r)   // get the value of a nRF24L01p register 
 { 
  byte c; 
  PORTB &=~_BV(2); //D10 
  //PORTC &=~_BV(1); //analogue 1 as SS 
  c = SPI.transfer(r&0x1F); 
  c = SPI.transfer(0);   
  PORTB |= _BV(2); 
  //PORTC |= _BV(1); //analogue 1 as SS 
  return(c); 
 } 
 

void setRegister(byte r, byte v)   // set the value of a nRF24L01p register 
 { 
  PORTB &=~_BV(2); 
  //PORTC &=~_BV(1); 
  SPI.transfer((r&0x1F)|0x20); 
  SPI.transfer(v); 
  PORTB |= _BV(2); 
  //PORTC |= _BV(1); 
 } 

 
void powerUp(void)  // power up the nRF24L01p chip 
 {setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x02); 
  delayMicroseconds(130); 
 } 
 
void powerDown(void){setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)&~0x02); }    // switch nRF24L01p off 
void enable(void){  PORTC |= _BV(1);}    // enable RX   
void disable(void){PORTC &=~_BV(1);}     // disable RX 

void setRX(void)   // setup RX-Mode of nRF24L01p 
{ setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x01); 
  enable(); 
  delayMicroseconds(scan_time);    // the recommended delay of 130 usec 



void scanChannels(void)   // scanning all channels in the 2.4GHz band 
{ disable(); 
  for( byte j=0 ; j<= SCAN_COUNT ; j++)
   {for( byte i=0 ; i<CHANNELS ; i++) 
    {
    setRegister(_NRF24_RF_CH,i);  // select a new channel 
    setRX();  // switch on RX 
    disable();        // this is actually the point where the RPD-flag   is set, when CE goes low 
    if( getRegister(_NRF24_RPD)>0 )  channel[i]++;    // read out RPD flag; set to 1 if  received power > -64dBm 
   } 
  } 
 } 

  /*      https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/NonOverlappingChannels2.4GHzWLAN-en.svg/720px-NonOverlappingChannels2.4GHzWLAN-en.svg.png
    WIFI MHz  NRF-CH  od-do
    -   2401     1    1-8
    1   2412    12    9-14
    2   2417    17    15-19
    3   2422    22    20-24
    4   2427    27    25-29
    5   2432    32    30-34
    6   2437    37    35-39
    7   2442    42    40-44
    8   2447    47    45-49
    9   2452    52    50-54
    10  2457    57    55-59
    11  2462    62    60-64
    12  2467    67    65-69
    13  2472    72    70-74
    --  2477    77    75-79
    14  2484    84    80-94

    802.11b - 20MHz (22MHz), ch. 1,6,11,14 - end 2.494 GHz
          g/n       16,25MHz (20MHz)   1,5,9,13 - end 2.4835 GHz
          n         33,75MHz (40MHz)    3,11  - end 2.4835 GHz
   */

void outputChannels(void) 

  feedChannel(0, 1, 8);
  feedChannel(1, 9, 14);
  feedChannel(2, 15, 19);
  feedChannel(3, 20, 24);
  feedChannel(4, 25, 29);
  feedChannel(5, 30, 34);
  feedChannel(6, 35, 39);
  feedChannel(7, 40, 44);
  feedChannel(8, 45, 49);
  feedChannel(9, 50, 54);
  feedChannel(10, 55, 59);
  feedChannel(11, 60, 64);
  feedChannel(12, 65, 69);
  feedChannel(13, 70, 74);
  feedChannel(14, 75, 79);
  feedChannel(15, 80, 94);


void feedChannel(byte CH_wifi, byte CH_low, byte CH_high) 
 { 
  byte strength = 0; 
  for( byte i=CH_low ; i<=CH_high ; i++){ 
   strength = strength + channel[i]; 
   if(CH_LEVEL[CH_wifi] < strength) CH_LEVEL[CH_wifi] = strength;
   if (SW_MODE == 0) {plot_minibars(CH_wifi, strength);}
   else              {plot_minibars(CH_wifi, CH_LEVEL[CH_wifi]);}
   channel[i] = 0;
  }



 void plot_minibars(byte location, byte strngth) 
 { 
  byte str_disp = strngth >> DISP_ZOOM; //ZOOM
  if (str_disp>15) 
  { 
   lcd.setCursor(location, 1); 
   lcd.write(7); 
   lcd.setCursor(location, 0); 
   lcd.write(7); 
  } 
  else if (str_disp>7) 
  { 
   lcd.setCursor(location, 1); 
   lcd.write(7); 
   lcd.setCursor(location, 0); 
   lcd.write(str_disp-8);   
  } 
  else 
  { 
   lcd.setCursor(location, 1); 
   lcd.write(str_disp); 
   lcd.setCursor(location, 0); 
   lcd.write(32);   
  } 
 } 




//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() 
 { 
  LCDdemo();
 
  // Setup SPI 
  SPI.begin(); 
  SPI.setDataMode(SPI_MODE0); 
  SPI.setClockDivider(SPI_CLOCK_DIV2); 
  SPI.setBitOrder(MSBFIRST); 

  pinMode(CE,OUTPUT);    // Activate Chip Enable 
  disable(); 
  powerUp();    // now start receiver 
  setRegister(_NRF24_EN_AA,0x0);    // switch off Shockburst 
  // make sure RF-section is set properly   
  // - just write default value...   
  setRegister(_NRF24_RF_SETUP,0x0F);   


void loop()   
 {   
  scanChannels();   
  outputChannels();   
 } 


clbiggs99

I keep getting the following error on the next to last "}"; the end of the "if" statement at the very end;
stray '\302' in program; \302 maps to a period; but there isn't one anywhere near this section. Any suggestions?

arduinorotto

I've portetd this to the SE8R01. This more or less nRF24L01(+)-compatible chip has in its RPD register not a simple flag, it has values for the dBm!

Code: [Select]

#include <SPI.h>

//  
//    CE       -> 9         -> PORTB 1  

//    used an configured by arduinos SPI-lib
//    SS       -> 10        -> PORTB 2   CSN on the SE8R01. SPI SlaveSelect/ChipSelect
//    MOSI     -> 11         SPI
//    MISO     -> 12         SPI
//    SCK      -> 13         SPI

//    IRQ   ->  not needed -> not used


#define CE  9
#define CS 10

#define CHANNELS  126      // number of channels
int8_t channel[CHANNELS];  // Array to hold Channel data

// nRF24L01P registers we need. are the same on the SE8R01
#define _NRF24_CONFIG      0x00  
#define _NRF24_EN_AA       0x01  
#define _NRF24_RF_CH       0x05  
#define _NRF24_RF_SETUP    0x06  
#define _NRF24_RPD         0x09  


byte getRegister(byte r) { // get the value of a register
  byte c;

 //digitalWrite(10,LOW);         //too slow
 PORTB &=~_BV(2); //pin 10 = SS  //faster
 c = SPI.transfer(r & 0x1F);     // only lower 5 Bit are relevant
 c = SPI.transfer(0);
 
 //digitalWrite(10,HIGH);       // too slow
 PORTB |= _BV(2);

 return c;
}


void setRegister(byte r, byte v) { // set the value of a register
 

 PORTB &=~_BV(2);  //digitalWrite(CS,LOW);
 SPI.transfer((r&0x1F)|0x20);
 SPI.transfer(v);
 PORTB |= _BV(2);  //digitalWrite(CS,HIGH);
}


void powerUp(void) {  // power up the  chip
 setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x02);
 delayMicroseconds(130);     // works. iirc in the datasheet the value must be higher
}

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

// enable RX
void enable(void){
   PORTB |= _BV(1);    // Pin 9 = CE HIGH  digitalWrite(CE,HIGH);
  
  
}

// disable RX
void disable(void){
   PORTB &=~_BV(1);   // Pin 9 = CE  LOW
   //digitalWrite(CE,LOW);
}

// setup RX-Mode of SE8R01
void setRX(void){
 setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x01);
 enable();
 // this is slightly shorter than
 // the recommended delay of 130 usec
 // - but it works for me and speeds things up a little...
 //delayMicroseconds(100);  
 delayMicroseconds(210);     // datasheet says 210
}


void scanChannels(void){
 disable();
 setRX();  // once called is enough we put it here outside the for loop
 
 
   for( int i=0 ; i<CHANNELS ; i++)   {  
     // select a new channel
     setRegister(_NRF24_RF_CH,i);

     // switch on RX
     //setRX();  unnecessary see call outside the for-loop above

     // wait enough for RX-things to settle
     //delayMicroseconds(40);  // we do not need this its in setRX()
     delayMicroseconds(20);    // but probably a good idea after chanel switching for the pll
                               // I dont know whats a good value here try yourself
                               // if you see a lot of the same values above the whole channel line you may need
                               // a higher delay

     // this is actually the point where the RPD-flag
     // is set, when CE goes low
     //disable();  //afaik for SE8R01 unnecessary -> yes

     // SE8R01 has signed value for dBm we save it
     channel[i] = getRegister(_NRF24_RPD);  // *-1 damit der Wert positiv werid ist bei der ausgabe dann platzsparender
   }
}



void outputChannels(void) {
  for ( uint8_t i=0; i<CHANNELS; i++) {

    // Some mapping for better reading in the terminal window
    // use a small font ( < 10pixel)  and disable autoscrolling
    if(channel[i] < -90) {
      Serial.print("   ");
    }
    else if (channel[i] >= -90 && channel[i] < -80 ) {
      Serial.print("1");
    }
    else if (channel[i] >= -80 && channel[i] < -70 ) {
      Serial.print("2");
    }
    else if (channel[i] >= -70&& channel[i] < -60  ) {
      Serial.print("3");
    }
    else if (channel[i] >= -60 && channel[i] < -50 ) {
      Serial.print("4");
    }
    Serial.print(" ");
  }
  Serial.println();
}



void setup(){
 Serial.begin(57600);

 // Setup SPI
 SPI.begin();
 SPI.setDataMode(SPI_MODE0);
 SPI.setClockDivider(SPI_CLOCK_DIV2);
 SPI.setBitOrder(MSBFIRST);

 pinMode(CE,OUTPUT);  // Activate Chip Enable
 pinMode(CS,OUTPUT);  // probaly set by the SPI-lib but we do it again
 
 disable();
 powerUp(); // now start receiver
 delay(110); // SE8R01 datasheet: 100ms wait after power on reset


 setRegister(_NRF24_EN_AA,0x0); // switch off Shockburst

 // make sure RF-section is set properly
 // - just write default value...
 //setRegister(_NRF24_RF_SETUP,0x0F); // SE8R01 has other Registerlayout -> other value here
 setRegister(_NRF24_RF_SETUP,0x08);

 // reset line counter
 line = 0;
}



void loop(){
 scanChannels();
 outputChannels();
 
 delay(300);


}

MustacheMtn

Thank you for this. It worked out of the box perfectly.

jjosealonso

Hi guys, I was reasing and I though...

Since 2.4ghz is the same freq than BT BLE, Would be possible to read beacons (iBeacon or eddystone) from there without too many issues?

Go Up