[SOLVED] Run Function Once Per Time Period

Mod Edit (@harrisonhjones): See the solution here

Hey Particle Community,

Hope you have had a good Christmas,

I have a function which I only want to run once per a given time period, I am currently using the following structure:

bool runOnce = false (defined bool value in setup rather than loop)

if ((periodStart[day][period] == minSinceMidnight) && (!runOnce)) {
    periodNotified = false;
    runOnce = true;
    //NEED A RESET FOR ONCE TRUE TO GO BACK TO FALSE NEXT PERIOD
}

However, I cannot reset the bool value once I have set the value to true.

Any ideas?

Thank you,

Sam

What have you tried and how have you tried to do it? What do you mean by “I cannot reset”?

Hey @harrisonhjones,

Great to hear from you,

Apologies about any ambiguity in my question,

By reset I mean to bring the Boolean value back to false, once a given time period has elapsed.

I have considered adding an else if the time period + condition, so that once it’s not during that period it will return to the false value, but the problem is that the script is run repeatedly as it is held within the main loop of the program. I haven’t had any success - I was hoping there might have been a clever function hidden away like WaitUntil() or a computable solution.

Thank you,

Sam

Added later:
P.s. Would timers be a possible route, so you run the function which starts a function and at a certain time it calls a function to set the bool value?

What about using a Software Timer or the EllapsedMillis library (in the WebIDE)?

Thanks for the links, I’ve had a quick look. I’m not sure whether it is a solution because the time periods vary. So I’m not sure if the library would work.

Hi @Sammy_Herring

I think your problem could be that when you reach the if statement the first time all is well, but when you come back again (around loop() or what have you) you will do it again since the time is equal (for a whole minute).

You could try having something that says only set the boolean flag to false again if the minSinceMidnight has changed from the previous value.

1 Like

Hi @bko,

Great to hear from you again,

Interesting idea, but I’m not sure as would it not just make a secondary boolean value - almost causing a loop effect? Unless there is a function which allows you to check if a value has changed - or am I taking this from the wrong perspective.

Thank you,

Sam

That comment sounds suspicious.
If runOnce is not a global variable, but defined (or declared) in setup() that version of it won’t be the same as the one you are using in loop().

You’d need to show more of your code so we can see more and have to guess less :wink:

You want

bool runOnce = false;

void setup()
{
}

void loop()
{
  if ((periodStart[day][period] == minSinceMidnight) && (!runOnce)) {
    periodNotified = false;
    runOnce = true;
    //NEED A RESET FOR ONCE TRUE TO GO BACK TO FALSE NEXT PERIOD
  }
}

Declaring a variable inside a function makes it local and short lived (unless declared static) - once you leave the function its content will be gone.

1 Like

Hi @ScruffR,

Thank you for your tip - I always seem to learn something when I’m on here.

In future, I will add the full source code at the bottom.

Source Code:

    /* ======================= PRODUCT SETUP ======================= */
    
    bool DEBUG_MODE = true;
    
    /* ======================= LIBRARY IMPORTS ====================== */
    
    #include "application.h"
    
    /* ======================= CONSTANTS ====================== */
    
    /* DEFINE VARIABLES */
    String formattedTime;
    int day;
    String formattedDay;
    int period;
    int previousPeriod;
    int movementVal = 0;
    int calibrateTime = 10000;
    int pirState = LOW;
    bool periodNotified = false;
    bool periodStateChange = false;
    bool runOnce = false;
    
    /* DEFINE PINOUTS */
    int pir = D2;
    
    /* ROOM ALLOCATION ARRAYS */
    
    // FORMAT: [WEEKDAY][PERIOD]
     int reservation[5][6] = {
       {1, 1, 0, 1, 1, 1} ,   /*  initializers for row indexed by 0 | MONDAY */
       {1, 0, 1, 1, 0, 1} ,   /*  initializers for row indexed by 1 | TUESDAY */
       {1, 1, 0, 1, 1, 0} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
       {1, 0, 1, 0, 1, 1} ,   /*  initializers for row indexed by 4 | THURSDAY*/
       {0, 1, 1, 1, 1, 1}     /*  initializers for row indexed by 5 | FRIDAY */
    };
    
    char * reserver[5][6] = {
       {"J Collins", "F Tumi", "NULL", "J Collins", "J Collins", "J Collins"} ,   /*  initializers for row indexed by 0 | MONDAY */
       {"J Collins", "NULL", "J Collins", "J Collins", "NULL" "H Jones"} ,   /*  initializers for row indexed by 1 | TUESDAY */
       {"N Bulless", "J Collins", "NULL", "J Collins", "J Collins", "NULL"} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
       {"J Collins", "NULL", "J Collins", "NULL", "J Collins", "J Collins"} ,   /*  initializers for row indexed by 4 | THURSDAY*/
       {"NULL", "J Collins", "J Collins", "L Hewett", "J Collins", "J Collins"}     /*  initializers for row indexed by 5 | FRIDAY */
    };
    
    int periodStartHr[5][6] = {
       {9, 10, 11, 12, 13, 14} ,   /*  initializers for row indexed by 0 | MONDAY */
       {9, 10, 11, 12, 13, 14} ,   /*  initializers for row indexed by 1 | TUESDAY */
       {8, 9, 10, 11, 13, 14} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
       {9, 10, 11, 12, 13, 14} ,   /*  initializers for row indexed by 4 | THURSDAY*/
       {9, 10, 11, 12, 13, 14}     /*  initializers for row indexed by 5 | FRIDAY */
    };
    
    int periodStartMin[5][6] = {
      {5, 0, 10, 5, 40, 35} ,   /*  initializers for row indexed by 0 | MONDAY */
      {5, 0, 10, 5, 40, 35} ,   /*  initializers for row indexed by 1 | TUESDAY */
      {50, 45, 55, 50, 20, 35} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
      {5, 0, 10, 5, 40, 35} ,   /*  initializers for row indexed by 4 | THURSDAY */
      {5, 0, 10, 5, 40, 35}     /*  initializers for row indexed by 5 | FRIDAY */
    };
    
    int periodEndHr[5][6] = {
       {10, 10, 12, 13, 14, 15} ,   /*  initializers for row indexed by 0 | MONDAY */
       {10, 10, 12, 13, 14, 15} ,   /*  initializers for row indexed by 1 | TUESDAY */
       {9, 10, 11, 12, 14, 15} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
       {10, 10, 12, 13, 14, 15} ,   /*  initializers for row indexed by 4 | THURSDAY*/
       {10, 10, 12, 13, 14, 15}     /*  initializers for row indexed by 5 | FRIDAY */
    };
    
    int periodEndMin[5][6] = {
       {0, 55, 5, 0, 35, 30} ,   /*  initializers for row indexed by 0 | MONDAY */
       {0, 55, 5, 0, 35, 30} ,   /*  initializers for row indexed by 1 | TUESDAY */
       {45, 40, 50, 45, 15, 30} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
       {0, 55, 5, 0, 35, 30} ,   /*  initializers for row indexed by 4 | THURSDAY*/
       {0, 55, 5, 0, 35, 30}     /*  initializers for row indexed by 5 | FRIDAY */
    };
    
    int periodStart[5][6];
    int periodEnd[5][6];
    
    /* ======================= SYSTEM SETUP ====================== */
    
    STARTUP(
      WiFi.selectAntenna(ANT_AUTO);
      System.enableUpdates();
      );
    SYSTEM_MODE(MANUAL);
    SYSTEM_THREAD(ENABLED);
    
    /* ======================= SETUP CODE (RUN ONCE) ====================== */
    
    void setup() {
      Serial.begin(115200);
    
      pinMode(pir, INPUT);
    
      WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
      int DBG = 0;
      while (!WiFi.ready()) {
        if (DEBUG_MODE) {if (DBG == 0) {Serial.println("Wi-Fi Antenna Not Ready."); DBG = 1;};}
      } 
      while (WiFi.ready()) {
        if (DEBUG_MODE) {Serial.println("Wi-Fi Antenna Ready.");}
        if (DEBUG_MODE) {Serial.println("W-Fi Connecting.");}
        Particle.connect();
        while (!Particle.connected()) {
        } while (Particle.connected()) {
          if (DEBUG_MODE) {Serial.println("W-Fi Connected.");}
            Particle.syncTime();
            updateTime();
            notify("boot", "IoT Sensor now online.");
            if (DEBUG_MODE) {Serial.println("Setup Complete.");}
        break;
        }
        break;
      }
      setPeriodTimes();
    }
    
    /* ======================= MAIN CODE (RUN REPEATEDLY) ====================== */
    
    void loop() {
      if (Particle.connected()) {Particle.process();};
      while (Particle.connected()) {
        updateTime();
        checkMode();
        updateMotion();
    
        Serial.println(formattedTime);
        Serial.println(formattedDay);
        Serial.println(period);
    
        if (reservation[day][period] == 0) {
          if (pirState == HIGH) {
            //IF NO RESERVATION AND MOVEMENT --> OFFER BOOKING (After timeout, +PUBLISH OPP)
            // SECOND DEVELOPMENT CYCLE TO ALLOW BOOKING
          } else {
            //IF NO RESERVATION AND NO BOOKING --> PUBLISH OPPOURTUNITY
          }
        } else if (reservation[day][period] == 1) {
          //NOTIFY RESERVED
        }
        Particle.process();
        break;
      }
    }
    
    /*
    
    If Period NOT RESERVED --> Check motion --> If motion --> Allow reservation --> UPDATE SOCIAL
    If Period RESERVED --> UPDATE SOCIAL
    
    */
    
    /* ======================= ALL FUNCTIONS ====================== */
    
    /* NOTIFYER FUNCTIONS */
    
    void notify(String type, String data) {
      int minSinceMidnight = (Time.local() % 86400) / 60;
      int periodLength = periodEnd[day][period] - periodStart[day][period];
      int periodLengthQ1 = periodLength / 4;
      int periodLengthQ2 = periodLength / 2;
      int periodLengthQ3 = (3 * periodLength) / 4;
      if ((periodStart[day][period] == minSinceMidnight) && (!runOnce)) {
        periodNotified = false;
        runOnce = true;
    
        //NEED A RESET FOR ONCE TRUE TO GO BACK TO FALSE NEXT PERIOD
      }
      //STATES
      //RED ==> RESERVED
      //GREEN ==> VACANT
      if ( type == "boot" ) {
        Particle.publish("IoTRoomSensor-Boot-G16", data, PRIVATE);
      }
      for (int i=0;i<6;i++) {
        if ( ((periodStart[day][period] == minSinceMidnight || periodLengthQ1 == minSinceMidnight || periodLengthQ2 == minSinceMidnight || periodLengthQ3 == minSinceMidnight) && (!periodNotified)) || (periodStateChange) ) {
          if ( type == "reserved" ) {
            Particle.publish("IoTRoomSensor-StateRed-G16", data, PRIVATE);
            periodNotified = true;
          } else if ( type == "vacant" ) {
            Particle.publish("IoTRoomSensor-StateGreen-G16", data, PRIVATE);
            periodNotified = true;
          }
        }
      }
    }
    
    void updateTime() {
      formattedDay = Time.format(Time.now(), "%A");
      formattedTime = Time.format(Time.now(), "%I:%M%p");
      day = Time.weekday();
      weekdayAlignment();
      period = updatePeriod();
    }
    
    /* PERIOD CONTROL FUNCTIONS */
    
    int updatePeriod() {
      if (day == 6 || day == 7 ) {
        return 7;
      }
        int minSinceMidnight = (Time.local() % 86400) / 60;  // only take the time and drop the date and the drop seconds too
        for (int i=0;i<6;i++) {
          if ( periodStart[day][i] <= minSinceMidnight && minSinceMidnight < periodEnd[day][i] ) {
            return i;
          }
        }
    }
    
    void setPeriodTimes() {
      for (int x=0; x<5; x++) {
        for (int y=0; y<6; y++) {
          int timeConvertStart = (periodStartHr[x][y] * 60) + periodStartMin[x][y];
          int timeConvertEnd = (periodEndHr[x][y] * 60) + periodEndMin[x][y];
          periodStart[x][y] = timeConvertStart;
          periodEnd[x][y] = timeConvertEnd;
          if (DEBUG_MODE) {
            Serial.print("Day: ");
            Serial.print(x+1);
            Serial.print(" | Period: ");
            Serial.print(y+1);
            Serial.print(" | Start Time: ");
            Serial.print(periodStart[x][y]);
            Serial.print(" | End Time: ");
            Serial.println(periodEnd[x][y]);
        }
        }
      }
      return;
    }
    
    void weekdayAlignment() {
      if (day == 1) {
        day = 7;
      } else if (day == 2) {
        day = 1;
      } else if (day == 3) {
        day = 2;
      } else if (day == 4) {
        day = 3;
      } else if (day == 5) {
        day = 4;
      } else if (day == 6) {
        day = 5;
      } else if (day == 7) {
        day = 6;
      }
      return;
    }
    
    /* OFFLINE MODE DURING NON-WEEKDAYS */
    
    void offlineMode() {
      Serial.println("--Offline Mode--");
      delay(1500);
      while (period == 7) {
        updatePeriod();
        System.sleep(300);
      }
      return;
    }
    
    void checkMode() {
      if (period == 7) {
        offlineMode();
        System.reset();
      }
      return;
    }
    
    /* PIR SESNOR FUNCTIONS */
    
    void updateMotion() {
      //if (periodCheck and notReserved) {
        if (calibrated()) {
          readPIR();
          reportPIR();
        }
      //}
      return;
    }
    
    bool calibrated() {
      return millis() - calibrateTime > 0;
    }
    
    void readPIR() {
      movementVal = digitalRead(pir);
    }
    
    void reportPIR() {
      if (movementVal == HIGH) {
        if (pirState == LOW) {
          //Particle.publish("designingiot/s15/motion");
          Serial.println("Motion Detected, Sir.");
          pirState = HIGH;
        }
      } else {
        if (pirState == HIGH) {
          pirState = LOW;
        }
      }
    }

Thank you,

Sam

Hi @bko,

I’ve been playing around with your idea and I realised that in the updatePeriod() function, there is a state where the new period data has not yet been set but exists as i and if I add an if statement there then I can flag that the period has changed, to prevent a loop.

Thank you for your help,

Sam

1 Like

Hey Sam,

Glad you got it figured out. Could you post an example to help aid the rest of the community and I’ll make this “solved”?

1 Like

Hi @harrisonhjones,

Sure!

The program is time based and calls a function which updates a variable (the current time), it does so using a for loop. The incremental value is used to update the variable, however, while it is still within this function you can check the previous value to the new one. If the value has not changed then you can set a boolean variable to false, while if the value is different to true. Thus, giving you a time-dependant function that will only run once per time period.

Loop:

void loop() {
period = updatePeriod();
}

Function:

int updatePeriod() {
    int minSinceMidnight = (Time.local() % 86400) / 60;  // only take the time and drop the date and the drop seconds too
    for (int i=0;i<6;i++) {
      if ( periodStart[day][i] <= minSinceMidnight && minSinceMidnight < periodEnd[day][i] ) {
        if ( period != 0 && i != period ) {periodNotified = false;} else {periodNotified = true;}
        return i;
      }
    }
}

The added period != 0, is only neccesary as period = 0 is initially defined as a global to prevent a false notification while the time has not yet been synced - which occurs during the setup.

Full Source Code:

/* ======================= PRODUCT SETUP ======================= */

bool DEBUG_MODE = true;

/* ======================= LIBRARY IMPORTS ====================== */

#include "application.h"

/* ======================= CONSTANTS ====================== */

/* DEFINE VARIABLES */
String formattedTime;
int day;
String formattedDay;
int period = 0;
int previousPeriod;
int movementVal = 0;
int calibrateTime = 10000;
int pirState = LOW;
bool periodNotified = false;
bool periodStateChange = false;
bool periodChange = false;

/* DEFINE PINOUTS */
int pir = D2;

/* ROOM ALLOCATION ARRAYS */

// FORMAT: [WEEKDAY][PERIOD]
 int reservation[5][6] = {
   {1, 1, 0, 1, 1, 1} ,   /*  initializers for row indexed by 0 | MONDAY */
   {1, 0, 1, 1, 0, 1} ,   /*  initializers for row indexed by 1 | TUESDAY */
   {1, 1, 0, 1, 1, 0} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
   {1, 0, 1, 0, 1, 1} ,   /*  initializers for row indexed by 4 | THURSDAY*/
   {0, 1, 1, 1, 1, 1}     /*  initializers for row indexed by 5 | FRIDAY */
};

char * reserver[5][6] = {
   {"J Collins", "F Tumi", "NULL", "J Collins", "J Collins", "J Collins"} ,   /*  initializers for row indexed by 0 | MONDAY */
   {"J Collins", "NULL", "J Collins", "J Collins", "NULL" "H Jones"} ,   /*  initializers for row indexed by 1 | TUESDAY */
   {"N Bulless", "J Collins", "NULL", "J Collins", "J Collins", "NULL"} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
   {"J Collins", "NULL", "J Collins", "NULL", "J Collins", "J Collins"} ,   /*  initializers for row indexed by 4 | THURSDAY*/
   {"NULL", "J Collins", "J Collins", "L Hewett", "J Collins", "J Collins"}     /*  initializers for row indexed by 5 | FRIDAY */
};

int periodStartHr[5][6] = {
   {9, 10, 11, 12, 13, 14} ,   /*  initializers for row indexed by 0 | MONDAY */
   {9, 10, 11, 12, 13, 14} ,   /*  initializers for row indexed by 1 | TUESDAY */
   {8, 9, 10, 11, 13, 14} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
   {9, 10, 11, 12, 13, 14} ,   /*  initializers for row indexed by 4 | THURSDAY*/
   {9, 10, 11, 12, 13, 14}     /*  initializers for row indexed by 5 | FRIDAY */
};

int periodStartMin[5][6] = {
  {5, 0, 10, 5, 40, 35} ,   /*  initializers for row indexed by 0 | MONDAY */
  {5, 0, 10, 5, 40, 35} ,   /*  initializers for row indexed by 1 | TUESDAY */
  {50, 45, 55, 50, 20, 35} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
  {5, 0, 10, 5, 40, 35} ,   /*  initializers for row indexed by 4 | THURSDAY */
  {5, 0, 10, 5, 40, 35}     /*  initializers for row indexed by 5 | FRIDAY */
};

int periodEndHr[5][6] = {
   {10, 10, 12, 13, 14, 15} ,   /*  initializers for row indexed by 0 | MONDAY */
   {10, 10, 12, 13, 14, 15} ,   /*  initializers for row indexed by 1 | TUESDAY */
   {9, 10, 11, 12, 14, 15} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
   {10, 10, 12, 13, 14, 15} ,   /*  initializers for row indexed by 4 | THURSDAY*/
   {10, 10, 12, 13, 14, 15}     /*  initializers for row indexed by 5 | FRIDAY */
};

int periodEndMin[5][6] = {
   {0, 55, 5, 0, 35, 30} ,   /*  initializers for row indexed by 0 | MONDAY */
   {0, 55, 5, 0, 35, 30} ,   /*  initializers for row indexed by 1 | TUESDAY */
   {45, 40, 50, 45, 15, 30} ,   /*  initializers for row indexed by 3 | WEDNESDAY */
   {0, 55, 5, 0, 35, 30} ,   /*  initializers for row indexed by 4 | THURSDAY*/
   {0, 55, 5, 0, 35, 30}     /*  initializers for row indexed by 5 | FRIDAY */
};

int periodStart[5][6];
int periodEnd[5][6];

/* ======================= SYSTEM SETUP ====================== */

STARTUP(
  WiFi.selectAntenna(ANT_AUTO);
  System.enableUpdates();
  );
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);

/* ======================= SETUP CODE (RUN ONCE) ====================== */

void setup() {
  Serial.begin(115200);

  pinMode(pir, INPUT);

  WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
  int DBG = 0;
  while (!WiFi.ready()) {
    if (DBG == 0) {Serial.println("Wi-Fi Antenna Not Ready."); DBG = 1;}
    } while (WiFi.ready()) {
    Serial.println("Wi-Fi Antenna Ready. v2");
    Serial.println("W-Fi Connecting.");
    Particle.connect();
    while (!Particle.connected()) {
    } while (Particle.connected()) {
        Serial.println("W-Fi Connected.");
        Particle.syncTime();
        setPeriodTimes();
        delay(2000);
        updateTime();
        Serial.println(formattedTime);
        Serial.println(formattedDay);
        Serial.println(period);
        notify("boot", "IoT Sensor now online.");
        Serial.println("Setup Complete.");
    break;
    }
    break;
  }
  //setPeriodTimes();
}

/* ======================= MAIN CODE (RUN REPEATEDLY) ====================== */

void loop() {
  updateTime();
  if (Particle.connected()) {Particle.process();};
  while (Particle.connected()) {
    delay(2000);
    updateTime();
    checkMode();
    updateMotion();

    Serial.println(formattedTime);
    Serial.println(formattedDay);
    Serial.println(period);

    delay(10000);

    //if (periodChange = true) { periodNotified = false; } else { periodNotified = true; }

    //if ( i != period ) {periodChange = true;} else {periodChange = false;}

    if (reservation[day][period] == 0) {
      if (pirState == HIGH) {
        //IF NO RESERVATION AND MOVEMENT --> OFFER BOOKING (After timeout, +PUBLISH OPP)
        // SECOND DEVELOPMENT CYCLE TO ALLOW BOOKING
        notify("vacant", "G16 is currently not booked, but movement has been detected.");
      } else {
        //IF NO RESERVATION AND NO BOOKING --> PUBLISH OPPOURTUNITY
        notify("vacant", "G16 is currently vacant.");
      }
    } else if (reservation[day][period] == 1) {
      //NOTIFY RESERVED
      notify("reserved", "G16 is currently reserved.");
    }
    Particle.process();
    break;
  }
}

/*

If Period NOT RESERVED --> Check motion --> If motion --> Allow reservation --> UPDATE SOCIAL
If Period RESERVED --> UPDATE SOCIAL

*/

/* ======================= ALL FUNCTIONS ====================== */

/* NOTIFYER FUNCTIONS */

void notify(char type[], char data[]) {

  if ( type == "boot" ) {
    Particle.publish("IoTRoomSensor-Boot-G16", data, PRIVATE);
  }
  Serial.println(periodNotified);
  Serial.println(periodStateChange);

  if ( !periodNotified || periodStateChange ) {
    if ( type == "reserved" ) {
      Serial.println("Notification: Reserved");
      Particle.publish("IoTRoomSensor-StateRed-G16", data, PRIVATE);
      periodNotified = true;
    } else if ( type == "vacant" ) {
      Serial.println("Notification: Vacant");
      Particle.publish("IoTRoomSensor-StateGreen-G16", data, PRIVATE);
      periodNotified = true;
    }
}
  return;
}

void updateTime() {
  formattedDay = Time.format(Time.now(), "%A");
  formattedTime = Time.format(Time.now(), "%I:%M%p");
  day = Time.weekday();
  weekdayAlignment();
  period = updatePeriod();
  return;
}

/* PERIOD CONTROL FUNCTIONS */

int updatePeriod() {
  if (day == 6 || day == 7 ) {
    return 7;
  }
    int minSinceMidnight = (Time.local() % 86400) / 60;  // only take the time and drop the date and the drop seconds too
    for (int i=0;i<6;i++) {
      if ( periodStart[day][i] <= minSinceMidnight && minSinceMidnight < periodEnd[day][i] ) {
        if ( period != 0 && i != period ) {periodNotified = false;} else {periodNotified = true;}
        return i;
      }
    }
}

void setPeriodTimes() {
  for (int x=0; x<5; x++) {
    for (int y=0; y<6; y++) {
      int timeConvertStart = (periodStartHr[x][y] * 60) + periodStartMin[x][y];
      int timeConvertEnd = (periodEndHr[x][y] * 60) + periodEndMin[x][y];
      periodStart[x][y] = timeConvertStart;
      periodEnd[x][y] = timeConvertEnd;
      if (DEBUG_MODE) {
        Serial.print("Day: ");
        Serial.print(x+1);
        Serial.print(" | Period: ");
        Serial.print(y+1);
        Serial.print(" | Start Time: ");
        Serial.print(periodStart[x][y]);
        Serial.print(" | End Time: ");
        Serial.println(periodEnd[x][y]);
    }
    }
  }
  return;
}

void weekdayAlignment() {
  if (day == 1) {
    day = 7;
  } else if (day == 2) {
    day = 1;
  } else if (day == 3) {
    day = 2;
  } else if (day == 4) {
    day = 3;
  } else if (day == 5) {
    day = 4;
  } else if (day == 6) {
    day = 5;
  } else if (day == 7) {
    day = 6;
  }
  return;
}

/* OFFLINE MODE DURING NON-WEEKDAYS */

void offlineMode() {
  Serial.println("--Offline Mode--");
  delay(1500);
  while (period == 7) {
    updatePeriod();
    System.sleep(300);
  }
  return;
}

void checkMode() {
  if (period == 7) {
    offlineMode();
    System.reset();
  }
  return;
}

/* PIR SESNOR FUNCTIONS */

void updateMotion() {
  //if (periodCheck and notReserved) {
    if (calibrated()) {
      readPIR();
      reportPIR();
    }
  //}
  return;
}

bool calibrated() {
  return millis() - calibrateTime > 0;
}

void readPIR() {
  movementVal = digitalRead(pir);
}

void reportPIR() {
  if (movementVal == HIGH) {
    if (pirState == LOW) {
      //Particle.publish("designingiot/s15/motion");
      Serial.println("Motion Detected, Sir.");
      pirState = HIGH;
    }
  } else {
    if (pirState == HIGH) {
      pirState = LOW;
    }
  }
}

Have a good day,

Sam

1 Like