USB MIDI interfész Arduinoval - MEGOLDVA

 ( lcsaszar | 2019. január 1., kedd - 14:33 )

Sziasztok!

Már kezd elegem lenni ezekből az olcsó kínai USB MIDI kábelekből. Az első konkrétan nem működött, kispórolták belőle az optocsatolót. Miután beleapplikáltam (=befejeztem a gyártást), már "jól" működött, de valahogy nem küldött NOTE OFF üzeneteket.
Vettem egy másikat, ami kinézetre is bizalomgerjesztőbb. Ez azt csinálja, hogy több hang lenyomásakor mindegyikre NOTE ON üzenetet küld, majd ha egymás után engedem fel azokat, akkor mindegyikre NOTE OFF üzenetet küld, és az utolső felengedése után ALL NOTES OFF-ot. Ez így rendben is van. Azonban, ha egyszerre engedem fel a billentyűket, akkor az egyikre NOTE OFF-ot, de a többire megint NOTE ON-t, és utána ALL NOTES OFF-ot küld. Emiatt a billentyűk elengedésekor ismét megszólalnak a hangok egy rövid időre.

Azon gondolkozom, hogy én magam csinálnék egy egyszerű USB MIDI interfészt, ami csak egyirányú (MIDI vezérlő billentyűzet -> PC). Tudna valaki segíteni, hogy hogyan induljak el? Az Arduinos fórumokon nem találtam egyértelmű útmutatást, illetve inkább a fordítottja van (PC -> MIDI instrument azaz hangszer), amihez USB host-ot ajánlanak. Nekem a fordítottja kell. Arduino Uno-t nemigen használnék erre, szerintem egy Mini is megtenné USB kimenettel ellátva, ami MIDI-USB-nek mutatja magát a PC felé.

Update: mint kiderült, a Mini nem alkalmas, valszeg Nano lesz (atmega32u4 alapú), a címet is módosítottam.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Nem minden USB kliens tudja mindenfélének mondani magát. Úgy tudom, hogy ahhoz hogy ilyet csinálj, az USB protokollt le kell programoznod, vagy legalább fel kell konfigurálnod a kliensen. Ez nagyságrendileg komplexebb, mint FTDI-on keresztül serial kapcsolatot nyitni.

Az Arduino UNO-ban FTDI csip van, ami célhardver arra a célra, hogy USB-serialként látsszon a PC-ről. Ez tudtommal nem programozható MIDI-vé - de nagyon nem olvastam utána. Amit Arduino IDE-ből lehet programozni, az az AVR csip csak serialt lát már, annak semmi köze az USB-hez.

Az Arduino Mini-n egyáltalán nincsen USB csatlakozó, azt eleve USB-TTL serial illesztővel szokás PC-hez kapcsolni.

Ezekben az Arduinoból programozható ATmega328-as csippekben nincsen hardveres USB támogatás.

Viszont tudtommal USB 1.0-t lehet bitmanging módon is csinálni akár AVR csippekkel is, csak fizikailag kell illeszteni az USB-t. Ilyen például a Pocket AVR programmer, amiben egy ATTiny-vel csináltak szoftveres úton USB klienst. Ennek a kódja és a hardver felépítése is nyílt, ezekből kiindulva lehetne egyedi USB klienst hekkelni például olcsón.

Link a Pocket AVR-re: https://www.sparkfun.com/products/9825 (Ilyenem van, és Arduino-ból tinyUSB)

Ehhez hasonló hardver van az USB-serial illesztőkben, valamelyikről olvastam, hogy a csipre egyedi szoftvert téve másféle működésre is bírható. De ebbe sem ástam bele magam jobban: https://www.sparkfun.com/search/results?term=usb+serial

Ezt nem ismerem, csak az AVR USB 1.0 keresőszóra találtam meg, ilyesmi szoftver lehet az ATTiny alapú programozókban és serial konverterekben: https://www.obdev.at/products/vusb/index.html

Ha az USB 1.0 nem elég gyors, és USB 2.0 kell, azt ismereteim szerint csak olyan csippel lehet megcsinálni, ami hardeveresen támogatja. Vannak ilyenek, de azokkal pláne nem foglalkoztam még. Az MBed-nek például az USB-s doksijában ott szerepel az USBMidi kulcssszó, lehet, hogy azzal lenne érdemes nekiállni: https://os.mbed.com/handbook/USBDevice

Hmmmm, egy klikkel tovább az MBed oldalán: https://os.mbed.com/handbook/USBMIDI Ennél sokkal egyszerűbbet nehezen tudok elképzelni...

Esetleg http://www.midi-and-more.de/stm32-usbmidicom.htm
A Nucleo lapkák elég egyszerűen elérhetők Farnelltől.

Arduinóból ahogy írták olyan kell ami direkt az USB-n ül, ilyen a Leonardo.

Köszönöm a válaszokat. Meg fogom próbálni egy Arduino nanoval, a következő leírások alapján:

https://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/
http://blog.stekgreif.com/?p=699

Csak arra figyelj, hogy ne a klón, ch340g-vel szerelt Unod legyen, hanem az eredeti, amin Atmega32U4 az USB chip.

Kicsit megzavart ez a kabel mizeria, de a vegere le esett, hogy a MIDI Keyboard-od nem ugy mukodik ahogyan szeretned.

Kihivasnak jo lehet az Arduino-s megoldas, de ha komolyabb hasznalatra gondolsz, akkor javaslom, hogy nezz utana egy ilyesminek: (talalomra valasztottam, egy hangszerbolt ajanlatabol, ara 16500HUF. A feature-k alapjan lenyegesen tobb munkad lesz benne, mintha megvenned.)

Akai Professional LPK25 USB MIDI kontroller billentyűzet, Ultra-hordozható produkciós billentyűzet.

USB-MIDI vezérlő szinte bármelyik audiószoftverhez
25 velocity-érzékeny minibillentyű
Arpeggiator, sustain gomb, oktáv fel és le, valamint tap tempo szabályzók
Driver-telepítést nem igénylő Plug-and-play USB PC és Mac csatlakozás
Kis méretéből adódóan könnyedén elfér hátizsákban vagy laptop-táskában
4 programozható memóriabank
Mac és PC szerkesztőszoftver mellékelve
USB tápellátás - külön tápkábelt nem igényel

Szia! Nem voltam elég egyértelmű. A midi billentyűzetemen csak 5-pólusú DIN csatlakozó van, a számítógépen (amin VSTi plugineket használok) pedig csak USB. A kettő közé tettem az említett kínai MIDI-USB adaptert, és ebből jött a probléma. Csináltam ellenpróbát, a billentyűzet MIDI DIN kimenetét egyszerű DIN-DIN kábellel közvetlenül összekötöttem egy másik (hardveresen megvalósított virtuális) hangszerrel, amin van MIDI DIN bemenet, és azzal tökéletesen működik. Tehát nem a billentyűzetem küld hibás adatokat, hanem a kínai adapter rontja el.

Persze vehetnék másik midi billentyűzetet, ahogy javaslod, amin van USB kimenet. De nem akarnám lecserélni a jelenlegit. Sajnos ezen csak DIN kimenet van, kell az átalakító USB-re.

Nem lehet, hogy az eredeti jel is szar volt, csak USB-vel az időzítési viszonyok változása miatt elő is jön a hiba? Mert az nekem gyanús, hogy egy ilyen adapter megváltoztatná a jeleket. Minek csinálna ilyet? Sokkal egyszerűbb ész nélkül továbbítani, nem?

A MIDI egy szögegyszerű soros, áramhurkos csatolás, 38400 baud sebességgel. Szinte semmi más nem kell hozzá, csak egy open collectoros illesztés, ha flancolunk, akkor optocsatoló :)

Hát ezt nem értem én sem. Ha közbeiktatom a MIDI USB interfészt, akkor nem jó, ha kihagyom (ugyanazon a lejátszón DIN bemeneten), akkor jó. PC-n MIDI-OX-szel megnézve látszik, hogy az USB nem jó. DIN-t nem tudom megnézni.

Képzeljük el, hogy ugyanúgy jön a note on+ ALL NOTES OFF a DIN bemeneten is, de egy tranzakción belül. Tehát a szintetizátor program még éppen nem szólaltatja meg a hangot, már azonnal le is állítja. Ezért hiába "hibás" a Midi stream, nem érzékeled.

Ha viszont a kettő között eltelik egym kis idő - ami alatt a szintetizátor program egy audio stream frame-t megtölt hangmintákkal - akkor már megszólal a hang, tehát az eddig elfedett hiba zavaróvá válik. Az USB-s csatoló mivel minimalizálni akarja a késleltetést, amint bejön egy minta, azt már küldi is a PC-nek egy USB keretben. Emiatt viszont a következő minta már egy következő keretbe kerül egy kis késleltetéssel.

Nekem ez az elméletem, egyszerűen nem tudom elképzelni, hogy az átalakító a MIDI jeleket megváltoztatná - az időzítésen kívül.

A hibát elkerülni úgy lehetne, ha az USB átalakító bevárná az összes jelet, és azokat egy tranzakcióban küldeni fel a PC-nek (ha erre egyáltalán van lehetőség) Ez azonban lehet, hogy mindenképpen plusz késleltetéssel járna.

Amennyire tudom a MIDI fix időkeretekkel dolgozik, saját firmware-rel lehet, hogy elég volna egyetlen plusz keretet megvárni, hogy van-e még további üzenete a kliensnek.

Meg lehetne próbálni a PC szoftver stackbe is betenni valami szűrőt, de ez sem volna egyszerű, és szintén késleltetéssel járna.

Én megpróbálnám először a hibás eset MIDI szekvenciáját lementeni és kielemezni akár egy egyszerű MIDI-serial konverterrel, ez ugye tetszőleges Arduino-val működik OOB. Ha benne van az általam vízionált hiba a MIDI szekvenciában, akkor aszerint érdemes tovább ügyködni.

Ez kezd egyre egzotikusabba valni.

Ha van lehetoseged muszeres vizsgalatra, akkor a DIN-es MIDI OUT-ot neznem meg a helyedben egy szkoppal.

Vagy alternativakent valami ilyesmire: http://codeandlife.com/2012/05/16/worlds-simplest-logic-analyzer-for-5/

(Hatha el tudod kapni az idozitesi hibat.)

Hát igen, ez jó lenne. Tárolós oszcilloszkóp hiányában sajnos nem tudom elvégezni a tesztet. De annyi biztos, hogy a billentyűzetem DIN-es MIDI-OUT jele kifogástalanul vezérel egy hardveresen megvalósított VSTi hostot annak DIN bemenetén. Ennek a hostnak van USB bemenete is. Ha erre küldöm a MIDI-OUT - MIDI/USB átalakító - USB vezérlést, akkor előjön a hiba, akárcsak a PC-n.

Odáig eljutottam a MIDI protokoll tanulmányozásában, hogy Note On with velocity 0 = Note Off (with default velocity 64). És azt tapasztalom, hogy az én adapterem a második és többi billentyűk elengedésekor Note On, velocity 64-et küld, velocity 0 helyett. Most már csak azt kell kiderítenem, miért lesz a 0-ból 64.

Itt is találtam egy ugyanilyen problémát:

https://homerecording.com/bbs/equipment-forums/midi-mania/note-instead-note-off-391117/

Na megoldódott. Arduino minivel összeraktam egy egyszerű DIN-USB átalakítót. Nem teljes, mert csak a DIN -> USB irányba visz. Azon belül is nem csináltam meg a SysEx-et, pitch bendet, modulation wheelt, sok egyebet. Csak Note On, Note Off, Aftertouch, Velocity működik, de ez nekem elég egyelőre. Később tovább lehet fejleszteni.

A kísérletből kiderült, hogy a kínai adapter kavarja össze a MIDI jelet (nem tudja helyesen kezelni a running statust, ezzel én is sokat küzdöttem).

Egyébként DIN-ről USB-re nem olyan triviális a konverzió. A DIN-en byte-onként jönnek az adatok (1, 2, vagy 3 byte-os csomagokban, vagy az előbb említett running status esetén folyamatosan), az USB-n pedig 4 byte-os adatcsomagok mennek ki, az első byte a header. A sebességek sem azonosak, a DIN 31250 b/s. A PC sem ismeri fel MIDI interfészként a sima soros bemenetet. Kicsit kellett trükközni, de végül is tanulságos volt. Akit érdekel, el tudom küldeni a kódot privátban.

jo par eve akartam foglalkozni hasonloval, akkor bukmarkoltam ezt a linket.
hatha hasznos lesz: http://www.dimitridiakopoulos.com/hiduino.html