Basic NRF Wifi Sensor Communication Between Arduinos

by Aggie115 in Circuits > Arduino

29 Views, 2 Favorites, 0 Comments

Basic NRF Wifi Sensor Communication Between Arduinos

thumbnail_image (2).png
NRF stock photo.jpg

In a recent class taken at Utah State University, my partner and I were tasked with creating a circuit that incorporates both electronics and software that involves multiple sensors and actuators. We chose to try and elaborate on the professor's project by creating a remote control that could replace the need for an app that wasn't available on Apple devices. due to time constraints (and many other obstacles that I won't list here) we had to simplify the device to a simple circuit that would instead light up one of four LEDs depending on the direction that you moved the joystick on the controller. By the end of our time in the class we were able to get the controller and the receiver to talk to each other and plot data via Serial Monitor in Arduino IDE. The attached project is as far as me and my partner got, meaning that the final project is incomplete.



TL;DR Allow us to show you how to properly wire and set up a simple circuit that uses NRF wifi sensors.

Supplies

HARDWARE

2 Arduino UNOs (or ELEGOO UNOs)

2 NRF24L01 sensors (Amazon.com: 4 Pieces of NRF24L01+ Wireless Transceiver Module 2.4G Wireless Transceiver Modules : Electronics)

2 hall effects thumb sticks (https://www.amazon.com/Replacement-Controller-Thumbsticks-Playstation-DualSense/dp/B0CXPGZFQW)

2 100 uF capacitors

4 LEDs

4 220 ohm resistors

male/male wires

female/male wires (or some way to attach the male pins of the NRF to different ports in the Arduino)


SOFTWARE

Arduino IDE

basic Arduino code libraries

NRFLite library by Dave Parson

RF24 library from TMRh20

*both of these can be found via the Arduino IDEs library manager. pictures can be found in step 5

Soldering

joystick soldering.png

For the joystick, we had to do some soldering. We used the controller that was already made in class to figure out the wiring and then plugged it into the analog in pins, the power pin, and the ground pin.

Wiring the NRF24L01 Sensor

basic NRF circuit setup.png

For the NRF sensor, we actually found a picture of what we thought the pins meant, and it actually turned out to be wrong, so we struggled with that for a while, but then we ended up finding the picture that we included, and those are the correct pins. We then took the wires and put them into the digital pins, the ground pin, and the 3.3 volt pin in the Arduino.

Bread Board Set Up (controller)

joystick circuit.png

For the controller side of the project, we had an NRF sensor, as we talked about in the step before. We also had to use a capacitor to make the flow of power stable, and with that, because we had to get voltage and ground to all of this, we had to run the ground pin and the voltage pin going to the capacitor and then back to the Arduino's ground and voltage pins.

Bread Board Set Up (receiver)

receiver circuit with theoretical expansion.png

For the receiver side of it, we just had to copy the wiring for the wireless sensor, and we also had to have the capacitor on this side. We then added some LED lights in the shape of a plus (+). This will show you if the joystick is getting pushed up, down, or side to side.


*NOTICE ON THIS DRAWING: While drawing it up we noticed that our code had been set up for pins 2-5 and did NOT include pin 0 (which you can see we originally used). As such, the WHITE drawn wiring of the resistor and LED is the original circuit that we created. This causes the LED to be constantly on. To remedy this, the RAINBOW/MULTI COLORED wiring path that we have drawn (connected to the "Pins 2-5" with the dashed lines and the italicized pin names) is the theoretical correct wiring to get the circuit to work as was originally intended

Coding the NRF24L01 Sensor (remote/joystick)

Screenshot 2025-12-07 150919.png

We will have the code attached to this so someone can use it and build upon it. To create the code, we had AI write it, and then we had to make minor fixes. I couldn't figure out why the code wasn't compiling on my computer for the longest time, and it was because I had to download a file in the Arduino library to make it actually work. I took a screenshot of the files I had to download. The attached file is the code already in a file, or you can copy it below. Whichever you choose. If the code/file doesn't initially open, try creating a folder named exactly as the code file is named and save it in there.



/*

Diagnostic NRF24L01 Transmitter

Tests if radio hardware is working and sends joystick data

NRF24L01 Connections (2x4 pin layout):

GND → Arduino GND (+ Capacitor negative)

VCC → Arduino 3.3V (+ Capacitor positive)

CE → Arduino Pin 9

CSN → Arduino Pin 10

SCK → Arduino Pin 13

MOSI → Arduino Pin 11

MISO → Arduino Pin 12

IRQ → Not connected

100µF Capacitor: Between GND and VCC on NRF24L01

Joystick Connections:

GND → Arduino GND

+5V (VCC) → Arduino 5V

VRx (X-axis) → Arduino A0

VRy (Y-axis) → Arduino A1

SW (button) → Not connected

*/


#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>


#define JoyStick_X_PIN A0

#define JoyStick_Y_PIN A1


RF24 radio(9, 10);

const byte address[6] = "00935";


uint8_t joystick[3];


void setup() {

Serial.begin(9600);

delay(1000);

Serial.println("========================================");

Serial.println("TRANSMITTER DIAGNOSTIC TEST");

Serial.println("========================================");

// Test if radio initializes

if (!radio.begin()) {

Serial.println("ERROR: Radio hardware not responding!");

Serial.println("Check NRF24L01 wiring!");

while(1); // Stop here

}

Serial.println("✓ Radio hardware detected");

// Check if chip is connected

if (!radio.isChipConnected()) {

Serial.println("ERROR: NRF24L01 chip not connected!");

Serial.println("Check wiring and power (3.3V!)");

while(1);

}

Serial.println("✓ NRF24L01 chip connected");

// Setup radio

radio.openWritingPipe(address);

radio.setPALevel(RF24_PA_LOW);

radio.stopListening();

Serial.println("✓ Radio configured as transmitter");

Serial.print("✓ Using address: ");

Serial.println((char*)address);

Serial.println("========================================");

Serial.println();

delay(1000);

}


void loop() {

// Read joystick

joystick[0] = map(analogRead(JoyStick_X_PIN), 0, 1023, 0, 255);

joystick[1] = map(analogRead(JoyStick_Y_PIN), 0, 1023, 0, 255);

joystick[2] = 100;

Serial.println("----- Sending Data -----");

Serial.print("X: ");

Serial.print(joystick[0]);

Serial.print(" | Y: ");

Serial.println(joystick[1]);

// Send data

bool success = radio.write(&joystick, sizeof(joystick));

if (success) {

Serial.println("✓ Transmission SUCCESSFUL");

} else {

Serial.println("✗ Transmission FAILED");

Serial.println(" Receiver might be off or out of range");

}

Serial.println();

delay(1000); // Send every 1 second for testing

}


Coding the NRF24L01 Sensor (receiver)

Here you will find the code for the Receiver end of the circuit. The attached file is the code already in file, or you can copy the code below. whichever you choose. Again, if the code/file doesn't initially open, try creating a folder named exactly as the code file is named and save it in there.




#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>


RF24 radio(9, 10);

const byte address[6] = "00935";


// LED pins

const int LED_UP = 2;

const int LED_DOWN = 3;

const int LED_LEFT = 4;

const int LED_RIGHT = 5;


// Array to receive joystick data

uint8_t joystick[3];


// Threshold for joystick direction detection

const int CENTER = 127; // Center value (0-255 scale)

const int THRESHOLD = 50; // How far from center to trigger LED


void setup() {

Serial.begin(9600);

delay(1000);

Serial.println("========================================");

Serial.println("RECEIVER DIAGNOSTIC TEST - 4 LEDs");

Serial.println("========================================");

// Setup LED pins

pinMode(LED_UP, OUTPUT);

pinMode(LED_DOWN, OUTPUT);

pinMode(LED_LEFT, OUTPUT);

pinMode(LED_RIGHT, OUTPUT);

// Turn all LEDs off initially

digitalWrite(LED_UP, LOW);

digitalWrite(LED_DOWN, LOW);

digitalWrite(LED_LEFT, LOW);

digitalWrite(LED_RIGHT, LOW);

// Test if radio initializes

if (!radio.begin()) {

Serial.println("ERROR: Radio hardware not responding!");

Serial.println("Check NRF24L01 wiring!");

while(1); // Stop here

}

Serial.println("✓ Radio hardware detected");

// Check if chip is connected

if (!radio.isChipConnected()) {

Serial.println("ERROR: NRF24L01 chip not connected!");

Serial.println("Check wiring and power (3.3V!)");

while(1);

}

Serial.println("✓ NRF24L01 chip connected");

// Setup radio

radio.openReadingPipe(0, address);

radio.setPALevel(RF24_PA_LOW);

radio.startListening();

Serial.println("✓ Radio configured as receiver");

Serial.print("✓ Listening on address: ");

Serial.println((char*)address);

Serial.println("========================================");

Serial.println("Waiting for data...");

Serial.println();

delay(1000);

}


void loop() {

if (radio.available()) {

// Data received!

radio.read(&joystick, sizeof(joystick));

Serial.println("===== DATA RECEIVED =====");

Serial.print("X: ");

Serial.print(joystick[0]);

Serial.print(" | Y: ");

Serial.println(joystick[1]);

// Control LEDs based on joystick position

// Y-axis: UP/DOWN

if (joystick[1] > CENTER + THRESHOLD) {

digitalWrite(LED_UP, HIGH);

Serial.println("LED UP: ON");

} else {

digitalWrite(LED_UP, LOW);

}

if (joystick[1] < CENTER - THRESHOLD) {

digitalWrite(LED_DOWN, HIGH);

Serial.println("LED DOWN: ON");

} else {

digitalWrite(LED_DOWN, LOW);

}

// X-axis: LEFT/RIGHT

if (joystick[0] < CENTER - THRESHOLD) {

digitalWrite(LED_LEFT, HIGH);

Serial.println("LED LEFT: ON");

} else {

digitalWrite(LED_LEFT, LOW);

}

if (joystick[0] > CENTER + THRESHOLD) {

digitalWrite(LED_RIGHT, HIGH);

Serial.println("LED RIGHT: ON");

} else {

digitalWrite(LED_RIGHT, LOW);

}

Serial.println();

} else {

// No data - turn all LEDs off and print occasionally

digitalWrite(LED_UP, LOW);

digitalWrite(LED_DOWN, LOW);

digitalWrite(LED_LEFT, LOW);

digitalWrite(LED_RIGHT, LOW);

static unsigned long lastPrint = 0;

if (millis() - lastPrint > 2000) {

Serial.println("Waiting for signal... (All LEDs OFF)");

lastPrint = millis();

}

}

delay(50);

}

Downloads

Launching the Code

A QUICK WARNING! When me and my partner did this, we had this incredibly strange issue where the code would just not upload to the receiver Arduino. We would click upload and it would be stuck uploading forever. To fix this (if you have the same problem) is to disconnect the wires that go from the Arduino to the LEDs. In our pictured example, since we only had the one LED we only had to unplug one thing. If that doesn't work, try disconnecting all the NRF sensor wires (but be sure to remember which is which and where they go). If the controller has the same problem of not uploading, also disconnect all the NRF wires prior to uploading. For both cases, once the code is uploaded you are good to plug everything back in. A possible cause of this error was, as seen in the receiver schematic, we had initially pinned the LED into pin 0 (which is bad because serial monitor stuff) instead of the intended pin 2 as the our code had been written.


Once the code is uploaded, open the Serial Monitor tab in the Arduino IDE for both the controller and the receiver to see if you are getting communication between the two circuits. When you move the joystick, the serial monitor on the controllers code should read different numbers. If there is communication between the two circuits, the receiver should also display the same numbers (or roughly the same depending on how still you can keep the stick pressed.

Final Product Pictures

PXL_20251205_014825100.jpg
PXL_20251205_014806116.jpg
PXL_20251205_014802004.jpg
PXL_20251205_014758127.jpg
PXL_20251205_014624146.jpg
PXL_20251205_014619885.jpg
PXL_20251205_014523258.jpg
PXL_20251205_014521982.jpg
PXL_20251205_001309245.jpg
PXL_20251205_001307671.jpg
PXL_20251205_001305444.jpg
PXL_20251205_001304077.MP.jpg
PXL_20251201_234519802.jpg