Question

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Initialize the LCD: address 0x27, 16 characters, 2 lines
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust the I2C address if needed

// Define pins for joystick module
const int vryPin = A0; // Y-axis
const int vrxPin = A1; // X-axis
const int buttonPin = 2; // Button

// Device list
const uint8_t listSize = 1;
const char* const devices[listSize] = {
"DEVICE 1",
};

// Enumeration for screen states
enum ScreenState {
LIST_SCREEN,
CONNECTING_SCREEN,
TEMPERATURE_SCREEN,
HUMIDITY_SCREEN,
LIGHT_INTENSITY_SCREEN,
GAS_CONCENTRATION_SCREEN,
SOIL_MOISTURE_SCREEN,
PRECIPITATION_LEVELS_SCREEN
};

// Enumeration for joystick directions
enum Direction { CENTER, UP, DOWN, LEFT, RIGHT };

// Current screen state
ScreenState currentScreen = LIST_SCREEN;

// Array of sensor screens for easy navigation
const ScreenState sensorScreens[] = {
TEMPERATURE_SCREEN,
HUMIDITY_SCREEN,
LIGHT_INTENSITY_SCREEN,
GAS_CONCENTRATION_SCREEN,
SOIL_MOISTURE_SCREEN,
PRECIPITATION_LEVELS_SCREEN
};
const uint8_t totalSensorScreens = sizeof(sensorScreens) / sizeof(sensorScreens[0]);
uint8_t currentSensorIndex = 0; // Start with the first sensor screen

// Current index for list display
uint8_t currentIndex = 0;

// Variables for joystick state
Direction mainDirection = CENTER;
bool isCentered = true;

// Timing variables for holding in a single direction
unsigned long holdStartTime = 0;
const unsigned long holdIncrementInterval = 500; // 500 milliseconds

// Variables for button handling
bool lastButtonState = HIGH; // Assume button is not pressed initially
bool buttonPressed = false;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // 50 milliseconds debounce

// Variable to store selected device
const char* selectedDevice = nullptr;

// Variables for screen transitions
unsigned long connectingStartTime = 0;
const unsigned long connectingDuration = 2000; // 2 seconds

// Function Prototypes
void displayInitialMessages();
void displayList();
void showConnectingScreen();
void showSensorScreen(ScreenState screen);
void handleJoystick();
void debounceButton();
void clearScreen();

// Optimized Display Functions
void displayInitialMessages() {
// ECOROOTS Message
lcd.clear();
lcd.setCursor((16 - 8) / 2, 0); // Center "ECOROOTS" on first line
lcd.print("ECOROOTS");

const char message[] = "ROOTING SUSTAINABILITY INTO THE FUTURE";
uint8_t msgLen = strlen(message);
if (msgLen <= 16) {
lcd.setCursor((16 - msgLen) / 2, 1);
lcd.print(message);
delay(5000);
} else {
for (uint8_t pos = 0; pos <= msgLen - 16; pos++) {
lcd.setCursor(0, 1);
lcd.print(&message[pos]);
delay(100); // Adjust scrolling speed as needed
}
delay(500); // Pause after scrolling
}

// Searching Message
lcd.clear();
const char searchMsg[] = "SEARCHING ENVIRONMENT FOR DEVICES";
msgLen = strlen(searchMsg);
if (msgLen <= 16) {
lcd.setCursor((16 - msgLen) / 2, 0);
lcd.print(searchMsg);
delay(5000);
} else {
for (uint8_t pos = 0; pos <= msgLen - 16; pos++) {
lcd.setCursor(0, 0);
lcd.print(&searchMsg[pos]);
delay(100);
}
delay(500);
}

// Device Found Message
lcd.clear();
const char deviceFoundMsg[] = "1 DEVICE FOUND";
lcd.setCursor(0, 0);
lcd.print(deviceFoundMsg);
delay(1000);
}

void displayList() {
lcd.clear();

// Display first device
const char* firstItem = devices[currentIndex];
lcd.setCursor(0, 0);
lcd.print(firstItem);

// Display second device if exists
if (currentIndex + 1 < listSize) {
const char* secondItem = devices[currentIndex + 1];
lcd.setCursor(0, 1);
lcd.print(secondItem);
} else {
lcd.setCursor(0, 1);
lcd.print(" "); // Clear second line
}
}

void showConnectingScreen() {
lcd.clear();

static const char connectingPrefix[] = "CONNECTING TO ";
char fullMessage[32];
snprintf(fullMessage, sizeof(fullMessage), "%s%s", connectingPrefix, selectedDevice);

uint8_t msgLen = strlen(fullMessage);
if (msgLen <= 16) {
lcd.setCursor(0, 0);
lcd.print(fullMessage);
} else {
for (uint8_t pos = 0; pos <= msgLen - 16; pos++) {
lcd.setCursor(0, 0);
lcd.print(&fullMessage[pos]);
delay(100); // Adjust scrolling speed as needed
}
}

connectingStartTime = millis(); // Start timer for transition
}

void showSensorScreen(ScreenState screen) {
lcd.clear();

// Sensor names and simulated values
switch(screen) {
case TEMPERATURE_SCREEN:
lcd.setCursor(0, 0);
lcd.print("TEMPERATURE");
// Simulate temperature
{
float temp = (random(200, 301)) / 10.0; // 20.0°C to 30.0°C
char tempStr[16];
snprintf(tempStr, sizeof(tempStr), "%.1f oC", temp);
lcd.setCursor(0, 1);
lcd.print(tempStr);
}
break;

case HUMIDITY_SCREEN:
lcd.setCursor(0, 0);
lcd.print("HUMIDITY");
// Simulate humidity
{
uint8_t hum = random(30, 91); // 30% to 90%
char humStr[16];
snprintf(humStr, sizeof(humStr), "%d %%", hum);
lcd.setCursor(0, 1);
lcd.print(humStr);
}
break;

case LIGHT_INTENSITY_SCREEN:
lcd.setCursor(0, 0);
lcd.print("LIGHT INTENSITY");
// Simulate light intensity
{
uint16_t lux = random(100, 1001); // 100 to 1000 Lux
char luxStr[16];
snprintf(luxStr, sizeof(luxStr), "%d Lux", lux);
lcd.setCursor(0, 1);
lcd.print(luxStr);
}
break;

case GAS_CONCENTRATION_SCREEN:
lcd.setCursor(0, 0);
lcd.print("GAS CONCENTRATION");
// Simulate gas concentration
{
float gas = (random(0, 501)) / 10.0; // 0.0 to 50.0 ppm
char gasStr[16];
snprintf(gasStr, sizeof(gasStr), "%.1f ppm", gas);
lcd.setCursor(0, 1);
lcd.print(gasStr);
}
break;

case SOIL_MOISTURE_SCREEN:
lcd.setCursor(0, 0);
lcd.print("SOIL MOISTURE");
// Simulate soil moisture
{
uint8_t moisture = random(20, 81); // 20% to 80%
char moistStr[16];
snprintf(moistStr, sizeof(moistStr), "%d %%", moisture);
lcd.setCursor(0, 1);
lcd.print(moistStr);
}
break;

case PRECIPITATION_LEVELS_SCREEN:
lcd.setCursor(0, 0);
lcd.print("PRECIPITATION");
// Simulate precipitation levels
{
float precipitation = (random(0, 1001)) / 10.0; // 0.0 to 100.0 mm
char precStr[16];
snprintf(precStr, sizeof(precStr), "%.1f mm", precipitation);
lcd.setCursor(0, 1);
lcd.print(precStr);
}
break;

default:
// Default to Temperature Screen
showSensorScreen(TEMPERATURE_SCREEN);
break;
}
}

void handleJoystick() {
// Read joystick analog values
uint16_t yValueCurrent = analogRead(vryPin);
uint16_t xValueCurrent = analogRead(vrxPin);

// Determine joystick direction
Direction direction = CENTER;
if (yValueCurrent > 800) {
direction = UP;
}
else if (yValueCurrent < 200) {
direction = DOWN;
}
else if (xValueCurrent > 800) {
direction = RIGHT; // Currently unused
}
else if (xValueCurrent < 200) {
direction = LEFT;
}

// Handle based on current screen
switch(currentScreen) {
case LIST_SCREEN:
if (direction == CENTER) {
isCentered = true;
}
else if (isCentered) {
mainDirection = direction;
isCentered = false;
holdStartTime = millis();

if (mainDirection == UP) {
if (currentIndex > 0) {
currentIndex--;
displayList();
}
}
else if (mainDirection == DOWN) {
if (currentIndex < listSize - 2) { // Display two devices at a time
currentIndex++;
displayList();
}
}
}
else {
if (mainDirection == direction && (millis() - holdStartTime >= holdIncrementInterval)) {
holdStartTime = millis();
if (mainDirection == UP) {
if (currentIndex > 0) {
currentIndex--;
displayList();
}
}
else if (mainDirection == DOWN) {
if (currentIndex < listSize - 2) {
currentIndex++;
displayList();
}
}
}
}
break;

case CONNECTING_SCREEN:
// No joystick handling during connecting
break;

case TEMPERATURE_SCREEN:
case HUMIDITY_SCREEN:
case LIGHT_INTENSITY_SCREEN:
case GAS_CONCENTRATION_SCREEN:
case SOIL_MOISTURE_SCREEN:
case PRECIPITATION_LEVELS_SCREEN:
if (direction == DOWN) {
// Scroll down to the next sensor screen
currentSensorIndex++;
if (currentSensorIndex >= totalSensorScreens) {
currentSensorIndex = 0; // Loop back to the first sensor screen
}
currentScreen = sensorScreens[currentSensorIndex];
showSensorScreen(currentScreen);
delay(200); // Simple debounce
}
else if (direction == UP) {
// Scroll up to the previous sensor screen
if (currentSensorIndex > 0) {
currentSensorIndex--;
}
else {
currentSensorIndex = totalSensorScreens - 1;
}
currentScreen = sensorScreens[currentSensorIndex];
showSensorScreen(currentScreen);
delay(200); // Simple debounce
}
else if (direction == LEFT) {
// Return to Device List
currentScreen = LIST_SCREEN;
displayList();
delay(200); // Simple debounce
}
break;
}
}

void debounceButton() {
int reading = digitalRead(buttonPin);

if (reading != lastButtonState) {
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonPressed) {
buttonPressed = reading;

if (buttonPressed == LOW) { // Button pressed
if (currentScreen == LIST_SCREEN) {
selectedDevice = devices[currentIndex];
currentScreen = CONNECTING_SCREEN;
showConnectingScreen();
}
}
}
}

lastButtonState = reading;
}

void setup() {
// Initialize Serial for debugging (optional)
Serial.begin(9600); // Changed to 9600 for better compatibility

// Initialize the LCD
lcd.init();
lcd.backlight();

// Set button pin as input with pull-up resistor
pinMode(buttonPin, INPUT_PULLUP);

// Seed the random number generator (for simulating sensor data)
randomSeed(analogRead(0));

// Display initial messages
displayInitialMessages(); // Display "ECOROOTS" and scrolling message
displayList(); // Display the device list
}

void loop() {
// Debounce and handle button press
debounceButton();

// Handle joystick navigation
handleJoystick();

// Handle screen transitions
if (currentScreen == CONNECTING_SCREEN) {
if (millis() - connectingStartTime >= connectingDuration) {
// Transition to first sensor screen
currentSensorIndex = 0;
currentScreen = sensorScreens[currentSensorIndex];
showSensorScreen(currentScreen);
}
}

// Small delay to prevent excessive CPU usage
delay(10);
}

Edit the above code so that the temperature and other sensor values, are now received from another arduino cionnected to an nrf24l01. The values are fixed, and not measured from any sensors. Also write me the transmitter code.

Thought

Piecing together the connection

I’m working through integrating nRF24L01 communication into the code to receive fixed values from another Arduino, using a specific library for this functionality.

Setting up the modules

I'm working through the setup process, starting with the nRF24L01 module, configuring it as a receiver, and adjusting the showSensorScreen function to display received values.

Preparing for communication

You're setting up the RF24 module by including its library, initializing the object with specific pins, and defining addresses for communication.

Receiving and sending data

First, gather data into a global variable. Then, tweak showSensorScreen() to integrate this data and finally, transmit the fixed values.

Setting up the sensor network

I’m configuring the RF24 network and preparing the sensor data structure. Next, I’ll initialize the radio in setup() and progressively read sensor data in loop().

Crafting transmitter code

I’m mapping out the transmitter code, which involves importing libraries, initializing RF24, setting up pipe addresses, defining SensorData structures, and sending fixed values in a loop.

Setting up data transmission

I initialized the nRF24L01 module, defined a fixed data structure for sensor readings, and configured the radio for reliable data transmission every second.

Ensuring smooth communication

I'm confirming that the receiver code is compatible with the nRF24L01 module, noting no conflicts between the LiquidCrystal_I2C and RF24 libraries. Serial initialization does not affect the process.

Answer

Certainly! Below is the modified code for both the receiver and the transmitter using the nRF24L01 modules. The receiver code has been adjusted to receive fixed sensor values from the transmitter, and the transmitter code sends these fixed values.


Receiver Code (Modified)

#include <Arduino.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <RF24.h> // Initialize the LCD: address 0x27, 16 characters, 2 lines LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust the I2C address if needed // Initialize the nRF24L01 module RF24 radio(9, 10); // CE, CSN pins // Address for communication const byte address[6] = "00001"; // 5-byte address // Define pins for joystick module const int vryPin = A0; // Y-axis const int vrxPin = A1; // X-axis const int buttonPin = 2; // Button // Device list const uint8_t listSize = 1; const char* const devices[listSize] = { "DEVICE 1", }; // Enumeration for screen states enum ScreenState { LIST_SCREEN, CONNECTING_SCREEN, TEMPERATURE_SCREEN, HUMIDITY_SCREEN, LIGHT_INTENSITY_SCREEN, GAS_CONCENTRATION_SCREEN, SOIL_MOISTURE_SCREEN, PRECIPITATION_LEVELS_SCREEN }; // Enumeration for joystick directions enum Direction { CENTER, UP, DOWN, LEFT, RIGHT }; // Current screen state ScreenState currentScreen = LIST_SCREEN; // Array of sensor screens for easy navigation const ScreenState sensorScreens[] = { TEMPERATURE_SCREEN, HUMIDITY_SCREEN, LIGHT_INTENSITY_SCREEN, GAS_CONCENTRATION_SCREEN, SOIL_MOISTURE_SCREEN, PRECIPITATION_LEVELS_SCREEN }; const uint8_t totalSensorScreens = sizeof(sensorScreens) / sizeof(sensorScreens[0]); uint8_t currentSensorIndex = 0; // Start with the first sensor screen // Current index for list display uint8_t currentIndex = 0; // Variables for joystick state Direction mainDirection = CENTER; bool isCentered = true; // Timing variables for holding in a single direction unsigned long holdStartTime = 0; const unsigned long holdIncrementInterval = 500; // 500 milliseconds // Variables for button handling bool lastButtonState = HIGH; // Assume button is not pressed initially bool buttonPressed = false; unsigned long lastDebounceTime = 0; const unsigned long debounceDelay = 50; // 50 milliseconds debounce // Variable to store selected device const char* selectedDevice = nullptr; // Variables for screen transitions unsigned long connectingStartTime = 0; const unsigned long connectingDuration = 2000; // 2 seconds // Data structure for sensor data struct SensorData { float temperature; uint8_t humidity; uint16_t lightIntensity; float gasConcentration; uint8_t soilMoisture; float precipitationLevel; }; // Variable to hold received sensor data SensorData sensorData; void displayInitialMessages(); void displayList(); void showConnectingScreen(); void showSensorScreen(ScreenState screen); void handleJoystick(); void debounceButton(); void clearScreen(); void displayInitialMessages() { // ECOROOTS Message lcd.clear(); lcd.setCursor((16 - 8) / 2, 0); // Center "ECOROOTS" on first line lcd.print("ECOROOTS"); const char message[] = "ROOTING SUSTAINABILITY INTO THE FUTURE"; uint8_t msgLen = strlen(message); if (msgLen <= 16) { lcd.setCursor((16 - msgLen) / 2, 1); lcd.print(message); delay(5000); } else { for (uint8_t pos = 0; pos <= msgLen - 16; pos++) { lcd.setCursor(0, 1); lcd.print(&message[pos]); delay(100); // Adjust scrolling speed as needed } delay(500); // Pause after scrolling } // Searching Message lcd.clear(); const char searchMsg[] = "SEARCHING ENVIRONMENT FOR DEVICES"; msgLen = strlen(searchMsg); if (msgLen <= 16) { lcd.setCursor((16 - msgLen) / 2, 0); lcd.print(searchMsg); delay(5000); } else { for (uint8_t pos = 0; pos <= msgLen - 16; pos++) { lcd.setCursor(0, 0); lcd.print(&searchMsg[pos]); delay(100); } delay(500); } // Device Found Message lcd.clear(); const char deviceFoundMsg[] = "1 DEVICE FOUND"; lcd.setCursor(0, 0); lcd.print(deviceFoundMsg); delay(1000); } void displayList() { lcd.clear(); // Display first device const char* firstItem = devices[currentIndex]; lcd.setCursor(0, 0); lcd.print(firstItem); // Display second device if exists if (currentIndex + 1 < listSize) { const char* secondItem = devices[currentIndex + 1]; lcd.setCursor(0, 1); lcd.print(secondItem); } else { lcd.setCursor(0, 1); lcd.print(" "); // Clear second line } } void showConnectingScreen() { lcd.clear(); static const char connectingPrefix[] = "CONNECTING TO "; char fullMessage[32]; snprintf(fullMessage, sizeof(fullMessage), "%s%s", connectingPrefix, selectedDevice); uint8_t msgLen = strlen(fullMessage); if (msgLen <= 16) { lcd.setCursor(0, 0); lcd.print(fullMessage); } else { for (uint8_t pos = 0; pos <= msgLen - 16; pos++) { lcd.setCursor(0, 0); lcd.print(&fullMessage[pos]); delay(100); // Adjust scrolling speed as needed } } connectingStartTime = millis(); // Start timer for transition } void showSensorScreen(ScreenState screen) { lcd.clear(); // Sensor names and received values switch (screen) { case TEMPERATURE_SCREEN: lcd.setCursor(0, 0); lcd.print("TEMPERATURE"); // Display temperature { char tempStr[16]; snprintf(tempStr, sizeof(tempStr), "%.1f oC", sensorData.temperature); lcd.setCursor(0, 1); lcd.print(tempStr); } break; case HUMIDITY_SCREEN: lcd.setCursor(0, 0); lcd.print("HUMIDITY"); // Display humidity { char humStr[16]; snprintf(humStr, sizeof(humStr), "%d %%", sensorData.humidity); lcd.setCursor(0, 1); lcd.print(humStr); } break; case LIGHT_INTENSITY_SCREEN: lcd.setCursor(0, 0); lcd.print("LIGHT INTENSITY"); // Display light intensity { char luxStr[16]; snprintf(luxStr, sizeof(luxStr), "%d Lux", sensorData.lightIntensity); lcd.setCursor(0, 1); lcd.print(luxStr); } break; case GAS_CONCENTRATION_SCREEN: lcd.setCursor(0, 0); lcd.print("GAS CONCENTRATION"); // Display gas concentration { char gasStr[16]; snprintf(gasStr, sizeof(gasStr), "%.1f ppm", sensorData.gasConcentration); lcd.setCursor(0, 1); lcd.print(gasStr); } break; case SOIL_MOISTURE_SCREEN: lcd.setCursor(0, 0); lcd.print("SOIL MOISTURE"); // Display soil moisture { char moistStr[16]; snprintf(moistStr, sizeof(moistStr), "%d %%", sensorData.soilMoisture); lcd.setCursor(0, 1); lcd.print(moistStr); } break; case PRECIPITATION_LEVELS_SCREEN: lcd.setCursor(0, 0); lcd.print("PRECIPITATION"); // Display precipitation levels { char precStr[16]; snprintf(precStr, sizeof(precStr), "%.1f mm", sensorData.precipitationLevel); lcd.setCursor(0, 1); lcd.print(precStr); } break; default: // Default to Temperature Screen showSensorScreen(TEMPERATURE_SCREEN); break; } } void handleJoystick() { // Read joystick analog values uint16_t yValueCurrent = analogRead(vryPin); uint16_t xValueCurrent = analogRead(vrxPin); // Determine joystick direction Direction direction = CENTER; if (yValueCurrent > 800) { direction = UP; } else if (yValueCurrent < 200) { direction = DOWN; } else if (xValueCurrent > 800) { direction = RIGHT; // Currently unused } else if (xValueCurrent < 200) { direction = LEFT; } // Handle based on current screen switch (currentScreen) { case LIST_SCREEN: if (direction == CENTER) { isCentered = true; } else if (isCentered) { mainDirection = direction; isCentered = false; holdStartTime = millis(); if (mainDirection == UP) { if (currentIndex > 0) { currentIndex--; displayList(); } } else if (mainDirection == DOWN) { if (currentIndex < listSize - 2) { // Display two devices at a time currentIndex++; displayList(); } } } else { if (mainDirection == direction && (millis() - holdStartTime >= holdIncrementInterval)) { holdStartTime = millis(); if (mainDirection == UP) { if (currentIndex > 0) { currentIndex--; displayList(); } } else if (mainDirection == DOWN) { if (currentIndex < listSize - 2) { currentIndex++; displayList(); } } } } break; case CONNECTING_SCREEN: // No joystick handling during connecting break; case TEMPERATURE_SCREEN: case HUMIDITY_SCREEN: case LIGHT_INTENSITY_SCREEN: case GAS_CONCENTRATION_SCREEN: case SOIL_MOISTURE_SCREEN: case PRECIPITATION_LEVELS_SCREEN: if (direction == DOWN) { // Scroll down to the next sensor screen currentSensorIndex++; if (currentSensorIndex >= totalSensorScreens) { currentSensorIndex = 0; // Loop back to the first sensor screen } currentScreen = sensorScreens[currentSensorIndex]; showSensorScreen(currentScreen); delay(200); // Simple debounce } else if (direction == UP) { // Scroll up to the previous sensor screen if (currentSensorIndex > 0) { currentSensorIndex--; } else { currentSensorIndex = totalSensorScreens - 1; } currentScreen = sensorScreens[currentSensorIndex]; showSensorScreen(currentScreen); delay(200); // Simple debounce } else if (direction == LEFT) { // Return to Device List currentScreen = LIST_SCREEN; displayList(); delay(200); // Simple debounce } break; } } void debounceButton() { int reading = digitalRead(buttonPin); if (reading != lastButtonState) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonPressed) { buttonPressed = reading; if (buttonPressed == LOW) { // Button pressed if (currentScreen == LIST_SCREEN) { selectedDevice = devices[currentIndex]; currentScreen = CONNECTING_SCREEN; showConnectingScreen(); } } } } lastButtonState = reading; } void setup() { // Initialize Serial for debugging (optional) Serial.begin(9600); // Initialize the LCD lcd.init(); lcd.backlight(); // Set button pin as input with pull-up resistor pinMode(buttonPin, INPUT_PULLUP); // Initialize the radio radio.begin(); radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_LOW); radio.startListening(); // Display initial messages displayInitialMessages(); // Display "ECOROOTS" and scrolling message displayList(); // Display the device list } void loop() { // Receive data if (radio.available()) { radio.read(&sensorData, sizeof(SensorData)); // Optionally, print received data to Serial for debugging Serial.println("Data received:"); Serial.print("Temperature: "); Serial.println(sensorData.temperature); Serial.print("Humidity: "); Serial.println(sensorData.humidity); Serial.print("Light Intensity: "); Serial.println(sensorData.lightIntensity); Serial.print("Gas Concentration: "); Serial.println(sensorData.gasConcentration); Serial.print("Soil Moisture: "); Serial.println(sensorData.soilMoisture); Serial.print("Precipitation Level: "); Serial.println(sensorData.precipitationLevel); } // Debounce and handle button press debounceButton(); // Handle joystick navigation handleJoystick(); // Handle screen transitions if (currentScreen == CONNECTING_SCREEN) { if (millis() - connectingStartTime >= connectingDuration) { // Transition to first sensor screen currentSensorIndex = 0; currentScreen = sensorScreens[currentSensorIndex]; showSensorScreen(currentScreen); } } // Small delay to prevent excessive CPU usage delay(10); }

Transmitter Code

#include <Arduino.h> #include <RF24.h> // Initialize the nRF24L01 module RF24 radio(9, 10); // CE, CSN pins // Address for communication const byte address[6] = "00001"; // 5-byte address // Data structure for sensor data struct SensorData { float temperature; uint8_t humidity; uint16_t lightIntensity; float gasConcentration; uint8_t soilMoisture; float precipitationLevel; }; // Fixed sensor values SensorData sensorData = { 25.5, // temperature in °C 65, // humidity in % 750, // light intensity in Lux 12.3, // gas concentration in ppm 40, // soil moisture in % 5.5 // precipitation level in mm }; void setup() { Serial.begin(9600); // Optional for debugging // Initialize the radio radio.begin(); radio.openWritingPipe(address); radio.setPALevel(RF24_PA_LOW); radio.stopListening(); // Set as transmitter } void loop() { // Send the data bool success = radio.write(&sensorData, sizeof(SensorData)); // Optionally print to Serial for debugging if (success) { Serial.println("Data sent successfully:"); } else { Serial.println("Data sending failed."); } Serial.print("Temperature: "); Serial.println(sensorData.temperature); Serial.print("Humidity: "); Serial.println(sensorData.humidity); Serial.print("Light Intensity: "); Serial.println(sensorData.lightIntensity); Serial.print("Gas Concentration: "); Serial.println(sensorData.gasConcentration); Serial.print("Soil Moisture: "); Serial.println(sensorData.soilMoisture); Serial.print("Precipitation Level: "); Serial.println(sensorData.precipitationLevel); Serial.println("------------------------"); delay(1000); // Send data every second }

Explanation:

  • Receiver Code Modifications:

    • Included the RF24 library and initialized the radio module with RF24 radio(9, 10);.
    • Defined a SensorData struct to hold the sensor values.
    • In the setup() function, initialized the radio as a receiver and started listening.
    • In the loop() function, checked if data is available and read it into sensorData.
    • Modified the showSensorScreen() function to display the received sensor data instead of simulated values.
  • Transmitter Code:

    • Included the RF24 library and initialized the radio module.
    • Defined the same SensorData struct and populated it with fixed values.
    • In the setup() function, initialized the radio as a transmitter.
    • In the loop() function, continuously sent the sensorData every second.

Notes:

  • Make sure both the transmitter and receiver are using the same address (address[6] = "00001";).
  • Ensure that the CE and CSN pins (RF24 radio(9, 10);) are correctly connected on both Arduinos.
  • The transmitter sends data every second, and the receiver updates the displayed data whenever new data is received.
  • No actual sensors are used; the transmitter sends predefined, fixed values.

Wiring for nRF24L01 Modules:

  • nRF24L01 Pins to Arduino:
    • VCC: 3.3V (do NOT connect to 5V)
    • GND: GND
    • CE: Pin 9
    • CSN: Pin 10
    • SCK: Pin 13
    • MOSI: Pin 11
    • MISO: Pin 12

Final Steps:

  • Upload the transmitter code to one Arduino connected to an nRF24L01 module.
  • Upload the receiver code to another Arduino with the LCD and joystick connected, along with an nRF24L01 module.
  • Power both Arduinos and ensure they are within range for the nRF24L01 modules to communicate.
  • The receiver's LCD should now display the fixed sensor values received from the transmitter when navigating through the sensor screens.

Share this Q&A