Noob alert

hi, never used the forum before hopefully I post correctly. I have spent a while perfecting my code to control a greenhouse. it works well, however I think it could be neater. I have been looking at modular code and writing bits from new but im stuggling to take my code and change it to modular. any advice would be appreciated. Thankyou.

it reads sensors for temp, humidity and soil moisture… displays current readings… target values defined by potentiometers… displays target value while potentiometer is moving… turns on output to bring current values up or down to match target vales… 2 day flush cycle to prevent stagnant water.

#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
#include <dht.h>
#define RELAY1 (22)
#define RELAY2 (23)
#define RELAY3 (24)// soil moisture
int idealtemp = 19;
int idealhumidity = 60;
int idealsoilmoisture = 50;
int changetemp = 0;
int changesoilmoisture = analogRead(A4);
int changehumidity = analogRead(A3);
int d_length = 0;
int c = 0;
int temphum = A0;
int soilmoist = A1; // Analog input pin that the Sensor is attached

int sensorValue = 0; // value read from the Soil Moisture
int outputValue = 0;
dht sensor;

void setup()
{
//Serial.begin(57600);
// Initialise the Arduino data pins for OUTPUT
pinMode(RELAY1, OUTPUT);
pinMode(RELAY2, OUTPUT);
pinMode(RELAY3, OUTPUT);
lcd.begin(16, 2); //16 by 2 screen
}

void dlay()
{
delay (172800000);// flushing cycle
digitalWrite(24, HIGH);
delay(300000);
digitalWrite(24, LOW);//finish flush (5 min)
c = 0;
do {
c = c + 1;
delay (1);

changetemp = analogRead(A2);
changetemp = map(changetemp, 0, 1023, 0, 40);
if (changetemp != idealtemp)
do {
idealtemp = changetemp;// save the changed value
//Serial.print(changetemp);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print (“Heater on at:”);
lcd.setCursor(0, 1);
lcd.print(changetemp);
lcd.print(“C”);

changetemp = analogRead(A2);
changetemp = map(changetemp, 0, 1023, 0, 40);
}
while (changetemp != idealtemp);
//////////////////////////////////////////////////////////////////////

c = c + 1;
delay (1);

changehumidity = analogRead(A3);
changehumidity = map(changehumidity, 0, 1023, 0, 100);

if (changehumidity != idealhumidity)
do {
idealhumidity = changehumidity;// save the changed value
//Serial.print(changetemp);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print (“Humidifier on at:”);
lcd.setCursor(0, 1);
lcd.print(changehumidity);
lcd.print("%");

changehumidity = analogRead(A3);
changehumidity = map(changehumidity, 0, 1023, 0, 100);
}
while (changehumidity != idealhumidity);
//

c = c + 1;
delay (1);
////////////////////////////////////////////////////////////////////////////////

c = c + 1;
delay (1);

changesoilmoisture = analogRead(A4);
changesoilmoisture = map(changesoilmoisture, 0, 1023, 0, 100);

if (changesoilmoisture != idealsoilmoisture)
do {
idealsoilmoisture = changesoilmoisture;// save the changed value
//Serial.print(changetemp);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print (“Water on at:”);
lcd.setCursor(0, 1);
lcd.print(changesoilmoisture);
lcd.print("%");

changesoilmoisture = analogRead(A4);
changesoilmoisture = map(changesoilmoisture, 0, 1023, 0, 100);
}
while (changesoilmoisture != idealsoilmoisture);
//

c = c + 1;
delay (1);

// copy and paste above code here
}

while (c != d_length);
delay (500);
}

void loop()

{
d_length = 1500;
dlay();

sensor.read11(temphum);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(“Humidity% =”);
lcd.print(sensor.humidity);
lcd.setCursor(0, 1);
lcd.print("Temp C = ");
lcd.print(sensor.temperature);

d_length = 1500;
dlay();

lcd.clear();
lcd.print(“Soil Moisture:”);// print the results to the LCD Display:
sensorValue = analogRead(soilmoist);// read the analog in value:
outputValue = map(sensorValue, 314, 596, 100, 0); // change for capacitive sensor changed from 101 to 100
lcd.setCursor(0, 1);
lcd.print(outputValue);
lcd.print("%");

changesoilmoisture = analogRead(A4);
changesoilmoisture = map(changesoilmoisture, 0, 1023, 0, 100);

if (changesoilmoisture != idealsoilmoisture)
idealsoilmoisture = changesoilmoisture;// save the changed value

changehumidity = analogRead(A3);
changehumidity = map(changehumidity, 0, 1023, 0, 100);

if (changehumidity != idealhumidity)
idealhumidity = changehumidity;// save the changed value

if ((sensor.temperature) > idealtemp) digitalWrite (RELAY1, HIGH);
if ((sensor.temperature) < idealtemp -2) digitalWrite (RELAY1, LOW);
if ((sensor.humidity) > idealhumidity) digitalWrite (RELAY2, LOW);
if ((sensor.humidity) < idealhumidity - 5) digitalWrite (RELAY2, HIGH);
if ((outputValue) > (idealsoilmoisture -5)) digitalWrite (RELAY3, HIGH);
if ((outputValue) < idealsoilmoisture) digitalWrite (RELAY3, LOW);

//delay (1000); digitalWrite (RELAY3, HIGH);
//delay (1000); digitalWrite (RELAY3, LOW);
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print(“output valaue =”);
//lcd.print(outputValue);

//lcd.setCursor(0, 1);
//lcd.print("soilmoist = ");
//lcd.print(idealsoilmoisture);
//delay(1000);

}

Hey dude, congrats on your first forum post!

You can use

 [.code] to write code in! 
without the full stops of course :P[./code]

I had the same problem, if you look at the millis example on the top of the forum, you'll see how to make stuff modular, just create new functions and call on them when needed!

Hope I helped!

As a new poster to this Forum, you will find it helpful to read "How to use this forum", which is at the top of the Forum list. In particular, please use code tags on your code. There are a number of benefits from this, not the least of which is that your listing will take up less real estate.

mattstrat14:
I have spent a while perfecting my code to control a greenhouse.

you haven't spent much time reading the forum rules, it would seem... :slight_smile:

start there --> Planning and Implementing a Program

Read about functions, that would already help clean up and structure the code


Please read the forum rules and correct your post above and add code tags around your code:
[code]`` [color=blue]// your code is here[/color] ``[/code].

It should look like this:// your code is here
(Also press ctrl-T (PC) or cmd-T (Mac) in the IDE before copying to indent your code properly)

And get rid of delay() calls.

Non-blocking timing tutorials:
Several things at a time.
Beginner's guide to millis().
Blink without delay().

void dlay()
{
  delay (172800000);// flushing cycle

Do nothing for 48 hours ?
The dlay() function is called twice from loop() so effectively the code spends most of its time doing nothing. Is that what you want ?

im stuggling to take my code and change it to modular.

Do you mean that you want to split into functions ? It looks like it would lend itself to being written as a state machine with meaningful state names which would make it easier to understand and maintain

Why have you posted this question twice

TOPIC MERGED.

You may want to READ THIS for future reference.
It will help you get the best out of the forum.

Bob.

You have several blocks of code that basically do the same thing, read an analog pin waiting for an ideal setting. The things that change from block to block are the pin number, the maximum value used in map(), the ideal setting and the strings that are printed to the LCD.

If you put all the redundant code in a function, passing in the things that change, it will reduce the amount of code and make it easier to read and maintain.

int getVal(byte pinNum, int maxVal)
{
  int val = analogRead(pinNum);
  return (map(val, 0, 1023, 0, maxVal) );
}

void setIdeal(byte pinNum, int maxVal, int idealVal, char *str, char *unit)
{
  int val = getVal(pinNum, maxVal);

  while ( val != idealVal)
  {
    idealVal = val;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(str);
    lcd.print (" on at:");
    lcd.setCursor(0, 1);
    lcd.print(val);
    lcd.print(unit);
    val = getVal(pinNum, maxVal);
  }
}

Then you would call the function like this:

setIdeal(A2, 40, idealtemp, "Heater", "C");

BTW, I don't understand what your code is doing. For example, the variable idealtemp is initialized to 19. In the do while loop the first line of code overwrites that value.

    if (changetemp != idealtemp)
      do {
        idealtemp = changetemp;// save the changed value

So from then on the temp is not compared to 19 but to the previous value read. How does that work?

UKHeliBob

That is what I would like to do, I didn't know I was called state machine but basically cant find how to separate it into sections that still run properly with lcd.. I recently added the flushing cycle by running code on separate Arduino and checking it flashed the built in LED. Haven't yet uploaded to active system.

I will look at the suggested threads

Blue Eyes

thankyou for the advice, ill give it a try :). The ideal temp variable was set with the idea that when first switched on before the potentiometer moved and gave a signal it would use the variable defined as idealtemp etc. Sort of a factory setting

To write a program as a state machine the first thing to do is to list the states that it can be in. For each state describe what should happen such as "wait until an input goes HIGH", "wait for user input", "stay in the current state for 5 seconds" etc. Then for each state describe what needs to happen to cause a change of state, what state the program should move to as a result and the things that must be set up before entering the next state such as saving the current time when the target state involves timing.

This may sound daunting but it makes you think logically about what you need to do and when. Note that you can have 2 or more state machines running at the same time doing different, independent actions but none of the code must block the free running of the loop() function