Turn on devices multiple times during set period

Hey guys,

I’m pretty new to this but I’m using Arduino for my research this semester.

Basically what I need to do is set times for conditioning with the apparatus I will ultimately create (I will be releasing an odor and heating a device simultaneously).

I need this apparatus to run from 9 am to 6 pm, and I need to turn on the odor device and heaters twice an hour (so every 30 minutes roughly, but it doesn’t have to be exact) and be on for 1-2 minutes. I am just not quite sure how to go about doing this. I read about using the blink without delay sketch but not sure how i would modify it to these specifics.

I already have a DS1307 RTC connected and running.

Here is what i have so far regarding this (the code before is the sparkfun code to just connect the RTC). I know it’s wrong but I am not quite sure what pieces I am missing.

uint32_t min = rtc.minute();

uint32_t hour = rtc.hour();

void loop () {
  if ((hour >= 9) || (hour <= 18)) {
  // turn on apparatus
  }
  
  else ((hour < 9 || (hour > 18 )) {
  // apparatus off
  }
  
  if ((min == 0) || (min == 30)) 
  {
  // release odor, turn on heat
  }

  else ((min != 0) || (min != 30)) {
  //don't release odor, turn off heat
  }
}

This is a framework that should work. It compiles as is (though I had to go to github to get the DS1307 lib and TimeLib.h…). Hopefully you just need to add the elements to control the apparatus and heat/odor.

Double check the logic; I think it’s right but you never know…

#include <DS1307RTC.h>
#include <TimeLib.h>
#include <Wire.h>

tmElements_t
    tm;

#define ON      true
#define OFF     false

const byte pinLED = LED_BUILTIN;

const unsigned long culOdorDispenseTime = 120000ul; //2 minutes

byte
    last_minute,
    last_hour;
bool
    bOdorState,
    bApparatusState;
unsigned long
    timeOdor;
    
void setup( void )
{
    Serial.begin(9600);

    //pin setups as needed

    Apparatus( OFF );
    Odor( OFF );

    //check if the RTC can be read; if not, send message and stop
    if( RTC.read(tm) )
    {
        last_minute = tm.Minute;
        last_hour = tm.Hour;
        
    }//if
    else
        HaltandCatchFire();
    
}//setup

void HaltandCatchFire( void )
{
    Apparatus( OFF );
    Odor( OFF );
    
    while( true )
    {
        //halt and catch fire; no need for fancy timing here; just blink LED rapidly to indicate fault
        digitalWrite( pinLED, HIGH );
        delay( 300 );
        digitalWrite( pinLED, LOW );
        delay( 300 );
        
        Serial.println( "Failed reading RTC." );
        
    }//while       
         
}//HaltandCatchFire
    
void loop ( void ) 
{
    static unsigned long
        timeReadRTC = 0;

    //read the RTC once every 500mS
    if( (millis() - timeReadRTC) > 500 )
    {
        //set up for read 500mS from now
        timeReadRTC = millis();

        //get the time
        if( RTC.read(tm) )
        {
            //if the apparatus is off now
            if( bApparatusState == OFF )
            {
                //check if time to turn on
                if( tm.Hour >= 9 && tm.Hour <= 18 )
                    Apparatus( ON );
                
            }//if
            else
            {
                //is on now; time to turn off?
                if( tm.Hour < 9 || tm.Hour > 18 )
                {
                    //turn off the apparatus
                    Apparatus( OFF );
                    //I also turn off the odor thing in case it's separate from Apparatus power
                    Odor( OFF );
                                    
                }//if
                
            }//else

            //check if time for a squirt of odor (!)
            // - apparatus turned on
            // - minute just turned 0 or 30
            if( (bApparatusState == ON) && (tm.Minute != last_minute) && (tm.Minute == 0 || tm.Minute == 30) )
            {
                //save the minute so we don't turn on the odor for the entire duration of 0 or 30
                last_minute = tm.Minute;
                //turn on
                Odor( ON );
                
            }//if            
            
        }//if
        else
            //if we can't read the time, shut everything down (?)
            HaltandCatchFire();
        
    }//if
    

    //check if odor on; if so, turn it off when time appropriate
    if( bOdorState == ON )
    {
        if( (millis() - timeOdor) >= culOdorDispenseTime )
            Odor( OFF );

    }//if
    
}//loop

void Apparatus( bool State )
{
    //asking for on?
    if( State )
    {
        //turn on apparatus
        //insert code to turn on apparatus here
        bApparatusState = ON;
        
    }//if
    else
    {
        //turn off apparatus
        //insert code to turn off apparatus here
        bApparatusState = OFF;
        
    }//else
    
}//Apparatus

void Odor( bool State )
{
    //asing for on?
    if( State )
    {
        //insert code to turn on odor thingamabob here
        timeOdor = millis();
        bOdorState = ON;
        
    }//if
    else
    {
        //insert code to turn off odor doohicky here
        bOdorState = OFF;
        
    }//else
    
}//Odor

I know it's wrong but I am not quite sure what pieces I am missing.

Aside from the obvious (that you need to read the clock on EVERY pass through loop(), not once at compile time), why do you think the code is wrong?

Before you try to do anything with ANY data, it is worth printing the data to make sure that it what you think it is.

PaulS:
Aside from the obvious (that you need to read the clock on EVERY pass through loop(), not once at compile time), why do you think the code is wrong?

Before you try to do anything with ANY data, it is worth printing the data to make sure that it what you think it is.

I wasn't sure if I identified the variables correctly, and the if/else statements seemed off but after reading about them for a while I was still confused. I also wasn't exactly sure how to combine the variables since both the hour and the minutes are important to when I need to turn everything on.

I initially tried using the blink sketch but couldn't seem to manipulate it correctly. I will play around with the code above to try to understand it more and adapt if I need to

Blackfin:
This is a framework that should work. It compiles as is (though I had to go to github to get the DS1307 lib and TimeLib.h…). Hopefully you just need to add the elements to control the apparatus and heat/odor.

Double check the logic; I think it’s right but you never know…

#include <DS1307RTC.h>

#include <TimeLib.h>
#include <Wire.h>

tmElements_t
    tm;

#define ON      true
#define OFF    false

const byte pinLED = LED_BUILTIN;

const unsigned long culOdorDispenseTime = 120000ul; //2 minutes

byte
    last_minute,
    last_hour;
bool
    bOdorState,
    bApparatusState;
unsigned long
    timeOdor;
   
void setup( void )
{

I am getting an error for redefinition of void setup, which I feel like shouldn’t happen if everything is defined within that and with the previous setup/loop codes from setting up the RTC.

But I really appreciate that code, it was quite helpful since I am still in a very early learning phase and figuring everything out as fast as I can (due to deadlines).

EDIT Just kidding i figured out how to fix the void setup/loop problem !

I also wasn't exactly sure how to combine the variables since both the hour and the minutes are important to when I need to turn everything on.

The easiest way is to calculate the minutes since midnight that you need to do something, and the minutes since midnight that it is now.

Calculating minutes since midnight is trivial.

unsigned int minutesSinceMidniggt = hour * 60 + minute;