Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2023:vstoica:carmenpedolu [2023/05/27 17:52]
carmen.pedolu [Bibliografie/Resurse]
pm:prj2023:vstoica:carmenpedolu [2023/05/29 20:18] (current)
carmen.pedolu
Line 7: Line 7:
 Scopul proiectului este de a putea canta la pian sau de a asculta melodii de pe card SD. Scopul proiectului este de a putea canta la pian sau de a asculta melodii de pe card SD.
  
-Ideea mi-a venit la laboratorul 4 in care am vazut cum se citi valoarea potentiometrului doar atunci cand se apasa un buton. Astfel mi-a venit ideea de a avea mai multe butoane care redau fiecare alt sunet si nota muzicala sunetului sa o afisez pe un monitor. Pentru a complica un pic ideea m-am gandit sa pot reda melodii de pe un un card MicroSD.+Ideea mi-a venit la laboratorul 4 in care am vazut cum se poate citi valoarea potentiometrului doar atunci cand se apasa un buton. Astfel mi-a venit ideea de a avea mai multe butoane care redau fiecare alt sunet si nota muzicala sunetului sa o afisez pe un monitor. Pentru a complica un pic ideea m-am gandit sa pot reda melodii de pe un un card MicroSD.
  
 Consider ca acest proiect va fi util atat pentru mine ca voi acumula si lega cunostinte, dar si pentru cei care doresc sa cante la pian sau sa asculte muzica de pe un card MicroSD, fara a fi nevoie de un pian fizic, care este mai costisitor. Consider ca acest proiect va fi util atat pentru mine ca voi acumula si lega cunostinte, dar si pentru cei care doresc sa cante la pian sau sa asculte muzica de pe un card MicroSD, fara a fi nevoie de un pian fizic, care este mai costisitor.
  
 ===== Descriere generală ===== ===== Descriere generală =====
-Utilizatorul apasa pe un buton, care este conectat in mod direct la placuta. Aceasta va interpreta ce buton este apasat si va reda sunetul specific butonului si va afisa pe monitor ce sunet se reda. Sunetul va fi redat doar cat timp este butonul apasat. Cand nu este niciun buton apasat, atunci ​nu se va intampla nimic.+Utilizatorul apasa pe un buton, care este conectat in mod direct la placuta. Aceasta va interpreta ce buton este apasat si va reda sunetul specific butonului si va afisa pe monitor ce sunet se reda. Sunetul va fi redat doar cat timp este butonul apasat. Cand nu este niciun buton apasat, atunci se va afisa doar "Hello world!"​ pe ecranul LCD.
  
-Pentru a reda muzica, va exista un buton special, care odata apasat va incepe sa cante prima melodie de pe cardul SD, cand este apasat din nou melodia se va opri din redat. In timpul in care melodia este redata pe monitor se va afisa un mesajul "Melodie" pe monitor.+Pentru a reda muzica, va exista un buton special, care odata apasat va incepe sa cante melodie de pe cardul SD pana la final. In timpul in care melodia este redata pe monitor se va afisa un mesajul "Play music!" pe monitor ​si un countdown de la 1000ms in timpul redarii melodiei. Daca timpul expira in locul countdown-ului va scrie "Timer expirat!"​.
  
-Daca in timpul in care o melodie este redata, se apasa o tasta a unei clape, atunci aceasta nu va fi luata in considerare pana cand melodia nu se opreste ​sau nu este apasat butonul de oprire a melodiei.+Daca in timpul in care o melodie este redata, se apasa o tasta a unei clape, atunci aceasta nu va fi luata in considerare pana cand melodia nu se opreste.
  
 Cand nu se reda nimic, pe monitor nu este afisat nimic Cand nu se reda nimic, pe monitor nu este afisat nimic
Line 42: Line 42:
  
 Descrierea functiilor: Descrierea functiilor:
 +  * void myCallback()- functia e apelata atunci cand are loc o intrerupere.
 +
 +In aceasta functie se citesc notele muzicale de pe cardul SD si durata fiecarei note, valorile fiind retinute intr-un array de valori integer, iar apoi se seteaza state-ul 9, pentru a stii ca are loc o intrerupere.
 +<code C>
 +void myCallback() {
 +  if (SD.exists("​MELODY.TXT"​) == 0) {
 +    Serial.println("​MELODY.TXT"​);​
 +  }
 +  if (SD.exists("​DURATI~1.TXT"​) == 0) {
 +    Serial.println("​DURATI~1.TXT"​);​
 +  }
 +  ​
 +  File melody_file = SD.open("​MELODY.TXT",​ FILE_READ);
 +  nr_elem = 0;
 +  while (melody_file.available()){
 +    String nr = melody_file.readStringUntil(','​);​
 +    melody[nr_elem] = nr.toInt();
 +    nr_elem++;
 +  }
 +  melody_file.close();​
 +
 +  File duration_file = SD.open("​DURATI~1.TXT",​ FILE_READ);
 +  for (int i = 0; i < nr_elem; i++) {
 +    String nr = duration_file.readStringUntil(','​);​
 +    noteDurations[i] = nr.toInt();
 +  }
 +  duration_file.close();​
 +  state = 9;
 +</​code>​
 +  * void setup() - setez pinii pentru pentru butoane, initializez ecranul LCD si afisez "Hello world!",​ atasez intreruperea pentru butonul de play, initializez cardul SD, setez timer-ul
 +<code C>
 +void setup() {
 +  Serial.begin(9600);​
 +  nr_elem = 0;
 +  lcd.init();
 +  lcd.backlight();​
 +  lcd.setCursor(0,​0);​
 +  lcd.print("​Hello,​ world!"​);​
 +  pinMode(pushButton1,​ INPUT_PULLUP);​
 +  pinMode(pushButton2,​ INPUT_PULLUP);​
 +  pinMode(pushButton3,​ INPUT_PULLUP);​
 +  pinMode(pushButton4,​ INPUT_PULLUP);​
 +  pinMode(pushButton5,​ INPUT_PULLUP);​
 +  pinMode(pushButton6,​ INPUT_PULLUP);​
 +  pinMode(pushButton7,​ INPUT_PULLUP);​
 +  pinMode(pushButton8,​ INPUT_PULLUP);​
 +  pinMode(pushButton9,​ INPUT_PULLUP);​
 +  attachInterrupt(digitalPinToInterrupt(pushButton9),​ myCallback, FALLING);
 +
 +  if (!SD.begin(10)) {
 +    Serial.println("​initialization failed!"​);​
 +  }
 +
 +  cli();
 +  OCR2A = 254;
 +  TCNT2 = 0;
 +  TCCR2A |= 0;
 +  TCCR2B |= 0;
 +  TCCR2A |= (1<<​WGM20) | (1<<​WGM21);​
 +  TCCR2B |= (1<<​WGM22);​
 +  TIMSK2 |= (1<<​TOIE2);​
 +
 +  TCCR2B |= (1<<​CS22);​
 +  sei();
 +}
 +</​code>​
 +  * ISR(TIMER2_OVF_vect) - functia e apelata de timer pentru a decrementa countdown-ul
 +<code C>
 +ISR(TIMER2_OVF_vect) {
 +  if (countdown > 0) {
 +    countdown--;​
 +  }
 +}
 +</​code>​
 +  * void loop()
 +Pentru a sti ce se intampla in cazul celor 10 stari, starile fiind 0 (in care se afiseaza pe ecran "Hello world!"​ si nu se intampla nimic), de la  1 la 8, daca se apasa un buton al unei clape si se afieaza nota specifica clapei si se reda sunetului asociat clapei, si 9 daca se apasa butonul de play de pe cardul SD am folosit o variabila globala volatile int state.
 +
 +Verific starea fiecarui buton specific unei clape, daca pentru un buton functia digitalRead intoarce valoarea 0, cat timp aceasta valoare este 0, atunci se va afisa pe monitorul LCD nota specifica butonului si se va reda sunetul specific butonului si state-ul va fi numarul specific butonului.
 +<code C>
 +  int buttonState1 = digitalRead(pushButton1);​
 +  while (buttonState1 == 0) {
 +    if (state != 1) {
 +      lcd.clear();​
 +      lcd.setCursor(0,​0);​
 +      lcd.print("​nota DO1!"​);​
 +      state = 1;
 +    }
 +    tone(buzzer,​ 440);
 +    buttonState1 = digitalRead(pushButton1);​
 +  }
 +</​code>​
 +La fel se intampla si pentru celelalte 7 butoane, fiind printat alt mesaj si redat alt sunet si setat alt state.
 +
 +Apoi daca state-ul este 9, se afiseaza "play music!",​ si sa se redea melodia salvata. In timpul redarii melodiei se va afisa pe ecranul LCD un countdown de la 1000ms, daca acest timp trece se va afisa "timer expirat!"​.
 +<code C>
 +if (state == 9) {
 +    lcd.clear();​
 +    lcd.setCursor(0,​0);​
 +    lcd.print("​play music!"​);​
 +    countdown = 2000;
 +    for (int i = 0; i < nr_elem; i++) {
 +      int noteDuration = 1000 / noteDurations[i];​
 +      tone(buzzer,​ melody[i], noteDuration);​
 +      int pauseBetweenNotes = noteDuration * 1.30;
 +      delay(pauseBetweenNotes);​
 +      if (countdown == 0) {
 +        lcd.clear();​
 +        lcd.setCursor(0,​0);​
 +        lcd.print("​play music!"​);​
 +        lcd.setCursor(0,​ 1);
 +        lcd.print("​Timer expirat!"​);​
 +      } else {
 +        lcd.setCursor(0,​ 1);
 +        lcd.print("​Time left: ");
 +        lcd.print(countdown/​2);​
 +        lcd.print("​ms"​);​
 +      }
 +      noTone(buzzer);​
 +    }
 +  }
 +</​code>​
 +
 +Iar la final daca state-ul este diferit de 0 sunetul este oprit si se afiseaza doar textul "Hello world!"​ pe ecranul LCD.
 +<code C>
 +  if (state != 0) {
 +    lcd.clear();​
 +    lcd.setCursor(0,​0);​
 +    lcd.print("​Hello World!"​);​
 +    noTone(buzzer);​
 +    state = 0;
 +  }
 +</​code>​
 +
  
-<note tip> 
-Descrierea codului aplicaţiei (firmware): 
-  * mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR) 
-  * librării şi surse 3rd-party (e.g. Procyon AVRlib) 
-  * algoritmi şi structuri pe care plănuiţi să le implementaţi 
-  * (etapa 3) surse şi funcţii implementate 
-</​note>​ 
  
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
Line 56: Line 182:
 {{:​pm:​prj2023:​vstoica:​pedolu_carmenpoza1.jpg?​300 |}}{{:​pm:​prj2023:​vstoica:​pedolu_carmenpoza2.jpg?​300 |}} {{:​pm:​prj2023:​vstoica:​pedolu_carmenpoza3.jpg?​300 |}} {{:​pm:​prj2023:​vstoica:​pedolu_carmenpoza1.jpg?​300 |}}{{:​pm:​prj2023:​vstoica:​pedolu_carmenpoza2.jpg?​300 |}} {{:​pm:​prj2023:​vstoica:​pedolu_carmenpoza3.jpg?​300 |}}
 ===== Concluzii ===== ===== Concluzii =====
-Proiectul mi s-a parut interesant, fascinant si util sa lucrez la proiect. Libertatea de a face ceea ce imi doresc m-a atras la inceput. Apoi mi-a placut sa invat sa lipesc componente. Mi s-a parut interesant sa caut in datasheet diverse informatii despre intreruperi,​ timere si pinii la care trebuie conectati piesele. Consider ca am invatat multe despre ​lucrul ​cu arduino si conectarea hardware-ului cu software-ul.+Proiectul mi s-a parut interesant, fascinant si util. Libertatea de a face ceea ce imi doresc m-a atras la inceput. Apoi mi-a placut sa invat sa lipesc componente. Mi s-a parut interesant sa caut in datasheet diverse informatii despre intreruperi,​ timere si pinii la care trebuie conectati piesele. Consider ca am invatat multe despre ​lucratul ​cu arduino si conectarea hardware-ului cu software-ul.
  
 ===== Download ===== ===== Download =====
- +{{:pm:prj2023:vstoica:proiect_pm_pedolu_carmen-petronela332ca.zip|Surse}}
-<note warning>​ +
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului:​ surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). +
- +
-Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:pm:prj20??:c?** sau **:pm:​prj20??:​c?:​nume_student** (dacă este cazul). **Exemplu:​** Dumitru Alin, 331CC -> **:​pm:​prj2009:​cc:​dumitru_alin**. +
-</​note>​+
  
 ===== Jurnal ===== ===== Jurnal =====
pm/prj2023/vstoica/carmenpedolu.1685199173.txt.gz · Last modified: 2023/05/27 17:52 by carmen.pedolu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0