Slow response - how to improve . . ?

Hello to all,

i have been writing some codes about a greenhouse project and testing them in parallel part by part.

The level i reached is :

Im using 4 soil moisture probe connected to 2 DO doing the alternate current thing and 4 AI to get the reading in percentage.

I get an LDR, with some code writing, to display light in LUX (not accurate)

Push Button to swap menu on LCD for the displaying of the above readings of soil moisture and Lux reading.

Later i shall interpret Output status when i will be connecting and doing the part for the output.

I like to share my code in the forum here as well as getting an idea where i stand . . :slight_smile: :slight_smile:

Actually when i press my button to swap menu on the lcd, it takes me about almost 5 seconds to be holding the button for the 1 Menu to change.

Is there any way to adapt a faster response without adding another push button becoz im out of inputs, as i have to cater for outputs to connected Pump and Ventillation Fan.

Here is the code : due to exceeding max number of characters, i cut some part of my code, the function block int SoilMoisture () is repeated 4 times due to the presence of 4 soilmoisture probe. hope it is still comprehensive :slight_smile:

/* 
 Soil Mositure probe Callibrated at 100% with water (H20)
 
/* Declaration of I/Os */

  #define moisture_input 1        // Analog Input pin 1 connected to collect Soil Moisture reading.
  #define LDR_input 2             // Analog Input pin 2 connected to read Light Intensity from Ambient environment.
  #define Moisture_Input1 3        // Analog Input pin 3 connected to Collect Soil Moisture reading
  #define Moisture_Input2 4        // Analog Input pin 4 connected to Collect Soil Moisture reading
  #define Moisture_Input3 5        // Analog Input pin 5 connected to Collect Soil Moisture reading
  #define SwapButton 4            // Digital pin 4 Push Button connected - Purpose : To sawp menu on LCD screen.
  #define dcSource_top 13         // Power source 5V top connected to digitsl pin 13
  #define dcSource_bottom 12      // Power Source 5V bottom connected to digital pin 12
  #define Pump 3                  // Irrigation Pump connected to digital pin 3
 

/* Library Code to be included */

#include <LiquidCrystal.h>      // include the library code:

/* Declaration Of Variables */

   int moisture;                 // Analogical value obtained from the experiment S.probe 1
   int Moisture1;                // Analogical value obtained from the experiment S.probe 1
   int Moisture2;                // Analogical value obtained from the experiment S.probe 1
   int Moisture3;                // Analogical value obtained from the experiment S.probe 1
   int val;                      // Variable for reading the pin status to compare with buttonState
   int val2;                     // Variable to read the debounced status
   int buttonState;              // Variable to hold the last button state
   int lcdMode = 0;              // Variable to store different Modes to swap between LCD menu.
   int Lux;                      // 
   int Luminosity;
   
   float RLDR;
   float Vout;
   
   double PercentMoisture;      // Varible to store % Percentage Soil Moisture Value
   double PercentMoisture1;
   double PercentMoisture2;
   double PercentMoisture3;
  

LiquidCrystal lcd(11, 10, 9, 8, 7, 6, 5);   // Initialize the library with the numbers of the interface pins


void setup (void) {
  
  Serial.begin(9600);                       // Set up Serial Communication at 9600 bps.
  
  pinMode(Pump,OUTPUT);                     // Define Digital Pin as output
  
  pinMode(SwapButton,INPUT);                // Define Digital Pin as Input    
  buttonState = digitalRead(SwapButton);    // Read the initial state and save into buttonState.


  lcd.begin(16,2);                          // Rows, columns. use 16,2 for a 16x2 LCD.
  lcd.clear();                              // Start with a blank screen
  lcd.setCursor(0,0);                       // Set cursor to column 0, row 0
}

int SoilMoisture(){
  
  // Variable to hold value from Moisture input.
  int reading;
 
  
  // Set driver pins to outputs
  pinMode(dcSource_top,OUTPUT);
  pinMode(dcSource_bottom,OUTPUT);

  // Drive a current through the divider in one direction
  digitalWrite(dcSource_top,LOW);
  digitalWrite(dcSource_bottom,HIGH);

  // Wait a moment for capacitance effects to settle
  delay(1000);

  // Take readings
  
  reading = analogRead(moisture_input);


  // Reverse the current
  digitalWrite(dcSource_top,HIGH);
  digitalWrite(dcSource_bottom,LOW);

  // Give as much time in 'reverse' as in 'forward'
  delay(1000);

  // stop the current
  digitalWrite(dcSource_top,LOW);

  return reading;

}

void LCDprintMenu (void) {
  
  lcd.clear();
  lcd.print("Tazlim -- GrnHse");
  lcd.setCursor(0,1);
  lcd.print("  EngineerinG");
}


void LCDprintSoilMoist(void) {

 lcd.clear();
 lcd.print("SoilMoisture");
 lcd.setCursor(0,1);
 lcd.print("Percentge:");
 lcd.print(PercentMoisture);
 lcd.print("%");
}

void LCDprintSoilMoist1(void) {

 lcd.clear();
 lcd.print("SoilMoisture 1");
 lcd.setCursor(0,1);
 lcd.print("Percentge:");
 lcd.print(PercentMoisture1);
 lcd.print("%");
}

void LCDprintSoilMoist2(void) {

 lcd.clear();
 lcd.print("SoilMoisture 2");
 lcd.setCursor(0,1);
 lcd.print("Percentge:");
 lcd.print(PercentMoisture2);
 lcd.print("%");
}

void LCDprintSoilMoist3(void) {

 lcd.clear();
 lcd.print("SoilMoisture 3");
 lcd.setCursor(0,1);
 lcd.print("Percentge:");
 lcd.print(PercentMoisture3);
 lcd.print("%");
}


void LCDprintLux (void){
  lcd.clear();
  lcd.print("Light Intensity");
  lcd.setCursor(0,1);
  lcd.print(" : "); 
  lcd.print (Luminosity);
  lcd.print ("LUX");
  
}
  
void PumpControl (){
  
if (PercentMoisture <= 60.00)
    {digitalWrite (Pump,HIGH);}
    
    else {
    
    if (PercentMoisture >= 90.00)
       {digitalWrite (Pump,LOW);}
    }
  
}

void SwapMenu (void){
  
// Push Button connected to PIN 4 by Pull up resistor Circuit for swapping Menu on LCD
 
  val = digitalRead(SwapButton);   // Read Input value and store in val.
  delay(10);
  val2 = digitalRead(SwapButton);  // Read Input again to check for bounces
  
  if (val == val2){
    
    if(val != buttonState){
      
      if (val == LOW){
        
        if (lcdMode == 0)
            {lcdMode = 1;}             // Execute LCDprintSoilMoist().
        
      else{
       
        if (lcdMode == 1)            
           {lcdMode = 2;}              // Execute LCDprintMenu().
                          
                          
      else {
      
        if (lcdMode == 2)
           {lcdMode = 3;}    
       
      else {
 
        if (lcdMode == 3)
           {lcdMode = 4;}
         
      else {
 
        if (lcdMode == 4)
           {lcdMode = 5;}
        
      else {
 
        if (lcdMode == 5)
            {lcdMode = 0;}   
      
        }  
       }
      }  
     }
    }
   }
      
  buttonState = val;               // Save the new state in the Variable for monitoring further button press (Continuous program loop). 
 }  
}      
       
       if (lcdMode == 0)
             {LCDprintMenu();}                                               // Display Intro Display on the LCD.
      
       if (lcdMode == 1)
             {LCDprintSoilMoist();}                                          // Display SoilMoist Reading in %
      
       
       if (lcdMode == 2)
             {LCDprintSoilMoist1();}
       
       
       if (lcdMode == 3)
             {LCDprintSoilMoist2();}
       
       if (lcdMode == 4)
             {LCDprintSoilMoist3();}
       
       if (lcdMode == 5)
             {LCDprintLux();}                                                //Display Light Intensity in LUX
   
}

int LightSensorLDR (void){
  
  int ADC;

  ADC = analogRead (LDR_input); 
 
  Vout = (ADC * 0.0048828125);           // Vout = Output voltage from potential Divider. [Vout = ADC * (Vin / 1024)] 

  RLDR = (10.0 * (5 - Vout))/Vout;     // Equation to calculate Resistance of LDR, [R-LDR =(R1 (Vin - Vout))/ Vout]
   // R1 = 10,000 Ohms , Vin = 5.0 Vdc.
                                     
  Lux = (500 / RLDR);  
  
  return Lux;
  
}  
  
void loop (void) {
 
  SwapMenu();
  
  Luminosity = LightSensorLDR();
 
  moisture=SoilMoisture();         // assign the result of SoilMoisture() to the global variable 'moisture'
  Moisture1=SoilMoisture1();      // assign the result of SoilMoisture 1() to the global variable 'Moisture1'
  Moisture2=SoilMoisture2();      // assign the result of SoilMoisture 2() to the global variable 'Moisture2'
  Moisture3=SoilMoisture3();      // assign the result of SoilMoisture 3() to the global variable 'Moisture3'
   
  PercentMoisture  = ((moisture/950.00)*100.00); // Derivation of Soil Moisture in %
  PercentMoisture1 = ((Moisture1/950.00)*100.00); 
  PercentMoisture2 = ((Moisture2/950.00)*100.00);
  PercentMoisture3 = ((Moisture3/950.00)*100.00);
   
}

[\code]

Thanks

taz

The SoilMoistureN() function has two one seconds delay()s. You call it 4 times. Those 4 calls will take 8 seconds to complete. Meanwhile, your switch is not being read.

One second seems like an awfully long time.

You could read the switch state after each call to SoilMoistureN().

Why do you need 4 nearly identical functions. One would do, if the pin numbers were passed in. Then, you could call the one function in a for loop, testing the switch state after each iteration.

The SwapMenu() code is ridiculous. Testing to see what value lcdMode has before incrementing it is silly. Just increment is, whatever value it has. Then, test to see if it is out of range. Fix it, it if is.

 if (lcdMode == 4)
           {lcdMode = 5;}

Is anyone else seeing a simple arithmetic series here?

Re-design the program after looking at

a. "blink without delay"

b. Finite State Machines, in the playground

c. button de-bouncing

Mark

Also the use of arrays can simplify the code as you have four times the same measurements.

   int moisture[4];   
   double PercentMoisture[4]; 

...
// this function takes the nr of the sensor as parameter
// printing its number and its percentage
void LCDprintSoilMoist(int i) 
{
  lcd.clear();
  lcd.print("SoilMoisture");
  lcd.print(i, DEC);
  lcd.setCursor(0,1);
  lcd.print("Perc:");
  lcd.print(PercentMoisture[i], 1);
  lcd.print("% ");
}

...
// somewhere in loop
for (int i = 0; i< 4; i++)
{
  moisture[i]  = SoilMoisture(i);  
  PercentMoisture[i]  = moisture[i]/9.5; // all math in one step
}

int SoilMoisture(int i) is a function that needs to be rewritten to but with the above +
the info about arrays in the tutorial section you should be able to figure it out.

Succes

Well your lux calculation is wrong, for a start.

You need to re-read the description of how the light-sensitive device works, and how it is approximately
linear on a log-log scale. It's the last bit of that sentence, I think you didn't understand.

Hello to all,

I would like to state that im still a noob and trying to learn as much as it needs to continue my progress with the Arduino.

Thanks for your prompt reply, i appreciate all your comments, that make me more motivated to go on further to improve my code and learn more and more. Thanks again. . :wink:

PaulS:
You could read the switch state after each call to SoilMoistureN().

Im i correct, if in the void loop, i place the SwapMenu() after each MoistureN = SoilMoistureN(); ? I.e using in all 4 SwapMenu(); ??

Why do you need 4 nearly identical functions. One would do, if the pin numbers were passed in. Then, you could call the one function in a for loop, testing the switch state after each iteration.

Im actually testing the soil moisture percentage for 4 different variety of plants, i shall conclude if they consume almost the same amount of water per day.

According to what you said about passing the pin numbers and calling a for loop, can you kindly please explain a little more so that i can grasp the max and try to implement it.

The SwapMenu() code is ridiculous. Testing to see what value lcdMode has before incrementing it is silly. Just increment is, whatever value it has. Then, test to see if it is out of range. Fix it, it if is.

I shall try to perform this increment algorithm, will keep thing posted to see if im on the right track.

robtillaart:
Also the use of arrays can simplify the code as you have four times the same measurements.

int SoilMoisture(int i) is a function that needs to be rewritten to but with the above +
the info about arrays in the tutorial section you should be able to figure it out.

I Shall consult the array tutorial and come back here for clarifications if needed, and im sure i will need those.

michinyon:
Well your lux calculation is wrong, for a start.

You need to re-read the description of how the light-sensitive device works, and how it is approximately
linear on a log-log scale. It's the last bit of that sentence, I think you didn't understand.

It seems i did not much understand the linear on a log-log scale, but i presumed it was for data logging, and i wrong, can you please guide me on this issue.

Thanks

taz3m:
I shall try to perform this increment algorithm, will keep thing posted to see if im on the right track.

The "increment algorithm"? As in, adding one to a variable?

Hello,

I have been through the tutorial for Arrays and For loop, that indeed will simplify several things.

Im in the process of rewriting my code, i shall keep things posted to know if im on the right track.

Can you please clarify these for me :

lcd.print(i, DEC);

lcd.print(PercentMoisture[i], 1);

Thanks

taz . .

Can you please clarify these for me :

Sure. You tell us what is not clear, and we'll clear that up.

lcd.print(i, DEC);

Display the integer value "i" in DECimal (the default)

lcd.print(PercentMoisture[i], 1);

Assuming "PercentMoisture" is a floating-point value, display it with one place of decimals after the point.

taz3m:
Can you please clarify these for me :
...

Add egg whites?

lcd.print(i, DEC);
Display the integer value "i" in DECimal (the default)

It is only explicitly needed when i is a unit8_t or byte as then the print() method is ambiguous (can be resolved in multiple ways by the compiler)

Hello,

Seems you did not like the phrase about clarification . . sorry about that . . :%

Im getting an error while compiling this code . .

Error Code :

Rev_05_Array_for_SoilMoist.cpp: In function 'int SoilMoisture(int)':
Rev_05_Array_for_SoilMoist:49: error: expected primary-expression before '[' token
Rev_05_Array_for_SoilMoist:49: error: expected primary-expression before ']' token
Rev_05_Array_for_SoilMoist:49: error: expected primary-expression before '{' token

Thanks

Taz
/* Declaration of I/Os */

  #define moisture_input [] = {1,3,4,5}        // Analog Input pin 1 connected to collect Soil Moisture reading.
  #define LDR_input 2                          // Analog Input pin 2 connected to read Light Intensity from Ambient environment.
  #define SwapButton 4                         // Digital pin 4 Push Button connected - Purpose : To sawp menu on LCD screen.
  #define dcSource_top 13                      // Power source 5V top connected to digitsl pin 13
  #define dcSource_bottom 12                   // Power Source 5V bottom connected to digital pin 12
  #define Pump 3                               // Irrigation Pump connected to digital pin 3
 

/*--------------------------------------------------------------------*/

   
   int Moisture[4];                 // Analogical value obtained from the experiment S.probes (1,2,3,4)
   int val;                      // Variable for reading the pin status to compare with buttonState
   int val2;                     // Variable to read the debounced status
   int buttonState;              // Variable to hold the last button state
   int lcdMode = 0;              // Variable to store different Modes to swap between LCD menu.
   int Lux;                      // 
   int Luminosity;
   
   float RLDR;
   float Vout;
   
   double PercentMoisture[4];      // Varible to store % Percentage Soil Moisture Value for S.probe (1,2,3,4)


int SoilMoisture(int i){
  
   
  // Variable to hold value from Moisture input.
  int reading[4];
 
  
  // Set driver pins to outputs
  pinMode(dcSource_top,OUTPUT);
  pinMode(dcSource_bottom,OUTPUT);

  // Drive a current through the divider in one direction
  digitalWrite(dcSource_top,LOW);
  digitalWrite(dcSource_bottom,HIGH);

  // Wait a moment for capacitance effects to settle
  delay(1000);

  // Take readings
  
  for (int i=0; i<4; i++)
  {
  reading[1] = analogRead(moisture_input[i]);
   //return reading[i];  
    }


  // Reverse the current
  digitalWrite(dcSource_top,HIGH);
  digitalWrite(dcSource_bottom,LOW);

  // Give as much time in 'reverse' as in 'forward'
  delay(1000);

  // stop the current
  digitalWrite(dcSource_top,LOW);

  

}
#define moisture_input [] = {1,3,4,5}

What's that?

try to get the application right for 1 sensor first. Then increase it to multiple sensors and then use array's.

Also read the book Kerningham & RItchie C language 2nd edition. "Worth its weight in brains"

hello,

I found that by using

#define moisture_input [] = {1,3,4,5}

whereby i was defining analog pin 1,pin 3, pin 4, pin 5 to be used to collect information from soil moisture probes.

Instead when i use

int moisture_input [] = {1,3,4,5};

It do compiles . .

whereby i was defining analog pin 1,pin 3, pin 4, pin 5

No, you weren't. You were defining a strange macro.
Do the substitution, and you'll see why the compiler complained.

robtillaart:
try to get the application right for 1 sensor first. Then increase it to multiple sensors and then use array's.

I already try the application for 1 sensor, it did work . . thats why i would like to extend to 4 now.

Anyway thanks for the reference book .

taz ..

AWOL:
Do the substitution, and you'll see why the compiler complained.

Which thing do i need to substitute . . ??