Teensy LC and Teensy 3.2 with nRF24L01

Status
Not open for further replies.

toxic

Member
Hi,
I am working with a project: transmitter Teensy LC with nRF24L01 and reciever Teensy 3.2 with nRF24L01.
Wich library best?

With regards

toxic
 
I am presently using two Tensy 3.2 boards with nRF24L01+PA+LNA devices to pass 5120 bytes of sonar data in 32 byte packets from a phased array on an RC boat to a shore station. The general consensus on the Arduino forum is the TMRh20 library.

https://github.com/TMRh20/RF24

You might also want to consider this adapter to power the nRF24 devices. It takes a 5v, or slightly higher, input and provides 3v3 to the nRF24l.

http://www.ebay.com/itm/Socket-Adapter-plate-Board-for-8Pin-NRF24L01-Wireless-Transceive-module-51-/200960749614?hash=item2eca31b02e:g:zWwAAOxykYtSKY0N
 
Hi,
I have ASM1117-33 (LC board) and UCC383-3 (3.2 board) so higher current problem am I aware of.
So https://github.com/TMRh20/RF24 is the best for LC and 3.2?
No SPI speed problem with LC? I wantt to have 48Mhz as CPU speed.

With regards
toxic
 
Last edited:
Comments on the Arduino/Network forum indicate the TMRh20 library is the best for the nRF24 and any Arduino board. I've used it for the Nano, Uno, Pro Mini, Mega, and Teensy 3.2 with success.

On the Teensy, I run the SPI buss at 4.5MHz using the following code just before radio.begin(). You can change the value to 8, 4, 2, or 1 for higher speeds. You will have to look at the nRF24 spec sheet to find it's upper limit.


Code:
    SPI.begin();                                    // Start the SPI buss
    SPI.setClockDivider( SPI_CLOCK_DIV16 );         // Set SPI clock to 4.5MHz, similar to 16M Arduino
 
On the Teensy 3.2, you should be able to set the clock to 9MHz using the command SPI_CLOCK_DIV8.

Good luck in your project.
Ed
 
Here is the code for LC:

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

Pick one up today in the adafruit shop!
------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

//#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "nRF24L01.h"
#include "RF24.h"

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define CE_PIN 9
#define CS_PIN 10

// Config Radio (CEPin, CSPin)
RF24 radio(CE_PIN, CS_PIN);

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
int txdata[1] = {0xA5};

int val;

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000
};



void setup() {
Serial.begin(9600);
SPI.begin(); // Start the SPI buss
SPI.setClockDivider( SPI_CLOCK_DIV16 ); // Set SPI clock to 4.5MHz,
radio.begin();
radio.setPALevel(RF24_PA_MIN);
radio.setDataRate(RF24_250KBPS);
radio.setAutoAck(1);
radio.setChannel(115);
//Set radio.setChannel(108); 2.508 Ghz - Above most Wifi Channels
/*The range is 2.400 to 2.525 Ghz which is 2400 to 2525 MHz (MegaHz).
The nRF24L01 channel spacing is 1 Mhz which gives 125 possible channels numbered 0 .. 124.
*/
radio.setRetries(15, 15);
radio.setPayloadSize(8);
// Open pipes to other nodes for communication
//
// This simple sketch opens two pipes for these two nodes to communicate
// back and forth.
// Open 'our' pipe for writing
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1, pipes[1]);
// Start listening
radio.startListening();
//speed RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps.
//250K Bits per second gives longest range.



// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
delay(2000);

// text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Starting up RF24\n");
delay(2000);
display.display();
display.clearDisplay();

radio.printDetails();

}


void loop() {

display.clearDisplay();
display.setCursor(0, 0);
val = analogRead(0);
display.print("Right stick x: ");
display.print(val);
//display.display();

display.setCursor(0, 8);
val = analogRead(1);
display.print("Right stick y: ");
display.print(val);
//display.display();

display.setCursor(0, 16);
val = analogRead(3);
display.print("Left stick x: ");
display.print(val);
//display.display();

display.setCursor(0, 24);
val = analogRead(2);
display.print("Left stick y: ");
display.print(val);

sendOrder();

display.display();

}


void sendOrder()
{

// First, stop listening so we can talk.
radio.stopListening();

// Take the time, and send it. This will block until complete
bool ok = radio.write( &val, sizeof(int) );

// Now, continue listening
radio.startListening();

// Wait here until we get a response, or timeout (10ms)
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 10 )
timeout = true;

// Describe the results
if ( timeout )
{
// At this point the ACK did not arrived so the red LED has to be on
display.setCursor(0, 32);
display.print("Reciever offline");
}
else
{
// Grab the response, compare, and send to debugging spew
unsigned long response;
radio.read( &response, sizeof(unsigned long) );

// At this point the ACK did arrived so the green LED has to be on
display.setCursor(0, 32);
display.print("Reciever online");

}
}

Debug output in 24Mhz and 48Mhz:

STATUS = 0xff RX_DR=1 TX_DS=1 MAX_RT=1 RX_P_NO=7 TX_FULL=1
RX_ADDR_P0-1 = 0xffffffffff 0xffffffffff
RX_ADDR_P2-5 = 0xff 0xff 0xff 0xff
TX_ADDR = 0xffffffffff
RX_PW_P0-6 = 0xff 0xff 0xff 0xff 0xff 0xff
EN_AA = 0xff
EN_RXADDR = 0xff
RF_CH = 0xff
RF_SETUP = 0xff
CONFIG = 0xff
DYNPD/FEATURE = 0xff 0xff
Data Rate = 1MBPS
Model = nRF24L01
CRC Length = 16 bits
PA Power = PA_MAX

Not good!

Connectio to nRF24L01+ :
CE = 9
CSE = 10
MOSI = 11
MISO = 12
SlK = 13
 
Last edited:
The debug info says the problem is back at radio.begin(). The initializing is not successful. Try setting the SPI clock to a lower frequency using 32 or 64 as the argument.

The first argument in radio.setRetries(15, 15); is a multiple of 250usec above a fixed value of 250usec. You may not need that high a value when things are running. I use 3 at 2Mbps. If you stay at 250Kbps, you may need all the delay for 32 byte packets but less for smaller ones.

At this point, I would set up another Arduino, Nano or Uno, with the LC as a pair and run the ping/pong example until you find the problems.

Also, put your code inside of tags using the # choice near the top of the post window.

Code:
// your code here
 
If the library is not already installed in your IDE then use the install from ZIP function in Sketch/Include library/Add ZIP library. The code you posted already contains all the references you need. However, I would run the 'pingpair_ack' example first to be sure the devices are running correctly at both ends of the link. That example is uploaded to both Arduinos and you ground a pin on one to set it's role. You should see some text in the serial monitor window for both.
 
Finaly: MOSI to MOSI and MISO to MISO !?!?!??!?!
Debug working! :D

pingpair_ack = working!!!
 
Last edited:
SPI is pin to pin with matched names instead of crossed over like serial connections. The devices take care of the crossover internally.

Try increasing the SPI clock speed back to 16 if not already done. You might even try one notch higher(8), just for kicks.
 
I have some questions regarding these nRF24L01+ boards. After reading the datasheet and some examples (RF24 library), I still couldn't find an answer:

1) Is there a way to identify a module (like the MAC address of an wifi board)? I want to exchange messages between two Teensy 3.2 boards (some kind of chat application) but I have concerns about communication security. How would I know that I'm talking with that specific board and not a fake one?

2) I've read that every board could have a maximum of 5(6) communications pipes. What if there are 10 active boards around? How do I choose which one to talk to?

3) What if two boards are trying to talk to each other at exactly the same time? As far as I've read, while a board is sending something it could not listen (and I prefer an asynchronous communication, not a master/slave one).

Thanks in advance for your time.
 
@Many thanks, @Arctic_Eddie.

I've just installed RF24Network library (TMRh20 version though) and I managed to run (somehow) the helloworld_tx(rx) example.

I said "somehow" because I have some troubles with serial terminals, as they seem to not print (or just randomly) the output of Serial.print commands. That's it, I have no visual feedback if those examples are running ok or not.

Anyway, I've just read some documentation about RF24Network and I understood the IP network analogy (gateway, node, subnet).

It's still not clear if there's a unique identifier (MAC address) for every nRF24L01+ radio module. Seems like you have to write some kind of ID into the Teensy's EEPROM to securely identify those nodes (to avoid sniffers/fake nodes).

Did you managed to test a two way (asynchronous chat) communication between two nodes (or the master and a node)?
 
I don't know of any RF24 built in ID like a MAC number but something could be included in the message. The Teensy ID could be used as one. However, an eavesdropper would see it as part of the message that does not change each time. It would be the same as sending an email password in open form with no encrypting. One way around that is to embed several bytes of data sprinkled throughout the message in known locations and using specific values. If those bytes don't match a list at the receiving end then the message is fake.

I have used only the simple form of RF24 link where the master sends a command/dev/data packet to one of the slaves and it then returns more data. This is on a radio controlled boat sending back phased array sonar data.
 
Seems like I have to implement some kind of encryption then (btw, thanks for your suggestions).

Anyway, I think I'll go further by using RF24Ethernet/Mesh library to allow internet access for every node.
 
I know this is an old thread but I see the "unique ID" question was never answered, so...

The nRF24L01+ does NOT have any built-in unique ID; it's all software controlled. You use 5 byte addresses (it can be configured shorter), which serve both as address filtering what you receive, and helps with bit sync and packet sync (there are some restrictions on good addresses in the datasheet). Typically you'd use the same 4 bytes for all the devices on your local on-air nRF24 "network", but assign a different 5th byte for each device. You can program up to 6 receive addresses (one for each "receive pipe"). One thing to realize is that the hardware doesn't provide or use a "return address"; if you want that, you need to include something in the data payload.

You have an option for automatic acknowledgement & resending up to 15 times for an unacknowledged packet. The way that works it that you temporarily program the first receive pipe with the same address you are sending the current packet to; the receiver transmits an ACK packet to to it's own address, which is picked up by the sender.

It would be possible for somebody to receive your packets, and "spoof" sending packets into your network. They have to use the same channel (frequency) and speed, and to discover your 5 byte address, but there exist techniques for so discovering (a bit convoluted and not part of the standard libraries). So you may want to use encryption to protect you data from viewing, or crypto signature to validate genuine packets. The problem is that the data payload is only 32 bytes maximum, so you need to keep the overhead small.
 
@Zeph:

Thanks a lot for your valuable suggestions (sorry for being late though). I gave up the security issue at the time as it was just a learning experiment.

For now, I'm gathering the Teensy USB serial number and its Freescale chip ID and I'm using them for security check (but It's still a work in progress).

Anyway.. I have another "problem": I'm using the RF24Network library with great success (TMRh20 rulz!) and during operation the Teensy LED is blinking very fast (almost solid lit). I've searched through the RF24 and RF24Network libraries for the LED turning on/off routine with no success. I just want to take over the LED control to only make it light when I receive a packet, by example.

Does anyone knows how to shut that LED off?!
 
I don't know anything about the RF24 library, but if the RF24 is accessed as a SPI device, it is due to the default SPI SCK pin (13) being the same as the LED pin. As far as I know, you can't disable the LED function, but you can change the SCK pin from 13 to 14 using:
Code:
  SPI.setSCK(14);

You would need to make sure that all of your SPI devices use pin 14 instead of 13. I don't know if you need to call SPI.setSCK before or after the SPI.begin call.

 
@MichaelMeissner:

You're a light(!) saver.. and I'm a dumb coder! That's what happens when you're doing things like a blind bot who's only focusing on (software OR hardware) but !(software AND hardware). Just imagine, I did myself the wiring so I have connected the SPI SCK to pin 13 with my bare hand but, as long as I didn't set any "pin 13" in my sketch, I've completely ignored this reality.

SPI.setSCK(14) it's working like a charm (btw, the nRF24L01+ board it's the only SPI connected device).. thanks a lot for your quick support!
 
@MichaelMeissner:

You're a light(!) saver.. and I'm a dumb coder! That's what happens when you're doing things like a blind bot who's only focusing on (software OR hardware) but !(software AND hardware). Just imagine, I did myself the wiring so I have connected the SPI SCK to pin 13 with my bare hand but, as long as I didn't set any "pin 13" in my sketch, I've completely ignored this reality.

SPI.setSCK(14) it's working like a charm (btw, the nRF24L01+ board it's the only SPI connected device).. thanks a lot for your quick support!
I'm glad it helped.
 
Status
Not open for further replies.
Back
Top