This shows you the differences between two versions of the page.
pm:prj2022:arosca:electronic-keyboard [2022/05/05 21:32] vlad.enculesei [Hardware Design] |
pm:prj2022:arosca:electronic-keyboard [2022/05/05 22:49] (current) vlad.enculesei [Download] |
||
---|---|---|---|
Line 24: | Line 24: | ||
* Fire | * Fire | ||
- | Aceasta 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?300 |}} | + | |
+ | {{ :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> |