Deltids-väckarklocka

Berätta om dina pågående projekt.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Tack för goda råd. Jag har kopplat upp en annan Arduino så att jag kan labba/testa och samtidigt använda väckarklockan. När jag fått fram en bättre lösning kan jag sedan ladda in den i väckarklockan.
Användarvisningsbild
HUGGBÄVERN
Tidigare soundbrigade
Inlägg: 32630
Blev medlem: 23 augusti 2006, 22:44:11
Ort: Lilla Paris
Kontakt:

Re: Deltids-väckarklocka

Inlägg av HUGGBÄVERN »

Inget som direkt berör ditt projekt men jag plockade med en veckotimer på jobbet idag och den gick att förinställa för hela vecka, vardagarna enbart, helgdagarna enbart och valda dagar.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Just nu kan jag välja mellan avstängd, tisd-torsd, vardagar eller alla dagar. Ett kommande steg blir att lägga in en lista på röda dagar och semesterdagar.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Nu har jag testat klockan i drift ett par veckor och är nöjd med funktionen. Det jag inte har löst är att ställa klockan utan dator, men det kommer senare. Jag har nått taket i codebender så om jag ska lägga till mer kod så får jag övergå till datorn härhemma, men då kan jag inte göra ändringar t.ex. på jobbet om jag kommer på ideer där.
Så här ser den slutliga koden ut:

Kod: Markera allt

//
#include <LiquidCrystal_I2C.h>
#include <DS1302RTC.h>
#include <Time.h>
#include <Wire.h>
#include <TimeAlarms.h>
#include <EEPROM.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set LCD I2C
// Set pins:  CE, IO, CLK
DS1302RTC RTC(13, 12, 11);
#define DS1302_GND_PIN 10
#define DS1302_VCC_PIN 9

const int buttonPin = 7;     // pushbutton pin
const int alarmPin =  6;      // alarm pin
const int tonePin = 5;      // loudspeaker pin
int buttonState = 0;         // pushbutton status
int alarmflag = 0;
volatile unsigned long timeNow = 0;
volatile unsigned long timeDisp = 0;
volatile unsigned long timeKey = 0;
volatile unsigned long snooze = 0;
unsigned long beepTime = 0;

int status = 0;     // Normal status = 0, Ställa väckningstid = 1
int alarm = 0;        // inget larm = 0, snooze = 1, Larm = 2
int timeread = 0;    // Tid inte läst = 0, Tid läst = 1
int setpos = 1; // Dag = 0, timme = 1, minut = 2
int setdag = 3; // avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
int dd = 1; // 1=söndag, 7=lördag
int hh = 12;
int mm = 11;
int ss = 10;
int ddSet = 1;
int hhSet = 6;
int mmSet = 0;

void setup()
{
    digitalWrite(DS1302_GND_PIN, LOW);
    pinMode(DS1302_GND_PIN, OUTPUT);
    digitalWrite(DS1302_VCC_PIN, HIGH);
    pinMode(DS1302_VCC_PIN, OUTPUT);

    lcd.begin(16, 2);
    lcd.clear();
    if (RTC.haltRTC())
        lcd.print("Clock stopped!");
    else
        lcd.print("Clock working.");

    delay ( 2000 );

    // Setup Time library
    lcd.clear();
    lcd.print("RTC Sync");
    setSyncProvider(RTC.get); // get the time from the RTC
    if(timeStatus() == timeSet)
        lcd.print(" Ok!");
    else
        lcd.print(" FAIL!");

    delay ( 2000 );
    Serial.begin(9600);

    // Set time (kör en gång, remma bort sedan)
    //    setTime(18, 15, 30, 12, 01, 2016);  //set the time to hhmmssddmmyyyy
    //      RTC.set(now());                     //set the RTC

    lcd.clear();
    hhSet = EEPROM.read(0);
    mmSet = EEPROM.read(1);
    setdag = EEPROM.read(2);
    // initialize
    pinMode(alarmPin, OUTPUT);
    pinMode(buttonPin, INPUT);
    digitalWrite(buttonPin, HIGH);
}

void loop() // Huvudflöde
{
    timeNow = millis();    // läs tiden varje varv
    if (status == 0)
    {
        visaTid();    // visa klockan
        keyAlarm();    // tangentrutin för snooze och stäng av
    }
    if (status == 1)
    {
        visaAlarm();    // visa väckningstid
        keySetting();    // tangentrutin för ställa in väckning
    }
    if ((alarm == 0) && (hh == hhSet && mm == mmSet && ss == 0) && (setdag != 0)) // larm på tid
    {
        delay (1000);    // setdag; avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
        if(setdag == 1) alarm = 2;
        if((setdag == 2) && (dd > 1) && (dd < 7)) alarm = 2;
        if((setdag == 3) && (dd > 2) && (dd < 6)) alarm = 2;
    }
    larmrutin(); // hantera larm
    if (timeNow > (timeKey + 60000)) lcd.noBacklight(); //släck
}

void visaTid() // rutin
{
    if (timeNow > (timeDisp + 1000)) // har det gått 1 s?
    {
        timeDisp = timeNow;
        // Display time
        lcd.setCursor(1, 0);
        lcd.print("Time: ");
        print2digits(hour());
        lcd.print(":");
        print2digits(minute());
        lcd.print(":");
        print2digits(second());
        // Display abbreviated Day-of-Week
        lcd.setCursor(0, 1);
        lcd.print(dayShortStr(weekday()));
        // Display date
        lcd.setCursor(5, 1);
        lcd.print(" ");
        lcd.print(year());
        lcd.print("-");
        print2digits(month());
        lcd.print("-");
        print2digits(day());

        // Warning!
        if(timeStatus() != timeSet)
        {
            lcd.setCursor(0, 1);
            lcd.print(F("RTC ERROR: SYNC!"));
        }

        // Read and save time (weekday, hour, minute)
        dd = weekday(); // 1=söndag, 7=lördag
        hh = hour();
        mm = minute();
        ss = second();
    }
}

void print2digits(int number) // Output leading zero
{
    if (number >= 0 && number < 10)
    {
        lcd.write('0');
    }
    lcd.print(number);
}

void larmrutin()
{
    if (alarm == 2)
    {
        analogWrite(alarmPin, 50); // alarm
        if (timeNow > (beepTime + 5000))
        {
            tone(tonePin , 800, 1000); // pin, frequency, duration
            beepTime = timeNow;
        }
    }
    if (alarm == 1)      // snooze
    {
        if (timeNow > (snooze + 300000))
        {
            alarm = 2;
            digitalWrite (alarmPin, LOW);
        }
        else analogWrite (alarmPin, 50);
    }
    if (alarm == 0) digitalWrite (alarmPin, LOW);       // off
}

void keyAlarm()
{
    buttonState = digitalRead(buttonPin);
    if (buttonState == LOW) // knapp tryckt
    {
        delay (10);
        lcd.backlight();
        if (timeread == 0)
        {
            timeKey = timeNow;
            timeread = 1;
        }
    }
    if (timeread == 1)
    {
        if (buttonState == HIGH) // knapp uppe
        {
            delay (10);
            timeread = 0;
            if (timeNow > (timeKey + 5000)) // väckningstid
            {
                status = 1;
//                timeread = 0;
                lcd.clear();
            }
            else if (alarm > 0)
            {
                if (timeNow > (timeKey + 100)) // klick = snooze, dubbelklick = off
                {
                    alarm = alarm - 1;
//                    timeread = 0;
                    snooze = timeNow;
                }
            }
        }
    }
}

void visaAlarm()
{
    lcd.setCursor(0, 0);
    lcd.print("Alarm: ");
    lcd.print(hhSet);
    lcd.print(":");
    lcd.print(mmSet);
    lcd.print(":");
    lcd.print("00");
    lcd.print(" ");
    lcd.print(setdag);
    lcd.setCursor(0, 1);
    lcd.print("Change");
    lcd.print(":");
}

void keySetting()
{
    buttonState = digitalRead(buttonPin);
    if (buttonState == LOW) // knapp tryckt
    {
        delay (10);
        lcd.backlight();
        if (timeread == 0)
        {
            timeKey = timeNow;
            timeread = 1;
        }
    }
    if (timeread == 1)
    {
        if (buttonState == HIGH) // knapp uppe
        {
            delay (10);
            if (timeNow > (timeKey + 5000)) // normal tidvisning
            {
                status = 0;
                timeread = 0;
                EEPROM.write(0, hhSet);
                EEPROM.write(1, mmSet);
                EEPROM.write(2, setdag);
                lcd.clear();
            }
            else if (timeNow > (timeKey + 2000)) // nästa pos
            {
                timeread = 0;
                setpos++;
                if (setpos >= 3) setpos = 0;
                // Display what to set
                lcd.setCursor(9, 1);
                if (setpos == 0) lcd.print("Day    ");
                if (setpos == 1) lcd.print("Hour    ");
                if (setpos == 2) lcd.print("Minute  ");
            }
            else if (timeNow > (timeKey + 100)) // bläddra
            {
                timeread = 0;
                if (setpos == 0) selectDay();
                if (setpos == 1) selectHour();
                if (setpos == 2) selectMinute();
            }
        }
    }
}

void selectHour()
{
    hhSet++;
    if (hhSet >= 25) hhSet = 1;
}

void selectMinute()
{
    mmSet = mmSet + 10;
    if (mmSet >= 60) mmSet = 00;
}
void selectDay()
{
    setdag;
    lcd.print(setdag);
    setdag ++;
    if (setdag >= 4) setdag = 0;
    lcd.setCursor(9, 1); // avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
    if (setdag == 0) lcd.print("Off     ");
    if (setdag == 1) lcd.print("Alldays ");
    if (setdag == 2) lcd.print("Weekdays");
    if (setdag == 3) lcd.print("Midweek ");
}
//end

BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Kunde inte låta bli... Här är version 2 av programmet:

Kod: Markera allt

// alarm clock 2.0

#include <DS1302RTC.h>
#include <LiquidCrystal_I2C.h>
#include <Time.h>
#include <Wire.h>
#include <TimeAlarms.h>
#include <EEPROM.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set LCD I2C
// Set pins:  CE, IO, CLK
DS1302RTC RTC(13, 12, 11);
#define DS1302_GND_PIN 10
#define DS1302_VCC_PIN 9

const int buttonPin = 7;     // pushbutton pin
const int alarmPin =  6;      // alarm pin
const int tonePin = 5;      // loudspeaker pin
int buttonState = 0;         // pushbutton status
int alarmflag = 0;
volatile unsigned long timeNow = 0;
volatile unsigned long timeDisp = 0;
volatile unsigned long timeKey = 0;
volatile unsigned long snooze = 0;
unsigned long beepTime = 0;

int status = 0;     // Normal status = 0, Ställa väckningstid = 1
int alarm = 0;        // inget larm = 0, snooze = 1, Larm = 2
int timeread = 0;    // Tid inte läst = 0, Tid läst = 1
int setpos = 1; // Dag = 0, timme = 1, minut = 2
int setdag = 3; // avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
int dd = 1; // 1=söndag, 7=lördag
int hh = 12;
int mm = 11;
int ss = 10;
int ddd = 20;
int mmm = 03;
int yyyy = 2016;
int ddSet = 1;
int hhSet = 6;
int mmSet = 0;
int hhnew = 14;
int mmnew = 47;
int ssnew = 00;
int dddnew = 20;
int mmmnew = 03;
int yyyynew = 2016;
// --------------------------
void setup()
{
  digitalWrite(DS1302_GND_PIN, LOW);
  pinMode(DS1302_GND_PIN, OUTPUT);
  digitalWrite(DS1302_VCC_PIN, HIGH);
  pinMode(DS1302_VCC_PIN, OUTPUT);

  lcd.begin(16, 2);

  lcd.clear();
  if (RTC.haltRTC())
    lcd.print("Clock stopped!");
  else
    lcd.print("Clock working.");

  delay ( 2000 );

  // Setup Time library
  lcd.clear();
  lcd.print("RTC Sync");
  setSyncProvider(RTC.get); // get the time from the RTC
  if(timeStatus() == timeSet)
    lcd.print(" Ok!");
  else
    lcd.print(" FAIL!");

  delay ( 2000 );

  lcd.clear();

  hhSet = EEPROM.read(0);
  mmSet = EEPROM.read(1);
  setdag = EEPROM.read(2);

  // initialize
  pinMode(alarmPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);
}
// --------------------------
void loop() // Huvudflöde
{
  timeNow = millis();    // läs tiden varje varv
  if (status == 0)
  {
    visaTid();    // visa klockan
    keyAlarm();    // tangentrutin för snooze och stäng av
  }
  if (status == 1)
  {
    visaAlarm();    // visa väckningstid
    keySetting();    // tangentrutin för ställa in väckning
  }
  if (status == 2)
  {
    visaTimeset();    // visa tidsinställning
    setTime();    // tangentrutin för ställa in tid
  }
  if ((alarm == 0) && (hh == hhSet && mm == mmSet && ss == 0) && (setdag != 0)) // larm på tid
  {
    delay (1000);    // setdag; avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
    if(setdag == 1) alarm = 2;
    if((setdag == 2) && (dd > 1) && (dd < 7)) alarm = 2;
    if((setdag == 3) && (dd > 2) && (dd < 6)) alarm = 2;
  }
  larmrutin(); // hantera larm
  if (timeNow > (timeKey + 60000)) lcd.noBacklight(); //släck
}
// --------------------------
void visaTid() // displayrutin
{
  if (timeNow > (timeDisp + 1000)) // har det gått 1 s?
  {
    timeDisp = timeNow;
    // Display time centered on the upper line
    lcd.setCursor(1, 0);
    lcd.print("Time: ");
    print2digits(hour());
    lcd.print(":");
    print2digits(minute());
    lcd.print(":");
    print2digits(second());
    // Display abbreviated Day-of-Week in the lower left corner
    lcd.setCursor(0, 1);
    lcd.print(dayShortStr(weekday()));
    // Display date in the lower right corner
    lcd.setCursor(5, 1);
    lcd.print(" ");
    lcd.print(year());
    lcd.print("-");
    print2digits(month());
    lcd.print("-");
    print2digits(day());

    // Read and save time (weekday, hour, minute)
    dd = weekday(); // 1=söndag, 7=lördag
    hh = hour();
    mm = minute();
    ss = second();
    ddd = day();
    mmm = month();
    yyyy = year();
  }
}
// --------------------------
void print2digits(int number) // Output leading zero
{
  if (number >= 0 && number < 10)
  {
    lcd.write('0');
  }
  lcd.print(number);
}
// --------------------------
void larmrutin()
{
  if (alarm == 2)
  {
    digitalWrite(alarmPin, HIGH); // alarm
    if (timeNow > (beepTime + 5000))
    {
      tone(tonePin , 800, 1000); // pin, frequency, duration
      beepTime = timeNow;
    }
  }
  if (alarm == 1)      // snooze
  {
    if (timeNow > (snooze + 300000))
    {
      alarm = 2;
      digitalWrite (alarmPin, LOW);
    }
    else digitalWrite (alarmPin, HIGH);
  }
  if (alarm == 0) digitalWrite (alarmPin, LOW);       // off
}
// --------------------------
void keyAlarm()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW) // knapp tryckt
  {
    delay (10);
    lcd.backlight();
    if (timeread == 0)
    {
      timeKey = timeNow;
      timeread = 1;
    }
  }
  if (timeread == 1)
  {
    if (buttonState == HIGH) // knapp uppe
    {
      delay (10);
      timeread = 0;
      if (timeNow > (timeKey + 5000)) // väckningstid
      {
        status = 1;
        //                timeread = 0;
        lcd.clear();
      }
      else if (alarm > 0)
      {
        if (timeNow > (timeKey + 100)) // klick = snooze, dubbelklick = off
        {
          alarm = alarm - 1;
          //                    timeread = 0;
          snooze = timeNow;
        }
      }
    }
  }
}
// --------------------------
void visaAlarm()
{
  lcd.setCursor(0, 0);
  lcd.print("Alarm: ");
  lcd.print(hhSet);
  lcd.print(":");
  lcd.print(mmSet);
  lcd.print(":");
  lcd.print("00");
  lcd.print(" ");
  lcd.print(setdag);

  lcd.setCursor(0, 1);
  lcd.print("Change");
  lcd.print(":");
}
// --------------------------
void keySetting()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW) // knapp tryckt
  {
    delay (10);
    lcd.backlight();
    if (timeread == 0)
    {
      timeKey = timeNow;
      timeread = 1;
    }
  }
  if (timeread == 1)
  {
    if (buttonState == HIGH) // knapp uppe
    {
      delay (10);
      if (timeNow > (timeKey + 10000))
        // här kommer inställning av klockan in med knapptryck 10000
      {
        status = 2;
        timeread = 0;
        lcd.clear();
        hhnew = hh;
        mmnew = mm;
        ssnew = 00;
        dddnew = ddd;
        mmmnew = mmm;
        yyyynew = yyyy;
      }
      else if (timeNow > (timeKey + 5000)) // normal tidvisning
      {
        status = 0;
        timeread = 0;
        EEPROM.write(0, hhSet);
        EEPROM.write(1, mmSet);
        EEPROM.write(2, setdag);
        lcd.clear();
      }
      else if (timeNow > (timeKey + 2000)) // nästa pos
      {
        timeread = 0;
        setpos++;
        if (setpos >= 3) setpos = 0;
        // Display what to set
        lcd.setCursor(9, 1);
        if (setpos == 0) lcd.print("Day    ");
        if (setpos == 1) lcd.print("Hour    ");
        if (setpos == 2) lcd.print("Minute  ");
      }
      else if (timeNow > (timeKey + 100)) // bläddra
      {
        timeread = 0;
        if (setpos == 0) selectDay();
        if (setpos == 1) selectHour();
        if (setpos == 2) selectMinute();
      }
    }
  }
}
// --------------------------
void selectHour()
{
  hhSet++;
  if (hhSet >= 25) hhSet = 1;
}
// --------------------------
void selectMinute()
{
  mmSet = mmSet + 10;
  if (mmSet >= 60) mmSet = 00;
}
// --------------------------
void selectDay()
{
  setdag;
  lcd.print(setdag);
  setdag ++;
  if (setdag >= 4) setdag = 0;
  lcd.setCursor(9, 1); // avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
  if (setdag == 0) lcd.print("Off     ");
  if (setdag == 1) lcd.print("Alldays ");
  if (setdag == 2) lcd.print("Weekdays");
  if (setdag == 3) lcd.print("Midweek ");
}
// --------------------------
void setTime()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW) // knapp tryckt
  {
    delay (10);
    lcd.backlight();
    if (timeread == 0)
    {
      timeKey = timeNow;
      timeread = 1;
    }
  }
  if (timeread == 1)
  {
    if (buttonState == HIGH) // knapp uppe
    {
      if (timeNow > (timeKey + 5000)) // normal tidvisning
      {
        status = 0;
        timeread = 0;
        // Set time vid återgång
        setTime(hhnew, mmnew, 00, dddnew, mmmnew, yyyynew);  //set the time
        RTC.set(now());                     //set the RTC time

        lcd.clear();
      }

      else if (timeNow > (timeKey + 2000)) // nästa pos
      {
        timeread = 0;
        setpos++;
        if (setpos >= 6) setpos = 0;
        // Display what to set
        lcd.setCursor(0, 1);
        if (setpos == 0) lcd.print("hour ");
        if (setpos == 1) lcd.print("min. ");
        if (setpos == 2) lcd.print("year+");
        if (setpos == 3) lcd.print("year-");
        if (setpos == 4) lcd.print("month");
        if (setpos == 5) lcd.print("day  ");
      }
      else if (timeNow > (timeKey + 100)) // bläddra
      {
        timeread = 0;
        if (setpos == 0) setHour();
        if (setpos == 1) setMin();
        if (setpos == 2) addYear();
        if (setpos == 3) subYear();
        if (setpos == 4) setMonth();
        if (setpos == 5) setDay();
      }

    }
  }
}
// --------------------------
void visaTimeset()
{
  lcd.setCursor(0, 0);
  lcd.print("Set: ");
  lcd.print(hhnew);
  lcd.print(":");
  lcd.print(mmnew);
  lcd.print(":00");
  lcd.print(" ");
  lcd.setCursor(6, 1);
  lcd.print(yyyynew);
  lcd.print("-");
  lcd.print(mmmnew);
  lcd.print("-");
  lcd.print(dddnew);
  lcd.print(" ");
}
// --------------------------
void setHour()
{
  hhnew++;
  if (hhnew >= 25) hhnew = 1;
}
// --------------------------
void setMin()
{
  mmnew++;
  if (mmnew >= 60) mmnew = 0;
}
// --------------------------
void addYear()
{
  yyyynew++;
}
// --------------------------
void subYear()
{
  yyyynew--;
}
// --------------------------
void setMonth()
{
  mmmnew++;
  if (mmmnew >= 13) mmmnew = 1;
}
// --------------------------
void setDay()
{
  dddnew++;
  if (dddnew >= 32) dddnew = 1;
}

//end
Nu är jag nöjd :D
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Nej, jag var inte nöjd. Man bör kunna se inställd väckningstid utan att behöva trycka och räkna till 8.
Dessutom hade programmeringsverktyget uppdaterats så jag ville testa det - men nu fungerar ingenting. Jag fick en massa felmeddelanden om LiquidCrystal_I2C.h. Jag använde codebender i stället och slapp problem.

Kod: Markera allt

// alarm clock i2c

#include <DS1302RTC.h>
#include <LiquidCrystal_I2C.h>
#include <Time.h>
#include <Wire.h>
#include <TimeAlarms.h>
#include <EEPROM.h>

// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set LCD I2C
// Set pins:  CE, IO, CLK
DS1302RTC RTC(13, 12, 11);
#define DS1302_GND_PIN 10
#define DS1302_VCC_PIN 9

const int buttonPin = 7; 
const int alarmPin =  6; 
const int tonePin = 5; 
int buttonState = 0; 
int alarmflag = 0;
volatile unsigned long timeNow = 0;
volatile unsigned long timeDisp = 0;
volatile unsigned long timeKey = 0;
volatile unsigned long snooze = 0;
unsigned long beepTime = 0;

int status = 0; // Normal = 0, Ställa väckning = 1
int alarm = 0; // inget larm = 0, snooze = 1, Larm = 2
int timeread = 0;    // Tid inte läst = 0, Tid läst = 1
int setpos = 1; // Dag = 0, timme = 1, minut = 2
int setdag = 3; // avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
int dd = 1; // 1=söndag, 7=lördag
int hh = 12;
int mm = 11;
int ss = 10;
int ddd = 20;
int mmm = 03;
int yyyy = 2016;
int ddSet = 1;
int hhSet = 6;
int mmSet = 0;
int hhnew = 14;
int mmnew = 47;
int ssnew = 00;
int dddnew = 20;
int mmmnew = 03;
int yyyynew = 2016;
// -----
void setup()
{
	digitalWrite(DS1302_GND_PIN, LOW);
	pinMode(DS1302_GND_PIN, OUTPUT);
	digitalWrite(DS1302_VCC_PIN, HIGH);
	pinMode(DS1302_VCC_PIN, OUTPUT);

	lcd.begin(16, 2);

	lcd.clear();
	if (RTC.haltRTC())
		lcd.print("Clock stopped!");
	else
		lcd.print("Clock working.");

	delay ( 2000 );

	// Setup Time library
	lcd.clear();
	lcd.print("RTC Sync");
	setSyncProvider(RTC.get); // get the time from the RTC
	if(timeStatus() == timeSet)
		lcd.print(" Ok!");
	else
		lcd.print(" FAIL!");

	delay ( 2000 );

	lcd.clear();

	hhSet = EEPROM.read(0);
	mmSet = EEPROM.read(1);
	setdag = EEPROM.read(2);

	// initialize
	pinMode(alarmPin, OUTPUT);
	pinMode(buttonPin, INPUT);
	digitalWrite(buttonPin, HIGH);
}
// -----
void loop() // Huvudflöde
{
	timeNow = millis();    // läs tiden varje varv
	if (status == 0)
	{
		visaTid();    // visa klockan
		keyAlarm();    // tangentrutin för snooze och stäng av
	}
	if (status == 1)
	{
		visaAlarm();    // visa väckningstid
		keySetting();    // tangentrutin för ställa in väckning
	}
	if (status == 2)
	{
		visaTimeset();    // visa tidsinställning
		setTime();    // tangentrutin för ställa in tid
	}
	if ((alarm == 0) && (hh == hhSet && mm == mmSet && ss == 0) && (setdag != 0)) // larm på tid
	{
		delay (1000);	// setdag; avstängd = 0, vecka = 1, vardagar = 2, tredagars = 3
		if(setdag == 1) alarm = 2;
		if((setdag == 2) && (dd > 1) && (dd < 7)) alarm = 2;
		if((setdag == 3) && (dd > 2) && (dd < 6)) alarm = 2;
	}
	larmrutin(); // hantera larm
	if (timeNow > (timeKey + 60000)) lcd.noBacklight(); //släck
}
// -----
void visaTid() // displayrutin
{
	if (timeNow > (timeDisp + 1000)) // har det gått 1 s?
	{
		timeDisp = timeNow;

		// Display on the upper line
		lcd.setCursor(0, 0);
		print2digits(hour());
		lcd.print(":");
		print2digits(minute());
		lcd.print(":");
		print2digits(second());
		lcd.print("   ");
		if (hhSet >= 0 && hhSet < 10) lcd.write('0');
		lcd.print(hhSet);
		lcd.print(":");
		if (mmSet >= 0 && mmSet < 10) lcd.write('0');
		lcd.print(mmSet);

		// Display on the lower line
		lcd.setCursor(0, 1);

		lcd.print(dayShortStr(weekday()));
		lcd.print(" ");
		print2digits(day());
		lcd.print("/");
		print2digits(month());

		lcd.print(" ");
		if (setdag == 0) lcd.print("Off   ");
		if (setdag == 1) lcd.print("Alltid");
		if (setdag == 2) lcd.print("Vardag");
		if (setdag == 3) lcd.print(" Ti-To");

		// Read and save time (weekday, hour, minute)
		dd = weekday(); // 1=söndag, 7=lördag
		hh = hour();
		mm = minute();
		ss = second();
		ddd = day();
		mmm = month();
		yyyy = year();
	}
}
// -----
void print2digits(int number) // Output leading zero
{
	if (number >= 0 && number < 10)
	{
		lcd.write('0');
	}
	lcd.print(number);
}
// -----
void larmrutin()
{
	if (alarm == 2)
	{
		digitalWrite(alarmPin, HIGH); // alarm
		if (timeNow > (beepTime + 5000))
		{
			tone(tonePin , 800, 1000); // pin, frequency, duration
			beepTime = timeNow;
		}
	}
	if (alarm == 1)      // snooze
	{
		if (timeNow > (snooze + 300000))
		{
			alarm = 2;
			digitalWrite (alarmPin, LOW);
		}
		else digitalWrite (alarmPin, HIGH);
	}
	if (alarm == 0) digitalWrite (alarmPin, LOW);       // off
}
// -----
void keyAlarm()
{
	buttonState = digitalRead(buttonPin);
	if (buttonState == LOW) // knapp tryckt
	{
		delay (10);
		lcd.backlight();
		if (timeread == 0)
		{
			timeKey = timeNow;
			timeread = 1;
		}
	}
	if (timeread == 1)
	{
		if (buttonState == HIGH) // knapp uppe
		{
			delay (10);
			timeread = 0;
			if (timeNow > (timeKey + 5000)) // väckningstid
			{
				status = 1;
				//				timeread = 0;
				lcd.clear();
			}
			else if (alarm > 0)
			{
				if (timeNow > (timeKey + 100)) // klick = snooze, dubbelklick = off
				{
					alarm = alarm - 1;
					//					timeread = 0;
					snooze = timeNow;
				}
			}
		}
	}
}
// -----
void visaAlarm()
{
	lcd.setCursor(0, 0);
	lcd.print("Set: ");
	if (hhSet >= 0 && hhSet < 10) lcd.write('0');
	lcd.print(hhSet);
	lcd.print(":");
	if (mmSet >= 0 && mmSet < 10) lcd.write('0');
	lcd.print(mmSet);

	lcd.print(" ");
	if (setdag == 0) lcd.print("Off    ");
	if (setdag == 1) lcd.print("Alltid ");
	if (setdag == 2) lcd.print("Vardag");
	if (setdag == 3) lcd.print("Ti-To ");

	lcd.setCursor(0, 1);
	lcd.print("Change: ");
	// Display what to set
	if (setpos == 0) lcd.print("Alarmday");
	if (setpos == 1) lcd.print("Hour    ");
	if (setpos == 2) lcd.print("Minute  ");
}
// -----
void keySetting()
{
	buttonState = digitalRead(buttonPin);
	if (buttonState == LOW) // knapp tryckt
	{
		delay (10);
		lcd.backlight();
		if (timeread == 0)
		{
			timeKey = timeNow;
			timeread = 1;
		}
	}
	if (timeread == 1)
	{
		if (buttonState == HIGH) // knapp uppe
		{
			delay (10);
			if (timeNow > (timeKey + 10000))
				// här kommer inställning av klockan in med knapptryck 10000
			{
				status = 2;
				timeread = 0;
				lcd.clear();
				hhnew = hh;
				mmnew = mm;
				ssnew = 00;
				dddnew = ddd;
				mmmnew = mmm;
				yyyynew = yyyy;
			}
			else if (timeNow > (timeKey + 5000)) // normal tidvisning
			{
				status = 0;
				timeread = 0;
				EEPROM.write(0, hhSet);
				EEPROM.write(1, mmSet);
				EEPROM.write(2, setdag);
				lcd.clear();
			}
			else if (timeNow > (timeKey + 2000)) // nästa pos
			{
				timeread = 0;
				setpos++;
				if (setpos >= 3) setpos = 0;
			}
			else if (timeNow > (timeKey + 100)) // bläddra
			{
				timeread = 0;
				if (setpos == 0) selectDay();
				if (setpos == 1) selectHour();
				if (setpos == 2) selectMinute();
			}
		}
	}
}
// -----
void selectHour()
{
	hhSet++;
	if (hhSet >= 25) hhSet = 1;
}
// ----
void selectMinute()
{
	mmSet = mmSet + 10;
	if (mmSet >= 60) mmSet = 00;
}
// -----
void selectDay()
{
	setdag;
	lcd.print(setdag);
	setdag ++;
	if (setdag >= 4) setdag = 0;
}
// -----
void setTime()
{
	buttonState = digitalRead(buttonPin);
	if (buttonState == LOW) // knapp tryckt
	{
		delay (10);
		lcd.backlight();
		if (timeread == 0)
		{
			timeKey = timeNow;
			timeread = 1;
		}
	}
	if (timeread == 1)
	{
		if (buttonState == HIGH) // knapp uppe
		{
			if (timeNow > (timeKey + 5000)) // normal tidvisning
			{
				status = 0;
				timeread = 0;
				// Set time vid återgång
				setTime(hhnew, mmnew, 00, dddnew, mmmnew, yyyynew);  //set the time
				RTC.set(now());                     //set the RTC time

				lcd.clear();
			}

			else if (timeNow > (timeKey + 2000)) // nästa pos
			{
				timeread = 0;
				setpos++;
				if (setpos >= 6) setpos = 0;
				// Display what to set
				lcd.setCursor(0, 1);
				if (setpos == 0) lcd.print("hour ");
				if (setpos == 1) lcd.print("min. ");
				if (setpos == 2) lcd.print("year+");
				if (setpos == 3) lcd.print("year-");
				if (setpos == 4) lcd.print("month");
				if (setpos == 5) lcd.print("day  ");
			}
			else if (timeNow > (timeKey + 100)) // bläddra
			{
				timeread = 0;
				if (setpos == 0) setHour();
				if (setpos == 1) setMin();
				if (setpos == 2) addYear();
				if (setpos == 3) subYear();
				if (setpos == 4) setMonth();
				if (setpos == 5) setDay();
			}

		}
	}
}
// -------
void visaTimeset()
{
	lcd.setCursor(0, 0);
	lcd.print("Set: ");
	lcd.print(hhnew);
	lcd.print(":");
	lcd.print(mmnew);
	lcd.print(":00");
	lcd.print(" ");
	lcd.setCursor(6, 1);
	lcd.print(yyyynew);
	lcd.print("-");
	lcd.print(mmmnew);
	lcd.print("-");
	lcd.print(dddnew);
	lcd.print(" ");
}
// -----
void setHour()
{
	hhnew++;
	if (hhnew >= 25) hhnew = 1;
}
// -----
void setMin()
{
	mmnew++;
	if (mmnew >= 60) mmnew = 0;
}
// -----
void addYear()
{
	yyyynew++;
}
// -----
void subYear()
{
	yyyynew--;
}
// -----
void setMonth()
{
	mmmnew++;
	if (mmmnew >= 13) mmmnew = 1;
}
// -----
void setDay()
{
  dddnew++;
  if (dddnew >= 32) dddnew = 1;
}

//end
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Eftersom klockan stannade när millis gjorde overflow försov jag mig var 50:e dag. Nu har jag ändrat så att programmet jämför senast lästa millis med aktuellt värde och om nollställer räknarna vid overflow. Det har inte gått 50 dagar sedan jag gjorde ändringen, men jag hoppas det fungerar.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Nu är jag 100% pensionär, så jag behöver ingen väckarklocka längre. Jag gjorde därför om tredagarsveckningen till "i morgon"-väckning, dvs den ringer nästa dag och ställer sig sedan i off-läge.
Skriv svar