Gå til innhold

Prosjekt: Smart vekkerklokke v2


Anbefalte innlegg

Bakgrunn

I forbindelse med nattesøvnen min og vekking så har eg tre problemer/utfordringer. Eg har forskjellige vekketider og må justere klokka hver kveld, eg er en stor snooze-fan og eg blander ofte snooze-knappen og "alarm av"-knappen. Det siste der er et stort problem. Eg har derfor bestemt meg for å lage ei vekkerklokke selv, som adresserer nettopp disse problemene. I tillegg føler eg at vekkeklokker stort sett er de samme i dag som for 30 år siden. Om vi ser bort i fra "Wake Up Light" så er det ofte kun designet som endrer seg. Funksjonsmessig er de veldig like. Dette håper eg også at eg kan gjøre noe med :)

 

Versjon 1 (alfa)

For ei tid tilbake(2 år+) kjøpte eg en ITX-maskin som eg skulle bruke til å utvikle vekkerklokka mi. Dette i seg selv gikk litt dårlig. Først og fremst ble det veldig stygt med en egen maskin på soverommet og i tillegg var det vanskeligere enn antatt å få til en fornuftig måte å vekke meg på. I tillegg var det litt overkill med Linux på vekkerklokka med MySQL og PHP som utviklingsplattform. Derfor prøver eg meg på nytt, med versjon 2. Og denne gangen skal eg lykkes. Her er to bilder av ITX-maskinen:

post-14502-1265659896_thumb.jpgpost-14502-1265659888_thumb.jpg

 

Funksjonsbehov

I grove trekk ser eg for meg å implementere følgende funksjoner i vekkerklokka:

  • Tilkoblet nettverk/internett for toveiskommunikasjon(styring og spørring).
  • Oppdatering av tid og dato via internett(NTP).
  • Standard vekketidspunkt klokka 06:00 for ukedager og kl 08:00 for helgedager.
  • Sjekk av varslet værforhold for natten mot YR.no(har det vært frost så skal eg vekkes 15 minutt før, snø, 15 minutt til tidligere).
  • Sjekk av kalender for å se om vekketidspunktet må justeres i forhold til avtaler(Google Calendar).
  • Når eg legger meg skal eg få vite når vekketidspunktet er, hvor lenge det er til(liker å vite hvor mange timer eg får på puta) eller om vekking i det hele tatt er deaktivert.
  • Vekking skal først forsøkes lysløst(putevibrator), og deretter lyd dersom det ikke fungerer.
  • Lokalradioen skal slås på rett før vekketidspunktet(squeezebox).
  • Slumring skal kun være mulig i 10-15 minutt etter vekketidspunkt.
  • Det skal ikke være mulig å slå av vekkingen så lenge eg ligger i senga.
  • Logging av leggetidspunkt, vekketidspunkt og faktiske tider eg står opp.

 

Valg av maskinvareplattform

En ting eg lærte av versjon 1 er at en datamaskin er for overkill for dette prosjektet. Størrelsen er upraktisk for formålet, kravet til vifteløs gjør maskinen dyr eller treg og strømforbruket gjør batteri upraktisk(i tilfelle strømmen går). I tillegg blir kabinettet så lite og trangt at det er en utfordring å legge til funksjoner for å koble opp brytere, skjermer og andre sensorer/duppeditter. Eg har derfor bestemt meg for å lage vekkerklokka av en eller flere mikrochipper. Fordelen er at eg kan får hele enheten inn på et kretskort som er en brøkdel av størrelsen til en vanlig maskin, og eg kan bestemme veldig mye av funksjonene og oppbygningen selv. I tillegg får eg gjøre noe eg liker veldig godt, å programmere.

 

Valget har derfor falt på å bruke Arduino i første omgang for å lage en litt større prototype, og deretter utvikle et eget kretskort med en Arduino som hjerne.

 

Handleliste så langt

 

Bygging av prototype med Arduino USB "brett"

Første steg blir å bygge en prototype som fungerer slik eg vil ha det endelige produktet. I første omgang venter eg nå på de første delene. Inntil da kan dere kommentere i kommentartråden til denne arbeidsloggen :)

Endret av nomore
Lenke til kommentar
  • 4 uker senere...
Videoannonse
Annonse

En liten oppdatering :)

 

Fikk delene tidligere denne uken og har brukt litt tid på å teste forskjellige småting før eg faktisk har påbegynt koblingen av selve klokkeprosjektet. Kommer tilbake til flere detaljer i løpet av helgen, men her er to bilder av koblingene så langt.

 

Her er et bilde av selve Arduino-kortet med en ATmel mikrokontroller. Her er de viktigste koblingene lagt opp mot koblingsbrettet(5V, GND, I2C mot DS1307(klokkekontrolleren) og TX/RX mot ZigBee-interfacet):

 

post-14502-1267702975,4936_thumb.jpg

 

 

Her er selve koblingsbrettet med klokkekontrolleren(DS1307), krystall til DS1307 og ZigBee-interfacet:

 

post-14502-1267702984,6342_thumb.jpg

 

Lenke til kommentar

Foreløpig kode som faktisk fungerer (se beskrivelse i kommentartråden) :)

 

#include <Wire.h>

#define DS1307_I2C_ADDRESS 0x68


/* Definer globale variabler */
int G_ALARM_TIDSPUNKT[] = {14, 03}; // Neste alarmtidspunkt.
int G_ALARM_UTSETT_MINUTTER = 2; // Antall minutter vekking skal utsettes.
int G_ALARM_FORSOK = 0; // Variabel for å telle antall vekkeforsøk.
int G_ALARM_BUZZER_FREQ1 = 1000; // Frekvens på vanlig vekking.
int G_ALARM_BUZZER_FREQ2 = 2000; // Frekvens på høy vekkelyd.
int G_ALARM_FORSOK_ESC = 5; // Hvor mange forsøk før lyden på buzzeren økes.
long G_ALARM_STARTTID = 0; // Millis når vekkingen startet.
long G_ALARM_BUZZER_CHANGED = 0; // Millis når buzzer ble slått av eller på.
boolean G_ALARM_RUN = false; // Aktiver buzzer.
boolean G_ALARM_BUZZER = false; // Om buzzeren faktisk er aktiv.


/* Definer innganger og utganger. */
int pinLed = 7; // Testlys.
int pinBuzzer = 11; // Buzzer.


void setup()
{
 Wire.begin();
 Serial.begin(9600);
 Serial.flush();

 pinMode(pinLed, OUTPUT);
 pinMode(pinBuzzer, OUTPUT);
 digitalWrite(pinLed, LOW);
}

void loop()
{
 SjekkAlarmTidspunkt();
 Vekking();
}

void SjekkAlarmTidspunkt()
{
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

 if (G_ALARM_TIDSPUNKT[0] == hour && G_ALARM_TIDSPUNKT[1] == minute && second == 0)
 {
   // Starter ikke vekkingen om vekking allerede er i gang.
   if (G_ALARM_RUN == false)
   {
     Serial.print("Tidspunkt: ");
     Serial.print(hour, DEC);
     Serial.print(":");
     Serial.print(minute, DEC);
     Serial.print(":");
     Serial.print(second, DEC);
     Serial.print(" ");
     Serial.print(dayOfMonth, DEC);
     Serial.print(".");
     Serial.print(month, DEC);
     Serial.print(".");
     Serial.print(year, DEC);
     Serial.print(" ");
     Serial.println(dayOfWeek, DEC);
     Serial.println("Vekketidspunkt.");
     VekkingStart();
   }
 }
}

void VekkingStart()
{
 Serial.println("Vekking startet.");
 G_ALARM_STARTTID = millis(); // Tidspunkt når vekking ble startet, for bruk ved evnt utsettelse.
 G_ALARM_FORSOK++;
 Serial.print("Forsøk ");
 Serial.println(G_ALARM_FORSOK, DEC);
 G_ALARM_RUN = true;
}

void VekkingUtsett()
{
 VekkingStopp();
 Serial.print("Ny vekking om ");
 Serial.print(G_ALARM_UTSETT_MINUTTER, DEC);
 Serial.println(" minutt.");

 /* Denne koden setter nytt vekketidspunkt når det skal utsettes. For å unngå at minutter settes til 64, som ikke vil være reelt
 så sjekkes det først om det er færre minutter igjen av timen enn antall minutter som skal utsettes, og da økes evnt timeantallet. */
 if (G_ALARM_TIDSPUNKT[1] <= 59 - G_ALARM_UTSETT_MINUTTER)
 {
   G_ALARM_TIDSPUNKT[0] = G_ALARM_TIDSPUNKT[0];
   G_ALARM_TIDSPUNKT[1] = G_ALARM_TIDSPUNKT[1] + G_ALARM_UTSETT_MINUTTER;
 }
 else
 {
   if (G_ALARM_TIDSPUNKT[0] == 23)
   {
     G_ALARM_TIDSPUNKT[0] = 0;
   }
   else
   {
     G_ALARM_TIDSPUNKT[0] = G_ALARM_TIDSPUNKT[0] + 1;
   }
   G_ALARM_TIDSPUNKT[1] = G_ALARM_UTSETT_MINUTTER - (60 - G_ALARM_TIDSPUNKT[1]);
 }
}

void VekkingStopp()
{
 Serial.println("Vekking stoppet.");
 G_ALARM_STARTTID = 0;
 G_ALARM_RUN = false;
}

void Vekking()
{
 // Skal noen vekkes?
 if (G_ALARM_RUN == true)
 {
   long TidNa = millis();
   digitalWrite(pinLed, HIGH);

   // Sjekk om buzzeren er av, og om det er mer enn 500 millisekund siden den ble slått av.
   if (G_ALARM_BUZZER == false && TidNa - G_ALARM_BUZZER_CHANGED > 500)
   {
     // Bør vi øke lydnivået?
     if (G_ALARM_FORSOK > G_ALARM_FORSOK_ESC)
     {
       tone(pinBuzzer, G_ALARM_BUZZER_FREQ2);
     }
     else
     {
       tone(pinBuzzer, G_ALARM_BUZZER_FREQ1);
     }
     G_ALARM_BUZZER = true;
     G_ALARM_BUZZER_CHANGED = millis();
   }
   // Sjekk om buzzeren er på, og om det er mer enn 500 millisekund siden den ble slått på.
   else if (G_ALARM_BUZZER == true && TidNa - G_ALARM_BUZZER_CHANGED > 500)
   {
     noTone(pinBuzzer);
     G_ALARM_BUZZER = false;
     G_ALARM_BUZZER_CHANGED = millis();
   }

   // Har vekkingen foregått mer enn 6 sekund? Da venter vi litt og prøver igjen senere.
   if (TidNa - G_ALARM_STARTTID > 6000)
   {
     VekkingUtsett();
   }
 }
 else if (G_ALARM_RUN == false)
 {
   noTone(pinBuzzer);
   G_ALARM_BUZZER = false;
   digitalWrite(pinLed, LOW);
 }
}


// All kode under her er hentet fra http://www.glacialwanderer.com/hobbyrobotics/?p=12
// Dette er kode kun for å snakke med klokkechippen, DS1307.

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
 // Reset the register pointer
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.send(0);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

 // A few of these need masks because certain bits are control bits
 *second     = bcdToDec(Wire.receive() & 0x7f);
 *minute     = bcdToDec(Wire.receive());
 *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
 *dayOfWeek  = bcdToDec(Wire.receive());
 *dayOfMonth = bcdToDec(Wire.receive());
 *month      = bcdToDec(Wire.receive());
 *year       = bcdToDec(Wire.receive());
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
 return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
 return ( (val/16*10) + (val%16) );
}

 

Vedlagt ligger selve koden. Rename denne til .pde for å åpne den direkte i Arduino IDE.

SmartVekkerklokke.txt

Endret av nomore
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...