This shows you the differences between two versions of the page.
pm:prj2024:iotelea:mihai.negru0025 [2024/05/18 22:25] mihai.negru0025 [Reprezentarea hardware reală] |
pm:prj2024:iotelea:mihai.negru0025 [2024/05/26 15:44] (current) mihai.negru0025 [Concluzii] |
||
---|---|---|---|
Line 87: | Line 87: | ||
{{pm:prj2024:iotelea:mihai_negru0025_hardware.gif|left|hardware}} | {{pm:prj2024:iotelea:mihai_negru0025_hardware.gif|left|hardware}} | ||
+ | Cum se poate observa și în schema logică și electrică de mai jos, controlul led-urilor este definit pur electronic, adică în dependență de output-ul fototranzistoarelor, culoarea led-ului va fi sau roșu sau verde (**1-roșu**, **0-verde**). Pe de altă parte diodele laser sunt doar conectate de un Vcc(+5V), și sunt mereu conectate atât timp cât plăcuța de dezvoltare este conectată la o sursă de alimentare, astfel tot ce se poate viziona din //gif-ul// de mai sus, este reprezentat pur hardware, fără nici o intervenție software. | ||
- | ==== Scheme Electrice ==== | + | Proiect-ul hardware, este definit în 2 părți(2 pcb-uri). În primul //PCB// se află plăcuța arduino, totodată se lipesc și buzzere-le pasive, pe cel de-al doilea //PCB// se află cele 9 circuite cu tranzistoare, care vor face switch-ul de la culoarea roșie a led-ului la culoarea verde (//și invers//), de același PCB, se conectează în sine și cele 9 leduri(a câte 2 fire fiecare), și output-ul care vine din fototranzistoare, fiindcă circuitul alcătuit din tranzistoare este controlat de output-ul fototranzistoarelor. |
- | <note tip> | + | <note warning> |
- | Aici puneţi tot ce ţine de hardware design: | + | Cele două părți au fost lipite ambele cu ajutorul unui ciocan electric, din cauza numărului mare de fire -> pentru **9** leduri câte **2** fire, mai apoi pentru 9 fototranzistoare cîte 3 fire(Vcc, Gnd și Out), în total **45** de fire, procesul de lipire a fost unul foarte anevoios. Initial am vrut să lipesc totul doar pe PCB-uri, după am avut idea "geniala", care a îngreunat tot procesul de a plasa led-urile separat, pentru a avea un efect vizual mai frumos. Într-un final totul a fost pus cap la cap, și ca bonus fiindcă nu mi-a plăcut cum "zboară" firele am decis să fac un pic de restructurare, și să ascund partea de circuit. |
- | * listă de piese | + | |
- | * scheme electrice (se pot lua şi de pe Internet şi din datasheet-uri, e.g. http://www.captain.at/electronic-atmega16-mmc-schematic.png) | + | |
- | * diagrame de semnal | + | |
- | * rezultatele simulării | + | |
</note> | </note> | ||
+ | |||
+ | |||
+ | ==== Reprezentare hardware logică ==== | ||
+ | |||
+ | Pentru dezvoltarea schemei electrice și logice s-a folosit aplicația **//Fritzing//**, unde pe breadboard, sunt reprezentate cele 18, tranzistoare care produc switch-ul dintre, culorile led-ului rgb cu anod comun, totodată din fototranzistoare se trag 2 fire de output, unul în baza tranzistoarelor de **switch** și altul în plăcuța de dezvoltare, care va intercepta semnalul fototranzistoarelor și în dependență de acesta va suna sau nu o notă muzicală prin buzzerele la fel conectate la pin-urile gpio ale plăcuței arduino. | ||
+ | |||
+ | {{pm:prj2024:iotelea:mihai_negru0025_electrical_schema.png?931x931|left|logical schema}} | ||
+ | |||
+ | ==== Reprezentare hardware electrică ==== | ||
+ | |||
+ | Pentru o înțelegere mai detaliată a circuitul vă prezint și schema electrocă a proiectului hardware | ||
+ | |||
+ | {{pm:prj2024:iotelea:mihai_negru0025_electrical_schema_next_1.png?956x785|left|electrical schema}} | ||
===== Software Design ===== | ===== Software Design ===== | ||
+ | Pentru dezvoltarea proiectului din punct de vedere soft, s-a folosit, **ArduinoIDE**. | ||
- | <note tip> | + | === Structuri === |
- | 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 ===== | + | In sine notele vor fi tinute drept niste pini logici, si vom avea un macro care va face maparea dintre un port logic si unul hardware: |
- | <note tip> | + | <code c> |
- | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | /* Trasform a logic pin into real pin */ |
- | </note> | + | #define REAL_ID(pin) (pin + 11) |
- | ===== Concluzii ===== | + | /* |
+ | * @brief possible playing notes, mapped to logical pins | ||
+ | */ | ||
+ | typedef enum note_s { | ||
+ | DO = 0, | ||
+ | RE = 1, | ||
+ | MI = 3, | ||
+ | FA = 5, | ||
+ | SO = 4, | ||
+ | LA = 9, | ||
+ | SI = 2, | ||
+ | NO_NOTE = -1 | ||
+ | } note_t; | ||
+ | </code> | ||
- | ===== Download ===== | + | Totodata fiecare nota va avea un status, in sensul daca coarda corespunzatoare notei este apasata sau nu: |
+ | <code c> | ||
+ | /* | ||
+ | * @brief - status for a single note, either Active or Idle. | ||
+ | * Active when the chord is pressed, and Idle when it is not | ||
+ | */ | ||
+ | typedef enum note_status_s { | ||
+ | ACTIVE = 0, | ||
+ | IDLE = 1 | ||
+ | } ns_t; | ||
- | <note warning> | + | /* Status for every note either Active or Idle */ |
- | 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ă ;-). | + | ns_t notes_status[MAX_NOTES]; |
+ | </code> | ||
- | 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**. | + | === Flow Design === |
- | </note> | + | |
- | ===== Jurnal ===== | + | Flow-ul general al programului tine de 3 pasi: |
+ | |||
+ | * Actualizeaza statusul notelor | ||
+ | * Canta notele active, atat timp cat exista buzzere libere | ||
+ | * Actualizeaza vectorul de memoizare | ||
+ | |||
+ | Astfel, bucla principala a programului este alcatuita de: | ||
+ | <code c> | ||
+ | /* Firstly update the status or each note */ | ||
+ | update_notes_status(); | ||
+ | |||
+ | /* Iterate through all notes and check their status */ | ||
+ | for (int i = 0; i < MAX_NOTES; ++i) { | ||
+ | if (notes_status[i] == ACTIVE) { | ||
+ | |||
+ | /* If note is active check if there is a tone available */ | ||
+ | int tone_idx = available_tone(notes[i]); | ||
+ | |||
+ | /* If a tone agrees to play the note, then play it. */ | ||
+ | if (tone_idx != -1) tones[tone_idx].play(notes_freq[i], 100); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* Update the memoization vector */ | ||
+ | update_tones_memoization(); | ||
+ | </code> | ||
+ | |||
+ | Vectorul de memoizare, este un simplu vector, care tine cont ce note sunt cantate la o actualizare de status, si in sine mimeaza functia de **isPlaying()**, pentru o structura **Tone**, am implementat aceasta structura de mana, fiindca aveam in sine nevoie de un **delay**, care foloseste si el un timer, insa cele 3 buzzere, folosesc si ele cate un timer aparte, deci pe ArduinoNano, exista doar 3 timere, si atunci pentru a nu sacrifica un buzzer, am sacrificat functia de delay. | ||
+ | |||
+ | Se folosesc in sine 3 buzzere, fiindca se doreste un flux cat mai asincron, adica daca in momentul cand sunt apasate 3 coarde, se doreste a fi cantate 3 note, insa pentru mai mult de 3, se vor canta primele 3 intrate pe **buss**. | ||
+ | |||
+ | <code c> | ||
+ | /* | ||
+ | * @brief Returns the tone that is available for playing | ||
+ | * | ||
+ | * @param note the note that wants to be played on the tone | ||
+ | * @return tone index if a tone agrees to play the note or | ||
+ | * -1 if all the tones are busy. | ||
+ | */ | ||
+ | int available_tone(note_t note) { | ||
+ | for (int i = 0; i < MAX_TONES; ++i) | ||
+ | if (buss[i] == note || buss[i] == NO_NOTE) { | ||
+ | buss[i] = note; | ||
+ | return i; | ||
+ | } | ||
+ | |||
+ | return -1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | === Biblioteci folosite === | ||
+ | |||
+ | S-a folosit o singura biblioteca **ToneLibrary**, inclusa in core, care poate simula **square waves**, pentru frecvente diferite si pentru durate de timp diferit, folosind //PWM//, in sine cum am specificat si mai sus, se pot canta note asincron folosing functia **Tone::play()**, insa numarul de note cantate asincron este limitat de numarul de timere, din acest motiv vom putea canta simultan doar 3 note. | ||
<note tip> | <note tip> | ||
- | Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. | + | Codul intreb poate fi gasit la acest link https://github.com/mihai-negru/electric-harp/blob/master/electric-harp.ino |
</note> | </note> | ||
- | ===== Bibliografie/Resurse ===== | ||
- | <note> | ||
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | ||
- | </note> | ||
- | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | + | ===== Concluzii ===== |
+ | A fost un proiect destul de interesant, si puternic vizual, cel mai complicat lucru a fost lipit-l, dat fiind faptul ca am dorit sa includ un grad mai inalt de estetica, astfel a fost nevoie de foarte fire, cum am mentionat si mai sus. In procesul de lipire am fost nevoit sa lipsesc niste piese de doua ori, fiindca in procesul de testare nu se comporta //as expected//. Dar la final a fost un proces destul de interesant. |