You can do that using timers and interrupts, but some more informations is needed (which board, which processor).
Note: F_CPU
is already defined if you are using arduino libraries (#define F_CPU 20000000U
)
Note 2: You may want to use another timer than TIMER0 since it is use to track time on arduino
#define GMilliSecondPeriod F_CPU / 1000
unsigned int gNextOCR = 0;
volatile unsigned long gMillis = 0;
bool valveOpened = false;
// This interruption will be called every 1ms
ISR(TIMER2_COMPA_vect)
{
if(valve_open){
gMillis++;
if(gMillis >= 30000){
close_valve();
gMillis = 0;
}
}
gNextOCR += GMilliSecondPeriod;
OCR2A = gNextOCR >> 8; // smart way to handle millis, they will always be average of what they should be
}
// Just call this function within your setup
void setupTime(){
TCCR2B |= _BV(CS02);
TIMSK2 |= _BV(OCIE0A);
sei(); // enable interupts
}