looking for input on my automated grow box sketch

#include <DHT.h>
#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
// hum = dht.readHumidity();   temp= dht.readTemperature();


unsigned long currentMillis;
unsigned long lightingMillis;//for timing grow lights
unsigned long soilMillis = (1000 * 60 * 60 * 6); //for timing soil sensor reads
unsigned long uvMillis;//for timing uv light
unsigned long solenoidMillis;//for timing water on duration
unsigned long tempMillis;
unsigned long lightCycle = (1000 * 60 * 60 * 12); //12on 12off
unsigned long soilCycle = (1000 * 60 * 60 * 12); //check soil every 12 hours
unsigned long tempCycle = (1000 * 10);
int soilMoistureSetpoint = 0;

int fanPin = 0; // for controlling fan relay
int lightingPin = 0; // for controlling lightinh relay
int solenoidPin = 0; // for controlling watering relay
int soilPinD = 0; // digital soil pin, for supplying vcc to soil sensor
int soilPinA = 0; // analog soil pin
int soilCapButPin = 0; // for a button to capture soil setpoint
int soilCapIndPin = 0; // for led to indicate soil setpoint capture
int uvPin = 0; // for controlling uv relay

void setup()
{
  dht.begin();
  pinMode (fanPin, OUTPUT);
  pinMode (lightingPin, OUTPUT);
  pinMode (solenoidPin, OUTPUT);
  pinMode (soilPinD, OUTPUT);
  pinMode (soilPinA, INPUT);
  pinMode (soilCapButPin, INPUT);
  pinMode (soilCapIndPin, OUTPUT);
  pinMode (uvPin, OUTPUT);
}

void loop()
{

  currentMillis = millis();
  ControlGrowLights();//ready for test
  ControlWateringSystem();//ready for test
  ControlTemp();

}

void ControlGrowLights()
{
  if (currentMillis - lightingMillis >= lightCycle)//if it has been 12 hours since the lights have been toggled
  {
    lightingMillis = currentMillis;//record current time for future light toggle
    digitalWrite(lightingPin, !digitalRead(lightingPin));// toggle lights
    if (digitalRead(lightingPin))
    {
      ControlUVLight();
    }
  }
}
void ControlWateringSystem()
{
  CaptureSoilMoistureSetpoint();//checks for button press, if yes debounces and waters plant

  if (currentMillis - soilMillis >= soilCycle) //if it has been 12 hours since the soil humidity has been measured
  {
    if (SoilMoisture() < soilMoistureSetpoint)//and if soil moisture is too low
    {
      WaterPlant();
    }
    soilMillis = currentMillis; //reset soil timer
  }
}


int SoilMoisture()
{
  digitalWrite(soilPinD, HIGH);
  delay(25);
  int soilReading = analogRead(soilPinA);
  digitalWrite(soilPinD, LOW);
  return soilReading;
}
void CaptureSoilMoistureSetpoint()
{
  for (int x = 0; digitalRead(soilCapButPin); x++)
  {
    if (x = 50)
    {
      soilMoistureSetpoint = SoilMoisture();
      digitalWrite(soilCapIndPin, HIGH);
      delay(1000 * 3);
      digitalWrite(soilCapIndPin, LOW);
      WaterPlant();
    }
  }
}
void WaterPlant()
{
  digitalWrite(solenoidPin, HIGH);    //|
  delay(1000 * 20);                     ////  water the plant
  digitalWrite(solenoidPin, LOW);    ///
}

void ControlTemp()
{
  int currentTemp = 0;
  int tempHighSetpoint = 90;
  int tempLowSetpoint = 75;
  if (currentMillis - tempMillis >= tempCycle)
  {
    currentTemp = CheckTemp();
    if (currentTemp >= tempHighSetpoint)
    {
      digitalWrite(fanPin, HIGH);
    }
    if (currentTemp <= tempLowSetpoint)
    {
      digitalWrite(fanPin, LOW);
    }
    tempMillis = currentMillis;

  }
}
int CheckTemp()
{
  int temp = dht.readTemperature();
  temp = temp * 1.8 + 32; //converty to farenheit
  return temp;

}
void ControlUVLight()
{
  digitalWrite(uvPin, HIGH);
  delay(1000 * 5);
  digitalWrite(uvPin, LOW);
}

I am building an automated grow box. The code I have written is posted above. Just looking for someone to say “looks like that will work,” or point out anything that looks like it won’t work.

the main things I am trying to accomplish are:
provide a 12 on 12 off light cycle
turn on a uv light for 5 seconds everytime the light cycles switches to 12 on
monitor soil moisture with a simple two probe, DIY resistive soil moisture sensor
add water when needed
use a fan to ventilate the tent when temps get too high
set the soilMoistureSetpoint with a button press when plant needs watering for the first time

let me know if you want more info on the hardware end, I have written the code so I can assign the actual pin numbers as I wire everything together. I have a simple 4 chanel relay modual to control 120v power. I intend to hook those up to recepticals as I am using typical plug in household appliances. I will also use a threeway switch to bypass the lighting relay so i can have 24 hours on if needed.

thank you

one question i have is do I need to declare a pinmode for the dht pin or is that taken care of in the dht library?

I certainly hope you have written programs or used examples to exercise each of your peripherals one a time so you understand how they operate individually.

Paul

I tried building one a while back that was much more extensive, it worked well enough for a plant to grow from seed to 2 ft or so, but the light schedule never switched like i wanted it to, i think i was querying my co2 sensor way to fast, and i never finished the grow. this is my attempt to scale back so i can add more features later. the only thing I don’t really understand well in this one is the dht11. however i will have a seperate temp gauge to monitor that the fan is keeping temps down.

one question i have is do I need to declare a pinmode for the dht pin or is that taken care of in the dht library?

Have you looked at the examples in the library?

i have, the dht library examples are hard for me to follow. i do notice that they use floats where i used an int, I'm hoping it will just round for me as I don't need that kind of resolution. i suppose i should probably play around with the temperature sensing part a bit seperately.

roosterqmoney:
I am building an automated grow box. The code I have written is posted above. Just looking for someone to say "looks like that will work," or point out anything that looks like it won't work.

So what happens when you upload it on an Arduino board and let it do its thing?

still need to put the hardware side together, need a few unforseen electrical components. im about 80% done with the project, will put you tube video up when it's ready to harvest in 13 weeks assuming it works. the ultimate end goal is to do a diy video on how to build an automated cannabis grow set up for less than $100

update for those that are interested, I "finished" the hardware side and my uv light is always on, and my lighting changes state every 12 seconds. I think i need to set the uv low in setup and i will also make sure the lighting is low in setup. haven't tested watering functionality yet, that will be last. Anyone have any idea why lighting is on a 12 second cycle instead of a 12 hr cycle?

The fan and dht11 are working together well, just need to get lighting sorted out and start the test run.

I started to show delay removal in the functions that were called from nested positions in other functions but most of the code is like that.

For example, ControlWateringSystem() gets called by void loop(), can use millis timing.
But CaptureSoilMoistureSetpoint(), SoilMoisture() and WaterPlant() can’t, so they have delays.

void ControlWateringSystem()
{
  CaptureSoilMoistureSetpoint();//checks for button press, if yes debounces and waters plant

  if (currentMillis - soilMillis >= soilCycle) //if it has been 12 hours since the soil humidity has been measured
  {
    if (SoilMoisture() < soilMoistureSetpoint)//and if soil moisture is too low
    {
      WaterPlant();
    }
    soilMillis = currentMillis; //reset soil timer
  }
}


int SoilMoisture()
{
  digitalWrite(soilPinD, HIGH);
  delay(25);
  int soilReading = analogRead(soilPinA);
  digitalWrite(soilPinD, LOW);
  return soilReading;
}

void CaptureSoilMoistureSetpoint()
{
  for (int x = 0; digitalRead(soilCapButPin); x++)
  {
    if (x = 50)
    {
      soilMoistureSetpoint = SoilMoisture();
      digitalWrite(soilCapIndPin, HIGH);
      delay(1000 * 3);
      digitalWrite(soilCapIndPin, LOW);
      WaterPlant();
    }
  }
}

void WaterPlant()
{
  digitalWrite(solenoidPin, HIGH);    //|
  delay(1000 * 20);                     ////  water the plant
  digitalWrite(solenoidPin, LOW);    ///
}

CaptureSoilMoistureSetpoint(), SoilMoisture() and WaterPlant() need to run in void loop().

The sensor readers should have associated global int variables that they update whenever they run.
The sensor readers should run at regular times, like at least 10 seconds apart?

WaterPlant() should have an associated global byte or int variable, make as small as needed.
When another function sets that value > 0, water the plant perhaps as long as the value.
WaterPlant() can decrement or zero the variable to shut off, ANY function can trigger or stop WaterPlant().
WaterPlant() should run all the time. if ( doWater > 0 ) …

Change ControlWateringSystem() to read the sensor variables instead of running the sensors.
Change ControlWateringSystem() to set the water variable instead of running WaterPlant().

Then – all those parts can use millis timing to ditch the delays. There are more but if you see how using
variables to pass data and control between tasks running void loop() to break dependencies between
tasks, you can rearrange your own code. The sensors are free to read as often as they should, the water
can be shut off by a button/task and you have cycles left over to do 300 other things.

PS tips:
don’t use an int where a byte would do.
you can time 250ms with 1 byte timers. 1 byte where unsigned long is most used.