Download presentation
Presentation is loading. Please wait.
Published byDora Hawkins Modified over 7 years ago
1
living with the lab nRF24L01+ Radio Frequency Modules and Infrared Distance Measuring Sensor Nordic nRF24L01+ +
2
Digital Wireless Communication using radio frequency (RF) transceivers
living with the lab Digital Wireless Communication using radio frequency (RF) transceivers Information is sent between each module using radio waves. The communication uses digital addresses similar to wifi or cellphones. Multiple pairs of wireless modules can be used in the same room with limited interference.
3
The “nirf” Module Nordic nRF24L01+ ultra low power RF transceiver
living with the lab The “nirf” Module Nordic nRF24L01+ ultra low power RF transceiver The nirf module uses frequencies around 2.4GHz to transmit and receive data.
4
Frequency-Shift Keying (FSK) Digital Modulation
living with the lab Examples include: amateur radio caller ID emergency broadcasts Frequency-Shift Keying (FSK) Digital Modulation Data can be transmitted serially one bit after another by changing (modulating) the frequency. The receiver decodes this signal information and converts it back to a bit stream. BFSK (Binary FSK) Sends information over radio using two frequencies, each to represent either “1” or “0”. Data in bit stream form to be sent (10101, in this case) 1 Base operating/carrier frequency of the transmitter (and receiver) No data/information is being transmitted by green trace FSK-modulated signal has distinct frequencies associated with HIGH and LOW data Data/information is being transmitted. 1
5
Serial Data Interfaces
living with the lab Main Types of Serial Data Interfaces Inter-integrated circuit I2C Serial peripheral interface SPI Universal asynchronous receiver transmitter UART Flexible, expandable Robust, paired Fast, easy nirf module uses SPI
6
Serial Data Interfaces
living with the lab “I squared C” Limited data rates Flexible, but can be challenging to implement Very expandable (up to 127 nodes/slaves) Can have multiple masters Uses 2 transmission lines total Clock (SCL; serial clock) Data (SDA; serial data) Addresses slave device and waits for return data Slave 3 SDA SCL Slave 4 SDA SCL Expandable
7
Serial Data Interfaces
living with the lab Limited data rates Can be challenging to implement, but robust when made operational No expansion / paired device combination Uses 2 transmission lines and possibly more for “handshaking” UART is a similar to a low power version of RS-232
8
Serial Data Interfaces
living with the lab Fast data rates Simple to implement Limited expansion capability based on output pin availability Requires 1 transmission line for output Master Out / Slave In (MOSI) 1 transmission line for input Master In / Slave Out (MISO) 1 line for clock (SCK; serial clock) +1 transmission line per slave Slave Select (SS) aka Chip Select (CS) Slave 3 MISO MOSI SCK CS CS3 When using a minimal number of devices, SPI is typically a good choice!
9
“nirf” Module Connection for Arduino
living with the lab “nirf” Module Connection for Arduino The “nirf” module uses a protocol called SPI to communicate with the Arduino. The following pins are used to connect the module to the Arduino. Arduino Pin “nirf” Pin 7 CSN 8 CE 11 MOSI 6 12 MISO 7 13 SCK GND GND 1 3v3* VCC *The “nirf” module uses 3.3 volts. DO NOT CONNECT VCC TO THE 5 VOLT PIN ON THE ARDUINO!
10
nRF24L01 module pinout living with the lab
nRF24L01 module pinout The nRF24L01+ Modules here all use the same pinout as shown in the following diagram, which is TOP VIEW (Left Image) and BOTTOM VIEW (Right Image)
11
nirf module code snippets
living with the lab Transmitter & Receiver codes Include files should include these 4 *.h files: Inequality signs indicate that this include file is installed in the Arduino library Quotes indicate that this include file is found in the sketch folder, not in the library Files should show as tabs in Arduino IDE Also include *.cpp files in the folder
12
nirf module code snippets
living with the lab Transmitter & Receiver codes void setup() should include configuration parameters: Serial.begin() baud rate can be changed, but requires consistency for Tx & Rx codes Mirf.setRADDR is radio address / name of the Arduino the code resides on Mirf.payload is the size of the data being sent Mirf.channel allows default to be changed to help avoid interference with wifi routers (optional) All of this code is required except for Mirf.channel…
13
nirf module code snippets
living with the lab Transmitter code void loop() should include a transmit to address and a send action: Identify the send-to address Send the data in byte-sized chunks (though actual transmission is bit-by-bit Wait for all data to be sent This code is required
14
nirf module code snippets
living with the lab Receiver code void loop() should include a “wait for incoming data” action: Look for data, wait if there is none incoming Make sure data variable is properly sized for incoming data This code is required
15
nirf module code snippets
living with the lab Declare variables to have an explicit size Transitioning/porting code from Arduino Uno to Arduino Mega or some other μcontroller? Eliminate potential variations in the default storage space of a variable type and know exactly how many bytes (bits) you need to send…. analogRead is a 10-bit value, so we round up to a 16 bit variable
16
nirf module code snippets
living with the lab There are many ways to send multivariable data…STRUCT is one method Tx & Rx codes Create the struct type Identify variables inside the struct Name the struct Apply data values to the struct variables Tx code Receive struct information Refer to struct information as <structname>.<variablename> Rx code
17
Distance Sensing using infrared (IR) distance measuring sensor
living with the lab Distance Sensing using infrared (IR) distance measuring sensor Infrared light emitting diode (IR LED) and position-sensitive detector. Distance measuring device that can be used as a proximity sensor. Triangulation method and signal processing circuitry help limit influence by variations in object reflectivity, environmental temperatures and operating durations. IR light reflection to sensor hotwheels.wikia.com
18
Distance Sensing using infrared (IR) distance measuring sensor
living with the lab Distance Sensing using infrared (IR) distance measuring sensor GND 5V Note peak voltage occurs at ~ 5cm analog signal Optimistic distances range*: 10cm – 80cm 5V supply voltage (7V max) analog output voltage (0V – ~supply voltage) *Range will vary based on application. 2in-12in is a reasonable distance for detection of most objects.
19
LWTL Arduino Code Links…
living with the lab LWTL Arduino Code Links… BASIC CODE WITH INCLUDE FILES: Transmit one sensor reading… ENGR122 RF transceiver/IR distance sensor demo Arduino code can be found at the following link ADVANCED CODE WITH INCLUDE FILES: Transmit multivariable data… Multisensor/Multivariable transmission Arduino code for RF transceiver modules
20
Sending Sketch Receiving Sketch BASIC CODE living with the lab
/* ENGR122_nRF_demo_receiver.ino * Sketch 2 of 2: receiver, aka HomeB(ase), the receiving sketch for use with the nRF24L01+ */ #include <SPI.h> #include "Mirf.h“ #include "nRF24L01.h" #include "MirfHardwareSpiDriver.h" uint16_t sensorReading; uint16_t coarseReading; const int SPKR = 4; int freq; int squelch; void setup(){ Serial.begin(9600); pinMode(SPKR, OUTPUT); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"HomeB"); Mirf.payload = sizeof(sensorReading); Mirf.channel = 90; Mirf.config(); } void loop(){ while(!Mirf.dataReady()){} Mirf.getData((byte *) &sensorReading); freq = sensorReading*5; squelch = analogRead(1); Serial.print("squelch: "); Serial.print(squelch); Serial.print(" IR reading: "); Serial.println(sensorReading); if(sensorReading > squelch) {tone(SPKR,freq);} else {noTone(SPKR);} Sending Sketch /* ENGR122_nRF_demo_transmitter.ino Sketch 1 of 2: transmitter, aka Rover, the sending sketch for use with the nRF24L01+ */ #include <SPI.h> #include "Mirf.h“ #include "nRF24L01.h“ #include "MirfHardwareSpiDriver.h" uint16_t sensorReading; int8_t reps = 10; void setup(){ Serial.begin(9600); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"Rover"); Mirf.payload = sizeof(sensorReading); Mirf.channel = 90; Mirf.config(); } void loop(){ sensorReading = 0; for(int i=0;i<reps;i++){ sensorReading += analogRead(0); sensorReading = sensorReading/reps; Mirf.setTADDR((byte *)"HomeB"); Mirf.send((byte *) &sensorReading); while(Mirf.isSending()){} delay(10);
21
Multivariable data transmission (ADVANCED CODE)
living with the lab Sending Sketch Receiving Sketch /* Mario_transmitter.ino * Sketch 1 of 2: transmitter, aka Mario, the sending sketch for use with the nRF24L01+ * * USE THIS CODE FOR TRANSMITTING MULTIPLE VARIABLES OVER RF * "Mario"/transmitter/sending sketch: * The code uses a "Mario" arduino in a standalone configuration that allows for remote * sensing and transmission of collected multivariable data. The data is read at one or * more analog inputs (or includes other variables to be sent) and is transmitted via * the nRF24L01+ communication pair to a "Luigi" arduino that reads the incoming * RF-transmitted data. * Additional files required (can be stored locally in the .ino sketch folders): * - Mirf.cpp, Mirf.h, MirfHardwareSpiDriver.cpp, MirfHardwareSpiDriver.h, * MirfSpiDriver.cpp, MirfSpiDriver.h, nRF24L01.h * last modified 4/12/16 by D. Moller */ #include <SPI.h> // <*.h> refers to an installed library #include "Mirf.h" // "*.h" refers to a local include file #include "nRF24L01.h" // (i.e., same folder) #include "MirfHardwareSpiDriver.h" int i; // indexing value i int reps = 10; // repetitions for analogRead give a more stable reading uint16_t sensordataA0; // can explictly acquire data in uint16_t sensordataA1; // these variables and place in // the struct, or omit these variables // and do an analogRead in struct itself // (similar to how millis() is placed) // Create a struct named 'data' to allow sending. // Struct must be similar on the receiving code. // Be sure to include all your variables to be transmitted // If you don't want the timer info, remove it and replace // with another measurement...use other more basic code // if you only want to send one sensor measurement. struct MYSTRUCT{ uint32_t timer; uint16_t sensorA0; uint16_t sensorA1; // could add more variables to your struct here // and here } data; void setup(){ //set the speed of data transfer on both sketches... // frequecies below are for sending a single analogRead value and time stamp // to the serial output without repetitious data sampling // Mbs = ~60Hz // Mbs = ~130Hz // Mbs = ~270Hz // Mbs = ~400Hz // Mbs = ~750Hz Serial.begin(9600); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"Mario"); //Mario is the address of this (sensor) arduino // first 5 letters must be unique // CHANGE THE NAME TO AVOID CROSSTALK! Mirf.payload = sizeof(data); // Important! You need to know the size // or amount of information to be // sent (must match receiving sketch) //Mirf.channel = 90; // uncomment this line if there is interference Mirf.config(); } void loop(){ // Smooth the collected A0 data by averaging a number of readings in a for loop for(i=0;i<reps;i++){ sensordataA0 += analogRead(0); sensordataA0 = sensordataA0/i; // Smooth the collected A1 data by averaging a number of readings in a for loop sensordataA1 += analogRead(1); sensordataA1 = sensordataA1/i; /* Populate the STRUCT with data before sending * Place time stamp and sensor measurement(s) in struct - ORDER MATTERS! * Reference to the struct variables take the form of <structname.var>, * in this case: data.timer or data.sensorA0 or (data.sensorA1, etc.) MYSTRUCT data = {micros(),sensordataA0,sensordataA1}; // ORDER MATTERS! /* code could also be written directly as... * MYSTRUCT data = (micros(),analogRead(0)); * with the sensordataA0 = analogRead(0); removed //Luigi is the address of the arduino we are sending data to (not this arduino). Mirf.setTADDR((byte *)"Luigi"); Mirf.send((byte *) &data); // sends the data to Luigi one byte at a time while(Mirf.isSending()){} // waits until nirf module is done sending delay(10); //optional delay for send timing /* Luigi_receiver.ino * Sketch 2 of 2: receiver, aka Luigi, the receiving sketch for use with the nRF24L01+ * * USE THIS CODE FOR TRANSMITTING MULTIPLE VARIABLES OVER RF * "Luigi"/receiver sketch: * The code for this "Luigi" arduino receives data from a "Mario" arduino that allows * for remote sensing and transmission of collected multivariable data. The data is * read at one or more analog inputs (or includes other variables to be sent) on the * "Mario" arduino and is transmitted via the nRF24L01+ communication pair to this * "Luigi" arduino that reads the incoming RF-transmitted data. * Additional files required (can be stored locally in the .ino sketch folders): * - Mirf.cpp, Mirf.h, MirfHardwareSpiDriver.cpp, MirfHardwareSpiDriver.h, * MirfSpiDriver.cpp, MirfSpiDriver.h, nRF24L01.h * last modified 4/5/16 by D. Moller */ #include <SPI.h> // <*.h> refers to an installed library #include "Mirf.h" // "*.h" refers to a local include file #include "nRF24L01.h" // (i.e., same folder) #include "MirfHardwareSpiDriver.h" // Create a struct named 'data' to allow sending. // Struct must be in the same order and sizes as on the receiving code. // Be sure to include all your variables to be transmitted // If you don't want the timer info, remove it and replace // with another measurement...use other more basic code // if you only want to send one sensor measurement. struct MYSTRUCT{ uint32_t timer; uint16_t sensorA0; uint16_t sensorA1; // could add more variables to your struct here // and here } data; void setup(){ // set the speed of data transfer on both sketches... // frequecies below are for sending a single analogRead value and time stamp // to the serial output without repetitious data sampling // Mbs = ~60Hz // Mbs = ~130Hz // Mbs = ~270Hz // Mbs = ~400Hz // Mbs = ~750Hz Serial.begin(9600); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"Luigi"); //Luigi is the address of this (receiver) arduino // first 5 letters must be unique // CHANGE THE NAME TO AVOID CROSSTALK! Mirf.payload = sizeof(data); // Important! You need to know the size // or amount of information to be // sent (must match receiving sketch) //Mirf.channel = 90; // uncomment this line if there is interference Mirf.config(); } void loop(){ while(!Mirf.dataReady()){} // if data is not ready, wait Mirf.getData((byte *) &data); // get the transmitted data one byte // at a time for as many bytes that // the struct 'data' requires Serial.print(data.timer); // enable view of received values in Serial.print(" "); // serial monitor Serial.print(data.sensorA0); // note: the struct variables must include // the struct name and its variable as // shown here <structname.var> Serial.print(" "); Serial.println(data.sensorA1);
22
Additional resources & references
living with the lab Additional resources & references nRF24L01+ An Arduino port of the tinkerer.eu library. It works with the Sparkfun nRF24L01+ modules. File to be extracted in the Arduino libraries folder (if not including in sketch folder): A good resource for bench testing nRF24L01+ modules: distance measuring sensor
23
Additional Arduino Code Appendices in subsequent slides…
living with the lab Additional Arduino Code Appendices in subsequent slides…
24
Another Receiving Sketch
living with the lab Another Receiving Sketch Another Sending Sketch #include <SPI.h> #include <Mirf.h> #include <nRF24L01.h> #include <MirfHardwareSpiDriver.h> int sensorReading; int ledValue; const int led = 6; void setup(){ Serial.begin(9600); pinMode(led, OUTPUT); Mirf.spi = &MirfHardwareSpi; Mirf.init(); Mirf.setRADDR((byte *)"Luigi"); Mirf.payload = sizeof(sensorReading); Mirf.config(); } void loop(){ while(!Mirf.dataReady()){ Mirf.getData((byte *) &sensorReading); Serial.println(sensorReading); delay(10); #include <SPI.h> #include <Mirf.h> #include <nRF24L01.h> #include <MirfHardwareSpiDriver.h> int sensorReading; void setup(){ Serial.begin(9600); Mirf.spi = &MirfHardwareSpi; Mirf.init(); //Mario is the address of this Arduino Mirf.setRADDR((byte *)"Mario"); Mirf.payload = sizeof(sensorReading); Mirf.config(); } void loop(){ sensorReading = analogRead(A0); //Luigi is the address of the arduino we // are sending information to. Mirf.setTADDR((byte *)"Luigi"); //Send the integer to Luigi Mirf.send((byte *) &sensorReading); //wait until nirf module is done sending while(Mirf.isSending()){} //wait one second before sending another packet. // You can make this go as fast as you want :) delay(1000);
25
Yet another sending sketch Key Features:
living with the lab Yet another sending sketch Key Features: Send data as individual characters, 1 BYTE at a time Adjust transmission rate (1 MHz) Mirf.configRegister(RF_SETUP,0x06); Select channel to avoid interference Mirf.channel = 90; #include <SPI.h> #include <Mirf.h> // converts a float into a char // and sends it via nRF24L01 { void transmit( float v) byte c; char buf[10]; dtostrf(v,9,3,buf); for( int i=0 ; i<8 ; i++ ) c = buf[i]; while( Mirf.isSending() ) ; Mirf.send(&c); } void transmit(const char *string) // sends a string via the nRF24L01 for( int i=0 ; string[i]!=0x00 ; i++ ) c = string[i]; // send a CR/LF sequence via the nRF24L01 void transmitlf(void) c = '\r'; c = '\n'; void setup() Mirf.init(); // init the transceiver // we transmit only a single byte each time Mirf.payload = 1; // selecting a channel which is not too noisy Mirf.channel = 90; Mirf.config(); Mirf.configRegister(RF_SETUP,0x06); // Set 1MHz data rate // Set address - this one must match the // address the receiver is using! Mirf.setTADDR((byte *)"TX_01"); void loop() float v01,v02; // read in some values v01 = analogRead(0); v02 = analogRead(1); // transmit a fixed token transmit(" : "); // transmit the first value transmit(v01); // transmit a separator transmit(v02); // transmit a second token // transmit a CR/LF for the PC // software to sync to transmitlf(); // ... just take your time delay(100); Yet another receiving sketch #include <Mirf.h> #include <SPI.h> void setup() { Serial.begin(9600); Mirf.init(); // name the receiving channel - must match tranmitter setting! Mirf.setRADDR((byte *)"TX_01"); // just a single byte is transmitted Mirf.payload = 1; // or channels used by wireless surveillance cameras // we use channel 90 as it is outside of WLAN bands Mirf.channel = 90; // now config the device.... Mirf.config(); // Set 1MHz data rate - this increases the range slightly Mirf.configRegister(RF_SETUP,0x06); } void loop() byte c; // is there any data pending? if( Mirf.dataReady() ) // well, get it Mirf.getData(&c); // ... and write it out to the PC Serial.print(c); you can select the text and paste into the Arduino IDE to view the code
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.