Showing posts with label wireless. Show all posts
Showing posts with label wireless. Show all posts

Wednesday, September 26, 2018

Easy Way to Create a Wireless Sensor Network

In this video we look at an easy way with not very much code to setup a wireless network using the nRF24L01 Transceiver and Arduino.



//***************************Master or Receiver code*****************
/*This code was used for a video tutorial on the ForceTronics YouTube Channel
 * This code is free and open for anybody 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 uint8_t pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const uint8_t pinCSN = 10; //This pin is used for SPI comm chip select
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t rAddress = 0xB00B1E50C3LL;  //Create pipe address for the network and notice I spelled boobies because I am mature, the "LL" is for LongLong type
const uint8_t rFChan = 89; //Set channel frequency default (chan 84 is 2.484GHz to 2.489GHz)

//Create a structure to hold fake sensor data and channel data
struct PayLoad {
  uint8_t chan;
  uint8_t sensor;
};

PayLoad payload; //create struct object

void setup() {
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.setChannel(rFChan); //set communication frequency channel
  wirelessSPI.openReadingPipe(1,rAddress);  //This is receiver or master so we need to be ready to read data from transmitters
  wirelessSPI.startListening();    // Start listening for messages
  Serial.begin(115200);  //serial port to display received data
  Serial.println("Network master is online...");
}

void loop() {
  if(wirelessSPI.available()){ //Check if recieved data
     wirelessSPI.read(&payload, sizeof(payload)); //read packet of data and store it in struct object
     Serial.print("Received data packet from node: ");
     Serial.println(payload.chan); //print node number or channel
     Serial.print("Node sensor value is: ");
     Serial.println(payload.sensor); //print node's sensor value
     Serial.println(); 
  }
}

//***************************Node or Transmitter code*****************
/*This code was used for a video tutorial on the ForceTronics YouTube Channel
 * This code is free and open for anybody 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 uint8_t pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const uint8_t pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t wAddress = 0xB00B1E50C3LL;  //Create pipe address to send data, the "LL" is for LongLong type
const uint8_t rFChan = 89; //Set channel default (chan 84 is 2.484GHz to 2.489GHz)
const uint8_t rDelay = 7; //this is based on 250us increments, 0 is 250us so 7 is 2 ms
const uint8_t rNum = 5; //number of retries that will be attempted 
const uint8_t chan1 = 2; //D2 pin for node channel check
const uint8_t chan2 = 3; //D3 pin for node channel check
const uint8_t chan3 = 4; //D4 pin for node channel check

//stuct of payload to send fake sensor data and node channel
struct PayLoad {
  uint8_t chan;
  uint8_t sensor;
};

PayLoad payload; //create struct object

void setup() {
  pinMode(chan1,INPUT_PULLUP); //set channel select digital pins to input pullup
  pinMode(chan2,INPUT_PULLUP);
  pinMode(chan3,INPUT_PULLUP);
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.setChannel(rFChan); 
  wirelessSPI.setRetries(rDelay,rNum); //if a transmit fails to reach receiver (no ack packet) then this sets retry attempts and delay between retries   
  wirelessSPI.openWritingPipe(wAddress); //open writing or transmit pipe
  wirelessSPI.stopListening(); //go into transmit mode
  randomSeed(analogRead(0)); //set random seed for fake sensor data
  setChannel();  //checks current channel setting for transceiver
}

void loop() {
  delay(3000); //send data every 3 seconds
  payload.sensor = random(0,255); //get made up sensor value
  if (!wirelessSPI.write(&payload, sizeof(payload))){  //send data and remember it will retry if it fails
    delay(random(5,20)); //as another back up, delay for a random amount of time and try again
    if (!wirelessSPI.write(&payload, sizeof(payload))){
      //set error flag if it fails again
    }
  }

}

//check for low digital pin to set node address
void setChannel() {
  if(!digitalRead(chan1)) payload.chan = 1;
  else if(!digitalRead(chan2)) payload.chan = 2;
  else if(!digitalRead(chan3)) payload.chan = 3;
  else payload.chan = 0;
}

Wednesday, November 23, 2016

Creating a Sensor Network that Connects to the Cloud Part 3

In this three part series we look at how to create a wireless sensor mesh network that stores data on the cloud using the Arduino platform. In part three we look at how to access the sensor data from the cloud with a PC or Android device.


GitHub link to access code from the series: https://github.com/ForceTronics/nRF24L01-Sensor-Network-that-Connects-to-the-Cloud/

Thursday, November 3, 2016

Creating a Sensor Network that Connects to the Cloud Part 2

In this three part series we look at how to create a wireless sensor mesh network that stores data on the cloud using the Arduino platform. In part two we look at how to add time stamps to our sensor data and track the battery state of our nodes.



GitHub: https://github.com/ForceTronics/nRF24L01-Sensor-Network-that-Connects-to-the-Cloud/tree/master

Monday, June 20, 2016

Building a Wireless Sensor Network with the nRF24L01 Part 6


In part 6 we look at the final hardware design, we switch to the TMRh20 library for the nRF24L01, and we look at a library wrapper that makes getting started with your own wireless sensor network real easy. Go to ForceTronics.com to purchase a wireless flex node and go to Github to access the code and PCB design files.

Tuesday, March 15, 2016

Building a Wireless Sensor Network with the nRF24L01 Part 5

In Part 5 of building a wireless sensor network with Arduino and the nRF24L01+ transceiver we take a look at our brand new PCB boards and look at the code for adding the DS18S20 and the STTS751 temperature sensors to the design. You can access the PCB Eagle files and the Arduino code from GitHub: https://github.com/ForceTronics/nRF24L01_Wireless_Sensor_Dev_Board






Wednesday, January 20, 2016

Building a Wireless Sensor Network with the nRF24L01 Part 4

In part 4 of Building a Wireless Sensor Network with the nRF24L01 we take a look at the design's PCB layout in Eagle software as well as cover some software and hardware updates to the design.


You can access the updated code and PCB files from GitHub: https://github.com/ForceTronics/nRF24L01_Wireless_Sensor_Dev_Board


Wednesday, January 6, 2016

Building a Wireless Sensor Network with the nRF24L01 Part 3

In part three we take a look at the updated hardware schematic of the router / end device design, how the router / end device settings work, and we go over the initial software of the router / end device. You can find the code from this video in GitHub at https://github.com/ForceTronics/nRF24L01_Wireless_Sensor_Dev_Board


Tuesday, December 22, 2015

Building a Wireless Sensor Network with the nRF24L01 Part 2

In part 2 we focus on powering our wireless sensor node. We talk about batteries, battery sizing, estimating battery life, and battery monitoring. If you have any feedback or questions use the comments section below.


Updated Schematic for Part 2


Tuesday, October 20, 2015

Building an Arduino Shield and Proto Board for the nRF24L01 Transceiver

The nRF24L01+ Transceiver is a great low cost way to add wireless capability to any project. But the down side of the nRF24L01+ is it can be a hassle to prototype with. In this video we look at how to build an Arduino shield and a mini proto board for the nRF24L01+. You can also purchase the shield and mini proto board covered in the video at forcetronics.com.



To Access the Eagle PCB files:
//*****************************Arduino Code for Transmitter***********************
//This sketch is from a tutorial video on the ForceTronics YouTube Channel. The tutorial discusses how to build a 
//shield and a prototyping board for the nRF24L01 Transceiver Module.
//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/

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
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
  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.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();
}

void loop()  
{
   byte t = analogRead(0);//note that we can cast the ADC value to a byte because we know the temp sensor is not going to return a value higher than 255
   if (!wirelessSPI.write(&t, 1 )){  //if the send fails let the user know over serial monitor
       Serial.println("packet delivery failed");      
   }
    delay(1000);
}

//*****************************Arduino Code for Receiver***********************
//This sketch is from a tutorial video on the ForceTronics YouTube Channel. The tutorial discusses how to build a 
//shield and a prototyping board for the nRF24L01 Transceiver Module.
//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/

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 bVal; //used to store ADC value payload from transmit module, the ADC value will be < 256 so it will fit in a byte
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
  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.openReadingPipe(1,pAddress);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.startListening();                 // Start listening for messages
}

void loop()  
{   
   //loop until all of the payload data is recieved, for this example loop should only run once
    while(wirelessSPI.available()){ 
     wirelessSPI.read( &bVal, 1 ); //read one byte of data and store it in bVal variable
     Serial.print("Temperature at transmitter is "); 
     Serial.print(calculateTempF(calculateArduinoVolt(bVal))); //convert the ADC value to a voltage value and than to a temperature value in F
     Serial.println(" F");
    }
 
  delay(200);    
}

//this function calculates temp in F from TMP36 temp sensor
float calculateTempF(float v1) { 
 float temp = 0;
 //calculate temp in C, .75 volts is 25 C. 10mV per degree
 if (v1 < .75) { temp = 25 - ((.75-v1)/.01); } //if below 25 C
 else if (v1 == .75) {temp = 25; }
 else { temp = 25 + ((v1 -.75)/.01); } //if above 25
 //convert to F
 temp =((temp*9)/5) + 32;
 return temp;
}

//This function takes an Arduino analog pin reading and converts it to a voltage value
float calculateArduinoVolt(int val) {
 float volt = (float)val * (5.0 / 1023.0); //convert ADC value to voltage
 return volt;
}



Wednesday, September 2, 2015

Contracting and Consulting Services for Open Source Hardware Design

This video provides an overview of ForceTronics LLC's contracting and consulting services. Whether you are a maker, entrepreneur, or a startup Forcetronics Contracting and Consulting Services can help turn your idea into reality leveraging the power of open source hardware.






If you are interested contact me on twitter or email:
  • Twitter: @ForceTronics
  • Email: forcetronics@gmail.com
Put “Contracting Services” or “Consulting Services” in the subject line



Friday, July 10, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 4

This is part 4 in a 5 part series where we build our own AVR / Arduino Internet of Things (IoT) development board, yay! In this part we will do the PCB layout and discuss how to get our PCB manufactured.


Download Eagle Files



Eagle Parts and Libraries
Libraries Used:
•Atmega 328P --> Library: SparkFun-DigitalIC Device: ATMEGA328P_PDIP
•LM317 --> Library: linear>*317 Device:317T
•Resonator ZTT16.0MHz --> Library: Adafruit Device: CERMOSCILL-THM (CERMOSCILL)
•Ceramic Cap --> Library: rcl > C-EU Device: C-EU050-030X075
•Electrolytic cap --> Library: rcl > CPOL-EU Device: CPOL-EUE2.5-6
•Resistor --> Library: resistor Device: R-EU_0207/10 (R-EU_) Package: 0207/10
•Reset switch --> Library: switch-omron Device: 10-XX
•LED --> Library: led Device: LED5MM (LED)
•Potentiometer --> Library: rcl > R-TRIMM Device: R-TRIMMT93YA
Note: Sparkfun and Adafruit libraries did not come with Eagle, but you can find them on their websites

Parts I made (included in files linked to my blog):
•ForceTronic.lbr --> All header and pin holes and 2.1mm DC Jack
•BLE_Micro_Module.lbr --> BLE Micro

Monday, July 6, 2015

Building Your Own AVR / Arduino Internet of Things (IoT) Development Board Part 3

This is part 3 in a 5 part series where we build our own AVR / Arduino Internet of Things (IoT) development board, yay! In this part we will finalize our design schematic and parts list so we are ready to do PCB layout in part 4.



Final Design Schematic:


Bill of Materials:
  • Atmega 328P MCU (Dip Package)
  • 16MHz resonator
  • BLE Micro from DFRobot or equivalent
  • LM317 Voltage Regulator
  • Resistors (Ohms): 10k, 2x 1k, 2x 300, 1k POTENTIOMETER or 500
  • Capacitors: 4x 100nF (Ceramic) and 1uF (electrolytic)
  • LED 5mm (any color you want)
  • 0.1” male pins
  • 2x 0.1” 2x4 female header (optional)
  • 4x 0.1” pin jumpers
  • DC Power Jack (+ pin is 2.1mm) 
  • 13uH Inductor (optional)
  • Female pin headers: 6 pin, 2x 8 pin, 10 pin
  • 28 pin DIP Socket (optional): part # 4828-3004-CP

Sunday, June 7, 2015

Intro to Bluetooth Low Energy (BLE) and the BLE Micro

In this video we will take a look at Bluetooth Low Energy or Bluetooth Smart and compare it to classic Bluetooth. From there we will look at how to get started with the BLE Micro module and look at how to communicate with it from an iOS device and another BLE Micro Module.




************************Arduino Code****************************************
/*
  This sketch is part of a video tutorial on the ForceTronics YouTube Channel for using the BLE Micro module which uses Bluetooth low energy. 
  The bluetooth module is connected to an Arduino and the Arduino is connected to an LED. 

  This code is in the public domain.
 */

// Pin 7 has a LED connected to it
int led = 7;

// the setup routine runs once when you press reset:
void setup() {
  
  Serial.begin(115200);
  // initialize the digital pin as an output and set it low initially
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

// the loop routine runs over and over again forever:
void loop() {
  delay(30);
  String t; //create an empty string to store messages from Android
  while(Serial.available()) { //keep reading bytes while they are still more in the buffer
    t += (char)Serial.read(); //read byte, convert to char, and append it to string
  }
  
  if(t.length()) { //if string is not empty do the following
    if(t == "on") { //if the string is equal to "on" then turn LED on
      digitalWrite(led, HIGH); //Set digital pin to high to turn LED on
      Serial.write("LED is on"); //Tell the Android app that the LED was turned on
    }
    else if (t == "off") { 
      digitalWrite(led, LOW);  
      Serial.write("LED is off");
    } // turn the LED off by making the voltage LOW
  }
}

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__