Go Down

Topic: (1000 * 60 * 60 * 12)=12 seconds when program runs? (Read 359 times) previous topic - next topic

roosterqmoney

Code: [Select]
unsigned long lightCycle = (1000 * 60 * 60 * 12); //check soil every 12 hours

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();
    }
  }
}


I am trying to control a light via a relay connected to a digital pin on my arduino uno.

that is the code I am using. I'd like the light to switch state every 12 hours problem is it is changeing state every 12 seconds.

not sure what is wrong. entire code posted below.


Code: [Select]
#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 = 10;

int fanPin = 8; // for controlling fan relay
int lightingPin = 5; // for controlling lightinh relay
int solenoidPin = 7; // for controlling watering relay
int soilPinD = 12; // digital soil pin, for supplying vcc to soil sensor
//int A0 = 0; // analog soil pin
int soilCapButPin = 9; // for a button to capture soil setpoint
int soilCapIndPin = 13; // for led to indicate soil setpoint capture
int uvPin = 2; // for controlling uv relay

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

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(A0);
  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);
}



jremington

#1
May 14, 2018, 02:50 am Last Edit: May 14, 2018, 02:51 am by jremington
Try
Code: [Select]
unsigned long lightCycle = (1000UL * 60 * 60 * 12); //check soil every 12 hours
The default for numeric calculations is 16 bit integer.

DrAzzy

You are getting integer math'ed - unless specified otherwise, numeric constants are ints - 16-bit signed integers - so the math is done with 16-bit int's, even though you're assigning the result to an unsigned long.

So the 1000 * 60 * 60 * 12 overflows, and works out to only 11776 (about 12 seconds)

Change it to 1000UL * 60 * 60 *12 to force it to do the intermediate calculations as unsigned longs, and you'll get the right result.
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy


Go Up