Pages: [1] 2   Go Down
Author Topic: Poor Man's 2.4 GHz Scanner  (Read 19826 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This little weekend project is a 2.4 GHz Scanner which can be used to
display interference signals in WLAN applications. It only requires
an Arduino, a common nRF24L01p-breakout board and software.

RF-activity is piped through the Arduino's serial interface and displayed
in a kind of waterfall display on any terminal application. The amplitude
in the different channels are displayed with the help of a simple
ASCII-greyscale mapping. Here's an example of what can be expected.



The picture shows the output of the scanner, displaying the interference
of a switched on BlueTooth-Device with a Channel-10 WLAN device, on the
Arduino-Terminal (colors were added just for clarity).

The scanner also shows interference from microwave ovens or wireless
surveilance cameras.

As the nFR24L01 only has a single bit for indicating RF-reception and the
output was desired to be readable on a simple terminal device, a few tricks
were necessary to create a decent display of the 2.4 GHz band. However, even
the  shifting of the carrier of a WLAN spot can clearly be seen in the waterfall
display.

As commom nFR24L01 libraries do not interface well with SPI-lib of the current
Arduino IDE (22), I wrote the necessary interface from scratch. Some timing is
pushing the limit of the device(s), as I wanted to scan as fast as possible, but
they are working reliably with my setup.

Basically, the setup is very simple. The nRF24L01p is a SPI-device, and you
have to run cables from the Arduino-specific pins to the nRF24L01p-breakout
board. Specifically, the connections are


SS       : Arduino Pin 10   -> Breakout Board CSN
MOSI     : Arduino Pin 11   -> Breakout Board MOSI
MISO     : Arduino Pin 12   -> Breakout Board MISO
SCK      : Arduino Pin 13    -> Breakout Board SCK


Furthermore, do not forget to connect the CE line which is required to drive
the nRF24L01 to RX and also triggers the RF power reading. It is defined in
the program as Arduino Pin 9:


CE       : Arduino Pin 9      -> Breakout Board CE


Here's an image of my actual setup, using a Boarduino instead of an orginal
Arduino.



Finally, here's the Arduino code:
Code:
#include <SPI.h>

// Poor Man's Wireless 2.4GHz Scanner
//
// uses an nRF24L01p connected to an Arduino
//
// Cables are:
//     SS       -> 10
//     MOSI     -> 11
//     MISO     -> 12
//     SCK      -> 13
//
// and CE       ->  9
//
// created March 2011 by Rolf Henkel
//

#define CE  9

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

// greyscale mapping
int  line;
char grey[] = " .:-=+*aRW";

// 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;
  
  PORTB &=~_BV(2);
  c = SPI.transfer(r&0x1F);
  c = SPI.transfer(0);  
  PORTB |= _BV(2);

  return(c);
}

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

// disable RX
void disable(void)
{
    PORTB &=~_BV(1);
}

// setup RX-Mode of nRF24L01p
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);
}

// scanning all channels in the 2.4GHz band
void scanChannels(void)
{
  disable();
  for( int j=0 ; j<200  ; 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(57600);
  
  Serial.println("Starting Poor Man's Wireless 2.4GHz Scanner ...");
  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.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setBitOrder(MSBFIRST);
  
  // 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
  scanChannels();
  
  // output the result
  outputChannels();
  
  // output WLAN-channel reference every 12th line
  if( line++>12 )
  {
    printChannels();
    line = 0;
  }
}


... have fun.
« Last Edit: March 09, 2011, 12:25:22 pm by cpixip » Logged

sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

VERY helpful tool, thanks!  smiley
works out of the box.
i used it for debugging my initial nRF24L01+ setup (wasn't sure if the other transceiver was sending) and found it very helpful for quickly judging antenna quality (having one arduino sending garbage and the other running your program)
Logged

Red Sea, Saudi Arabia
Offline Offline
God Member
*****
Karma: 12
Posts: 579
..On The Red Sea
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
NICE! Got it working in 5 mins with some jumpers..

Having my Nokia N78 scan for and run on my nearby WiFi network gave me a lot of activity.

With the phone 5 cm from the transceiver antenna I saw lots of wideband low-intensity dots.

Question: Can / should your communications routines be used instead of those in the Playground examples??  How might they be used for point-to-point data transmission?

Thanks!

Regards, Terry King

terry@yourduino.com
Logged

Regards, Terry King  ..On the Red Sea at KAUST.edu.sa
terry@yourduino.com  LEARN! DO! (Arduino Boards, Sensors, Parts @ http://yourduino.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Terry, Forest - thanks for your nice feedback.

Acutally, the MIRF-lib available in the playground has been updated in the meantime to use the SPI-lib build into the Arduino 22 IDE. I think the playground library would benefit from some nice and simple examples, making the great features of the nRF24L01+ more accessible to  everybody.

Personally, I did not have yet the time to expand my own lib to a state were it would be useful. And due to time restraints, it will take me some additional months until I will be able to finish this one. I will post it here in the forum as soon as I have something workable.

However, there is another nRF24L01+/Arduino library available on the net which features a slightly different design and interface and which might be interesting for people using the Arduino/nRF24L01+ combination. It can be found here: http://maniacbug.github.com/RF24/index.html.

Furthermore, there is also a nice nRF24L01-library design for the mbed-platform at http://mbed.org/cookbook/nRF24L01-wireless-transceiver, also with a slightly different approach, which could easily be adapted for the Arduino.

Currently, only the mbed-lib does feature direct access to important parameters of the Enhanced-Shockburst mode, which is in my point of view the most convenient and important feature of these chips. Another nice property of a full lib would probably be a simple, automatic packaging mechanism, making oneself somewhat more independent from the maximum 32 byte packet size of the  nRF24L01+ ... - I am thinking along these lines, but did not yet come up with a good implementation idea here.

Terry: you posted in another thread that you are researching the possibilities of an enhanced nRF24L01+ with power amplifiers and/or low-noise receivers. I'd love to hear about your results!

Best, cpixip

Logged

Red Sea, Saudi Arabia
Offline Offline
God Member
*****
Karma: 12
Posts: 579
..On The Red Sea
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@cpixip thanks a lot for your work on this stuff; it's given me a leg up.

I have 2 of the "1000 meters distance NRF24L01 + PA + LNA wireless module" (As translated from the Chinese...) coming; we know Mr. Tang who runs this TaoBao (Chinese Ebay) shop.

Take a look here:  http://item.taobao.com/item.htm?id=9107958905&frm=  (Chinese) , but use Google Translate or run Google Chrome.

I like the idea that we have a transceiver that has 3 levels of price and performance with exact same software!

I THINK the prices will be something like $5 - plain nRF24L01 with PCB antenna  ,  $12 with Power Amplifier +15 dBm - sma RF connector, $18 with Power Amp and Low-Noise receiver preamp,  Antenna for last 2 about $1.50   

But I want to get good working Arduino examples before I start selling these to the newbies and having people be unhappy...

I should have them in about a week....

Logged

Regards, Terry King  ..On the Red Sea at KAUST.edu.sa
terry@yourduino.com  LEARN! DO! (Arduino Boards, Sensors, Parts @ http://yourduino.com

Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

However, there is another nRF24L01+/Arduino library available on the net which features a slightly different design and interface and which might be interesting for people using the Arduino/nRF24L01+ combination. It can be found here: http://maniacbug.github.com/RF24/index.html.

By the way, I am actively developing this library.  Feel free to IM if there's anything you need on it.  The goal is to completely cover the chip's entire usage.  I'm getting there.
Logged


Red Sea, Saudi Arabia
Offline Offline
God Member
*****
Karma: 12
Posts: 579
..On The Red Sea
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi James/Maniac!

Glad to hear that!  I'm reading thru your ping-pong examples now and will try to get that running soon.

I'd like to talk about what a good set of examples for newbies would be, and how that all might progress. 

I'm working on documenting a lot of Arduino stuff to make it approachable. Example: http://arduino-info.wikispaces.com/Nrf24L01-Poor+Man%27s+2.4+GHz+Scanner

I'd like to get a couple of examples based on your work working and documented. 

One might be a "control of the remote device's LEDs and Motors", with feedback??

One might be "Transmit remote sensor data to base" ??

What do you think would be good examples, and how might a user-friendly set of functionality be exposed for new users??

Thanks for your good work on this; your code is very well done...

Regards, Terry
Logged

Regards, Terry King  ..On the Red Sea at KAUST.edu.sa
terry@yourduino.com  LEARN! DO! (Arduino Boards, Sensors, Parts @ http://yourduino.com

Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks!

These are all great ideas.  It is helpful to hear some of these ideas for what would help new people.  My own usage of the library has grown rather monstrous and complex, so I'm kind of losing perspective.  

The problem is, as the usefulness increases so does the complexity, and then inversely goes the approachability.

My full-blown usage is a multi-hop mesh network with sensor nodes reporting readings back to a base unit that logs to a MySQL database.  But, uh, good luck to new users figuring that all out.

I have this notion of writing a higher-level library that sits atop the RF24 library, and manages the mesh network details.  That might make the complex stuff more approachable.

I'll try working up some examples based on your suggestions, though.  If you think of more details on how a user might actually do something with those parts, do feel free to expound.
« Last Edit: May 24, 2011, 12:20:46 am by maniacbug » Logged


Red Sea, Saudi Arabia
Offline Offline
God Member
*****
Karma: 12
Posts: 579
..On The Red Sea
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, Wow, cool applications.. That should be really extensible with long-range radios.. like over a campus.

There are two levels of users to support. I am doing a workshop with guys here at the King Abdullah University of Science and Technology who are Supercomputer admins, Algorithm researchers, Unix/SQL weenies, BioDatabase guys etc.  Then I have 9th graders.  I think there can be a higher level API with the lower levels exposed so a user can learn and do more complex things. 

So let's think about it a bit and try to figure out the appropriate levels...

Thanks for your work and your willingness!
Logged

Regards, Terry King  ..On the Red Sea at KAUST.edu.sa
terry@yourduino.com  LEARN! DO! (Arduino Boards, Sensors, Parts @ http://yourduino.com

United States of America, Florida
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
Watching electrolytic caps exploding is one of my favorite past-times.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This works great.  (wondering the first thing I was going to build with these things.)

I made sure that all WiFi, Bluetooth, and (anything  around 2.4Ghz) was off. 
(I only got a few minor blips from some random device.)
Then I turned on the microwave.
On all chanels, I got very heavy interfierence.

So you can also put this as a microwave detector.

Awesome project.[/shadow]
Logged

Memento Mori
------------
Sola Christus

The Christian Hacker:
https://www.facebook.com/groups/141258275980190/

Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey, sorry for hijacking the thread, above.  I posted a new thread http://arduino.cc/forum/index.php/topic,62222.0.html for RF24, so as to keep this one on-topic.
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for all the nice feedback!

Just a short note I forgot to mention in the intial post: the above listed scanner program switches off the Enhanced Shockburst feature of the nRF24L01+. As all libs available currently for nRF24L01+ do not initialize this feature of the chip correctly on start-up, you need to power down your circuit once before uploading and using another program/lib in order to reset the nRF24L01+. Otherwise programs which use the Enhanced Shockburst feature (basically all libs available for the nRF24L01+ do this) won't run.

The reason is that a simple reset (as happening for example when uploading new programs with the Arduino IDE) won't reset the nRF24L01+ to it's factory setting. However, simply unconnecting the power-supply and/or USB for a few seconds will do the trick.

Have fun! - cpixip
Logged

Lancaster, England
Offline Offline
Jr. Member
**
Karma: 0
Posts: 85
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

new people
Hey, That's me! smiley

I just got a pair of transceivers in the mail this morning from an eBay seller in China ($12.80 for 2 with free shipping).  Don't need them yet, but figured that at that price they're be worth getting to play around with at some point, so will be keeping an eye on this thread (and Maniac's newly created one). smiley

Thanks for all the hard work guys.
Logged

John

Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As all libs available currently for nRF24L01+ do not initialize this feature of the chip correctly on start-up, you need to power down your circuit once before uploading and using another program/lib in order to reset the nRF24L01+.

Yes, indeed.  I suppose this could be stated more broadly.  The available libs do not reset the chip registers to the factory state on startup.  If you want the factory state, you have to power cycle.  Not sure this is "incorrect".
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi maniacbug -

...  I suppose this could be stated more broadly.  The available libs do not reset the chip registers to the factory state on startup.  If you want the factory state, you have to power cycle.  Not sure this is "incorrect".

... - as we are doing this for a hobby, it's probably ok. Just need to remember that only a power cycle gets your device in a properly defined state.

On the other hand, from a design point of view, any lib (for any device, not just the nRF24L01+) which only works if the device is in a certain state on start-up will fail under some circumstances.

Clearly something you want to avoid if that device is mission-critical ... smiley-wink

A lib which does not a full initialization will probably also fail in an application featuring a watchdog function - as this won't "reset" external chips properly when a restart is occuring. So it maybe a good idea to mention this fact for other users of a lib.

My code of the 2.4 GHz scanner above does of course violate this as well - it does assume that the nRF24L01+ is in the factory reset state when it starts. For a hobby project, I think this is ok. You just need to be aware that a simple reset won't get the nRF24L01+ back into a working state for other libraries/programs... smiley

Best, cpixip.
Logged

Pages: [1] 2   Go Up
Jump to: