Trouble Passing Variable Alarm Time using Timealarm library

Hello forum,

First post here of a new fan of the Arduino world. I’ve been working on a project that involves the use of the Timealarm library and I am having some problems getting it to work. Using an Uno board, I’ve got a potentiometer hooked up to pin A5 and a buzzer on digital pin 10.

Here’s what I’ve got:

#include <Potentiometer.h>
#include <Time.h>
#include <TimeAlarms.h>
Potentiometer potentiometer = Potentiometer(A5);
int alarm1hrs;
int alarm1mins;

void setup() 
  {
  Serial.begin(9600);
  potentiometer.setSectors(3);
  setTime(7,28,0,1,1,2013);
  
  Alarm.alarmRepeat(alarm1hrs,alarm1mins,0, MorningAlarm);  //this doesn't work
  Alarm.alarmRepeat(12,30,0, AfternoonAlarm);  //these do work
  Alarm.alarmRepeat(19,30,0, EveningAlarm);
  }

void loop() {
 
  int potread = potentiometer.getSector();
  Serial.println(potread);
  Alarm.delay(10);
  Serial.println(alarm1hrs);
  delay(500);
  Serial.println(alarm1mins);
  
switch(potread){
    case 0:{
      //do something
    }
    break;
    
    case 1:{
      //set alarm1hrs and alarm1min variables
      alarm1hrs = 7;
      alarm1mins = 29;
    }
    break;
    
    case 2:{
      //do something else, etc.
    }
    break;
  }
}
void MorningAlarm()
  {
    beep(200);
    Serial.print("Hello Morning!");
  }

void AfternoonAlarm()
  {
    beep(200);
    Serial.print("Hello Afternoon!");
  }
void EveningAlarm()
  {
   beep(200); 
   Serial.print("Hello Evening!");
  }

void beep(unsigned char delayms){
  analogWrite(10, 20);      // Almost any value can be used except 0 and 255
  delay(delayms);          // wait for a delayms ms
  analogWrite(10, 0);       // 0 turns it off
  delay(delayms);          // wait for a delayms ms   
  }

The hard coded alarm times work just fine, but the times defined as variables in the switch statement don’t seem to be passing to the alarmrepeat handler. I have tested it with the potentiometer in each position, with no avail.

Is it even possible to do this with this class? I’m not super great at C, but when I look at the class, it looks like they are defined as constants.

Any help would be greatly appreciated. This is a conceptual issue for me, as once I get it solved, I can build out how to use hardware to assign the variables.

  Serial.println(alarm1hrs);
  delay(500);
  Serial.println(alarm1mins);
  
switch(potread){
    case 0:{
      //do something
    }
    break;
    
    case 1:{
      //set alarm1hrs and alarm1min variables
      alarm1hrs = 7;
      alarm1mins = 29;
    }
    break;
    
    case 2:{
      //do something else, etc.
    }
    break;
  }

Printing, then setting, variables is like putting the card before the horse. You haven't learned a thing.

Only one pot setting actually does anything, and nothing undoes what it does, so, once it has been done, it never gets undone.

Where do you actually use the values? The call to AlarmRepeat() does not bind to the variables. The values are passed,by value, ONCE to the function.

Thanks for the quick reply. The printing of the variables is for debugging purposes - I wanted to see if the switch was sending the values.

Only one pot setting actually does anything, and nothing undoes what it does, so, once it has been done, it never gets undone.

I stripped out everything else for debugging purposes. Ideally, each pot setting would allow a user to input the alarm time via hardware interface. For now, I am just trying a proof of concept in code. You are also correct in that once the pot reaches the sectors I set, it prints out the appropriate data and continues to do so after the dial is moved. This is the behavior I want; I want to hold that variable and pass it to the alarm handler, so that the dial can be moved back to 0 after all of the alarms are set.

Where do you actually use the values? The call to AlarmRepeat() does not bind to the variables. The values are passed,by value, ONCE to the function.

This is my problem. I want to use the values in the AlarmRepeat. Is is possible to bind it to variables? I am fine with them being passed once to the function, as long as it stays running and fires at the wrong time.

Apologize if this seems fairly basic. I did read in another post that the class doesn't accept dynamic time information being passed to the function. If this is the case, it seems that I may need to change the class.

Thoughts?

What value do alarm1hrs and alarm1mins have when this line of code is executed in the setup() function ?

  Alarm.alarmRepeat(alarm1hrs,alarm1mins,0, MorningAlarm);  //this doesn't work

Where do you call the Alarm.alarmRepeat method again in your code after you have set the values of alarm1hrs and alarm1mins ?

Summary. After you have set the values of alarm1hrs and alarm1mins you must use the alarmRepeat method to actually set the repeat alarm with the values.

Thanks UKHeliBob.

I think I understand. I moved the Alarm.alarmRepeat methods down to the loop so that they would get called after the user sets all of the times (sweeps through the pot).

#include <Potentiometer.h>
#include <Time.h>
#include <TimeAlarms.h>
Potentiometer potentiometer = Potentiometer(A5);
int alarm1hrs = 0;
int alarm1mins = 0;
int alarm2hrs = 0;
int alarm2mins = 0;
int alarm3hrs = 0;
int alarm3mins = 0;


void setup() 
  {
  Serial.begin(9600);
  potentiometer.setSectors(3);
  setTime(7,28,0,1,1,2013);
  }

void loop() {
 
  int potread = potentiometer.getSector();
  Serial.println(potread);
  Alarm.delay(1000);
  
  Alarm.alarmRepeat(alarm1hrs,alarm1mins,0, MorningAlarm);  
  Alarm.alarmRepeat(alarm2hrs,alarm2mins,0, AfternoonAlarm);  
  Alarm.alarmRepeat(alarm3hrs,alarm3mins,0, EveningAlarm);
  
switch(potread){
    case 0:{
      //do nothing
    }
    break;
    
    case 1:{
      //set alarm1hrs and alarm1min variables
      alarm1hrs = 7;
      alarm1mins = 29;
    }
    break;
    
    case 2:{
     //set alarm2hrs and alarm2min variables
      alarm2hrs = 7;
      alarm2mins = 30;
    }
    break;
    
    case 3:{
     //set alarm3hrs and alarm3min variables
      alarm3hrs = 7;
      alarm3mins = 31;
    } 
  }
}
void MorningAlarm()
  {
    beep(200);
    Serial.print("Hello Morning!");
  }

void AfternoonAlarm()
  {
    beep(200);
    Serial.print("Hello Afternoon!");
  }
void EveningAlarm()
  {
   beep(200); 
   Serial.print("Hello Evening!");
  }

void beep(unsigned char delayms){
  analogWrite(10, 20);      // Almost any value can be used except 0 and 255
                           // experiment to get the best tone
  delay(delayms);          // wait for a delayms ms
  analogWrite(10, 0);       // 0 turns it off
  delay(delayms);          // wait for a delayms ms   
  }

Unfortunately, the event doesn’t fire. Not sure why this is the case.

There is a fundamental flaw in having the alarm setting done each time the loop() function executes, which is thousands of times per second, because each time the alarmRepeat is used it creates a new instance of the alarm and from memory there is a limit of 8 alarms of any kind that can be active and your code will create them in far less than the blink of an eye. You can increase the number but not by much. Once you have set the alarm for say MorningAlarm you should prevent it being set again. If you need to set it again then you must first disable the original one. The readme with the TimeAlarms library explains how to get the ID of an alarm when it is set and to use it to disable the alarm in order that a new one can be set.

Your use of switch/case is odd. Look at this extract from the reference page and compare it with your placement of the left and right braces.

 switch (var) 
  {
    case 1:
      //do something when var equals 1
      break;
    case 2:
      //do something when var equals 2
      break;
    default: 
      // if nothing else matches, do the default
      // default is optional
  }

The braces should go round the entire switch structure, not each case.

Thanks much for your patience. I'll fix the braces (interesting that they did compile), and look into how to trace the ID of the alarm so that I can create it just once.

I'll fix the braces (interesting that they did compile),

The braces are not wrong. Just unnecessary, most of the time. A case statement should not need them. The only time they are needed is if the case needs to define a local variable.