3

I'm working on a project to build a plant monitor that works from the outside with Arduino that picks up light and water values from it's environment then uses a nRF24L01 with an antenna and I've come across a roadblock in the code with using a transmitter and receiver, heres the code fully below.

Appreciate any help, been stuck for weeks trying to figure this out.

Transmitter Code

/*
 * NAME: <Mario Ronci>
 * Healthy Plant Monitor  V2  T 
 * 
 * 
 */

 //** **/
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
//create an RF24 object
RF24 radio(9, 8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";


int ldrValue;
int sensorPin = A0;    // select the input pin for the Water Comparator
int sensorValue = 0;
int light_threshold = 650;
int water_threshold = 850;
String dark_message = " ALERT:Plant is Dark!";
String bright_message =" Brightness Achieved! ";
String water_message1 = " Plant has enough water.";
String water_message2 = " Need Water...!";
String healthy_message = "Plant is Healthy!";
String unhealthy_message = "Unhealthy...!";
//String engineerinfo = "Mario Ronci 2023";


void setup() {

  pinMode(LDR, INPUT);
  pinMode(POT, INPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  Serial.begin(9600);
  Serial.println(engineerinfo);
  // put your setup code here, to run once:
radio.begin();
  //set the address
  radio.openWritingPipe(address);
  //Set module as transmitter
  radio.stopListening();


}

//This checks if the plant is getting enough light,//
//by taking a acceptable or unacceptable light value 
//from a LDR and prints the value to the serial monitor
//and if the light value is acceptable 

void ldrCheck(int device, int duration1,int duration2){

ldrValue = analogRead(device);

if(ldrValue >= light_threshold)

{
  messageLight = light_message + String(ldrValue);
  sendByteMessage(); // Call the function to send the byte message
   delay(duration1);// Wait for some time before sending the next message

  
}

if(ldrValue < light_threshold){
  messageLight = dark_message + String(ldrValue)
  byte messageBytes[message.length() + 1]; // Create a byte array to store the message
  delay(duration2);
}

void sendByteMessage() {
  byte messageBytes[message.length() + 1]; // Create a byte array to store the message

  // Convert the string message into a byte array
  message.getBytes(messageBytes, message.length() + 1);

  // Send the byte array through the transmitter
  radio.write(&messageBytes, sizeof(messageBytes));
}

}

////This checks if the plant is getting enough water,//
//by taking a acceptable or unacceptable hydration value 
//from a LDR and prints the value to the serial monitor
//and if the hydration value is acceptable , the yellow LED will turn on
//and blink, if it's not it will print a message to the serial monitor
//to alert you



//********* Note replace POT with hydrometer code*********//
void potCheck(int device,int duration3){

potValue = analogRead(device2);

if(potValue > water_threshold)
{
  Serial.print(potValue);
  Serial.println(water_message1);
  

}

else{
  Serial.println(water_message2);
    
}

}

//This checks if the plant is getting enough water and light
//, if it's not it will print a message to the serial monitor
//to alert you and if it is getting enough it will print a 
//message to the serial monitor telling you the plant is healthy

void healthyCheck(int led_4,int duration4,int duration5){

if((ldrValue >= light_threshold) && (potValue > water_threshold)){
digitalWrite(led_4, HIGH);
Serial.println(healthy_message);
delay(duration4);
}

else{
digitalWrite(led_4,HIGH);
delay(duration5);
digitalWrite(led_4,LOW);
delay(duration5);
Serial.println(unhealthy_message);

}


}



void loop(){

//This calls the function/method

//in loop call transmitter


ldrCheck(LDR, 1000,100 );
sendByteMessage(LDR)
potCheck();
healthyCheck(2000,800);


}




Receiver Code

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>


//Create an rf24 object

RF24 radio(9,8) ; //CE,CSN

//address through which two modules communicate.

const byte address[6]  = "00001";

void setup() {

while(!Serial);
 Serial.begin(9600);

 radio.begin();

 //set the address
 radio.openReadingPipe(0, address);

 //set module as receiver
 radio.startListening();
  
}

void loop() {
  //Read the data if available in buffer
  
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.print(ldrValue);
    Serial.println(light_message);
  }

What specifically do you need help with?

I'm trying to modify original code to work with the transmitter and receiver functionality before I had code that used leds meaning the plant monitor would turn on certain colored LEDs based on condition.Now in V2 of this project i decided to do away with the LED's and make the goal to have communication between the componets from the outside to send messages about the plant status inside where another arduino would print to the serial monitor

I need help with having the transmitter code work with the conditional statements atm I'm confused where to insert the each piece of code so the transmitter sends a message to the receiver and prints in the serial monitor.It should work as the componets take inputs from the environment like the ldr, then that value is stored and applied to if statment , if x is this value then send this message and then the transmitter sends the message to the receiver that prints it to the serial monitor

What have you tried?

I've tried to create a seperate variable for the message I want to send along with the analog sensor values from the ldr.( I've not gotten to the hydrometer yet I only got the wiring for it done) Turn the ldr from int to a string and then call the variable in the byte message function within a function for checking for ldr values. Then in the receiver code i tried testing by writing Serial Print for each value but It's not working and I think its because the value is out of scope.Not in the same sketch.

What do you think the problem is?

I think it may be the order of the code and or syntax,maybe if I put the transmitter code outside of the ldr check function it would work, but im not sure. Could also be that the datatypes are strings and ints and changing that to the bytes isn't as straightfoward as I thought.

The actual build and components

Master ( transmitter ) takes inputs from the environment using a Ldr and hydrometer both water and light values and sends it to the slave microcontroller the receiver, wiring is correct. enter image description here

Slave ( receiver) processes the values from the transmitter and prints them in the serial monitor the messsage it recieves will depend on conditions such as light value thresholds and water value thresholds in simple terms if the light or water values exceed a certain value or are below a certain value it will send a different message for each situation.

enter image description here

7
  • at this time, your post is equivalent to I need help with building a car ... please focus on only one problem ... start with the communication link ... forget all about LEDs, water, and plants ... focus on sending a single byte between the two devices, nothing more
    – jsotola
    May 31, 2023 at 23:32
  • Ok i get the idea of working one step at a time. But i was already able to send message to the transciever and print it to the serial monitor , but when I added the code where I added the conditional if statements it fell apart. That's my issue : Can i send the message using the conditionals? Jun 1, 2023 at 0:16
  • your code is a mess ... it is not formatted properly ... looks like there are extra braces, but it is not immediately evident ... do yourself a favor and format your code and then examine it ... correctly formatted code looks something like this ... programiz.com/cpp-programming/examples/… ... for example, there is no guessing which code executes when an if statement runs ... you should never see two successive closing braces at equal indent level as are in your code
    – jsotola
    Jun 1, 2023 at 2:10
  • I would restructure the code. The transmitter side should regularly collect data from the environment (light value, water value, other health values) and bundle these raw data items into a single fomatted message (C++ struct) for transmission. The receiver, on receiving such a message, unpacks it, interprets it and generates any messages on the display etc. This matches your text description near the pictures but not your code. Incidentally, where in the receiver do the values ldrValue and light_message come from?
    – 6v6gt
    Jun 1, 2023 at 5:32
  • Use Ctrl+T in the IDE to attempt to format the code better. (Tools menu -> Auto Format).
    – Nick Gammon
    Jun 1, 2023 at 7:49

1 Answer 1

2

I figured the issue out.

  1. code was a mess but after troubleshooting it for a while the if statements didn't make sense and had no good flow to them plus too complicated. I had copied and pasted some code without making sense of it.

  2. It worked when I focused on one component like @jstola said. The photoresistor only and so the main thing is to add the conditional then turn string into a byte message and then void loop sends byte message to receiver arduino. Then the next part there were symbols appearing in the serial monitor and that was weird. So I experimented with the char data type instead of string and worked. Also use chatgpt as well for some syntax help.

Now I have base to work from. So next is to tackle the hydrometer.

Transmitter Code - with photoresistor only

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(9, 8); // Create an instance of the RF24 object

const byte address[6] = "00001"; // Set the pipe address

int ldrValue;
int sensorPin = A2;    // Select the input pin for the LDR
int light_threshold = 650;
String light_message = "Plant has enough light :";
String dark_message ="Alert: Plant is Dark! :" ;
String water_message1 = " Plant has enough water.";
String water_message2 = " Need Water...!";
String healthy_message = "Plant is Healthy!";
String unhealthy_message = "Unhealthy...!";


void setup() {
  
  pinMode(sensorPin, INPUT);
  radio.begin();
  radio.openWritingPipe(address);
  radio.stopListening();

}

void loop() {
  ldrCheck(sensorPin, 1000, 100);
}

void ldrCheck(int device, int duration1, int duration2) {
  ldrValue = analogRead(device);

  if (ldrValue >= light_threshold) {
    String message = light_message + String(ldrValue);
    sendByteMessage(message);
    delay(duration1);
  }
  else {
    String message = dark_message + String(ldrValue);
    sendByteMessage(message);
    delay(duration2);
  }
}

void sendByteMessage(String message) {
  byte messageBytes[message.length() + 1];
  message.getBytes(messageBytes, message.length() + 1);
  radio.write(&messageBytes, sizeof(messageBytes));
}  

reciever Code - with photoresistor only

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(9, 8); // Create an instance of the RF24 object

byte address[6] = "00001"; // Set the pipe address

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, address);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    char message[32] = ""; // Create a character array to store the message
    radio.read(&message, sizeof(message));
    processMessage(message);
  }
}

void processMessage(char* message) {
  String receivedMessage = String(message); // Convert the character array to a String
  Serial.println(receivedMessage);
  delay(1000);
}


result:

enter image description here

Video

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.