Trigger an Event

Hi.

Im using the minute() to call a function once. I'm trying the following, but what do I have to do to make it call the function only once - and not constantly?

int checkMinuteOn = 0;
boolean minuteLog = false;

  if (minute()==0 || minute()==30) {
    checkMinuteOn = 1;
  }

  if (checkMinuteOn == 1) {
    minuteLog = true;
  }

  if (minuteLog) {
    callFunction();
  }

  println(minuteLog);
  minuteLog = false;
  checkMinuteOn = 0;

Answers

  • edited October 2013

    There are many approaches. My favorite is to use a separate Thread to exclusively take care of timing.

    /** 
     * Timer Example (v1.01)
     * by  GoToLoop (2013/Oct)
     * 
     * forum.processing.org/two/discussion/110/trigger-an-event
     */
    
    final static int TIMER = 2*60 * 1000;  // 2 minutes
    boolean hasTriggered, isEnabled = true;
    
    void setup() {
      frameRate(1);
      fill(#FFFF00);
      textSize(32);
      textAlign(CENTER, CENTER);
    
      thread("timer");
    }
    
    void draw() {
      final String msg = nf(minute(), 2) + ":" + nf(second(), 2);
    
      background(0);
      text(msg, width>>1, height>>1);
    
      if (hasTriggered) {
        hasTriggered = false;
        logger("Triggered @ " + msg);
      }
    }
    
    void timer() {
      while (isEnabled) {
        hasTriggered = true;
        delay(TIMER);
      }
    }
    
    static final void logger(String log) {
      println(log);
    }
    
  • edited October 2013 Answer ✓

    And an alternative 1 in which the extra timer() Thread itself is also responsible to invoke logger().
    Although the time it takes to run logger() slows down timer(). :-(

    /** 
     * Timer Example 2 (v1.01)
     * by  GoToLoop (2013/Oct)
     * 
     * forum.processing.org/two/discussion/110/trigger-an-event
     */
    
    final static int TIMER = 1*60 * 1000;  // 1 minute
    
    static boolean isEnabled = true;
    static String msg;
    
    void setup() {
      frameRate(1);
      fill(#FFFF00);
      textSize(32);
      textAlign(CENTER, CENTER);
    
      thread("timer");
    }
    
    void draw() {
      msg = nf(minute(), 2) + ":" + nf(second(), 2);
    
      background(0);
      text(msg, width>>1, height>>1);
    }
    
    void timer() {
      while (isEnabled) {
        delay(TIMER);
        logger();
      }
    }
    
    static final void logger() {
      println("Triggered @ " + msg);
    }
    
  • Answer ✓

    Your checkMinuteOn variable is a bad boolean, duplicate of the minuteLog variable...

    One way to do this is:

    boolean madeAction;
    
    [...]
    
    if (!madeAction && (minute() == 0 || minute() == 30)) // Don't repeat on this minute if already done
    {
      callFunction();
      madeAction = true;
    }
    if (madeAction && (minute() == 1 || minute() == 31))
    {
      madeAction = false; // For next half-hour
    }
    
  • Hi thanks for the help.

    Actually I tried something else that I think is much easier and works in my sketch:

    if (minute()==0 || minute==30){ doThis(); delay(60000); }

    So, it will trigger my action and wait one minute. The next minute will be a different minute() value, and will not execute the function until the next reading.

  • That's exactly the approach of my example: use delay(TIMER) to hibernate till time has come to another action. (~~)
    Only diff. is that in my case, delay() won't halt draw(), since it's in another Thread :bz
    You can see that is so due to continuous minutes:seconds display, while the specialized Thread does its timing work. :D

  • As said: the problem with delay() is that it freezes the sketch, nothing new will be drawn until the delay is done. If that's fine with your kind of sketch, why not.

    GoToLoop's method is probably the best, but a bit technical (threads can be intimidating for new users), my method is low-tech and doesn't freeze the sketch.

Sign In or Register to comment.