Hallo, ich möchte mit meinem AVR über UART MIDI programm changes empfangen. Softwaremäßig stellt das denke ich kein größeres Problem da, allerdings hab ich eine Frage zur Hardware: Ich wollte den Midi Eingang so wie beim Mr.Midi realisieren: http://www.mikrocontroller.net/articles/Bild:Eagle-schematic.gif Allerdings hatte der elektronikladen um die Ecke heute keinen 6N138, sondern nur den 6N137 optokoppler. Laut datenblatt ist der ziemlich identisch was die Geschwindigkeit angeht. Allerdings hat der keinen Darlington Ausgang. Kann ich sie schaltung trotzdem so aufbauen, oder muss ich irgendwas beachten? oder ändern? Gruß
Google und midi 6n137 helfen weiter :-o Such z.B. dort mal nach 6n137: http://www.midi.org/techspecs/electrispec.php
MIDI kann man mit jedem Wald- und Wiesenoptokoppler, wie z.B. CNY17 oder PC817 oder ähnliche Typen aufbauen, weil die 31250 Bit/s schaffen alle. Lediglich der Arbeitswiderstand des Ausgangstransistors ist kritisch, um den richtigen Arbeitspunkt für ausreichend steile Flanken einzustellen. Der 6N136/137 ist mit Kanonen auf Spatzen geschossen.
> die 31250 Bit/s schaffen alle Machen dabei aber eine nicht ohne weiters vernachlässigbare Verschiebung der steigenden bzw. fallenden Flanke. Der Arbeitspunkt ist elementar wichtig, mit Rc=1k gilt bei sättigendem Betrieb des Ausgangstransistors (CNY17): ton = 25us, toff = 42,5us --> dmit überschlägig 25us+42,5us = 67us --> 15kHz... Auch die Daten aus den Datenblättern (PC817) bei Rc=100 Ohm (nicht sättigender Betrieb) mit ton=4..18us und toff=3..18us sind m.E. bei einer Bitdauer von 32us irgendwie, naja, hmmm... > Der 6N136/137 ist mit Kanonen auf Spatzen geschossen. Hauptsache: immer getroffen ;-)
Also die beiden Beispiele CNY17 und PC817 sind getestete Typen in mehrfach aufgebauten Schaltungen. Beide Koppler verwende ich mit etwa 470Ohm Arbeitswiderstand seit Jahren und ohne Probleme. Auch bei MIDI-Verkabelung in Serie hat es bisher keine (hörbaren) Verzögerungen gegeben.
Wie gesagt: hauptsache getroffen ;-) noch ne kleine verständnisfrage: Sind in dieser schaltung die 280ohm der arbeitswiederstand? http://www.midi.org/techspecs/electrispec.php
Ephraim Hahn schrieb:
> Sind in dieser schaltung die 280ohm der arbeitswiederstand?
Ja. Und der ist hübsch niederohmig.
Naja - nur dann, wenn der Optokoppler dann noch schnell genug ist. Im Zweifel einfach probieren.
hm, ich hab das jetzt mal alles aufm steckbrett aufgebaut und wollt ein wenig testen, da ist mir im datenblatt des 6N137 aufgefallen, das der Ausgang der single channel variante invertiert ist. dem USART des atmega 644 kann man nicht irgendwie sagen, alles was reinkommt zu invertieren, oder? inverter hab ich leider keinen da, nur einen BC328. Lässt sich damit ein inverter basteln? (ich kenne nur eine Schaltung mit npn)
> 6N137 ... der Ausgang ... invertiert ist. Also laut DB: Strom durch die Diode -> 0V am Ausgang Das ist üblich und gilt übrigens auch für die Zweikanal-Variante. Sieh dir das mal an: Genau das selbe macht die Schaltung aus http://www.midi.org/techspecs/electrispec.php Auch hier gilt: Strom durch die Diode -> 0V am UART Fazit: alles im grünen Bereich. > inverter hab ich leider keinen da, nur einen BC328. Lässt sich damit ein > inverter basteln? (ich kenne nur eine Schaltung mit npn) Klar geht das, jeder Transistor ist als Inverter beschaltbar, und nicht immer in der Geschichte der Elektronik war der Minuspol auch zugleich GND.
1 | ------o------- +5V |
2 | | |
3 | __ |< |
4 | IN -|__|--| |
5 | 5V/0V |\ |
6 | | |
7 | o---- OUT |
8 | | 0V/5V |
9 | .-. |
10 | | | |
11 | '-' |
12 | | |
13 | ------o------- GND |
Nun, zwar eine Weile her, aber jetzt erst habe ich die Beschaltung in Betrieb genommen. Funktioniert einwandfrei, ohne Inverter. Allerdings habe ich jetzt ein Softwareseitiges Problem: Mich interessieren nur eingehende Program change befehle. Diese filtere ich im RX Complete interrupt. Das klappt soweit auch ganz gut. Nun steht die Programmnummer aber im zweiten gesendeten Byte, und das krig ich nicht abgefangen, da bin ich immer zu langsam und bekomme irgendwelche daten von nachfolgenden midi befehlen.
1 | // midi rx interrupt
|
2 | ISR(USART0_RX_vect) |
3 | {
|
4 | if((UDR0 & 0b11110000) == 0b11000000) // filter program change command on any channel |
5 | {
|
6 | UCSR0A &= ~(1<<RXC0); |
7 | while(UCSR0A & (1<<RXC0)); |
8 | printf("Program change %d\n", UDR0); // <- Hier kommt irgendwas |
9 | }
|
10 | }
|
Da wenn ich die Daten garnicht behandle und nur ausgebe, komischerweise alles ankommt hab ich es auch mal mittels Flag probiert:
1 | volatile uint8_t pcf = 0; |
2 | |
3 | // midi rx interrupt
|
4 | ISR(USART0_RX_vect) |
5 | {
|
6 | if(pcf) |
7 | {
|
8 | printf("%d\n", UDR0); |
9 | pcf = 0; |
10 | }
|
11 | if((UDR0 & 0b11110000) == 0b11000000) // filter program change command on any channel |
12 | pcf = 1; |
13 | }
|
Das funktioniert auch fast prima. Nur bekomme ich neben dem program change wert, kurz darauf noch einen weiteren (immer 177) ausgegeben. Als würde vor dem löschen des flags ein interrupt eintreten, was in der ISR aber kaum sein kann. Ich bin bei beiden Varianten ratlos. Kann mir jemand weiterhelfen?
Sichere dir das UDR in einer temporären Variablen. Sobald du es nämlich ein Mal ausgelesen hast, ist der Inhalt nicht mehr erreichbar.
> if((UDR0 & 0b11110000) == 0b11000000) // filter program change command >on any channel > { > UCSR0A &= ~(1<<RXC0); > while(UCSR0A & (1<<RXC0)); > printf("Program change %d\n", UDR0); // <- Hier kommt irgendwas > } Dein RXC0-Polling kollidiert mit dem Interrupt.
okay, wunderbar, jetzt gehts, wobei ich das polling problem nochnicht ganz versteh. in der ISR kann ja kein interrupt auftreten. So funktionierts jetzt:
1 | // midi rx interrupt
|
2 | ISR(USART0_RX_vect) |
3 | {
|
4 | uint8_t data = UDR0; |
5 | if(pcf) |
6 | {
|
7 | printf("%d\n", data+1); |
8 | pcf = 0; |
9 | }
|
10 | if((data & 0b11110000) == 0b11000000) // filter program change command on any channel |
11 | pcf = 1; |
12 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.