Deltids-väckarklocka

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

Deltids-väckarklocka

Inlägg av BjörnO »

Om ett par veckor har jag nått mitt bäst-före-datum. Jag kommer att vara kvar på jobbet, men bara tre dagar i veckan. Mina helger kommer därför att vara fyra dagar långa :)
Min gamla väckarklocka har hittills väckt mig varje dag klockan 6, vardag som helg. Så vill jag inte ha det i fortsättningen. Klockan 6 är OK tre dagar i veckan men annars ska det vara tyst.
Visst, jag kan lösa det med mobilen, men jag vill ha en dedicerad väckarklocka. Jag har en Arduino och en display kvar från ett tidigare projekt, resten kan jag säkert hitta i mina gömmor.
Senast redigerad av BjörnO 22 februari 2016, 15:49:40, redigerad totalt 1 gång.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Efter några veckors labbande började det arta sig.
En plastbox där jag samlade diverse visitkort fick bli sjäva skalet. Ena högtalaren från hörlurar som jag tror härrör från en flygning får bli det som väcker mig. Det ska bara vara en knapp att trycka på, oavsett om man ska snooza, stänga av ringsignalen eller ställa in väckningstid.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Förutom Arduinon och displayen blev det en timerkrets med batteribackup, en lysdiod för att indikera att klckan är i snooze-mod och en transistorkrets som får driva högtalaren.
Knappen ska reagera på:
- klick, för att stänga av ringsignalen och för att stega fram när man ställer in väckningstiden
- dubbelklick för att stänga av ringsignalen och snooze
- lång klick (ett par sekunder) för att växla till nästa läge när man ställer in väckningstiden
- längre klick (>5 sekunder) för att växla mellan vanlig tidvisning och inställning av väckningstid
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Den är färdig i en första fungerande version. Har använt den under veckan med min gamla väckarklocka som backup.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Deltids-väckarklocka

Inlägg av Icecap »

Kul! "Man tager vad man haver..." Ett princip jag starkt gillar!
MiaM
Inlägg: 9903
Blev medlem: 6 maj 2009, 22:19:19

Re: Deltids-väckarklocka

Inlägg av MiaM »

Batteribackup/batteridrift?

En bekant påpekade att Arduino dumt nog använder några pinnar på "fel" sätt för att gå ned i maximal djupsömn. Men det är väl ändå så låg strömförbrukning (med släckt backlight på displayen) att ett batteri räcker några timmar?

P.S. om backlighten ska vara igång vid normaldrift så vill du nog ha röd, och en fotocell/fototransistor som känner av rummets ljusstyrka och styr displayens ljusstyrka.
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Deltids-väckarklocka

Inlägg av Icecap »

Jag läste "timerkrets med batteribackup" som "RTC med batteribackup" och tror att det nog rör sig om den standard DS1307 som finns i drösvis här och där.
Användarvisningsbild
MicaelKarlsson
Inlägg: 4669
Blev medlem: 18 juni 2004, 09:16:07
Ort: Aneby
Kontakt:

Re: Deltids-väckarklocka

Inlägg av MicaelKarlsson »

BjörnO: Tjusig klocka!
Icecap skrev:Kul! "Man tager vad man haver..." Ett princip jag starkt gillar!
Kan bara instämma!!
MiaM skrev:En bekant påpekade att Arduino dumt nog använder några pinnar på "fel" sätt för att gå ned i maximal djupsömn. Men det är väl ändå så låg strömförbrukning (med släckt backlight på displayen) att ett batteri räcker några timmar?
Detta kanske kan vara intressant: , http://www.kevindarrah.com/download/ard ... rVideo.ino
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Just det, där sitter en DS1307. Än så länge strömförsörjs min klocka med USB-laddare.
Nu när hårdvaran är klar blir det dags att vidareutveckla programmet. Displayen lyste för starkt så den får i alla fall sova. Ett tryck på knappen och den tänds en liten stund.
Klockan håller tiden även när övrigt är avstängt, men inställd tid försvinner. Alltså dags att lära sig hantera minnet i DS1307:an.
MiaM
Inlägg: 9903
Blev medlem: 6 maj 2009, 22:19:19

Re: Deltids-väckarklocka

Inlägg av MiaM »

Men DS1307 verkar inte ha någon alarm-utgång. Därmed försover man sig minst till strömavbrottets slut (eller man vaknar av sig själv) om det är strömavbrott vid ordinarie väckningstid.

En fulvariant är förstås att istället ordna så att väckning går igång på batteri direkt vid strömavbrott, så får man vakna till och ställa någon annan klocka på väckning. Osmidigt men fungerar.
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Du har alldeles rätt. Det får fortsätta vara en nätdriven klocka, eventuellt med batteri-backup som håller den igång tills strömmen återkommit. Det får plats rätt mycket i lådan så det blir inget problem.
Ett problem däremot är hur man skriver/läser till minnesarean i DS1307. Jag förstår inte riktigt hur man ska göra det. Kan någon peka på kod som jag kan kopiera och klistra in i min kod så :D
BjörnO
Inlägg: 242
Blev medlem: 3 juni 2013, 19:52:42

Re: Deltids-väckarklocka

Inlägg av BjörnO »

Om någon är nyfiken på koden:

Jag använder dessa bibliotek:

Kod: Markera allt

#include <LiquidCrystal_I2C.h>
#include <DS1302RTC.h>
#include <Time.h>
#include <Wire.h>
#include <TimeAlarms.h>
Detta är min huvudrutin:

Kod: Markera allt

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();
}
Vanlig tidvisning:

Kod: Markera allt

void visaTid() // rutin
{
    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();
    }
}

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

Kod: Markera allt

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
}
Avkoda knapptryck:

Kod: Markera allt

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;
                }
            }
        }
    }
}
Visa väckningstid på display:

Kod: Markera allt

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(":");
}
Ställa in väckningstid:

Kod: Markera allt

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;
                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 ");
}
qx5
Inlägg: 1678
Blev medlem: 14 augusti 2014, 04:23:04

Re: Deltids-väckarklocka

Inlägg av qx5 »

Om MCU:n sätts i "sleepmode" när det är elavbrott och t.ex väcks varje minut i några millisekunder så kan den aktivera alarmet även på batteri. Så mycket energi går det inte åt till det. Om man t.ex använder 10 W under 5 minuter för alarmljud så har man gjort av med 3 kJ. Ett standard R6 NiMH batteri på 2200 mAh rymmer 8,6 kJ. Med en liten blyackumulator får man kanske 25 kJ.

Så vid elavbrott släck bakgrundsbelysningen för det är den som förbrukar den största mängden energi och låt processorn gå i "sleepmode". Initiera uppväckning av processorn varje minut som varar i några millisekunder där den kontrollerar om larmet skall aktiveras den närmsta minuten. Om så är fallet så kvarstår den i aktivt läge och kanske förbrukar 16 mW i ström de minutrarna som larmet varar.

På detta sätt får du både väckning och batteritid oavsett om det finns elnät som fungerar.
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Deltids-väckarklocka

Inlägg av Icecap »

DS1307 kan ge ut en puls varje sekund.

Den kan användas som aktivering och µC'n kan då dels räkna upp tiden internt utan att behöva "prata" med RTC'n och dels kolla larm innan den går i sleep igen.

Detta kan bli en mycket strömsnål lösning och lägger man till lite koll av back-up spänning kan man även styra att displayen släcks ner helt osv.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4689
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Deltids-väckarklocka

Inlägg av Swech »

Det går att göra det hela lite mer läsbart

Kod: Markera allt

if (timeread == 1)
Om du istället definierar
off = 0
on = 1

så blir det

Kod: Markera allt

if (timeread == on)
Koden blir lättare att läsa / underhålla

Swech
Skriv svar