This shows you the differences between two versions of the page.
pm:prj2024:azamfir:oana_maria.bacaran [2024/05/23 13:46] oana_maria.bacaran |
pm:prj2024:azamfir:oana_maria.bacaran [2024/05/27 14:28] (current) oana_maria.bacaran |
||
---|---|---|---|
Line 2: | Line 2: | ||
===== Introducere ===== | ===== Introducere ===== | ||
<note tip> | <note tip> | ||
- | * Autor: Oana Maria Băcăran \\ | + | * Autor: Oana Maria Băcăran |
- | * Grupa: 334CB | + | * Grupa: 334CB |
</note> | </note> | ||
<note> | <note> | ||
*** Ce face?** \\ | *** Ce face?** \\ | ||
- | Tom este o jucărie interactivă, care știe să imite ceea ce spui, poate sa redea cântecele și poate realiza efecte vizuale, folosind LED-uri colorate și redând mici animații pe un ecran OLED.\\ | + | Tom este o jucărie interactivă, care știe să imite ceea ce spui, poate sa redea cântecele și poate realiza efecte vizuale, redând mici animații pe un ecran OLED.\\ |
*** Care este scopul lui?** \\ | *** Care este scopul lui?** \\ | ||
Scopul acestui proiect este acela de a implementa o jucărie amuzantă, folosind și materiale reciclabile.\\ | Scopul acestui proiect este acela de a implementa o jucărie amuzantă, folosind și materiale reciclabile.\\ | ||
Line 22: | Line 22: | ||
- Modul ascultare și redare, în care acesta primește un input audio de la utilizator, apasând pe butonul de rec (înregistrare) și redă ulterior ceea ce a înregistrat, cu ajutorul unui difuzor. Butoanele necesare se află pe modulul audio ISD1820. | - Modul ascultare și redare, în care acesta primește un input audio de la utilizator, apasând pe butonul de rec (înregistrare) și redă ulterior ceea ce a înregistrat, cu ajutorul unui difuzor. Butoanele necesare se află pe modulul audio ISD1820. | ||
- Modul ascultare muzică, unde utilizatorul poate folosi butoanele de play/pause, next și previous ca să navigheze printre fișierele stocate pe un card sd; se folosește un card reader compatibil SPI pentru a reda melodiile. | - Modul ascultare muzică, unde utilizatorul poate folosi butoanele de play/pause, next și previous ca să navigheze printre fișierele stocate pe un card sd; se folosește un card reader compatibil SPI pentru a reda melodiile. | ||
- | Pentru a adăuga un strop de culoare și dinamsim, în ambele moduri, pe ecranul OLED se vor afișa mici animații, care vor alterna constant. De asemenea, LED-urile vor realiza un mic joc de culori atunci când se vor reda elemente auditive. | + | Pentru a adăuga un strop de culoare și dinamsim, în ambele moduri, pe ecranul OLED se vor afișa mici animații, care vor alterna constant si vor fi randomizate in modul music player. |
</note> | </note> | ||
- | + | {{:pm:prj2024:azamfir:diagrama_proiect_pm_2.drawio.png?800|}} | |
- | {{:pm:prj2024:azamfir:diagrama_proiect_pm.jpg?800|}} | + | |
===== Hardware Design ===== | ===== Hardware Design ===== | ||
- | <note tip> | + | **Lista piese:** |
- | Aici puneţi tot ce ţine de hardware design: | + | * Arduino ATmega2560 |
- | * listă de piese | + | |
- | * scheme electrice | + | |
- | * diagrame de semnal | + | |
- | * rezultatele simulării | + | |
- | </note> | + | |
- | Lista piese: \\ | + | |
- | * Arduino ATmega328P | + | |
* Modul inregistrare redare audio ISD1820 | * Modul inregistrare redare audio ISD1820 | ||
* Modul Amplificator Audio LM386 | * Modul Amplificator Audio LM386 | ||
- | * Difuzor | + | * 2 x Difuzor |
* Display grafic OLED | * Display grafic OLED | ||
- | * Circuit integrat SN74HC595N, 74HC595 | ||
* Placa de stocare Micro SD TF Card reader Shield | * Placa de stocare Micro SD TF Card reader Shield | ||
* Card SD | * Card SD | ||
- | * LED-uri | + | * 5 x push buttons |
- | * 3 x butoane push | + | |
* fire conectare | * fire conectare | ||
- | Schema electrică: \\ | + | **Schema electrică:**\\ |
- | {{:pm:prj2024:azamfir:schema_2.jpg?800|}} | + | {{:pm:prj2024:azamfir:schema_electrica_finala.jpg?800|}}\\ |
+ | \\ | ||
+ | **Descriere pini:** | ||
+ | * Ecran OLED: conectat la pinii corespunzatori protocolului I2C, SCL(PD0) si SDA(PD1), conform datasheet-ului | ||
+ | * Modul ISD1820: conectat la pinii GPIO 2 si 3 | ||
+ | * MicroSD Card Reader: foloseste protocolul SPI, iar pinii corespunzatori acestuia sunt: D53 pentru CS, D52 pentru SCK, D51 pentru MOSI, D50 pentru MISO | ||
+ | * LM385: acesta are nevoie de un pin de input pentru speaker si foloseste pinul D46 | ||
+ | * Butoanele: folosesc pinii digitali 5,6,7,8,9 | ||
+ | \\ | ||
+ | **Componentele conectate:**\\ | ||
+ | {{:pm:prj2024:azamfir:imagine_circuit.jpg?800|}} | ||
===== Software Design ===== | ===== Software Design ===== | ||
- | Mediu de dezvoltare: | + | **Mediu de dezvoltare**: |
* dezvoltare cod: Arduino IDE | * dezvoltare cod: Arduino IDE | ||
- | * realizare animații: OLED animations | + | * animații: Wokwi animations |
* realizare schemă bloc: draw.io | * realizare schemă bloc: draw.io | ||
* realizare schemă electrică: Kicad | * realizare schemă electrică: Kicad | ||
- | Biblioteci: | + | **Biblioteci**: |
- | * SD.h | + | * SD.h - ofera suport pentru initializarea card reader-ului si citirea cardului microSD |
- | * TMRpcm.h | + | * TMRpcm.h - folosita pentru redarea, intreruperea audio-urilor |
- | * SPI.h | + | * SPI.h - folosita pentru cititorul de card SD |
- | * Adafruit_GFX.h | + | * Adafruit_GFX.h - ofera primitive pentru grafica |
- | * Adafruit_SSD1306.H | + | * Adafruit_SSD1306.h - folosita pentru manipularea animatiilor de pe display-ul OLED, specifica pentru tipul de ecran OLED |
+ | * Animations.h - stochez frame-urile animatiilor | ||
+ | <code cpp> | ||
+ | #include <SD.h> | ||
+ | #include <TMRpcm.h> | ||
+ | #include <Adafruit_GFX.h> | ||
+ | #include <Adafruit_SSD1306.h> | ||
+ | #include <SPI.h> | ||
+ | #include "Animations.h" | ||
+ | </code> | ||
+ | **Configurari si variabile globale:**\\ | ||
+ | Pentru display, am initializat o instanta a clasei Adafruit_SSD1306, aceasta este variabila care controleaza display-ul. De asemenea, am setat si variabilele de measurements, precum viteza de redare a frame-urilor, latimea si lungimea animatiei in ecran si o variabila currentAnimation, care va stoca o referinta la o animatie aleasa random, pentru partea de music player. | ||
+ | <code cpp> | ||
+ | #define SCREEN_I2C_ADDR 0x3C // or 0x3C | ||
+ | #define SCREEN_WIDTH 128 // OLED display width, in pixels | ||
+ | #define SCREEN_HEIGHT 64 // OLED display height, in pixels | ||
+ | #define OLED_RST_PIN -1 // Reset pin (-1 if not available) | ||
- | ===== Rezultate Obţinute ===== | + | Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST_PIN); |
- | <note tip> | + | #define FRAME_DELAY (42) |
- | Care au fost rezultatele obţinute în urma realizării proiectului vostru. | + | #define FRAME_WIDTH (48) |
- | </note> | + | #define FRAME_HEIGHT (48) |
+ | #define FRAME_COUNT (sizeof(recording) / sizeof(recording[0])) | ||
+ | const byte (*currentAnimation)[288]; | ||
+ | |||
+ | int frame = 0; | ||
+ | int frame_music = 0; | ||
+ | </code> | ||
+ | |||
+ | Pentru partea de redare a audio-urilor, am setat variabilele necesare butoanelor, pentru controlarea audio-ului (setarea calitatii audiolui, a volumului, porninrea si oprirea acestuia), a directorului in care se afla fisierele .wav si doua variabile care stocheaza numarul de audio-uri si indexul melodiei curente, incepand de la 1. | ||
+ | <code cpp> | ||
+ | #define SD_CS_PIN 53 | ||
+ | #define SPEAKER_PIN 46 | ||
+ | #define PREV_PIN 7 | ||
+ | #define PLAY_PIN 6 | ||
+ | #define NEXT_PIN 5 | ||
+ | #define FILENAME_SIZE 20 | ||
+ | |||
+ | TMRpcm audio; | ||
+ | File root; | ||
+ | |||
+ | int numSongs = 0; | ||
+ | int songIdx = 1; | ||
+ | </code> | ||
+ | Alte variabile initializate au legatura cu partea de inregistrare a vocii, de la butoanele de control, pana la doua variabile bool care blocheaza folosirea inermitenta a celor doua moduri de functionare. | ||
+ | <code cpp> | ||
+ | int rec=2; | ||
+ | int play=3; | ||
+ | int button_rec=8; | ||
+ | int button_play=9; | ||
+ | bool music_player_on = false; | ||
+ | bool recording_on = false; | ||
+ | </code> | ||
+ | \\ | ||
+ | **Setup:** | ||
+ | <code cpp> | ||
+ | void setup() { | ||
+ | |||
+ | // MUSIC PLAYER PART | ||
+ | Serial.begin(9600); | ||
+ | |||
+ | // initialize buttons | ||
+ | pinMode(PREV_PIN, INPUT_PULLUP); | ||
+ | pinMode(PLAY_PIN, INPUT_PULLUP); | ||
+ | pinMode(NEXT_PIN, INPUT_PULLUP); | ||
+ | |||
+ | Serial.print(F("Initializing SD card...")); | ||
+ | |||
+ | // check if card is initialized correctly | ||
+ | if (!SD.begin(SD_CS_PIN)) { | ||
+ | Serial.println(F("Failed to initialize SD card")); | ||
+ | while(true); // stay here. | ||
+ | } | ||
+ | |||
+ | Serial.println("SD card is OK!"); | ||
+ | |||
+ | // open the directory and count the number of .wav/.WAV files | ||
+ | root = SD.open("/"); | ||
+ | Serial.print(F("Number of .wav files: ")); | ||
+ | numSongs = numberAudios(root); | ||
+ | Serial.println(numSongs); | ||
+ | |||
+ | // set audio | ||
+ | audio.speakerPin = SPEAKER_PIN; | ||
+ | audio.setVolume(6); | ||
+ | audio.quality(0); | ||
+ | audio.stopPlayback(); | ||
+ | |||
+ | // ISD + DISPLAY PART | ||
+ | pinMode(rec,OUTPUT); | ||
+ | pinMode(play,OUTPUT); | ||
+ | pinMode(button_rec,INPUT_PULLUP); | ||
+ | pinMode(button_play,INPUT_PULLUP); | ||
+ | |||
+ | // init display | ||
+ | display.begin(SSD1306_SWITCHCAPVCC, SCREEN_I2C_ADDR); | ||
+ | display.clearDisplay(); | ||
+ | display.display(); | ||
+ | |||
+ | // init isd | ||
+ | digitalWrite(rec,LOW); | ||
+ | digitalWrite(play,LOW); | ||
+ | |||
+ | // check if any button is pressed at start point, | ||
+ | // wait for them to not be pressed, helps for debouncing | ||
+ | if (digitalRead(button_rec) == LOW) { | ||
+ | while (digitalRead(button_rec) == LOW); | ||
+ | } | ||
+ | if (digitalRead(button_play) == LOW) { | ||
+ | while (digitalRead(button_play) == LOW); | ||
+ | } | ||
+ | |||
+ | if (digitalRead(PREV_PIN) == LOW) { | ||
+ | while (digitalRead(PREV_PIN) == LOW); | ||
+ | } | ||
+ | if (digitalRead(PLAY_PIN) == LOW) { | ||
+ | while (digitalRead(PLAY_PIN) == LOW); | ||
+ | } | ||
+ | |||
+ | if (digitalRead(NEXT_PIN) == LOW) { | ||
+ | while (digitalRead(NEXT_PIN) == LOW); | ||
+ | } | ||
+ | |||
+ | // for random animations | ||
+ | randomSeed(analogRead(0)); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | In functia de setup, se initializeaza butoanele la INPUT_PULLUP, este deschis fisierul ce stocheaza audio-urile, este initializat isd-ul si display-ul si se verifica daca nu cumva un buton este apasat in timpul setup-ului. | ||
+ | Pentru cititorul de card SD, am formatat cardul de 1GB in format FAT, iar fisierele le-am convertit in format .wav cu setarile: Samples Per second (Hz): 16000, Channel: Mono, Bits Per Sample: 8PCM, format: PCM unsigned 8-bit. | ||
+ | \\ | ||
+ | \\ | ||
+ | **Implementare:**\\ | ||
+ | Functia loop():\\ | ||
+ | In functia loop, se afla tratarea cazurilor in care apasam unul din cele 5 butoane. Pentru music player, daca apasam unul din butoanele previous sau next, cu functia playAudio ne vom muta la anteriorul, respectiv urmatorul audio, scazand sau adunand 1 la indexul audio-ului curent. Audio-urile pot fi accesate in loop (cand ultima melodie va fi redata ne putem intoarce la prima) si vom selecta de fiecare data cand apasam aceste butoane o animatie random cu functia selectRandomAnimation(). Apasam butonul play pentru a da start primei melodii dupa setup, dar si pentru a intrerupe melodia. Cand melodia se termina, ecranul se va opri de asemenea. Pentru a da replay, apasam tot butonul play. Pentru a realiza efectul de debounce, am dat un mic delay. Cat timp o melodie este in desfasurare, nu ne putem inregistra vocea, si viceversa. \\ | ||
+ | Pentru partea de inregistrare si redare a ceea ce spunem, apasam butonul rec cat timp vorbim. In timp ce vorbim, o animatie se va derula. Apasam butonul play recording pentru derularea inregistrarii. O animatie de 4 secunde se va declansa cand vom apasa acest buton. | ||
+ | <code cpp> | ||
+ | void loop() { | ||
+ | // put your main code here, to run repeatedly: | ||
+ | int prevState = digitalRead(PREV_PIN); | ||
+ | int playState = digitalRead(PLAY_PIN); | ||
+ | int nextState = digitalRead(NEXT_PIN); | ||
+ | |||
+ | // MUSIC PLAYER BUTTONS | ||
+ | if (recording_on == false) { | ||
+ | if (prevState == LOW) { | ||
+ | // debounce | ||
+ | delay(100); | ||
+ | |||
+ | if (songIdx == 1) { | ||
+ | playAudio(numSongs); | ||
+ | } else { | ||
+ | playAudio(songIdx - 1); | ||
+ | } | ||
+ | music_player_on = true; | ||
+ | selectRandomAnimation(); | ||
+ | updateAnimation(); | ||
+ | |||
+ | } else if (playState == LOW) { | ||
+ | // debounce | ||
+ | delay(100); | ||
+ | |||
+ | if (audio.isPlaying()) { | ||
+ | if(music_player_on) { | ||
+ | audio.pause(); | ||
+ | music_player_on = false; | ||
+ | stopAnimation(); | ||
+ | } else { | ||
+ | audio.pause(); | ||
+ | music_player_on = true; | ||
+ | updateAnimation(); | ||
+ | } | ||
+ | } else { | ||
+ | playAudio(songIdx); | ||
+ | music_player_on = true; | ||
+ | selectRandomAnimation(); | ||
+ | updateAnimation(); | ||
+ | } | ||
+ | |||
+ | } else if (nextState == LOW) { | ||
+ | // debounce | ||
+ | delay(100); | ||
+ | |||
+ | if (songIdx == numSongs) { | ||
+ | playAudio(1); | ||
+ | } else { | ||
+ | playAudio(songIdx + 1); | ||
+ | } | ||
+ | music_player_on = true; | ||
+ | selectRandomAnimation(); | ||
+ | updateAnimation(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // ISD BUTTONS | ||
+ | if (music_player_on == false) { | ||
+ | if (digitalRead(button_rec) == LOW) { | ||
+ | |||
+ | digitalWrite(rec, HIGH); | ||
+ | recording_on = true; | ||
+ | |||
+ | while (digitalRead(button_rec) == LOW) { | ||
+ | display.clearDisplay(); | ||
+ | display.drawBitmap(40, 8, recording[frame], FRAME_WIDTH, FRAME_HEIGHT, 1); | ||
+ | display.display(); | ||
+ | frame = (frame + 1) % FRAME_COUNT; | ||
+ | delay(FRAME_DELAY); | ||
+ | } | ||
+ | |||
+ | digitalWrite(rec, LOW); | ||
+ | recording_on = false; | ||
+ | delay(50); // Debounce delay | ||
+ | display.clearDisplay(); | ||
+ | display.display(); | ||
+ | } | ||
+ | |||
+ | else if (digitalRead(button_play) == LOW) { | ||
+ | |||
+ | digitalWrite(play, HIGH); | ||
+ | while (digitalRead(button_play) == LOW) { | ||
+ | delay(10); | ||
+ | } | ||
+ | |||
+ | unsigned long startTime = millis(); | ||
+ | unsigned long playbackDuration = 4000; | ||
+ | |||
+ | while (millis() - startTime < playbackDuration) { | ||
+ | display.clearDisplay(); | ||
+ | display.drawBitmap(40, 8, talking[frame], FRAME_WIDTH, FRAME_HEIGHT, 1); | ||
+ | display.display(); | ||
+ | frame = (frame + 1) % FRAME_COUNT; | ||
+ | delay(FRAME_DELAY); | ||
+ | } | ||
+ | |||
+ | digitalWrite(play, LOW); | ||
+ | display.clearDisplay(); | ||
+ | display.display(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // stop animation when audio stops | ||
+ | if (music_player_on && !audio.isPlaying()) { | ||
+ | music_player_on = false; | ||
+ | stopAnimation(); | ||
+ | } | ||
+ | // play animation while playing music | ||
+ | else if (music_player_on && audio.isPlaying()) { | ||
+ | updateAnimation(); | ||
+ | } else if (!music_player_on) { | ||
+ | display.clearDisplay(); | ||
+ | display.display(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Functia numberAudios(): | ||
+ | Pentru a numara cate audio-uri avem in directorul root, parcurgem fiecare fisier din director si verificam daca string-ul format din numele fisierului se termina in extensia .wav .Daca da, marim contorul. | ||
+ | <code cpp> | ||
+ | int numberAudios(File dir) { | ||
+ | int count = 0; | ||
+ | |||
+ | for (File file = dir.openNextFile(); file; file = dir.openNextFile()) { | ||
+ | if (!file.isDirectory()) { | ||
+ | String name = file.name(); | ||
+ | if (name.endsWith(".wav") || name.endsWith(".WAV")) { | ||
+ | count++; | ||
+ | } | ||
+ | } | ||
+ | file.close(); | ||
+ | } | ||
+ | |||
+ | return count; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Functia playAudio(): | ||
+ | Reda audio-ul cu index-ul curent, opriind orice alt audio care s-ar derula in acel moment. | ||
+ | <code cpp> | ||
+ | void playAudio(int index) { | ||
+ | audio.stopPlayback(); | ||
+ | |||
+ | // make the name of the file | ||
+ | songIdx = index; | ||
+ | char fileName[FILENAME_SIZE]; | ||
+ | snprintf(fileName, FILENAME_SIZE, "song_%d.wav", index); | ||
+ | |||
+ | audio.play(fileName); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Functia selectRandomAnimation(): | ||
+ | Alege un numar din 3 si, in functie de numarul ales, reda o animatie. | ||
+ | <code cpp> | ||
+ | void selectRandomAnimation() { | ||
+ | int animationChoice = random(3); | ||
+ | switch (animationChoice) { | ||
+ | case 0: | ||
+ | currentAnimation = cd; | ||
+ | |||
+ | break; | ||
+ | case 1: | ||
+ | currentAnimation = tape; | ||
+ | |||
+ | break; | ||
+ | case 2: | ||
+ | currentAnimation = music; | ||
+ | |||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Functia updateAnimation(): | ||
+ | Aceasta șterge ecranul, desenează cadrul curent al animației, actualizează ecranul pentru a afișa noul cadru, avansează la următorul cadru și introduce o pauză scurtă pentru a controla viteza animației. % FRAME_COUNT asigură că, dacă frame_music ajunge la FRAME_COUNT, acesta revine la 0 (creând o animație în buclă). | ||
+ | <code cpp> | ||
+ | void updateAnimation() { | ||
+ | display.clearDisplay(); | ||
+ | display.drawBitmap(40, 8, currentAnimation[frame_music], FRAME_WIDTH, FRAME_HEIGHT, 1); | ||
+ | display.display(); | ||
+ | frame_music = (frame_music + 1) % FRAME_COUNT; | ||
+ | delay(FRAME_DELAY); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Functia stopAnimation(): | ||
+ | <code cpp> | ||
+ | void stopAnimation() { | ||
+ | display.clearDisplay(); | ||
+ | display.display(); | ||
+ | } | ||
+ | </code> | ||
+ | \\ | ||
+ | ** Optimizări: **\\ | ||
+ | Am mutat variabilele constante care stocau animatiile in PROGMEM. \\ | ||
+ | ** Probleme intampinate: **\\ | ||
+ | Codul a fost prea mare in ciuda optimizarilor, nu am mai avut loc pe memoria flash pe placuta Arduino Uno. Solutia cea mai smart si rapida a fost sa schimb placuta cu Arduino Mega, unde totul a mers smooth. | ||
+ | |||
+ | ===== Rezultate Obţinute ===== | ||
+ | Am reusit sa realizez o jucarie draguta pentru copii, care poate si sa cante si sa repete tot ce spui. De asemenea, animatiile variate adauga dinamism proiectului. Tot ce mai trebuie terminat este carcasa din carton a robotelului (voi pune poze, lipiciul dureaza cam mult sa se usuce :-D ).\\ | ||
+ | [[https://youtu.be/oykXTy-1w_U]]\\ | ||
+ | Update:\\ | ||
+ | {{:pm:prj2024:azamfir:robot_gata.jpg?400|}} | ||
===== Concluzii ===== | ===== Concluzii ===== | ||
+ | A fost un proiect interesant, aparte de temele pe care le-am realizat pana acum. Desi acest proiect a venit si cu stresul constant ca piesele mi se pot defecta sau ca pot veni deja defecte (inca mai am aceasta spaima pana voi prezenta la PM fair), m-am distrat cel mai mult la partea de scris cod si de implementat functionalitati diverse, iar sentimentul pe care l-am avut la final, cand am vazut ca merge ce mi-am propus, a fost unul satisfacator. | ||
===== Download ===== | ===== Download ===== | ||
- | <note warning> | + | {{:pm:prj2024:azamfir:tom.zip|}} |
- | 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 ===== | ||
Line 89: | Line 421: | ||
06 mai - achizitionare piese \\ | 06 mai - achizitionare piese \\ | ||
09-10 mai - primire piese \\ | 09-10 mai - primire piese \\ | ||
- | 14-17 mai - realizare asamblare hardware \\ | + | 14-16 mai - realizare asamblare hardware \\ |
- | 21-24 mai - scrierea codului | + | 23 mai - achizitionarea unor elemente noi \\ |
+ | 21-25 mai - scrierea codului \\ | ||
+ | 26 mai - realizarea robotelului de carton | ||
</note> | </note> | ||
Line 96: | Line 431: | ||
<note> | <note> | ||
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | **Datasheet:**\\ |
+ | [[https://docs.arduino.cc/resources/datasheets/A000067-datasheet.pdf|Arduino ATmega2560 Datasheet]] \\ | ||
+ | **Resurse Software:** \\ | ||
+ | [[https://animator.wokwi.com/|Animations]] \\ | ||
+ | [[https://www.instructables.com/Music-Player-Using-Arduino/|Music player inspiration]] \\ | ||
+ | **Resurse Hardware:** \\ | ||
+ | [[https://www.instructables.com/Music-Player-Using-Arduino/|CardSD setup]] \\ | ||
+ | [[https://www.youtube.com/watch?v=o3PhC_VJdXo&t=16s|OLED setup]] \\ | ||
+ | [[https://www.electronicshub.org/interfacing-isd1820-voice-recorder-module-with-arduino/|ISD setup]] | ||
</note> | </note> | ||
<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> | ||