MIDI an UART 0 - ttyAMA0

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Ich hoffe, jemand hier im Forum beschäftigt sich

    Zwecks Musikmachereien auch mit dem RasPi.


    Ich habe mir mit einem 6N137 Optokoppler einen MIDI Eingang

    an den UART-RX Pin (Steckerleiste: Pin#10) eines Raspi 3 gebaut.

    Die Ausgangsseite des 6N137 wird mit der 5V Boardspannung des Raspi betrieben.

    Da es sich beim Ausgang dieses Optokopplers, wie bei den anderen typischen MIDI Kandidaten,

    um einen offenen Kollektor Ausgang handelt

    und die Eingänge des Raspi nicht 5V tollerant sein sollen,

    habe ich den mit einem Pullup von 4K7 auf die nominellen 3,3V

    (Pin#2 der Steckerleiste) hochgezogen

    In der /boot/config.txt habe ich dazu folgende Einträge,

    nach Vorlage: https://zuzebox.wordpress.com/tag/midi/ gemacht,

    um die Baudrate anzupassen:

    Code
    # Enables the UART. It isn’t strictly necessary
    # when combined with pi3-miniuart-bt:
    enable_uart=1
    # Reassigns the weaker UART (ttyS0) for
    # Bluetooth and frees ttyAMA0 for our MIDI interface:
    dtoverlay=pi3-miniuart-bt
    # Using an DT overlay to achieve the same
    # UART clock settings as our init_uart_clock etc. trick:
    dtoverlay=midi-uart0

    Soweit, so mittelprächtig, die Midibyte müßten demnach also

    bei oder in ttyAMA0 landen.

    Damit habe ich zwar noch weder ein /dev/midi, noch irgendwas,

    das sich unter Alsa als MIDI device ansprechen läßt,

    aber da wenigstens die Baudrate nun stimmen soll,

    könnte ich MIDI Eingaben von meinem MIDI Keyboard mit

    cat /dev/ttyAMA0 abhorchen.

    In der Tat kommt da auch was.

    Leider ist das aber nur Bitsalat, was die Schnittstelle da kommen sieht,

    zudem verschluckt sie immer wieder etliche Byte.


    Ich habe dann mit meinem Oskar die Signalspannungen

    an RX gemessen:

    Low liegt bei 0,25V und High liegt bei 3V an RX,

    das sollten eigentlich Werte sein, bei denen die UART eindeutige

    Highs und Lows erkennen müßte und der Wert für den

    externen Pullupwiderstand von 4K7 wäre O.K..


    Mir scheint es eher, daß das mit der Baudrate immer noch nicht hinhaut,

    oder dem Raspi das MIDI-Datenformat 8n1 nicht genehm ist.


    Bin zwischenzeitlich über ein Kommando gestolpert, das die Geschwindigkeit

    der UART anzeigen soll, Ausgabe ist folgende:

    Code
    pi@ratherfast:~ $ vcgencmd measure_clock uart
    frequency(22)=47999000

    Das sieht jedenfalls noch astronomisch aus für MIDI und nicht so,

    als hätte dieses Overlay "midi-uart0" irgendwas ausgerichtet.

    Kommentiere ich das Overlay aus und starte den Raspi neu,

    zeigt mir dieses Kommando: frequency(22)=48000000,

    also ganze 1000 mehr :)


    Ich bin jedenfalls im Augenblick etwas ratlos

    und würde mich freuen, wenn da wer Abhilfe weiß.

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

  • Na ja, ein Midi-Stream ist doch binaer, soviel ich weiss. Binaere Daten waeren also erst mal normal.


    Vor einem cat von der Schnittstelle sollte sie erst mal konfiguriert werden. Linux hat sehr eigene Ansichten was ein Terminaldriver machen sollte...


    Ich wuerde mal so anfangen: stty -F /dev/ttyAMA0 raw 31250


    (Keine Ahnung ob der PI diese Baudrate einstellen kann. Wenn's nicht geht, das naechstmoegliche nehmen)


    Dann nachsehen ob Echo aus ist. Die meisten Geraete moegen kein Echo.

  • Habt Dank für die Antworten.

    Quote from Tell

    Na ja, ein Midi-Stream ist doch binaer, soviel ich weiss. Binaere Daten waeren also erst mal normal.

    So steht's wohl seit 1983 geschrieben und was anderes kommt naturgemäß aus dem Optokoppler 6N137 nicht raus,

    da der intern vor dem Ausgang einen Schmittrigger nachgeschaltet hat.

    Schnell genug für die 31250 Baud sollte er jedenfalls sein.

    Die Frage wäre nur, ob ich mit den beschriebenen 0,25V für eine eindeutige "0" noch in der Spezifikation bin.

    Quote

    Vor einem cat von der Schnittstelle sollte sie erst mal konfiguriert werden.

    Linux hat sehr eigene Ansichten was ein Terminaldriver machen sollte...

    Genau diese Konfiguration sollte ja das Overlay "midi-uart0" machen: 8n1,31250Baud,

    mehr liefert das gewöhnliche /dev/midi oder /dev/snd/midiC0Dschießmichtot auch nicht,

    bzw. wird das so auch vom Keyboard geliefert. Im Prinzip gehts nicht simpler,

    nur steht da Linux und die Mehrfachfunktionalitäten der i/o Pins vor.

    Wenn das jedenfalls mit "cat" funktioniert, kann ich mir einfach unter /dev einen Link namens "midi"

    auf das ttyAMA0 anlegen.



    Es scheint jedenfalls noch einige Hürden zu geben:

    Ich habe jetzt noch die Kernelparameter "console=serial0,115200 console=tty1" aus der /boot/cmdline.txt entfernt,

    das scheint auchnoch dazwischenzufunken.


    Der Raspi soll ja zwei UARTS haben.

    Ich habe hier:

    https://www.raspberrypi.org/do…ion/configuration/uart.md

    noch sehr hilfreiche Informationen dazu gefunden.

    Z.B.über das Overlay "pi3-disable-bt":

    "pi3-disable-bt disables the Bluetooth device and restores

    UART0/ttyAMA0 to GPIOs 14 and 15.

    It is also necessary to disable the system service

    that initialises the modem so it doesn't use the UART:

    sudo systemctl disable hciuart."

    Das soll die "echte" UART, die eingebaute "Prime Cell UART PL011" wieder

    über die i/o Pins zugänglich machen. Bluetooth wäre dann aber abgehängt,

    was mich nicht stört.

    Die 2. UART, die sog. "mini uart" kann man für MIDI getrost vergessen:

    "The baud rate of the mini UART is linked to the core frequency of the VPU on the VC4 GPU.

    This means that as the VPU frequency governor varies the core frequency,

    the baud rate of the UART also changes."

    Wofür die überhaupt gut sein soll, wenn sie nichtmal eine eigene Clock besitzt, ist

    eine gute Frage.


    In der Beschreibung des Overlays "midi-uart0" steht dann noch Folgendes:

    Wie cladish auch schreibt:

    Das Overlay verbiegt also nur die Clock so,

    daß danach der Teiler der PL011 für eine ganzzahlige Teilung auf

    reale 31250 Baud eingestellt werden kann.

    Für eine Terminalausgabe muß dann also die "falsche" Baudrate

    von 38400 angegeben werden.


    Ehrlich gesagt, halte ich das für ein fürchterliches Durcheinander

    und ein Hack scheints obendrein, da der Takt der UART dann nichtmehr dem

    Nominellen entspricht.

    Aber man sieht, ich komme der Sache wohl schon näher.

    :)


    Danke nochmal, von dem Linuxkrempel weiß ich eigentlich nicht viel,

    das Schönste wäre, wenn ich mit dem gcc und ner vernünftigen Dokumentation

    der UART direkt in den Registern dieses "PL011" stochern könnte,

    wie man es auch bei den Atmels tut. :)


    Habe heute nicht mehr viel Zeit, das alles auszuprobieren,

    aber wenn es dann endlich pfundst, werde ich es nochmal zusammenfassen.

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

  • Ein Smartphone ist eben kein Atari unt trotzdem ist ein MIDI in/out unter Linux möglich, wenn auch mit etwas Aufwand und Grips.



    Servus !

    RTFM = Read The Factory Manual, oder so

  • […] da der intern vor dem Ausgang einen Schmittrigger nachgeschaltet hat.

    Der 6N137 hat keinen Schmitt-Trigger. HP sagt:

    Quote

    The reason for omitting hysteresis was not to permit analog operation, but rather to permit maximum data rate. With hysteresis, there would be a higher immunity to both differential- and common-mode noise but the shifting threshold would reduce the data rate capability.

    Aber MIDI braucht ja nicht 10 Mbit/s, sondern 0,031 Mbit/s; ein PC900 H11L1 wäre mehr als genug. Ist aber letztendlich auch egal.


    Quote

    Die Frage wäre nur, ob ich mit den beschriebenen 0,25V für eine eindeutige "0" noch in der Spezifikation bin.

    Die MIDI-Spezifikation kümmert sich nur um die Schnittstelle zwischen zwei MIDI-Geräten; der Ausgang des Optokopplers muss nur zum Eingang des RaspPi passen. Und da ist alles unter 0,5 V erlaubt.


    Quote

    Der Raspi soll ja zwei UARTS haben.

    https://zuzebox.wordpress.com/…27/setting-up-rpi-midi-2/ sagt:

    Quote

    This combination […] Reassigns the weaker UART (ttyS0) for Bluetooth and frees ttyAMA0 for our MIDI interface


    Quote

    und ein Hack scheints obendrein, da der Takt der UART dann nichtmehr dem Nominellen entspricht.

    Tools wie stty unterstützen Nicht-Standard-Baudraten wie 31250 oft gar nicht.

  • > Genau diese Konfiguration sollte ja das Overlay "midi-uart0" machen: 8n1,31250Baud,

    Wenn das Ding nicht den Terminaldriver vollkommen ausser Kraft setzt, dann gibt es immer noch viel einzustellen.

    Echo, Behandlung der Sonderzeichen...


    Was sagt stty -D /dev/ttyAMA0 -all ?

  • Mojn!

    Quote from TE

    Was sagt stty -D /dev/ttyAMA0 -all ?


    Es sagt wörtlich:

    "stty: Wenn ein Ausgabestil angegeben ist, kann kein Modus gesetzt werden."


    ich habe ein kleines C-Progrämmchen als MIDI Monitor geschrieben.

    Das sollte ja auch mit dem ttyAMA0 laufen, da da auch nichts anderes aufläuft

    als beim USB-MIDI Kabel im /dev/snd/midiC1D0.

    Immerhin hat das Progrämmchen mittlerweile nun schon etwa 10 Byte nach Programmstart richtig erkannt.

    Dahinter wird es dann wieder wüst.

    Die Masterclock des PL011 scheint nicht zu wissen, nach welchem Takt sie laufen soll.

    Mal sagt "vcgencmd measure_clock uart" das:

    frequency(22)=47999000

    dann wieder das:

    frequency(22)=48000000

    Ich weiß nicht, wie ernst man den Output von vcgencmd nehmen kann,

    aber 48MHz lassen sich auf 31,25KBaud glatt durch 1536 Teilen,

    47,999MHz durch den Teiler 1536 sind dagegen etwa 31249,349 Baud

    Die Differenz sind zwar nur 0,651 Baud, aber müßte ein Byte da nicht

    schon nach 2 Sek. um mehr als ein Bit nachgehen?

    Andererseits "rastet" das Folgebyte durch das Stoppbit ja auch wieder auf

    Byteanfang ein.

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

  • Oh, das sieht abenteuerlich aus :) :

    9600 Baud sind jedenfalls völlig abwegig, immerhin erkennt mein Monitor schon nach Start die ersten paar Byte.


    Nochn' Nachtrag,

    mein Programm zeigt auch nur was an, wenn ich in der /boot/cmdline.txt den Kernelparameter

    "console=serial0, 38400"

    eintrage.

    War sone Idee von mir. /dev/@serial0 ist ein Link auf /dev/ttyAMA0.

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

    Edited once, last by Heinrich ().

  • Wenn es Dir nicht gelingt die Baudrate am UART auf MIDI (per eigener Software) zu verbiegen, dann kannst Du das auch einem externem MIDI Converter überlassen. Entweder per MIDI -> USB Converter, oder per MIDI -> RS232 Converter (mit Pegelwandler auf 3,3 V ).


    Die Baudrate am UART wird durch Teilung und Multiplikation einer Grundftrequenz eingestellt. Die MIDI Baudrate passt in das Raster der möglichen Baudrates nicht hinein.



    Servus !

    RTFM = Read The Factory Manual, oder so

  • Hi,

    Die Baudrate am UART wird durch Teilung und Multiplikation einer Grundftrequenz eingestellt. Die MIDI Baudrate passt in das Raster der möglichen Baudrates nicht hinein.

    ich würde da mal über bitbanging nachdenken ... eine reine Übertragung mit der MIDI Baudrate sollte relativ einfach umzusetzen sein ...

    cu,

    -ds-

  • > Oh, das sieht abenteuerlich aus :) :

    Es sieht ganz gut aus. iutf8 wuerde ich noch abschalten, sonst faellt mir nichts besonderes auf.


    Und im C-Programm natuerlich die Schnittstelle richtig konfigurieren!



  • Das ist das Progrämmchen "*mcat":

    Und das ist im Augenblick eine (nachsortierte) Ausgabe:

    Die ersten 6 Zeilen sind völlig O.K.

    0x90 bedeutet Tastenanschlag auf Kanal1, die 37 danach bedeutet Tastennummer Hex 37, dann Anschlagwert Hex 7c

    0x80 in der nächsten Zeile: Taste auf Kanal 1 losgelassen, dann kommt Tastennummer Hex 37, Loslaßgeschwindigkeit Hex 64 usw.

    Wie man sieht, habe ich 3x eine Taste gedrückt und dann wieder losgelassen.

    Was dann aber kommt, ist nicht mehr sinnvoll zu interpretieren, 4 Datenbyte ohne vorgestellten Status

    und dann 5 Statusbyte, obwohl ich nur weiterhin Tasten gedrückt und losgelassen habe.

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

    Edited 3 times, last by Heinrich ().

  • Ist iutf8 jetzt ausgeschaltet?


    Das Programm uebernimmt einfach die Konfiguration des Terminal-Drivers, deshalb muss die Schnittstelle vor dem Start richtig eingestellt sein.


    fgetc gibt einen int zurueck. Ich wuerde den auch so uebernehmen und dem switch einen default-Fall geben.


    Kann man herausfinden welche Codes fehlen? Vielleicht interpretiert der Driver immer noch irgendwas.

  • Quote from TE

    Kann man herausfinden welche Codes fehlen? Vielleicht interpretiert der Driver immer noch irgendwas.

    Nein, was hinter den sechs richtig erkannten Triplets kommt, kann z.T. nicht aus dem Keyboard kommen.

    Der Status 0xfc z.B. bedeutet "stop sequence", das kann das Keyboard aber garnicht.

    Das ist nurnoch Bitsalat.


    Ich könnte ein paar Tasten drücken und die zu erwartenden Byte notieren, nur den Notenanschlag kann ich dabei nicht quantitativ voraussagen,

    das ist nach Gefühl.


    Quote from TE

    Ich wuerde den auch so uebernehmen und dem switch einen default-Fall geben.

    eigentlich sind alle Bytewerte abgedeckt und was anderes kommt ja garnicht rein:

    0x00 bis 0x7f, dann 0x80-0xff, mehr Fälle gibts nicht.


    Quote

    Ist iutf8 jetzt ausgeschaltet?

    Öh, wie gehtn das?


    Hab jedenfalls ausdrücklichen Dank!

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

  • > Öh, wie gehtn das?

    Code
    stty -F /dev/ttyAMA0 -iutf8


    > Die ersten 6 Zeilen sind völlig O.K.

    Dann wird die Baudrate recht gut stimmen, sonst kaemen die nicht durch.


    Wenn ein Oszilloskop greifbar ist, wuerde ich das jetzt an die Schnittstelle klemmen und mir die Signale ansehen.


    Wenn das gut aussieht, die Einstellungen vom Terminal-Driver ganz genau studieren (Da sehe ich zwar nichts auffaelliges bis auf das iutf8)

  • Ich Danke Dir nochmal,


    ich habe die Einstellung mit stty gemacht, es ändert aber leider nix.

    Das Kommando werde ich mir auch nochmal genau angucken, hat ja ne schicke man page :)


    Zudem hab ich mir nochmal alles mit meinem alten Hameg angeguckt.

    Direkt an RX sehen die Signale wirklich sauber aus.

    Den Status für "modulation" kann ich am Oskar gut einfangen und breitziehen,

    dahinter zappeln dann die zugehörigen Datenbyte, wenn ich das Modulationsrad

    des Keyboards einigermaßen kontinuierlich betätige.

    Genau so soll es sein und da dürfte der Raspi wirklich nix zu meckern haben.

    Ich bin dann mal auf die Idee gekommen, den Pullup von den 3,3V abzuziehen

    und -siehe da- der interne Pullup des Raspi scheint an RX enabled und,

    wie das aussieht, sogar ohne zusätzlichen Pullup auszureichen.

    Ohne den externen Pullup sehe ich an RX immernoch ein sauberes Signal,

    von den 3V runter mit steilen Flanken und ohne Überschwingen auf <0,5V.

    Da kann ich sogar die Bits abzählen.


    Quote from Tell

    fgetc gibt einen int zurueck

    Ich habe in meinem Progrämmchen auch nochmal einen "cast" eigefügt in Zeile 17:

    von byte_in=fgetc(midi_in); in byte_in=(fgetc(midi_in));

    Ich hoffe, sorum ist es richtig :) , der Compiler meckert jedenfalls nicht,

    aber machen tuts auch nix.


    Na ja, mal gucken, wie stur ich noch bleibe, bischen nervig wird das langsam.

    Der PL011 sollte sich jedenfalls, wenn er mit kontinuierlichen 48MHz läuft

    und über den ganzzahligen Teiler >dez.1536 verfügt, auch ohne Verstellen durch Nachkalibrierung

    o.ä. auf genau 31250Baud teilen lassen, deswegen wundert es mich schon, daß ich nur nen Output

    kriege, wenn ich dem Kernel den "falschen" Parameterwert: console=serial0,38400

    mitgeben muß, um überhaupt einen Input zu bekommen,

    aber vlt. will es das Overlay "midi-uart0" ja so.


    have a lotta fun :)

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

  • Saubere Signale von 3V und 0.5V sollten passen.


    Es muesste also ein Software-Problem sein.


    > byte_in=(fgetc(midi_in));

    Das ist kein Cast, das sind bloss ueberfluessige Klammern. Dass die nichts bewirken ist auch klar.


    Gemeint war: den Returnwert in einem int ablegen und den switch um einen default-Fall erweitern, der alle Werte groesser als 0xFF erfasst.


    Nach der Beschreibung von fgetc sollte das nicht vorkommen, aber irgendwas muss ja falsch sein, sonst wuerde das Programm doch laufen.


    Die Baudrate kann es nicht sein, sonst wuerden nicht 12 Bytes hintereinander richtig ankommen.


    Kommt etwas anderes raus wenn die Schnittstelle direkt angesprochen wird, so wie hier: https://blog.heimetli.ch/raspberry-display-mc-crypt.html

  • Quote from Tell

    Gemeint war: den Returnwert in einem int ablegen und den switch um einen default-Fall erweitern,

    der alle Werte groesser als 0xFF erfasst.


    Nach der Beschreibung von fgetc sollte das nicht vorkommen,

    aber irgendwas muss ja falsch sein, sonst wuerde das Programm doch laufen.

    Ja gut, hab ich auch nochmal gemacht:

    byte_in als int deklariert und:


    default: //fuer alles, was uebrig ist....

    printf("\033[33m%x ",byte_in); //... nach den cases angefügt.

    //Das wuerde dann in Gelb angezeigt.


    Läuft ohne Meldung durch den Compiler, aber im Augenblick macht mein Progrämmchen an ttyAMA0

    wieder garnichts mehr, keine Ahnung, warum.

    Der Oskar zeigt dabei immer noch saubere Signale an RX.


    Mit /dev/snd/midiC1D0 vom USB MIDI Inputkabel als Eingabe kompiliert,

    funktioniert es mit dem "int- byte_in" auch immernoch einwandfrei.

    Ein "Default-Fall" ist dort auch nach Traktieren der Tasten

    und Controllerräder nicht aufgetreten.


    Oder, um es unkomplizierter zu sagen:

    Das Programm funktioniert einwandfrei , wenn ich es für die USB Midischnittstelle kompiliere.

    "Volt, Watt, Ampere, Ohm, ohne mich gibts keinen Strom"

    Der Elektrolurch (Guru Guru)

    Edited once, last by Heinrich ().