Table of Contents

💤 Deadlines Alarm Clock 💤 - Culea Cosmin - 331CA

Introducere

Deadlines Alarm Clock, dupa cum sugereaza si numele este un sistem de stocare si de atentionare a studentilor asupra deadline-urilor pe care acestia le au la facultate. Cu totii stim cat de incarcate pot fi anumite perioade din facultate (sa nu uitam de anul 2 semestrul 2), iar de cele mai multe ori te gasesti in mijlocul semestrului cu 3-4-5 teme/proiecte suprapuse carora nu le mai poti face fata, nu stii cat timp mai ai pentru fiecare, trebuie sa intrebi mereu prin stanga si prin dreapta: “CAND ERA DEADLINE-UL LA PA???”, astfel iritandu-i si mai mult pe colegii tai. Cateodata esti atat de bulversat incat nici nu mai stii ce zi a saptamanii este (mai ales daca au trecut 4 zile si 4 nopti rezolvand tema la protocoale).

De aceea, propun acest sistem cu alarma care stocheaza pana la 6 deadline-uri (an/luna/zi/ora/minut/secunda) alaturi de un mesaj cu numele materiei, si te atentioneaza inainte cu 3, 2 si o zi inainte de deadline pentru a fi sigurx ca ai timp suficient sa-ti poti rezolva tema. In plus, ai acces la o listare a tuturor deadline-urilor pentru a-ti putea face o imagine de ansamblu asupra lor, poti face update pe un deadline sau il poti chiar sterge in momentul in care ai terminat proiectul/ti-ai dat seama ca ai puncte destule pe parcurs si nu mai are rost sa o faci.

Descriere generală

Sistemul preia date de la utilizator prin intermediul a 6 butoane NEXT, PREV, UP, DOWN, SELECT si MENU. Meniul are 2 optiuni de LIST si ADD prin care se pot lista toate deadline-urile stocate anterior si de adaugare de dealine-uri noi. In comanda LIST vor fi afisate pe rand alarmele cu cu data si ora la care sunt ele setate si se poate naviga printre ele prin intermediul butoanelor NEXT si PREV. In momentul cand este listat un anumit deadline se poate apasa buton SELECT si se vor afisa 2 optiuni de comenzi si anume UPDATE sau DELETE. Atat in cadrul comenzii de update si de add vor fi afisate pe rand anul, luna, ziua, ora, minutul, secunda care pot fi modificate incremental cu ajutorul butoanelor UP and DOWN, iar navigarea prin data se realizeaza tot prin NEXT si PREV.

Pe LCD va fi afisata constant data si ora curenta preluata de la modulul RTC, mai putin in momentele in care utilizatorul realizeaza o anumita comanda. Buzzerul va fi activat cu 3, 2, si o zi inainte de deadline, anuntand cate zile ramase mai sunt pana cand tema/proiectul la materia respectiva trebuie predata. De asemenea, sistemul dispune si de un senzor de miscare care va verifica daca este sau nu cineva in camera. In cazul in care seznorul nu detecteaza miscare in camera, alarma nu va suna la ora fixata, ci doar in momentul in care a simtit prezenta cuiva. Astfel, alarma ta nu va suna sa deranjeze colegii de apartament/vecinii cand tu nu esti acasa, insa te va anunta imediat ce ai ajuns ca ai pierdut o atentionare de deadline.

Schema bloc

Hardware Design

Piesele folosite în cadrul proiectului sunt:

Schema Electrica

Software Design

Organizarea codului

Codul este organizat in mai multe fisiere .cpp, fiecare cu headerul aferent:

/* Face deep copy pe cele doua structuri (din source in destination) */
int copy_dt(Ds1302::DateTime *destination, Ds1302::DateTime *source);
 
/* Functie care invalideaza data primita, dandu-i valori invalide pentru fiecare camp. */ 
int invalid_dt(Ds1302::DateTime *dt);
 
/* Functie care verifica daca data este invalida. */
int is_invalid_dt(Ds1302::DateTime *dt);
 
/* Aduna o zi la data primita. Functie folositoare la verificare alarmei inainte cu 3, 2, o zi. */
void increment_day(Ds1302::DateTime &dt);
 
/* Verifica daca doua date sunt egale. */
int are_dates_equal(Ds1302::DateTime &dt1, Ds1302::DateTime &dt2);
 
/* Functie care primeste 2 date, si verifica dt1 == dt2 || dt1 + o zi == dt2 || dt1 + 2 zile == dt2 
 * || dt1 + 3 zile == dt si intoarce un define corespunzator in functie de cum ar trebui sa sune 
 * alarma sau nu (NOT_NOW, NOW, ONE_DAY, TWO_DAYS, THREE_DAYS).
 */
int is_deadline_due(Ds1302::DateTime &dt1, Ds1302::DateTime &dt2);
void print_introduce_year(char *year, char *next_op);
 
void print_introduce_month(char *month, char *next_op);
 
void print_introduce_day(char month, char *day, char *next_op);
 
void print_introduce_hour(char *hour, char *next_op);
 
void print_introduce_minutes(char *minutes, char *next_op);
 
void print_introduce_seconds(char *seconds, char *next_op);
 
void introduce_subject_to_lcd(char* subject);
 
void introduce_date_to_lcd(Ds1302::DateTime &dt);
/* Afiseaza pe lcd data trimisa ca parametru cu toate campurile. */
void print_date(Ds1302::DateTime &dt);
 
/* Printeaza un deadline-ul care are indexul primit ca parametru in array-ul dts */
void print_deadline(int index);
 
/* Functia intoarce urmatorul index al unei date valide din cadrul array-ului dts dupa 
 * indexul dat ca parametru
 */
int next_index(int index);
 
/* Functia intoarce indexul unei date valide din cadrul array-ului dts anterior intexului
 * dat ca parametru
 */
int prev_index(int index);
 
/* Functie care face update sau sterge un deadline cu indexul primit ca parametru, in functie 
 * de butonul apasat de utilizator 
 */
void update_or_delete(int *index);
 
/* Functie care listeaza deadline-urile pe rand, cu posibilitatea iterarii prin acestea prin 
 * apasarea butoanelor NEXT sau PREV. Se iese din functie in momentul apasarii butonului MENU.
 */
void list();
 
/* Functie care adauga un nou deadline prin introducerea datei si a materiei interfatate 
 * prin butoane si lcd 
 */
void add();
 
/* Functie care afiseaza meniul cu comenzile ADD si LIST si asteapta input din partea utilizatorului.
 * Prin apasarea butonul NEXT se apeleaza functia list(), iar prin apasarea butonului PREV se 
 * apeleaza functia add(). Se iese din functie la apasarea butonului MENU.
 */
void display_menu();
/* Functia activeaza alarma pentru deadline-ul dt_index, cu deadline_state fiind NOW, ONE_DAY,
 * TWO_DAYS sau THREE_DAYS, pe pinul buzzerPin
 */
void play_alarm(int buzzerPin, int dt_index, int deadline_state);

Logica implementarii

Logica implementarii se afla in fisierul deadlines_alarm.ino care contin functiile setup(), loop() si includ toate fisierele header anterior mentionate.

void setup() {
  lcd.init();
  lcd.clear();
  lcd.backlight();
 
  pinMode(BUTTON_DOWN, INPUT_PULLUP);
  pinMode(BUTTON_UP, INPUT_PULLUP);
  pinMode(BUTTON_MENU, INPUT_PULLUP);
  pinMode(BUTTON_NEXT, INPUT_PULLUP);
  pinMode(BUTTON_PREV, INPUT_PULLUP);
  pinMode(BUTTON_SELECT, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  pinMode(PIR, INPUT);
 
  rtc.init();
  /* // Code if the RTC fails to print correct date time  
    Ds1302::DateTime dt;
    introduce_date_to_lcd(dt);
    rtc.setDateTime(&dt); */
 
  /* Initializeaza deadline-urilor si array-ul de delayed flag */
  for (int i = 0; i < 6; i++) {
    invalid_dt(&dts[i]);
    delayed[i] = NOT_NOW;
  }
}
void loop() {
  Ds1302::DateTime dt;
  int deadline_due = 0;
 
  /* Printeaza data si ora curenta extrasa din RTC */
  rtc.getDateTime(&dt);
  print_date(dt);
 
  /* Pastreaza o copie globala a datei afisate anterior pentru
   * afisarea eficienta a datei la lcd
   */
  copy_dt(&prev_dt, &dt);
 
  /* Itereaza prin toate deadline-urile pentru a verifica daca 
   * trebuie sunata alarma 
   */
  for (int i = 0; i < 6; i++) {
    /* Extrage starea deadline-ului curent */
    int deadline_state = is_deadline_due(dt, dts[i]);
 
    /* Reface structura dt cu data curenta, aceasta fiind modificata anterior in
     * functia is_deadline_due 
     */
    copy_dt(&dt, &prev_dt);
 
    /* Citeste starea senzorului de miscare */
    int state_sensor = digitalRead(PIR);
 
    /* Daca senzorul detecteaza miscare */
    if (state_sensor == HIGH) {
          /* Daca starea deadline-ului indica faptul ca alarma trebuie activata */
          if (deadline_state != NOT_NOW){
            play_alarm(BUZZER, i, deadline_state);
            deadline_due = 1;
          /* Daca alarma a fost amanata anterior, acum trebuie activata */
          } else if (delayed[i] != NOT_NOW) {
            play_alarm(BUZZER, i, delayed[i]);
            deadline_due = 1;
          }
 
          /* Daca este ultima alarma a deadline-ului, atunci deadline-ul este sters*/
          if (deadline_state == NOW || delayed[i] == NOW) {
            invalid_dt(&dts[i]);
          }
 
          delayed[i] = NOT_NOW;
     /* Daca senzorul nu detecteaza miscare si starea deadline-ului este de a fi activata 
      * atunci se pastreaza in array-ul delayed pentru a putea fi sunata ulterior
      */
    } else if (deadline_state != NOT_NOW){
        delayed[i] = deadline_state;
    }
 
  }
 
  /* Curata LCD-ul daca alarma a fost activata */
  if (deadline_due == 1) {
    lcd.clear();
    invalid_dt(&prev_dt);
  }
 
  /* Daca functionalitatea meniului este activata prin buton, atunci 
   * se apeleaza functia display_menu
   */
  if (digitalRead(BUTTON_MENU) == LOW) {
    delay(200);
    display_menu();
    lcd.clear();
    invalid_dt(&prev_dt);
    delay(200);
  }
}

Biblioteci folosite

Mediul de dezvoltare

Rezultate Obţinute

Proiectul final contine toate functionalitatile mentionate in descriere. Pentru mai multe detalii despre cum se poate folosi puteti accesa sectiunea Videos de aici.

Concluzii

Desi la inceput am fost foarte speriat de acest proiect, intrucat nu aveam experienta mai deloc sa lucrez cu componente hardware (in afara laboratoarelor de pm), nu stiam cat de mult timp ar lua sa il finalizez si nu stiam la ce probleme ar trebui sa ma astept, pot spune ca a fost o experienta foarte placuta. Totul a fost mai greu pana mi-au venit piesele, tocmai pentru ca nu stiam la ce sa ma astept. Apoi am incercat usor usor sa pun toate pisele cap la cap, sa le testez, sa caut tutoriale pe youtube si am realizat cat de multe resurse utile exista.

Implementarea software mi-a placut cel mai mult, dar a fost si destul de challenging, intrucat desi poate nu pare foarte complicata ideea proiectului in sine, a fost destul de dificil si extrem de mult cod de scris ca sa pot implementa toate functionalitatile asa cum mi le doream. Am avut parte de foarte multe buguri evident, mai ales la implementarea logicii butoanelor, pe care am reusit sa le rezolv pe parcurs prin testarea continua (+ printf-uri cat cuprinde pe interfata seriala ^_^ ).

Din punct de vedere hardware, spre bucuria mea, nu am intampinat foarte multe dificultati, asa cum am zis am gasit foarte multe materiale care m-au ajutat sa inteleg principiile de functionare ale componentelor. Singurul meu regret este ca nu mi-am cumparat un buzzer sau un difuzor mai performant, intrucat nu sunt destul de multumit de cum se audea alarma. Am incercat sa convertesc niste melodii, dar nu se aud asa cum m-as fi asteptat.

Download

Arhiva cu fisierele sursa .cpp .h si .ino se pot gasi aici.

Jurnal

Bibliografie/Resurse

Export to PDF