This shows you the differences between two versions of the page.
pm:prj2022:cristip:soundactivatedstrobelights [2022/05/31 03:43] theodor.tulba |
pm:prj2022:cristip:soundactivatedstrobelights [2022/05/31 04:51] (current) theodor.tulba [Descriere generală] |
||
---|---|---|---|
Line 2: | Line 2: | ||
===== Introducere ===== | ===== Introducere ===== | ||
- | Acest proiect reprezintă implementarea unui analizator de spectru ce capteaza sunetul din mediul încojurător. Asupra sample-urilor de sunet captate se realizeaza o transformare Fouriersi se obtine spectrul de frecvente ale sunetului. Datele sunt afisate codificând spectograma obtinuta pe un ecran de 24x8 LED-uri (alcatuita din 3 matrici LED 8x8) in functie de frecventa (coloane) si intensitate (randuri). Matricile sunt organizate in asa fel incat frecventele joase sunt reprezentate cu rosu, cele medii cu verde si cele inalte cu albastru. | + | Acest proiect reprezintă implementarea unui analizator de spectru ce captează sunetul din mediul încojurător. Asupra sample-urilor de sunet captate se realizează o transformare Fourier și se obține spectrul de frecvențe. Datele sunt afișate codificând spectograma obtinută pe un "ecran" de 24x8 LED-uri (alcatuită din 3 matrici LED 8x8) în funcție de frecvență (coloane) și intensitatea sunetului (rânduri). Matricile sunt organizate în așa fel încât frecvențele joase sunt reprezentate cu roșu, cele medii cu verde și cele înalte cu albastru. |
===== Descriere generală ===== | ===== Descriere generală ===== | ||
Principiul de funcționare al proiectului este următorul: | Principiul de funcționare al proiectului este următorul: | ||
- | 1. Prin intermediul unui microfon sunt preluate sunetele sub forma de date analog; | + | 1. Prin intermediul unui microfon sunt preluate sunetele sub formă de date analog; |
- | 2. Asupra acestor date se aplica o transformare Fourier si se obtine spectograma de frecvente; | + | 2. Asupra acestor date se aplică o transformare Fourier și se obține spectograma; |
- | 3. Spectograma este afisata pe ecranul de LED-uri. | + | 3. Spectograma este afisată pe ecranul de LED-uri. |
| | ||
=== Schemă bloc === | === Schemă bloc === | ||
- | {{ :pm:prj2022:cristip:diagrama_proiect_stroboscop.png?800 }} | + | {{ :pm:prj2022:cristip:diagrama_proiect_stroboscop.png?720 }} |
===== Hardware Design ===== | ===== Hardware Design ===== | ||
Line 24: | Line 24: | ||
* 1x [[https://ardushop.ro/ro/home/2257-lm8x83mmblue.htm|Matrice LED 8x8 3mm albastru(32mm)]]; | * 1x [[https://ardushop.ro/ro/home/2257-lm8x83mmblue.htm|Matrice LED 8x8 3mm albastru(32mm)]]; | ||
* 4x [[https://ardushop.ro/ro/electronica/141-ic-shift-register-sn74hc595n-74hc595.html|Shift register SN74HC595N]]; | * 4x [[https://ardushop.ro/ro/electronica/141-ic-shift-register-sn74hc595n-74hc595.html|Shift register SN74HC595N]]; | ||
- | * 24x [[https://www.tme.eu/ro/details/1_4w220r/rezistente-carbon-tht-1-4w/royal-ohm/cfr0w4j0221a50/|Rezistor 200Ω]]. | + | * 24x [[https://www.tme.eu/ro/details/1_4w220r/rezistente-carbon-tht-1-4w/royal-ohm/cfr0w4j0221a50/|Rezistor 220Ω]]; |
+ | * 2x [[https://cleste.ro/breadboard-830-puncte-mb-102-mb102.html|Breadboard 830 puncte]]; | ||
+ | * 3x [[https://cleste.ro/placa-prototipare-5x7.html|Placă prototipare 5x7 cm]] | ||
+ | * 1x Carcasă printată 3D | ||
- | === Schema electrica === | + | === Schema Electrică === |
- | {{ :pm:prj2022:cristip:Schema_Electrica_GabiTulba_EG.png?600 }} | + | {{ :pm:prj2022:cristip:Schema_Electrica_GabiTulba_EG.png?720 }} |
===== Software Design ===== | ===== Software Design ===== | ||
=== Biblioteci Externe === | === Biblioteci Externe === | ||
+ | |||
+ | * [[https://www.arduino.cc/reference/en/libraries/fix_fft/|fix_fft]] - folosit pentr a aplica transformata Fourier | ||
+ | * [[https://www.arduino.cc/reference/en/libraries/timerone/|TimerOne]] - folosit pentru interrupt-uri | ||
=== Implementare === | === Implementare === | ||
+ | **Setup** | ||
- | ===== Rezultate Obţinute - Demo ===== | + | În setup se initializează pinii, se testează că funcționează matricile LED și se initializează un timer. Timer-ul este folosit pentru a crea întreruperi în mod regulat ce va declanșa randarea următoarei coloane de pixeli ai "ecranului". |
+ | <code cpp> | ||
+ | void setup() { | ||
+ | // Initialize pins | ||
+ | pinMode(SER1, OUTPUT); | ||
+ | pinMode(RCLK1, OUTPUT); | ||
+ | pinMode(SRCLK1, OUTPUT); | ||
+ | pinMode(OE, OUTPUT); | ||
+ | pinMode(SER2, OUTPUT); | ||
+ | pinMode(RCLK2, OUTPUT); | ||
+ | pinMode(SRCLK2, OUTPUT); | ||
- | Demo functionalitate: [[https://studio.youtube.com/video/wtGvMIOnKYM/edit|link]] | + | digitalWrite(OE, HIGH); |
- | ===== Concluzii ===== | + | // Code for checking if the LED lights work |
+ | for(int i = 1; i <= 8; i++) { | ||
+ | for(int j = 0; j < 8; j++) { | ||
+ | write_mat((1<<i) - 1, (1<<i) - 1, (1<<i) - 1, 1<<j); | ||
+ | delay(50); | ||
+ | } | ||
+ | } | ||
+ | write_mat(255, 255, 255, 255); | ||
+ | delay(2000); | ||
- | **TODO** | + | // Initialize Timer for the interrupts |
+ | Timer1.initialize(1000); //microseconds | ||
+ | Timer1.attachInterrupt(draw_column); | ||
+ | } | ||
+ | </code> | ||
- | ===== Download ===== | + | **Comunicare cu Shift Register** |
- | <note warning> | + | Conform datasheet-ului, se transmit date seriale ce sunt reținute în shift register. cel mai simplu mod de interacționare este folosirea funcției ''shiftOut'' care transmite un întreg byte de date. |
- | 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ă ;-). | + | <code cpp> |
+ | // Send one byte of data to a shift register | ||
+ | void write_to_register(byte data, int rclk, int ser, int srclk) { | ||
+ | digitalWrite(rclk, LOW); | ||
+ | shiftOut(ser, srclk, LSBFIRST, data); | ||
+ | digitalWrite(rclk, HIGH); | ||
+ | } | ||
+ | </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**. | + | **Randarea Matricelor LED** |
- | </note> | + | |
+ | Randarea unei matrici se face pe coloane. Refresh rate-ul este de 1000 * 24 µs = 24ms. | ||
+ | <code cpp> | ||
+ | // Write to the 24x8 LED matrix using the shift registers | ||
+ | void write_mat(byte r, byte g, byte b, byte row) { | ||
+ | digitalWrite(OE, HIGH); | ||
+ | |||
+ | write_to_register(b, RCLK1, SER1, SRCLK1); | ||
+ | write_to_register(g, RCLK1, SER1, SRCLK1); | ||
+ | write_to_register(r, RCLK1, SER1, SRCLK1); | ||
+ | |||
+ | write_to_register(row ^ 255, RCLK2, SER2, SRCLK2); | ||
+ | |||
+ | digitalWrite(OE, LOW); | ||
+ | } | ||
+ | |||
+ | // Renders the next column of the matrix | ||
+ | void draw_column() { | ||
+ | if(mat_line < 8) { // Draw a red column | ||
+ | write_mat((1 << min(8, histogram[mat_line])) - 1, 0, 0, 1 << mat_line); | ||
+ | } else if(mat_line < 16) { // Draw a green column | ||
+ | write_mat(0, (1 << min(8, histogram[mat_line])) - 1, 0, 1 << (mat_line & 7)); | ||
+ | } else { // Draw a blue column | ||
+ | write_mat(0, 0, (1 << min(8, histogram[mat_line])) - 1, 1 << (mat_line & 7)); | ||
+ | } | ||
+ | |||
+ | mat_line++; | ||
+ | if(mat_line == 24) { // Reset the rendering process | ||
+ | mat_line = 0; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | **Main Loop** | ||
+ | |||
+ | În ''loop'' se citesc datele analog de la microfon și sunt transformate in spectograma utilizând funcția ''fix_fft''. | ||
+ | <code cpp> | ||
+ | void loop() | ||
+ | { | ||
+ | static int i, j, step; | ||
+ | int val; | ||
+ | |||
+ | // get audio data | ||
+ | for(i = 0; i < SAMPLES; i++) { | ||
+ | val = analogRead(AUDIO); // 0-1023 | ||
+ | |||
+ | real[i] = (char)(val/4 - 128); // store the result on 8 bits | ||
+ | imag[i] = 0; // set all imaginary parts to 0 | ||
+ | } | ||
+ | |||
+ | // run FFT | ||
+ | fix_fft(real, imag, LOG_SAMPLES, 0); | ||
+ | |||
+ | histogram[0] = 0; // noise, so we ignore it | ||
+ | |||
+ | // extract absolute value of data only, for half the results | ||
+ | for(i = 1; i < SAMPLES/2; i++) { | ||
+ | histogram[i] = (int)sqrt(real[i] * real[i] + imag[i] * imag[i]); | ||
+ | } | ||
+ | |||
+ | // compress the histogram to 24 values so it can be printed on the LED matrices | ||
+ | for(int i = 0; i < LED_COLS; i++) { | ||
+ | // magic to make the spectogram look good and ignore low frequency signals | ||
+ | histogram[i] = (histogram[i * 2 + 6] + histogram[i * 2 + 7] + histogram[i * 2 + 8]) * 1.33f; | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ===== Rezultate Obţinute ===== | ||
+ | |||
+ | **Demo funcționalitate:** [[https://youtu.be/wtGvMIOnKYM|link]] | ||
+ | |||
+ | ===== Concluzii ===== | ||
+ | |||
+ | Proiectul a fost finalizat cu succes. | ||
+ | |||
+ | ===== Download ===== | ||
- | ===== Bibliografie===== | + | Codul sursa al proiectului poate fi găsit aici: {{:pm:prj2022:cristip:Spectrum_Analyser.zip| Spectrum Analyser}}. |
+ | ===== Bibliografie ===== | ||
=== Datasheets === | === Datasheets === | ||
Line 63: | Line 176: | ||
=== Resurse === | === Resurse === | ||
- | * Tutorial Shift Registers: [[https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial|link]] | + | * Setup Shift Registers: [[https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial|link]]; |
- | * Spectrum Analyzer: [[https://create.arduino.cc/projecthub/mircemk/diy-fft-audio-spectrum-analyzer-ca2926|link]] | + | * Spectrum Analyzer: [[https://create.arduino.cc/projecthub/mircemk/diy-fft-audio-spectrum-analyzer-ca2926|link]]; |
- | * Timer Interrupts: [[https://www.instructables.com/Arduino-Timer-Interrupts|link]] | + | * Timer Interrupts: [[https://www.instructables.com/Arduino-Timer-Interrupts|link]]. |
<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> | ||