Showing posts with label Nordic. Show all posts
Showing posts with label Nordic. Show all posts

Monday, December 7, 2015

Building a Wireless Sensor Network with the nRF24L01 Part 1

This is part 1 in a series where we look at how to build a large wireless network using Arduino and the nRF24L01+ Transceiver Modules. At the end of this series you will have a reference design for a wireless sensor development board and the code needed to turn the wireless sensor developments boards into a network. You will be able purchase all the hardware for this project at my site: www.forcetronics.com


Initial Hardware Design

Saturday, May 9, 2015

Creating a nRF24L01 Transceiver Network

In this video we will look at how to create an nRF24L01 Transceiver module network (more than two). This is useful if you want to build a wireless sensor network or some type of wireless automation system that has multiple wireless nodes.



***************************Arduino Code for Receiver*******************************
//This sketch is from a tutorial video for networking more than two nRF24L01 tranciever modules on the ForceTronics YouTube Channel
//the code was leverage from the following code http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte daNumber = 0; //The number that the transmitters are trying to guess
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t rAddress[] = {0xB00B1E50D2LL, 0xB00B1E50C3LL};  //Create pipe addresses for the 2 nodes to recieve data, the "LL" is for LongLong type
const uint64_t wAddress[] = {0xB00B1E50B1LL, 0xB00B1E50A4LL};  //Create pipe addresses for the 2 nodes to transmit data, the "LL" is for LongLong type

void setup()   
{
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  daNumber = (byte)random(11); //Create random number that transmitters have to guess
  Serial.begin(57600);  //start serial to communication
  Serial.print("The number they are trying to guess is: "); 
  Serial.println(daNumber); //print the number that they have to guess
  Serial.println();
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.openReadingPipe(1,rAddress[0]);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.openReadingPipe(2,rAddress[1]);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.startListening();                 // Start listening for messages
}

void loop()  
{   
    byte pipeNum = 0; //variable to hold which reading pipe sent data
    byte gotByte = 0; //used to store payload from transmit module
    
    while(wirelessSPI.available(&pipeNum)){ //Check if recieved data
     wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
     Serial.print("Recieved guess from transmitter: "); 
     Serial.println(pipeNum); //print which pipe or transmitter this is from
     Serial.print("They guess number: ");
     Serial.println(gotByte); //print payload or the number the transmitter guessed
     if(gotByte != daNumber) { //if true they guessed wrong
      Serial.println("Fail!! Try again."); 
     }
     else { //if this is true they guessed right
      if(sendCorrectNumber(pipeNum)) Serial.println("Correct! You're done."); //if true we successfully responded
      else Serial.println("Write failed"); //if true we failed responding
     }
     Serial.println();
    }

  delay(200);    
}

//This function turns the reciever into a transmitter briefly to tell one of the nRF24s
//in the network that it guessed the right number. Returns true if write to module was
//successful
bool sendCorrectNumber(byte xMitter) {
    bool worked; //variable to track if write was successful
    wirelessSPI.stopListening(); //Stop listening, stop recieving data.
    wirelessSPI.openWritingPipe(wAddress[xMitter-1]); //Open writing pipe to the nRF24 that guessed the right number
    if(!wirelessSPI.write(&daNumber, 1))  worked = false; //write the correct number to the nRF24 module, and check that it was recieved
    else worked = true; //it was recieved
    wirelessSPI.startListening(); //Switch back to a reciever
    return worked;  //return whether write was successful
}

***************************Arduino Code for Transmitter 1****************************
//This sketch is from a tutorial video for networking more than two nRF24L01 tranciever modules on the ForceTronics YouTube Channel
//the code was leverage from the following code http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
bool done = false; //used to know when to stop sending packets
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t wAddress = 0xB00B1E50D2LL;              // Pipe to write or transmit on
const uint64_t rAddress = 0xB00B1E50B1LL;  //pipe to recive data on

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.openWritingPipe(wAddress);        //open writing or transmit pipe
  wirelessSPI.openReadingPipe(1,rAddress);  //open reading or recieve pipe
  wirelessSPI.stopListening(); //go into transmit mode
}


void loop()  
{
   if(!done) { //true once you guess the right number
     byte randNumber = (byte)random(11); //generate random guess between 0 and 10
   
    if (!wirelessSPI.write( &randNumber, 1 )){  //if the write fails let the user know over serial monitor
         Serial.println("Guess delivery failed");      
     }
     else { //if the write was successful 
          Serial.print("Success sending guess: ");
          Serial.println(randNumber);
       
        wirelessSPI.startListening(); //switch to recieve mode to see if the guess was right
        unsigned long startTimer = millis(); //start timer, we will wait 200ms 
        bool timeout = false; 
        while ( !wirelessSPI.available() && !timeout ) { //run while no recieve data and not timed out
          if (millis() - startTimer > 200 ) timeout = true; //timed out
        }
    
        if (timeout) Serial.println("Last guess was wrong, try again"); //no data to recieve guess must have been wrong
        else  { //we recieved something so guess must have been right
          byte daNumber; //variable to store recived value
          wirelessSPI.read( &daNumber,1); //read value
          if(daNumber == randNumber) { //make sure it equals value we just sent, if so we are done
            Serial.println("You guessed right so you are done");
            done = true; //signal to loop that we are done guessing
          }
          else Serial.println("Something went wrong, keep guessing"); //this should never be true, but just in case
        }
        wirelessSPI.stopListening(); //go back to transmit mode
      
     }
   }
    delay(1000);
}

***************************Arduino Code for Transmitter 2****************************
//This sketch is from a tutorial video for networking more than two nRF24L01 tranciever modules on the ForceTronics YouTube Channel
//the code was leverage from the following code http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
bool done = false; //used to know when to stop sending guesses
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t wAddress = 0xB00B1E50C3LL;  //pipe for writing or transmitting data
const uint64_t rAddress = 0xB00B1E50A4LL;  //pipe for reading or recieving data

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.openWritingPipe(wAddress);    // setup pipe to transmit over
  wirelessSPI.openReadingPipe(1,rAddress);  //set up pipe to recieve data
  wirelessSPI.stopListening();  //turn off recieve capability so you can transmit
}


void loop()  
{
  if(!done) { //true once you guess the right number
     byte randNumber = (byte)random(11); //generate random guess between 0 and 10
   
    if (!wirelessSPI.write( &randNumber, 1 )){  //if the write fails let the user know over serial monitor
         Serial.println("Guess delivery failed");      
     }
     else { //if the write was successful 
          Serial.print("Success sending guess: ");
          Serial.println(randNumber);
       
        wirelessSPI.startListening(); //switch to recieve mode to see if the guess was right
        unsigned long startTimer = millis(); //start timer, we will wait 200ms 
        bool timeout = false; 
        while ( !wirelessSPI.available() && !timeout ) { //run while no recieve data and not timed out
          if (millis() - startTimer > 200 ) timeout = true; //timed out
        }
    
        if (timeout) Serial.println("Last guess was wrong, try again"); //no data to recieve guess must have been wrong
        else  { //we recieved something so guess must have been right
          byte daNumber; //variable to store recived value
          wirelessSPI.read( &daNumber,1); //read value
          if(daNumber == randNumber) { //make sure it equals value we just sent, if so we are done
            Serial.println("You guessed right so you are done");
            done = true; //signal to loop that we are done guessing
          }
          else Serial.println("Something went wrong, keep guessing"); //this should never be true, but just in case
        }
        wirelessSPI.stopListening(); //go back to transmit mode
      
     }
   }
    delay(1000);
}

Monday, February 16, 2015

Getting Started with the nRF24L01 Transceiver

In this video we look at how to get up and running with the low cost nRF24L01+ transceiver module from Nordic.



nRF24L01 connected to an Arduino Pro Mini


***********Arduino code for transmit module*********************************
//This sketch is from a tutorial video for getting started with the nRF24L01 tranciever module on the ForceTronics YouTube Channel
//the code was leverage from Ping pair example at http://tmrh20.github.io/RF24/pingpair_ack_8ino-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include "printf.h" //This is used to print the details of the nRF24 board. if you don't want to use it just comment out "printf_begin()"

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
bool done = false; //used to know when to stop sending packets
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t pAddress = 0xB00B1E5000LL;              // Radio pipe addresses for the 2 nodes to communicate.

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  printf_begin();        //This is only used to print details of nRF24 module, needs Printf.h file. It is optional and can be deleted
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.setAutoAck(1);                    // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
  wirelessSPI.enableAckPayload();               // Allow optional ack payloads
  wirelessSPI.setRetries(5,15);                 // Sets up retries and timing for packets that were not ack'd, current settings: smallest time between retries, max no. of retries
  wirelessSPI.openWritingPipe(pAddress);        // pipe address that we will communicate over, must be the same for each nRF24 module
  wirelessSPI.stopListening();
  wirelessSPI.printDetails();                   // Dump the configuration of the rf unit for debugging
}


void loop()  
{

 if(!done) { //if we are not done yet
    Serial.print("Now send packet: "); 
    Serial.println(counter); //serial print the packet number that is being sent
    unsigned long time1 = micros();  //start timer to measure round trip
    //send or write the packet to the rec nRF24 module. Arguments are the payload / variable address and size
   if (!wirelessSPI.write( &counter, 1 )){  //if the send fails let the user know over serial monitor
       Serial.println("packet delivery failed");      
   }
   else { //if the send was successful 
      unsigned long time2 = micros(); //get time new time
      time2 = time2 - time1; //calculate round trip time to send and get ack packet from rec module
      Serial.print("Time from message sent to recieve Ack packet: ");
      Serial.print(time2); //print the time to the serial monitor
      Serial.println(" microseconds");
       counter++; //up the packet count
   }
   
   //if the reciever sends payload in ack packet this while loop will get the payload data
   while(wirelessSPI.available() ){ 
       char gotChars[5]; //create array to hold payload
       wirelessSPI.read( gotChars, 5); //read payload from ack packet
       Serial.print(gotChars[0]); //print each char from payload
       Serial.print(gotChars[1]);
       Serial.print(gotChars[2]);
       Serial.println(gotChars[3]);
       done = true; //the ack payload signals we are done
     }
  }

    delay(1000);
}

***********Arduino code for receiver module*********************************
//This sketch is from a tutorial video for getting started with the nRF24L01 tranciever module on the ForceTronics YouTube Channel
//the code was leverage from Ping pair example at http://tmrh20.github.io/RF24/pingpair_ack_8ino-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include "printf.h" //This is used to print the details of the nRF24 board. if you don't want to use it just comment out "printf_begin()"

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte gotByte = 0; //used to store payload from transmit module
bool done = false;
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t pAddress = 0xB00B1E5000LL;  //Create a pipe addresses for the 2 nodes to communicate over, the "LL" is for LongLong type

void setup()   
{
  Serial.begin(57600);  //start serial to communicate process
  printf_begin();  //This is only used to print details of nRF24 module, needs Printf.h file. It is optional and can be deleted
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.setAutoAck(1);                    // Ensure autoACK is enabled, this means rec send acknowledge packet to tell xmit that it got the packet with no problems
  wirelessSPI.enableAckPayload();               // Allow optional payload or message on ack packet
  wirelessSPI.setRetries(5,15);                 // Defines packet retry behavior: first arg is delay between retries at 250us x 5 and max no. of retries
  wirelessSPI.openReadingPipe(1,pAddress);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.startListening();                 // Start listening for messages
  wirelessSPI.printDetails();                   //print details of nRF24 module to serial, must have printf for it to print to serial
}

void loop()  
{   
    if(gotByte >= 9 & !done) { //once we get 10 packets send ack packet with payload telling the transmit module we are done
       char cArray[5] = "done"; //create char array to store "done," note that the fifth char is for the null character
       wirelessSPI.writeAckPayload(1, cArray, sizeof(cArray));  //send ack payload. First argument is pipe number, then pointer to variable, then variable size
     }
   //loop until all of the payload data is recieved, for this example loop should only run once
    while(wirelessSPI.available() & !done){ 
     wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
     Serial.print("Recieved packet number: "); //payload counts packet number
     Serial.println(gotByte); //print payload / packet number
    }
    
    if(gotByte > 9) done = true; //we are finished so set "done" to true
   
  delay(200);    
}

***********Arduino code for Printf.h file*********************************
/*
 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.
 */

/**
 * @file printf.h
 *
 * Setup necessary to direct stdout to the Arduino Serial library, which
 * enables 'printf'
 */

#ifndef __PRINTF_H__
#define __PRINTF_H__

#ifdef ARDUINO

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;


void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}

#else
#error This example is only for use on Arduino.
#endif // ARDUINO

#endif // __PRINTF_H__