This shows you the differences between two versions of the page.
pm:prj2023:apredescu:sintetizator [2023/05/07 14:45] radu_andrei.popescu [Descriere generală] |
pm:prj2023:apredescu:sintetizator [2023/05/28 23:36] (current) radu_andrei.popescu |
||
---|---|---|---|
Line 33: | Line 33: | ||
</note> | </note> | ||
+ | <note> | ||
+ | {{ :pm:prj2023:apredescu:20230528_114729.jpg?600 |}} | ||
+ | </note> | ||
+ | |||
+ | <note> | ||
+ | {{ :pm:prj2023:apredescu:schema_completa.png?600 |}} | ||
+ | </note> | ||
===== Software Design ===== | ===== Software Design ===== | ||
- | <note tip> | + | **Mediul de dezvoltare** |
- | Descrierea codului aplicaţiei (firmware): | + | * Arduino IDE |
- | * mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR) | + | **Biblioteci folosite** |
- | * librării şi surse 3rd-party (e.g. Procyon AVRlib) | + | * Arduino.h |
- | * algoritmi şi structuri pe care plănuiţi să le implementaţi | + | * usbh_midi.h |
- | * (etapa 3) surse şi funcţii implementate | + | * usbhub.h |
- | </note> | + | * SD.h |
+ | * TMRpcm.h | ||
+ | * SPI.h | ||
+ | * Wire.h | ||
+ | * LiquidCrystal_I2C.h | ||
+ | * input_converter.h (bibliotecă proprie) | ||
+ | **Implementare** | ||
+ | * Pentru citirea input-ului MIDI: | ||
+ | <code> | ||
+ | ... | ||
+ | void MIDI_poll(); | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | _MIDI_SERIAL_PORT.begin(31250); | ||
+ | |||
+ | if (Usb.Init() == -1) { | ||
+ | while (1); | ||
+ | } | ||
+ | delay( 200 ); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | Usb.Task(); | ||
+ | |||
+ | if ( Midi ) { | ||
+ | MIDI_poll(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Poll USB MIDI Controler and send to serial MIDI | ||
+ | void MIDI_poll() | ||
+ | { | ||
+ | uint8_t outBuf[ 3 ]; | ||
+ | uint8_t size; | ||
+ | |||
+ | do { | ||
+ | if ( (size = Midi.RecvData(outBuf)) > 0 ) { | ||
+ | if (outBuf[0] == 144) { // 144 reprezintă codul pentru când se apasă clapa respectivă | ||
+ | _MIDI_SERIAL_PORT.print(outBuf[1], DEC); | ||
+ | _MIDI_SERIAL_PORT.println(); | ||
+ | } | ||
+ | } | ||
+ | } while (size > 0); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | * Pentru citirea input-ului de pe cealaltă placă Arduino: | ||
+ | <code> | ||
+ | ... | ||
+ | if (Serial.available() > 0) { | ||
+ | // Read the incoming data | ||
+ | c = Serial.read(); | ||
+ | if (c != '\n'){ | ||
+ | note[i++] = c; | ||
+ | } else { | ||
+ | note[i] = c; | ||
+ | i = 0; | ||
+ | note_int = atoi(note); | ||
+ | Serial.print(note_int); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | * Pentru a cânta nota primită ca input: | ||
+ | <code> | ||
+ | ... | ||
+ | if (note_int != 0){ | ||
+ | sprintf(file, "%s%d.wav", MIDI_to_note(note_int), curr_preset); | ||
+ | Serial.print(file); | ||
+ | Serial.println(); | ||
+ | tmrpcm.play(file); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | * Pentru a citi valoarea potențiometrului și pentru a afișa preset-ul ales: | ||
+ | <code> | ||
+ | ... | ||
+ | void loop() { | ||
+ | val = analogRead(A0); | ||
+ | val = map(val, 0, 1020, 1, 6); | ||
+ | |||
+ | if (val != curr_preset && val != 6){ | ||
+ | curr_preset = val; | ||
+ | printPreset(); | ||
+ | } | ||
+ | } | ||
+ | ... | ||
+ | void printPreset(){ | ||
+ | clearCharacters(); | ||
+ | lcd.setCursor(0,1); | ||
+ | if (curr_preset == 5) | ||
+ | lcd.print("Drums"); | ||
+ | else lcd.print(curr_preset); | ||
+ | } | ||
+ | ... | ||
+ | void clearCharacters() | ||
+ | { | ||
+ | for (int i = 0; i < 10; i++) | ||
+ | { | ||
+ | lcd.setCursor (i,1); // | ||
+ | lcd.write(254); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | De asemenea, pentru a converti valoarea input-ului MIDI într-o notă muzicală, am creat propria bibliotecă. | ||
+ | **input_converter.cpp:** | ||
+ | <code> | ||
+ | #include "input_converter.h" | ||
+ | |||
+ | char* MIDI_to_note(int note) { | ||
+ | if (note == 60) | ||
+ | return "C1"; | ||
+ | if (note == 61) | ||
+ | return "C#1"; | ||
+ | if (note == 62) | ||
+ | return "D1"; | ||
+ | if (note == 63) | ||
+ | return "D#1"; | ||
+ | if (note == 64) | ||
+ | return "E1"; | ||
+ | if (note == 65) | ||
+ | return "F1"; | ||
+ | if (note == 66) | ||
+ | return "F#1"; | ||
+ | if (note == 67) | ||
+ | return "G1"; | ||
+ | if (note == 68) | ||
+ | return "G#1"; | ||
+ | if (note == 69) | ||
+ | return "A1"; | ||
+ | if (note == 70) | ||
+ | return "A#1"; | ||
+ | if (note == 71) | ||
+ | return "B1"; | ||
+ | return ""; | ||
+ | } | ||
+ | </code> | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
Line 73: | Line 223: | ||
<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> | ||
- |