check pump control

Can someone check my program and tell me if i am approaching this in the correct manner?

LDR looks for a certain light level and if it is day then one timing program runs and if night then the other timing applies.
During the off cycle on either, an LED flashes to show the system is still alive.

Board is the mini 328 clone.
Yet to write the timing but I have seen where using millis is best but I am still a bit green on this.

Thanks...Jorgo

//......Version_04.....26/7/2014
//Timer for running a pump for hydrophonics in 2 different modes. 
//modeOne will run in the daytime and modeTwo will run at night.
//control will look for input from a daylight sensor and if say for example(1.5V) so .0049*1.5= approx 300  <=300(set between 0 and 1023)then pump will run in night mode.
//note....sensor volltage goes down as it gets darker.
//Daytime (dRun and dDelay) will be ON for 60 minutes(60*60*1000) and OFF for 15 minutes(15*60*1000).
//Nighttime (nRun and nDelay) will be ON for 30 minutes (30*60*1000) and OFF for 30 minutes(30*60*1000).
//with either, a led will flash on the "delay" period to show the system is still working.
//Later addition may be LCD with times counting as total_run(tRun) or total_delay(tDelay) time.
//Program uses millis() to track time.

unsigned long dRun = 3600000UL;  //day run time
unsigned long dDelay = 900000UL; //day delay time
unsigned long nRun = 1800000UL;  //night run time
unsigned long nDelay =1800000UL; //night delay time
int delayLed=13;               //Delay LED indicator
int pumpPin=12;               //pump relay via transistor 
int sensorPin=A0;             //Light dependant resistor
int sensorValue=0;            //variable for the sensor value storage
int dayLed=10;                // used so person can see LDR is working
int nightLed=9;               // same as above



int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 100;           // interval at which to blink (milliseconds)





void setup()
{
  pinMode(delayLed,OUTPUT);      //lit when delay is on to show unit still operating
  digitalWrite(delayLed,LOW);    
  pinMode(pumpPin,OUTPUT);      //pump relay connected through transistor
  digitalWrite(pumpPin,LOW);
  pinMode(dayLed,OUTPUT);      //lit when day running
  pinMode(nightLed,OUTPUT);    //lit when night running
}




void loop()
{
  //timeOut();                //tests the delay LED working at time of writing...rem out when finished
  sensorValue = analogRead(sensorPin);  //read the sensor and put the value into sensorValue
    if (sensorValue<=300)
{
    nightRun();              //jump to nightRun times
}

    else 
    dayRun();                //or else jump to dayRun times
}






void nightRun()
{
    //millis code to go here
  
  
  
    if (pumpPin==LOW)
{
    timeOut();
  }
  
}  
  



void dayRun()
{
    //millis code to go here
  
  
  
    if (pumpPin==LOW)
{
    timeOut();
}
  
}





void timeOut()
{
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) 
  {
  previousMillis = currentMillis;            // save the last time you blinked the LED

    if (ledState == LOW)                      // if the LED is off turn it on and vice-versa:
      ledState = HIGH;
    else
      ledState = LOW;                                            
    
 digitalWrite(delayLed, ledState);        // set the LED with the ledState of the variable:
 
  }
  
}

what would help is using CTRL-T to reindent the code which make is more readable.

at first sight I think you are in the good direction.
You seem to layer the architecture and do some "separation of concerns" which is good.

try to use better variable names that explain the function ==> less comments

example:

unsigned long dRun = 3600000UL; //day run time
unsigned long dDelay = 900000UL; //day delay time

==>

unsigned long dayRunTime = 60 * 60 * 1000UL;
unsigned long dayDelayTime = 15 * 60 * 1000UL;

Note compiler will do above math compile time.

The great thing about the Arduino system is that it is so eaasy to try things out.

While you are developing your program you could substitute an LED for the pump and reduce the times to a few seconds so that you don't have to wait forever to see if your code works. That's one attraction of using @robtillart's approach to defining the timing - it is easy to see what it represents so, for example, you know that you have the test values in place rather than the real ones.

This demo several things at a time might help to illustrate the use of millis().

...R

Thank for the replies.....

Not sure what CTRL-T does but I will give it a try.......do you mean after things like void loop () ..??

Had planned on doing substitutes as suggested but went searching for my breadboard and after an hour of searching I remembered it went out in all the other "flood damage stuff" last year.
New one on the way.

Will look at millis demo also...very interested in this particular subject at present ..
Thanks again....Jorgo

CTRL-T does only work on windows, don't know for Mac/linux

Menu -> Tools -> Autoformat does the trick

robtillaart:
unsigned long dayRunTime = 60 * 60 * 1000UL;
unsigned long dayDelayTime = 15 * 60 * 1000UL;

Note compiler will do above math compile time.

Thanks...I was not aware the compiler converted this, incorrectly assumed it would be calculated by the processor.

In my code below I have used the "millis()" approach in both the day and night running.

Will one or the other timing be upset using this arrangement i.e. will the "oldMillis = nowMillis" not work in this instance.

Still waiting for new breadboard to come before i can do any practical...sorry.

//......Version_04.....26/7/2014
//Timer for running a pump for hydrophonics in 2 different modes. 
//modeOne will run in the daytime and modeTwo will run at night.
//control will look for input from a daylight sensor and if say for example(1.5V) so .0049*1.5= approx 300  <=300(set between 0 and 1023)then pump will run in night mode.
//note....sensor volltage goes down as it gets darker.
//Daytime (dRun and dDelay) will be ON for 60 minutes(60*60*1000) and OFF for 15 minutes(15*60*1000).
//Nighttime (nRun and nDelay) will be ON for 30 minutes (30*60*1000) and OFF for 30 minutes(30*60*1000).
//with either, a led will flash on the "delay" period to show the system is still working.
//Later addition may be LCD with times counting as total_run(tRun) or total_delay(tDelay) time.
//Program uses millis() to track time.

unsigned long dRun = 60*60*1000UL;  //day run time
unsigned long dDelay = 15*60*1000UL; //day delay time
unsigned long nRun = 30*30*1000UL;  //night run time
unsigned long nDelay =30*30*1000UL; //night delay time
int delayLed=13;               //Delay LED indicator
int pumpPin=12;               //pump relay via transistor 
int sensorPin=A0;             //Light dependant resistor
int sensorValue=0;            //variable for the sensor value storage
int dayLed=10;                // used so person can see LDR is working
int nightLed=9;               // same as above
unsigned long oldMillis = 0;  //tracks the last time event fired for pump
unsigned long pumpInterval = dRun;  //
boolean pump12state = true;          //used to track if pump should be on or off



int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 100;           // interval at which to blink (milliseconds)





void setup()
{
  pinMode(delayLed,OUTPUT);      //lit when delay is on to show unit still operating
  digitalWrite(delayLed,LOW);    
  pinMode(pumpPin,OUTPUT);      //pump relay connected through transistor
  digitalWrite(pumpPin,LOW);
  pinMode(dayLed,OUTPUT);      //lit when day running
  pinMode(nightLed,OUTPUT);    //lit when night running
}




void loop()
{
  //timeOut();                //tests the delay LED working at time of writing...rem out when finished
  sensorValue = analogRead(sensorPin);  //read the sensor and put the value into sensorValue
    if (sensorValue<=300)
{
    nightRun();              //jump to nightRun times
}

    else 
    dayRun();                //or else jump to dayRun times
}






void nightRun()
{
    //millis code to go here
  digitalWrite (12, pump12state);
  unsigned long nowMillis = millis();
  if (nowMillis-oldMillis >= pumpInterval)
{
if (pump12state)
{
pumpInterval = nDelay;
}
else
{
pumpInterval = nRun;
}
}
 pump12state = !(pump12state);
 oldMillis = nowMillis; 
  
    if (pumpPin==LOW)
{
    timeOut();
  }
  
}  
  



void dayRun()
{
    //millis code to go here
  digitalWrite(12, pump12state);    //set pin 12 to state of pump12state each time through the loop
                                    //if pump12state hasn't changed, pin won't change either
 unsigned long nowMillis = millis();  //grab snapshot of current time, this keeps all timing consistent, regardless of how much code is in the next "if" statement
 if (nowMillis-oldMillis >= pumpInterval)
 {
 if (pump12state)
 {
 pumpInterval = dDelay;
 }
 else
 {
 pumpInterval=dRun;
 }
 }
  pump12state = !(pump12state);
  oldMillis = nowMillis;
  
    if (pumpPin==LOW)
{
    timeOut();
}
  
}





void timeOut()
{
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) 
  {
  previousMillis = currentMillis;            // save the last time you blinked the LED

    if (ledState == LOW)                      // if the LED is off turn it on and vice-versa:
      ledState = HIGH;
    else
      ledState = LOW;                                            
    
 digitalWrite(delayLed, ledState);        // set the LED with the ledState of the variable:
 
  }
  
}

I can't quickly see all the implications of your use of oldMIllis.

I normally set nowMillis = millis() as the first thing in loop() and then the same value is available for all functions.

If you need different timings for different things then you need to have different time variables - in other words a different version of oldMillis (oldMillsA, oldMillisB etc) - for each of them. That way the timing of one is separate from the others. I think that is illustrated in the several things at a time demo.

...R

Went through your "several things at a time" demo and it was a great help.
Thanks....

I had an inkling there may have been a problem with my version so maybe I'm starting to learn I guess.
Once again...good demo...thanks

Do you have intentions of doing other demos..??
SPI needs a similar " easy for newbie" demo.

bluejets:
SPI needs a similar " easy for newbie" demo.

Thanks for the idea.

...R