Using Struct to make a function that changes ?

Hi, Im doing a new program to control a grow chamber, mostly is the humidity control and the fogger times, at this point I like to have two mayor "subrutines" one for the watering in the day and another on the night, since they use the same variables, but different variables, It occurs to me, it might be handy to write a "universal watering program"

The idea is to have a function to change between the day and night programs, and use the same subrutine but each with is one values.

So this is what I got so far:

//time definitions------------------------------------------
#define segundo	1000
#define minuto	(60*segundo)
#define hora	(60*minuto)

//struct definitinions--------------------------------------
 struct factors {	byte id; 
					int minHum; 
					int maxHum; 
					unsigned long timeBtwWatering; 
					unsigned long timeInWatering;
					} ;//factors;  
 


//definitions for watering machine: 
enum wateringMachineOptions {startFogger, startTimmer, waitMaxHum, startMaxHTimer, endWatering}; 
wateringMachineOptions wateringMachine = startFogger; 

//Hardware Pins 
const byte fogger = 2; 
const byte foggerFan = 3; 

//////////////////////////////////////////////////////////////////////
void setup() 
{
pinMode(fogger, OUTPUT);
pinMode(foggerFan, OUTPUT);

//---------------------------------------
Serial.begin(9600); 

//day time factors------------------------
factors dayProgram; 
dayProgram.id = 0; 
dayProgram.minHum = 20; 
dayProgram.maxHum = 90; 
dayProgram.timeBtwWatering = (10*minuto);
dayProgram.timeInWatering = (10*minuto); 

//nigth factors---------------------------
factors ngtProgram; 
ngtProgram.id = 1; 
ngtProgram.minHum = 10; 
ngtProgram.maxHum = 70; 
ngtProgram.timeBtwWatering = (30*minuto);
ngtProgram.timeInWatering = (5*minuto); 

}



void loop() 
{

}

//Fuction dedicated to start the watering machine and keep 
//min time in max humidity. 
void watering()
{


switch(wateringMachine)
{
    case (startFogger):
    		//turn on the fogger and move foward 
    		foggerON(); 
    		Serial.println("Start Fogger"); 
    		wateringMachine = startTimmer; 
    		break;
    
    case (startTimmer):
    		//start the timmer and move foward 
    		Serial.println("The timmer begins"); 
    		wateringMachine = waitMaxHum; 
    		break;
    
    case (waitMaxHum):
    		wateringMachine = startMaxHTimer; 
    		break;
    
    case (startMaxHTimer):
    		Serial.println("Watering End "); 
    		wateringMachine = endWatering; 
    		break; 
    
    case(endWatering):
    		Serial.println("Exit Watering");
    		break; 
}






}

void foggerON()
{
	digitalWrite(fogger,	 LOW);
    digitalWrite(foggerFan , LOW);	
}

void srtTimmer()
{
	
}

The idea is to have a switch case to call each subroutine, and each subroutine call its owns timmers and such.

I have the two struct with its factors, and be possible to write two routines for this, but since Im trying to learn.

How I can write a "Univerasal roututine for this structs"?

Pseudo:

loop()
{
if (time = dayTime) waterignOption = DayTime;
if (time = ngtTime) wateringOption = nigtTime;

watering()
{
case (startFogger):

brake; ///

case (startTimmer):
//start the timmer and move foward
Serial.println("The timmer begins");
wateringMachine = waitMaxHum;
break;

}

}

void starTimmer()
{
if(millis() - programType.srt.Timmer > program.Type.program.watter.delay ?????
}

}

I hope this make some sense.
Thnaks.

-Alex.

In a clever solution you'll have an array of the struct, with one element for day and one for night. Then pass the applicable element to the subroutine. Or have a global variable telling every subroutine whether they should use the Day or Night struct.

Yes, I was thinking on something like that, but how?
Do you have some example? or anything like a pseudocode?

Thanks.
-Alex.

I would have the actual watering routing figure out the time and adjust watering patterns based on it.

Or set a global flag telling the day/night thing, and then have the function(s) react to that - turning it into a finite state machine, which I think is much more flexible.

I have used array of functions for a project, where at compile time the various sensors are added as defined in a separate file. This to have a single code base for several related projects - allowing me to simply enable/disable the various sensors and other peripherals as needed.

Hi again, Im thinking I was trying to make a finite state machine by using the switch case statement,
I can put back the functions and timers inside the function but it loocks much more messy, here is the firs tried I make on the subject;

void growChamberInDayTime()
{
	//In day time reac to the different scenarios
	if(STMhum == OkHumidity)
		{
			if(H < dayMinHum) STMhum = LowHumidity;  
			if(H > dayMaxHum) STMhum = HighHumidity; 
		}


	if(STMhum == LowHumidity)
	{
		if(STMLOW != STMLOWpast) //for print just once the state machine 
		{
			Serial.print("---->STM "); Serial.println(STMLOW); 
			STMLOWpast = STMLOW; 
		}

		switch(STMLOW) //state machien for watering the crops. 
		{
		//if the minumum time btw watterign  has elapsed, move foward
		case (minTimeBtwWateringElapsed):					
						
			//For print the timmer at a second resolution
				if(millis() - dayTimeWateringEnd < dayTimeBtwWatering)
				{
					cuSecWateringnEnd = (dayTimeBtwWatering - (millis() - dayTimeWateringEnd)) /1000;  

					if(cuSecWateringnEnd != pasSecWateringEnd)
						{
							Serial.println(cuSecWateringnEnd);	
							pasSecWateringEnd = cuSecWateringnEnd; 
						}
				}
				else {	STMLOW = startFogger; }
			break; 
				
		//start the fogger and fand and move foward
		case (startFogger):

			digitalWrite(fogger, LOW);
			digitalWrite(foggerFan, LOW);
			Serial.println("------Fogger ON");
			Serial.println("------Fogger Fan ON");
							
			STMLOW = humReachLevel; 
			break; 

		case (humReachLevel):
				if(H > dayMaxHum)  						//stop fogger 
				{
					digitalWrite(fogger, HIGH);
					digitalWrite(foggerFan, HIGH);
					Serial.println("Fogger OFF");
					Serial.println("Fogger OFF"); 
						
					if(startMaxHTimmer == true)			//start the max humidity timmer
						{
							dayTimeInMaxHumStartTime = millis(); 
							startMaxHTimmer = false; 
							STMLOW = timeHumReachLevel;
						}
				}
			break;

		//if the timmer of wattering has elapsed move foward
		case(timeHumReachLevel):
			  //if(millis() < dayTimeInMaxHumStartTime + dayTimeInMaxHumStartTime) //evit desbordaiento
				if(millis() - dayTimeInMaxHumStartTime < dayTimeInMaxHumDelay)
				{
					//while wattering dont allow the humidity 
					//to drop below this level
					if(H < dayMaxHum - 10)  //start fogger
						{
							digitalWrite(fogger, LOW);
							digitalWrite(foggerFan, LOW);
							Serial.println("Fogger OFF");
							Serial.println("Fogger Fan OFF"); 
						}
				}
				else
				{
					startMaxHTimmer = true; 	//restart function 
					STMLOW = endWatering; 		//changue the next step STM 	
				}
			break;
				
		//if the humidity ok and timmer elapsed move foward 
		case (endWatering): 
				//stop fogger
				digitalWrite(fogger, HIGH);
				digitalWrite(foggerFan, HIGH);
				STMLOW = backToSTMhum; 
				break;

		//reset variables and go back to sense humidity
		case (backToSTMhum): 
				//take time at the end of watering
				dayTimeWateringEnd = millis();
				Serial.println("Se ha salido de baja humedad"); 
				STMhum = OkHumidity; 
				STMLOW = minTimeBtwWateringElapsed; //restart the machine 
				break;

		}			
	}
}//--End of daytime machine

this is the complete code

And like was mentioned before, this is only the day time wattering, so I think is much more compact to use a single fuction, as you say, if any body have a pice of code, or pseudocode will be very much appreciated.
-Alex.

Use the same state machine for day and night time. As in your previous code, init dayProgram and ngtProgram and inside loop() make the wateringOption point to the applicable struct. In the state machine you use wateringOption->minHum etc.