ESP32 nRF24 Walkie-Talkie (Main Description)
This project is a wireless communication terminal built on the ESP32 microcontroller, utilizing the nRF24L01 2.4GHz transceiver module for data transmission. The system features a 0.96" I2C OLED display to show real-time operational status (such as current channel and transmission states) and an incremental rotary encoder with a push button for user input. Rotating the encoder adjusts the active channel, while pressing the integrated button triggers an outgoing transmission packet.
Code:
#include <SPI.h>
#include <Wire.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define CE_PIN 4
#define CSN_PIN 5
RF24 radio(CE_PIN, CSN_PIN);
const byte address[6] = "00001";
#define CLK_PIN 25
#define DT_PIN 26
#define SW_PIN 27
int counter = 1;
int currentStateCLK;
int lastStateCLK;
unsigned long lastButtonPress = 0;
void setup() {
Serial.begin(115200);
pinMode(CLK_PIN, INPUT_PULLUP);
pinMode(DT_PIN, INPUT_PULLUP);
pinMode(SW_PIN, INPUT_PULLUP);
lastStateCLK = digitalRead(CLK_PIN);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.println("Starting...");
display.display();
delay(1000);
if (!radio.begin()) {
display.clearDisplay();
display.setCursor(0, 10);
display.println("nRF24 Error!");
display.display();
while (1) {}
}
radio.openWritingPipe(address);
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
updateDisplay("RX Mode");
}
void loop() {
currentStateCLK = digitalRead(CLK_PIN);
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
if (digitalRead(DT_PIN) != currentStateCLK) {
counter--;
if(counter < 1) counter = 1;
} else {
counter++;
if(counter > 99) counter = 99;
}
updateDisplay("Channel Changed");
}
lastStateCLK = currentStateCLK;
int btnState = digitalRead(SW_PIN);
if (btnState == LOW) {
if (millis() - lastButtonPress > 500) {
sendData();
lastButtonPress = millis();
}
}
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
updateDisplay(text);
}
}
void sendData() {
radio.stopListening();
char text[32];
sprintf(text, "Ping Ch: %d", counter);
if (radio.write(&text, sizeof(text))) {
updateDisplay("TX OK");
} else {
updateDisplay("TX Fail");
}
radio.startListening();
}
void updateDisplay(String statusMsg) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print("CH: ");
display.print(counter);
display.setTextSize(1);
display.setCursor(0, 30);
display.print("Status: ");
display.println(statusMsg);
display.drawLine(0, 50, 128, 50, WHITE);
display.setCursor(0, 55);
display.print("Press SW to TX");
display.display();
}