Forum: Mikrocontroller und Digitale Elektronik Midi empfangen, hardware


von Ephraim H. (ephi)


Lesenswert?

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ß

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Google und midi 6n137 helfen weiter  :-o

Such z.B. dort mal nach 6n137:
http://www.midi.org/techspecs/electrispec.php

von Ephraim H. (ephi)


Lesenswert?

hm okay, na wenn der sogar besser ist...

Dank Dir auf jeden fall!

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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  ;-)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

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.

von Ephraim H. (ephi)


Lesenswert?

Wie gesagt: hauptsache getroffen ;-)

noch ne kleine verständnisfrage:
Sind in dieser schaltung die 280ohm der arbeitswiederstand?
http://www.midi.org/techspecs/electrispec.php

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ephraim Hahn schrieb:
> Sind in dieser schaltung die 280ohm der arbeitswiederstand?
Ja. Und der ist hübsch niederohmig.

von Ephraim H. (ephi)


Lesenswert?

d.h.? soll ich den lieber größer machen?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Naja - nur dann, wenn der Optokoppler dann noch schnell genug ist. Im 
Zweifel einfach probieren.

von Ephraim H. (ephi)


Lesenswert?

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)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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

von Ephraim H. (ephi)


Lesenswert?

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?

von STK500-Besitzer (Gast)


Lesenswert?

Sichere dir das UDR in einer temporären Variablen.
Sobald du es nämlich ein Mal ausgelesen hast, ist der Inhalt nicht mehr 
erreichbar.

von STK500-Besitzer (Gast)


Lesenswert?

>  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.

von Ephraim H. (ephi)


Lesenswert?

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
Noch kein Account? Hier anmelden.