This shows you the differences between two versions of the page.
|
pm:prj2022:arosca:electronic-keyboard [2022/05/05 21:33] vlad.enculesei [Hardware Design] |
pm:prj2022:arosca:electronic-keyboard [2022/05/05 22:49] (current) vlad.enculesei [Download] |
||
|---|---|---|---|
| Line 26: | Line 26: | ||
| Mai jos este schema electrica a proiectului realizata in Tinkercad, cu mentiunea ca LCD-ul cu I2C nu putea fi simulat in Tinkercad deoarece nu exista componenta respectiva. In implementarea fizica LCD-ul cu I2C este conectat la GND, VCC, iar iesirile SDA si SCL sunt conectate la A4, respectiv A5. | Mai jos este schema electrica a proiectului realizata in Tinkercad, cu mentiunea ca LCD-ul cu I2C nu putea fi simulat in Tinkercad deoarece nu exista componenta respectiva. In implementarea fizica LCD-ul cu I2C este conectat la GND, VCC, iar iesirile SDA si SCL sunt conectate la A4, respectiv A5. | ||
| - | {{ :pm:prj2022:arosca:schema_tinkercad_vlad_enculesei.png?500 |}} | + | {{ :pm:prj2022:arosca:schema_tinkercad_vlad_enculesei.png?750 |}} |
| ===== Software Design ===== | ===== Software Design ===== | ||
| + | Mediul de dezvoltare a fost Tinkercad, iar mai apoi Arduino IDE, mai ales pentru ca nu exista LCD cu I2C in Tinkercad, asa cum s-a mai mentionat si mai sus. | ||
| - | <note tip> | + | Pentru LCD-ul cu I2C a fost instalata biblioteca LiquidCrystal I2C by Marco Schwartz version 1.1.2 si a fost initializata o variabila LiquidCrystal_I2C cu adresa 0X27 LCD-ului si 16 caractere pe cate 2 linii. Functia setup seteaza starea initiala a butoanelor (LOW), seteaza corespunzator pinii si seteaza si LCD-ul. |
| - | 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 ===== | + | Functia resetDisplay reseteaza display-ul pe 7 segmente si LCD-ul in asa fel incat sa nu se afiseze nimic. Functiile p*, unde * apartine multimii de note muzicale, seteaza LCD-ul si display-ul cu 7 segmente pentru a se afisa o nota muzicala in doua moduri si respectiv o cifra de la 1 la 8. Functia debounce, dupa cum ii spune si numele, face debouncing pentru butoanele pianului. |
| - | <note tip> | + | Finctiile check*, unde * apartine multimii de note muzicale, verifica daca s-a apasat butonul corespunzator notei muzicale respective, activeaza buzzer-ul si apoi apeleaza p* pentru afisaj. In functia loop, se apeleaza functiile check* si mai apoi resetDisplay. |
| - | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | |
| - | </note> | + | |
| - | ===== Concluzii ===== | + | <code java> |
| - | ===== Download ===== | + | #include <Wire.h> |
| + | #include <LiquidCrystal_I2C.h> | ||
| - | <note warning> | + | #define piezoPin A2 |
| - | 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ă ;-). | + | #define DO 2 |
| + | #define RE 3 | ||
| + | #define MI 4 | ||
| + | #define FA 5 | ||
| + | #define SOL 6 | ||
| + | #define LA 7 | ||
| + | #define SI 8 | ||
| + | #define DO2 13 | ||
| + | #define A 12 | ||
| + | #define B 9 | ||
| + | #define C A3 | ||
| + | #define D A0 | ||
| + | #define E A1 | ||
| + | #define F1 10 | ||
| + | #define G 11 | ||
| - | 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**. | + | int buttonState; |
| - | </note> | + | LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); |
| - | ===== Jurnal ===== | + | void setup() { |
| + | Serial.begin(9600); | ||
| + | lcd.init(); | ||
| + | lcd.clear(); | ||
| + | lcd.backlight(); | ||
| + | buttonState = LOW; | ||
| + | pinMode(DO, INPUT); | ||
| + | pinMode(RE, INPUT); | ||
| + | pinMode(MI, INPUT); | ||
| + | pinMode(FA, INPUT); | ||
| + | pinMode(SOL, INPUT); | ||
| + | pinMode(LA, INPUT); | ||
| + | pinMode(SI, INPUT); | ||
| + | pinMode(DO2, INPUT); | ||
| + | pinMode(A, OUTPUT); | ||
| + | pinMode(B, OUTPUT); | ||
| + | pinMode(C, OUTPUT); | ||
| + | pinMode(D, OUTPUT); | ||
| + | pinMode(E, OUTPUT); | ||
| + | pinMode(F1, OUTPUT); | ||
| + | pinMode(G, OUTPUT); | ||
| + | pinMode(piezoPin, OUTPUT); | ||
| + | } | ||
| - | <note tip> | + | void resetDisplay(void) { |
| - | Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. | + | lcd.clear(); |
| - | </note> | + | lcd.noCursor(); |
| + | digitalWrite(A, LOW); | ||
| + | digitalWrite(B, LOW); | ||
| + | digitalWrite(C, LOW); | ||
| + | digitalWrite(D, LOW); | ||
| + | digitalWrite(E, LOW); | ||
| + | digitalWrite(F1, LOW); | ||
| + | digitalWrite(G, LOW); | ||
| + | } | ||
| + | |||
| + | void pDO(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("DO"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("C"); | ||
| + | digitalWrite(A, LOW); | ||
| + | digitalWrite(B, HIGH); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, LOW); | ||
| + | digitalWrite(E, LOW); | ||
| + | digitalWrite(F1, LOW); | ||
| + | digitalWrite(G, LOW); | ||
| + | } | ||
| + | |||
| + | void pRE(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("RE"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("D"); | ||
| + | digitalWrite(A, HIGH); | ||
| + | digitalWrite(B, HIGH); | ||
| + | digitalWrite(C, LOW); | ||
| + | digitalWrite(D, HIGH); | ||
| + | digitalWrite(E, HIGH); | ||
| + | digitalWrite(F1, LOW); | ||
| + | digitalWrite(G, HIGH); | ||
| + | } | ||
| + | |||
| + | void pMI(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("MI"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("E"); | ||
| + | digitalWrite(A, HIGH); | ||
| + | digitalWrite(B, HIGH); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, HIGH); | ||
| + | digitalWrite(E, LOW); | ||
| + | digitalWrite(F1, LOW); | ||
| + | digitalWrite(G, HIGH); | ||
| + | } | ||
| + | |||
| + | void pFA(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("FA"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("F"); | ||
| + | digitalWrite(A, LOW); | ||
| + | digitalWrite(B, HIGH); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, LOW); | ||
| + | digitalWrite(E, LOW); | ||
| + | digitalWrite(F1, HIGH); | ||
| + | digitalWrite(G, HIGH); | ||
| + | } | ||
| + | |||
| + | void pSOL(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("SOL"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("G"); | ||
| + | digitalWrite(A, HIGH); | ||
| + | digitalWrite(B, LOW); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, HIGH); | ||
| + | digitalWrite(E, LOW); | ||
| + | digitalWrite(F1, HIGH); | ||
| + | digitalWrite(G, HIGH); | ||
| + | } | ||
| + | |||
| + | void pLA(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("LA"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("A"); | ||
| + | digitalWrite(A, HIGH); | ||
| + | digitalWrite(B, LOW); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, HIGH); | ||
| + | digitalWrite(E, HIGH); | ||
| + | digitalWrite(F1, HIGH); | ||
| + | digitalWrite(G, HIGH); | ||
| + | } | ||
| + | |||
| + | void pSI(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("SI"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("B"); | ||
| + | digitalWrite(A, HIGH); | ||
| + | digitalWrite(B, HIGH); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, LOW); | ||
| + | digitalWrite(E, LOW); | ||
| + | digitalWrite(F1, LOW); | ||
| + | digitalWrite(G, LOW); | ||
| + | } | ||
| + | |||
| + | void pDO2(void) { | ||
| + | lcd.setCursor(7, 0); | ||
| + | lcd.print("DO"); | ||
| + | lcd.setCursor(7, 1); | ||
| + | lcd.print("C"); | ||
| + | digitalWrite(A, HIGH); | ||
| + | digitalWrite(B, HIGH); | ||
| + | digitalWrite(C, HIGH); | ||
| + | digitalWrite(D, HIGH); | ||
| + | digitalWrite(E, HIGH); | ||
| + | digitalWrite(F1, HIGH); | ||
| + | digitalWrite(G, HIGH); | ||
| + | } | ||
| + | |||
| + | int debounce(int buttonPin) { | ||
| + | int stateNow = digitalRead(buttonPin); | ||
| + | if(buttonState != stateNow) { | ||
| + | delay(10); | ||
| + | stateNow = digitalRead(buttonPin); | ||
| + | } | ||
| + | return stateNow; | ||
| + | } | ||
| + | |||
| + | void checkDO(void) { | ||
| + | while(debounce(DO) == HIGH) { | ||
| + | tone(piezoPin, 261.63, 200); | ||
| + | pDO(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkRE(void) { | ||
| + | while(debounce(RE) == HIGH) { | ||
| + | tone(piezoPin, 293.665, 200); | ||
| + | pRE(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkMI(void) { | ||
| + | while(debounce(MI) == HIGH) { | ||
| + | tone(piezoPin, 329.628, 200); | ||
| + | pMI(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkFA(void) { | ||
| + | while(debounce(FA) == HIGH) { | ||
| + | tone(piezoPin, 349.228, 200); | ||
| + | pFA(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkSOL(void) { | ||
| + | while(debounce(SOL) == HIGH) { | ||
| + | tone(piezoPin, 391.995, 200); | ||
| + | pSOL(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkLA(void) { | ||
| + | while(debounce(LA) == HIGH) { | ||
| + | tone(piezoPin, 440, 200); | ||
| + | pLA(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkSI(void) { | ||
| + | while(debounce(SI) == HIGH) { | ||
| + | tone(piezoPin, 493.883, 200); | ||
| + | pSI(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void checkDO2(void) { | ||
| + | while(debounce(DO2) == HIGH) { | ||
| + | tone(piezoPin, 523.251, 200); | ||
| + | pDO2(); | ||
| + | delay(200); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | checkDO(); | ||
| + | checkRE(); | ||
| + | checkMI(); | ||
| + | checkFA(); | ||
| + | checkSOL(); | ||
| + | checkLA(); | ||
| + | checkSI(); | ||
| + | checkDO2(); | ||
| + | resetDisplay(); | ||
| + | } | ||
| + | |||
| + | </code> | ||
| + | ===== Rezultate Obţinute ===== | ||
| + | |||
| + | {{ :pm:prj2022:arosca:image1_vlad_enculesei.jpg?700 |}} | ||
| + | {{ :pm:prj2022:arosca:image2_vlad_enculesei.jpg?700 |}} | ||
| + | {{ :pm:prj2022:arosca:image3_vlad_enculesei.jpg?700 |}} | ||
| + | ===== Concluzii ===== | ||
| + | |||
| + | Proiectul acesta poate fi folositor ca jucarie pentru copiii foarte mici care doresc sa se joace cu un pian si sa si invete, in acelasi timp, notele muzicale. Mie mi-a placut proiectul pentru ca am invatat cum sa folosesc un LCD cu I2C si un buzzer pasiv. In plus, am invatat sa fac debouncing pentru butoanele pianului. | ||
| + | ===== Download ===== | ||
| + | {{:pm:prj2022:arosca:vlad_enculesei_335ca.zip|Arhiva proiectului (cod + README)}} | ||
| ===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
| - | <note> | + | * [[https://www.electroniclinic.com/common-anode-and-common-cathode-seven-segment-display-arduino-project-for-beginners/|Display pe 7 segmente (catod comun vs anod comun)]] |
| - | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | * [[https://www.electronics-lab.com/project/arduino-button-debounce-tutorial/|Debounce butoane]] |
| - | </note> | + | * [[https://arduinogetstarted.com/tutorials/arduino-lcd-i2c|LCD cu I2C]] |
| + | * [[https://pages.mtu.edu/%7Esuits/notefreqs.html|Note muzicale (de la C4 la C5)]] | ||
| + | * [[https://create.arduino.cc/projecthub/littlefalcon9/passive-buzzer-d4997b|Buzzer pasiv]] | ||
| <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | ||