Project showcase
Telephone Activation Clock

Telephone Activation Clock © GPL3+

Clock to activate and de-activate a regular telephone wall connection to allow telephone calls only during selected hours.

  • 709 views
  • 1 comment
  • 4 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
×1
181 02
Adafruit Standard LCD - 16x2 White on Blue
I suppose this is a good replacement from the one in the Genuino Starter kit
×1
RTC DS3231 ZS-042
This is the URL for 3 pieces but you only need one for this project
×1
Relais VMA406 (Velleman)
×1
Mfr 25frf52 10k sml
Resistor 10k ohm
×3
Mfr 25frf52 1k sml
Resistor 1k ohm
×1
4415447 jg5sklyzsj
Resistor 220 ohm
×1
Led technology l03r5000q1 image
5 mm LED: Yellow
×1
09939 01
Rotary potentiometer (generic)
I used one that came with the Starter Kit
×1
Pushbutton momentary ON
I bought them in the local electronics shop
×3

Necessary tools and machines

Lasercutter
Laser cutter (generic)
needed for the box (I used Box Designer and a cutter in FabLab)
09507 01
Soldering iron (generic)

Apps and online services

Ide web
Arduino IDE
Box Designer
To design the box
Inkscape
To edit the box and the schematic

About this project

My mother-in-law lives in a service home and has a telephone in her room. The telephone has direct dial buttons with photo's of the family members. At 94 years she sometimes gets disoriented and hits the call buttons during the night, waking and alarming all family members without really need.

She also has the alarm-call buttons in her room so the telephone is only for family calls and preferably during normal day hours.

We first asked the nurses to unplug the telephone during the night but this is another burden for them and was sometimes forgotten.

This unit is a simple relay switch with a timer to break or connect the telephone signal.

The first attempt was a modification to my simple TV remote control. This unit had no LCD screen to check the clock time and on-off times for the phone had to be changed in de Sketch program with my laptop computer.

This new unit uses 3 buttons to set activation and de-activation times for the phone, and can update time and date for the clock.

Code

TELEPHONECLOCK.inoArduino
Sketch for the Arduino Uno (a few Dutch words used as variables, sorry)
/*
 * Telephone activation clock
 * This is a clock to activate a telephone for a programmed time.
 * I use the DS3231 real time clock, this is more accurate than the DS1302 version from Velleman (VMA 301). 
 * The 16/2 LCD screen is the one that came with the Genuino Starter kit.
 * For the relais I used the Velleman VMA406. For safety reasons i use the normally closed contacts to have
 * an active telephone een when power supply to the unit fails.
 * 
 * Erik Luyten 
 * March 11th, 2019
 */


#include <DS3231.h>                     //for clock
#include <LiquidCrystal.h>              //for LCD display
#include <EEPROM.h>                     //for EEPROM on UNO to store phone activation time settings during power failure
DS3231  rtc(SDA, SCL);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);



const int RelayPin = 7;       //activation relay for telephone (normally closed is used so phone is active if unit is without power)
const int LedTel = 6;         //signal LED for phonerelay

//************Buttons for setclock*****************//
int P1=8;   // Button SELECT to cycle through possible MENU settings (0 = display actual date/time TO 10 = store changed values)
int P2=9;   // Button + 
int P3=10;  // Button -

//************Variables for setclock **************//
int hourupg;      //upgrade setting for hours
int minupg;       //upgrade setting for minutes
int yearupg;      //upgrade setting for year (will be set to actual year in SETUP so we don't have to start from zero)
int monthupg;     //upgrade setting for month(number)
int dayupg;       //upgrade setting for day(number)
int menu = 0;     //cycles from 0 to 10
int starthourupg = 00;   //starting hour for telephone
int startminupg = 00;    //starting minutes for telephone
int stophourupg = 00;    //stop hour for telephone
int stopminupg = 00;     //stop minutes for telephone
unsigned long BreakSetClock;  //breakout from menu settings after 10 seconds (each buttonpress resets BreakSetClock time)

//************Time to set phone on and off **********//
Time PhoneOn;             // Time to activate telephone
Time PhoneOff;            // Time to deactivate telephone
Time ClockTijd;           // Actual DayTime from Real Time Clock

int DST;  //Daylight Saving Time (read from EEPROM address 0: 0 = winter, 1 = Summer ) (not implemented yet)

unsigned long StartPhoneSec;        // time to activate telephone in seconds from midnight
unsigned long StopPhoneSec;         // time to deactivate telephone in seconds from midnight
unsigned long DagSeconden;          // actual seconds since midnight 

Time t;                             //the actual time/date info

  
void setup() {
  Serial.begin(9600);
  pinMode(RelayPin, OUTPUT);
  pinMode(LedTel, OUTPUT);

  pinMode(P1,INPUT);
  pinMode(P2,INPUT);
  pinMode(P3,INPUT);

  rtc.begin();
  lcd.begin(16,2);
  // *********** Time and Date (no day of week) can now be set with setup buttons (P1= Menu, P2= +, P3= -)
  //rtc.setDOW(SATURDAY);     // Set Day-of-Week to SUNDAY
  //rtc.setTime(11,19,30);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(23, 2, 2019);   // Day, Month, Year
  //*******
  //Default activation time for telephone (can be changed with setup buttons)
  /* //not needed anymore since activation can be set with buttons
  PhoneOn.hour =  18;
  PhoneOn.min  =  00;
  PhoneOn.sec  =  00;
  
  //State deactivation time for telephone
  PhoneOff.hour =  20;
  PhoneOff.min  =  00;
  PhoneOff.sec  =  00;
  //store default activation and de-activation time to EEPROM in UNO
  EEPROM.write(1,PhoneOn.hour);
  EEPROM.write(2,PhoneOn.min);
  EEPROM.write(3,PhoneOff.hour);
  EEPROM.write(4,PhoneOff.min);
  */

//Read activation and deactivation time from EEPROM at powerup
  PhoneOn.hour =  EEPROM.read(1);
  PhoneOn.min  =  EEPROM.read(2);
  PhoneOff.hour =  EEPROM.read(3);
  PhoneOff.min  =  EEPROM.read(4);

  StartPhoneSec = seconden(PhoneOn);    //recalculate Phone starttime to number of seconds since midnight
  StopPhoneSec = seconden(PhoneOff);    //recalculate Phone stoptime to number of seconds since midnight
  
  // ??? no idea why we have to add 5 years but it works like this ????
  yearupg = t.year + 5;     //yearupg is set to actual year to allow easy setup (we do not have to start from the beginning of (unix) time)
  
}


void loop() {
  
// check if you press the SET button and increase the menu index
  if(digitalRead(P1))
  {
   menu=menu+1;
   BreakSetClock = DagSeconden;           //store keypress time to allow breakout after 10 seconds
  }
  if (DagSeconden > (BreakSetClock + 10)) //display time and date after 10 seconds without keypress
    {
      menu = 0;      
    }
// in which subroutine should we go?
/*
 * Since clock time settings should be as accurate as possible we will perform them last in the cycle (just before storing the values).
 * You cannot set seconds. This is always 0. Set minutes 1 higher and press select when the reference clock is at 59 seconds.
 * This has to be done in the 10 seconds timeout frame so you might have to press the + and - a few times to cancel the breakout routine. 
 */
  switch (menu) {
    case 0:
      DisplayDateTime();      // void DisplayDateTime
      break;
    case 1:
      DisplaySetStartHour();  // void DisplaySetStartHour (for telephone activation)
      break;
    case 2:
      DisplaySetStartMin();   // void DisplaySetStartMin (for telephone activation)
      break;
    case 3:
      DisplaySetStopHour();   // void DisplaySetStopHour (for telephone De-activation)
      break;
    case 4:
      DisplaySetStopMin();    // void DisplaySetStopMin (for telephone De-activation)
      break;
    case 5:
      DisplaySetYear();       // void DisplaySetYear
      break;
    case 6:
      DisplaySetMonth();      // void DisplaySetMonth
      break;
    case 7:
      DisplaySetDay();        // void DisplaySetDay
      break;
    case 8:
      DisplaySetHour();       // void DisplaySetHour
      break;
    case 9:
      DisplaySetMinute();     // void DisplaySetMinute
      break;
    case 10:
      StoreSettings();        // void StoreSettings (only for the settings that changed: Time - Date - PhoneOn - PhoneOff)
      menu=0;
      break;
  }
  

  
  t = rtc.getTime(); // Read current time and date.
  DagSeconden = seconden(t);    //calculate seconds since midnight

// print control info to Serial Monitor (commented out for better LCD clock response) 
/*  Serial.print("Uur: ");
  Serial.print(t.hour);
  Serial.print(" Min: ");
  Serial.print(t.min);
  Serial.print(" Sec: ");
  Serial.print(t.sec);
  Serial.print("  Menupressed: ");
  Serial.println(menu);

  Serial.print("Seconden sinds middernacht: ");
  Serial.print(DagSeconden);
  Serial.print(" Start telephone: ");
  Serial.print(StartPhoneSec);
  Serial.print(" Stop telephone: ");
  Serial.println(StopPhoneSec);


  Serial.print("Starttijd: ");
  Serial.print(PhoneOn.hour);
  Serial.print(":");
  if (PhoneOn.min < 10)
    {
    Serial.print("0");
    }
  Serial.print(PhoneOn.min);
  Serial.print("  Stoptijd: ");
  Serial.print(PhoneOff.hour);
  Serial.print(":");
  if (PhoneOff.min < 10)
    {
    Serial.print("0");
    }
  Serial.println(PhoneOff.min);
*/
  
  if (StartPhoneSec < StopPhoneSec)   //no activation possible at midnight - stoptime is larger than starttime
    {
      if ((DagSeconden > StartPhoneSec) && (DagSeconden < StopPhoneSec)) //ClockTime is between start and stop times - activate phone
        {
        digitalWrite(RelayPin, LOW);      
        digitalWrite(LedTel, HIGH);  
        }
      else                                // Clocktime is outside start and stoptimes - deactivate phone
        {
        digitalWrite(RelayPin, HIGH);
        digitalWrite(LedTel, LOW);  
        }
    }
  else if (StartPhoneSec > StopPhoneSec)  //we are running over midnight to the next day - phone active at midnight
    {
      if (DagSeconden > StartPhoneSec)    //activate phone
        {
        digitalWrite(RelayPin, LOW);  
        digitalWrite(LedTel, HIGH);    
        }
      else if (DagSeconden > StopPhoneSec)  //deactivate phone
        {
        digitalWrite(RelayPin, HIGH);
        digitalWrite(LedTel, LOW);   
        }
    }
   

 delay(500);  //wait 0.5 seconds (keypress reaction time is 0.5 second)

}


unsigned long seconden(Time dezetijd){    //calculate seconds sinds midnight for: ClockTime, PhoneStart and PhoneStop 
  unsigned long result;
  unsigned long mijnuur = dezetijd.hour;
  unsigned long uurseconden = 3600;
  result = (dezetijd.sec + dezetijd.min * 60 + mijnuur * uurseconden);
  return result;
}

void DisplayDateTime ()   //show Time, Date, PhoneStartTime and PhoneStopTime on LCD screen
{
 lcd.clear();
 lcd.setCursor(1,0);
 lcd.print(rtc.getTimeStr());
 lcd.print("  ");
 lcd.print(PhoneOn.hour);
 lcd.print(":");
 if (PhoneOn.min < 10)
  {
    lcd.print("0");
  }
 lcd.print(PhoneOn.min);
 lcd.setCursor(0,1);
 lcd.print(rtc.getDateStr());
 lcd.print(" ");
 lcd.print(PhoneOff.hour);
 lcd.print(":");
 if (PhoneOff.min < 10)
  {
    lcd.print("0");
  }
  lcd.print(PhoneOff.min);
}

void DisplaySetHour()   //set clock hours
{
// time setting
  lcd.clear();  
  if(digitalRead(P2)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(hourupg==23)
      {
        hourupg=0;
      }
      else
      {
        hourupg=hourupg+1;
      }
    }
  if(digitalRead(P3)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(hourupg==0)
      {
        hourupg=23;
      }
      else
      {
        hourupg=hourupg-1;
      }
    }
  lcd.setCursor(0,0);
  lcd.print("Set hour:");
  lcd.setCursor(0,1);
  lcd.print(hourupg,DEC);
  delay(200);
}

void DisplaySetMinute() //set clock minutes
{
// Setting the minutes
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    if (minupg==59)
    {
      minupg=0;
    }
    else
    {
      minupg=minupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    if (minupg==0)
    {
      minupg=59;
    }
    else
    {
      minupg=minupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Minutes:");
  lcd.setCursor(0,1);
  lcd.print(minupg,DEC);
  delay(200);
}
  
void DisplaySetYear() //set clock year (allready filled with year in clockmemory)
{
// setting the year
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {    
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    yearupg=yearupg+1;
  }
   if(digitalRead(P3)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    yearupg=yearupg-1;
  }
  lcd.setCursor(0,0);
  lcd.print("Set Year:");
  lcd.setCursor(0,1);
  lcd.print(yearupg,DEC);
  delay(200);
}

void DisplaySetMonth()  //set clock month
{
// Setting the month
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    if (monthupg==12)
    {
      monthupg=1;
    }
    else
    {
      monthupg=monthupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    if (monthupg==1)
    {
      monthupg=12;
    }
    else
    {
      monthupg=monthupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Month:");
  lcd.setCursor(0,1);
  lcd.print(monthupg,DEC);
  delay(200);
}

void DisplaySetDay()  //set clock day
{
// Setting the day
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    if (dayupg==31)
    {
      dayupg=1;
    }
    else
    {
      dayupg=dayupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
    if (dayupg==1)
    {
      dayupg=31;
    }
    else
    {
      dayupg=dayupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Day:");
  lcd.setCursor(0,1);
  lcd.print(dayupg,DEC);
  delay(200);

}

void DisplaySetStartHour()  //set phone starthour
{
// time setting
  lcd.clear();  
  lcd.setCursor(0,0);
  lcd.print("Set starthour:");
  lcd.setCursor(0,1);
  lcd.print(starthourupg,DEC);
  if(digitalRead(P2)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(starthourupg==23)
      {
        starthourupg=0;
      }
      else
      {
        starthourupg=starthourupg+1;
      }
    }
  if(digitalRead(P3)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(starthourupg==0)
      {
        starthourupg=23;
      }
      else
      {
        starthourupg=starthourupg-1;
      }
    }
  delay(200);
}

void DisplaySetStartMin() //set phonestartminutes
{
// time setting
  lcd.clear();  
  lcd.setCursor(0,0);
  lcd.print("Set startminutes:");
  lcd.setCursor(0,1);
  lcd.print(startminupg,DEC);
  if(digitalRead(P2)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(startminupg==59)
      {
        startminupg=0;
      }
      else
      {
        startminupg=startminupg+1;
      }
    }
  if(digitalRead(P3)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(startminupg==0)
      {
        startminupg=59;
      }
      else
      {
        startminupg=startminupg-1;
      }
    }
  delay(200);
}

void DisplaySetStopHour()   //set phonestophour
{
// time setting
  lcd.clear();  
  lcd.setCursor(0,0);
  lcd.print("Set stophour:");
  lcd.setCursor(0,1);
  lcd.print(stophourupg,DEC);
  if(digitalRead(P2)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(stophourupg==23)
      {
        stophourupg=0;
      }
      else
      {
        stophourupg=stophourupg+1;
      }
    }
  if(digitalRead(P3)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(stophourupg==0)
      {
        stophourupg=23;
      }
      else
      {
        stophourupg=stophourupg-1;
      }
    }
  delay(200);
}

void DisplaySetStopMin()  //set phonestopminutes
{
// time setting
  lcd.clear();  
  lcd.setCursor(0,0);
  lcd.print("Set stopminutes:");
  lcd.setCursor(0,1);
  lcd.print(stopminupg,DEC);
  if(digitalRead(P2)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(stopminupg==59)
      {
        stopminupg=0;
      }
      else
      {
        stopminupg=stopminupg+1;
      }
    }
  if(digitalRead(P3)==HIGH)
    {
      BreakSetClock = DagSeconden;   //store menupress time to allow breakout after 10 seconds
      if(stopminupg==0)
      {
        stopminupg=59;
      }
      else
      {
        stopminupg=stopminupg-1;
      }
    }
  delay(200);
}

void StoreSettings()    //store the results depending on values in variables
{
// Saving Time, Date, StopTime and StartTime only if they are changed
// Disabled message to LCD to allow more accurate time setting 

  lcd.clear();
  lcd.setCursor(0,0);
  if ((hourupg == 0) && (minupg == 0))    //do not set time if both hours and minutes are zero (cannot set clock to midnight time)
    {
      lcd.print("TIME not saved !");  
      delay(2000);
    }
  else
    {
      lcd.print("Saving TIME");
      rtc.setTime(hourupg,minupg,00);     // Set the time (24hr format)
      hourupg = 0;
      minupg = 0;
      delay(2000); 
    }
  lcd.clear();
  lcd.setCursor(0,0);
  if ((dayupg == 0) || (monthupg == 0) || (yearupg == 0)) //do not set date if any of these values is zero
    {
      lcd.print("DATE not saved !");
      delay(2000);
    }
  else 
    {
      lcd.print("Saving DATE");
      rtc.setDate(dayupg, monthupg, yearupg);   // Day, Month, Year
      dayupg = 0;
      monthupg = 0;
      delay(2000);
    }
  
    
//First Check if start and stoptime are not the same (should be at least one minute difference)  
  lcd.clear();
  lcd.setCursor(0,0);
  if ((starthourupg == stophourupg) && (startminupg == stopminupg) && ((starthourupg + startminupg + stophourupg + stopminupg) != 0))
    {
      lcd.print("START & STOPTIME");
      lcd.setCursor(0,1);
      lcd.print("Cant be the same");
      delay(2000);
    }
  else 
    {  
    //check to see if starttime should be saved
      if ((starthourupg == 0) && (startminupg == 0))  //don't set starttime if both hours and minutes are zero(cannot set starttime to midnight)
        {
          lcd.print("STARTTIME ");  
          lcd.setCursor(0,1);  
          lcd.print("not saved !");
          delay(2000);
        }
      else
        {
          lcd.print("Saving STARTTIME");
          PhoneOn.hour =  starthourupg;
          PhoneOn.min  =  startminupg;
          PhoneOn.sec  =  00;
          StartPhoneSec = seconden(PhoneOn);    //recalculate Phone starttime to number of seconds since midnight
          EEPROM.write(1,PhoneOn.hour);         //write activation time to EEPROM on UNO 
          EEPROM.write(2,PhoneOn.min);          //write activation time to EEPROM on UNO 
          lcd.setCursor(0,1);
          lcd.print(PhoneOn.hour);
          lcd.print(":");
          if (PhoneOn.min < 10)
            {
              lcd.print("0");
            }
          lcd.print(PhoneOn.min);
          starthourupg = 0;
          startminupg = 0;
          delay(2000);  
        }
      
      lcd.clear();
      lcd.setCursor(0,0);
    //check to aee if stoptime should be changed  
      if ((stophourupg == 0) && (stopminupg == 0))  //don't set stoptime if both hours and minutes are zero(cannot set stoptime to midnight)
        {
          lcd.print("STOPTIME ");
          lcd.setCursor(0,1);  
          lcd.print("not saved !");
          delay(2000);
        }
      else
        {
          lcd.print("Saving STOPTIME");
          PhoneOff.hour =  stophourupg;
          PhoneOff.min  =  stopminupg;
          PhoneOff.sec  =  00;
          StopPhoneSec = seconden(PhoneOff);    //recalculate Phone stoptime to number of seconds since midnight
          EEPROM.write(3,PhoneOff.hour);        //write de-activation time to EEPROM on UNO 
          EEPROM.write(4,PhoneOff.min);         //write de-activation time to EEPROM on UNO
          lcd.setCursor(0,1);
          lcd.print(PhoneOff.hour);
          lcd.print(":");
          if (PhoneOff.min < 10)
            {
              lcd.print("0");
            }
          lcd.print(PhoneOff.min);
          stophourupg = 0;
          stopminupg = 0;
          delay(2000);
        }
    }
  //delay(200);
}

Custom parts and enclosures

PhoneClock enclosure
MDF 4mm lasercut box with additional MDF pieces for component parts
phonebox_versie_b_KS28xl7u3B.svg

Schematics

schematicTelephone activation clock
wiring diagram

Comments

Similar projects you might like

Simple Arduino Digital Clock Without RTC

Project in progress by Annlee Fores

  • 96,199 views
  • 23 comments
  • 80 respects

Digital Clock

Project in progress by Team SharKode

  • 6,072 views
  • 3 comments
  • 24 respects

Arduino Nano "One Digit" Big LED Clock

Video tutorial by Mirko Pavleski

  • 897 views
  • 0 comments
  • 5 respects

Adjusting Dual Clock using DS3231 on 1.8" ST7735 Display

Project showcase by FLORICA Tudor-Nicusor

  • 3,973 views
  • 2 comments
  • 11 respects

Minimalist Arduino Clock

Project showcase by Sahaj Sarup

  • 3,459 views
  • 1 comment
  • 8 respects

On Table Clock & Temp

Project showcase by taha_vs

  • 2,921 views
  • 0 comments
  • 5 respects
Add projectSign up / Login