www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MIDI Daten senden?


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte ganz einfach ein paar MIDI-Daten an ein Keyboard senden. 
Leider komme ic nicht zum Ziel. Vielleicht bin ich auch schon ein wenig 
betriebsblind -- so dass der Fehler ganz nah liegen könnte.

Ich habe Wahlweise einen ATmega8 bzw. einen ATmega8535 mit je 6MHz.
Compiler: AVR-Studio mit GCC/WinAVR

Mein Quellcode:


#include <avr/io.h>
#include <inttypes.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#define F_CPU       6000000UL
#define BAUD        31250UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)


// USART initialisieren
void uart_init(void)
{
    // Baudrate einstellen (Normaler Modus)
    UBRRH = (uint8_t) (UBRR_BAUD>>8);
    UBRRL = (uint8_t) (UBRR_BAUD);

    // Aktivieren vom transmitter
    UCSRB = (1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

int main(void)
{
    uint8_t buffer;

    // USART initialisieren
    uart_init();

    while (1)
    {
        // Warten bis der Sendepuffer frei ist
        while ( !( UCSRA & (1<<UDRE)) );
        // Daten in den Puffer schreiben und damit senden
        buffer = 0x91;
        UDR = buffer ;
        _delay_ms(10);

        // Warten bis der Sendepuffer frei ist
        while ( !( UCSRA & (1<<UDRE)) );
        // Daten in den Puffer schreiben und damit senden
        buffer = 0x3C;
        UDR = buffer ;
        _delay_ms(10);

        // Warten bis der Sendepuffer frei ist
        while ( !( UCSRA & (1<<UDRE)) );
        // Daten in den Puffer schreiben und damit senden
        buffer = 0x7F;
        UDR = buffer ;
        _delay_ms(10);
    }
}



PD1(TXD) --> Pin 4 der MIDI Buchse
+5V      --> Pin 4 der MIDI Buchse

jeweils über 220R

Auf dem Oszilloskop kann man die einzelnen gesetzten Bits auszähen. Es 
sieht auf dem ersten und zweiten Blick nicht verkehrt aus.

Im Moment lese ich die gesendeten Daten mit einem MIDI-USB-Übertrager 
aus. Leider erhalte ich nur Müll, obwohl die EmpfangsLED leuchtet.

Kann mir jemand sagen, was ich falsch gemacht habe??

Vielen Dank und viele Grüße

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entschuldigung, ein kleiner Fehler. Es muss natürlich so sein:

PD1(TXD) --> Pin 5 der MIDI Buchse
+5V         --> Pin 4 der MIDI Buchse

Autor: C. H. (_ch_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

die Fuses für externen Quarz sind gesetzt?

Gruß
Christian

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Japp - zusätzlich durch Oszi verifiziert.
--> Es ergibt sich eine Bitbreite von ca. 32µs.

Gruß Sebastian

Autor: Mano Wee (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso wartest Du eigentlich immer 10ms ? Du könntest doch in der Zeit 
schon längst wieder senden.

Autor: C. H. (_ch_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sende doch mal nur ein einzelnes Byte und schaue was der 
MIDI-Usb-Übertrager macht.
So spontan kann ich auch keinen Fehler im Code finden.

Gruß
Christian

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe immer 10ms dazwischen gesetzt, damit man auf dem Oszi 
die Bits besser auszählen kann. Auch wenn ich nur 1 Byte sende wird nur 
Müll erkannt.

Der USB-Umsetzer ist soweit ich das beurteilen kann in Ordnung, da das 
Einspeisen von anderen MIDI-Quellen problemlos funktioniert.

Gruss
Sebastian

Autor: cyberlink (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich würde gerne mit Bascom Midi-Befehle senden.
soweit ich das kapiert habe, hat midi eine baudrate von 3125 Baud. 
stimmt das?

mein code:
------------------------------------------------------------------------ 
-----
$regfile = "m8def.dat"
$crystal = "8000000"
Baud = 3125

Do
  print chr(144) ; chr(60) ; chr(64) 'Taste C drücken (Kanal 0)
  print chr(128) ; chr(60) ; chr(64) 'Taste C loslassen (Kanal 0)
  wait 1
Loop
End
------------------------------------------------------------------------ 
-----
quelle der midi-codes: 
http://web.archive.org/web/20071005165328/www.borg...

funktioniert der so?

mfg cyberlink

Autor: Mano Wee (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ cyberlink

>Hallo, ich würde gerne mit Bascom Midi-Befehle senden.
>soweit ich das kapiert habe, hat midi eine baudrate von 3125 Baud.
>stimmt das?

Nicht ganz. Sie beträgt 31,25 kBauds, so wie es oben steht.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>hat midi eine baudrate von 3125 Baud.
Wo hast du diese Info her ?

Und überlege Dir mal wie lange die Taste C in Deiner Schleife in etwa 
gedrückt bleibt.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, erstaunlicher Weise funktioniert die Lösung mit BASCOM (Baud = 
31250).


Daraus schlussfolgere ich, dass meine Peripherie und Pinbelegung richtig 
sind.

Dann kann ja nur noch mein Quellcode falsch sein...

Gruß
Sebastian

Autor: Mano Wee (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Sebastian

Die Fragen kann ich mir wahrscheinlich sparen: ohne die beiden ersten 
_delay_ms(10) hast Du es sicher auch schon probiert, oder?

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Japp, ohne gehts auch nit.
Die Zeiten dienen nur zum besseren anschauen auf dem Oszi.

Gruß

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein komisches Problem. Mir fällt auf, dass das BASCOM Beispiel 
den Kanal 0 benutzt, während du im C Beispiel Kanal 1 hast. Kann es 
sein, dass das Keyboard auf Monophonie eingestellt ist? Meine andere 
Idee ist, dass vielleicht der Ton einen langsamen Attack hat und du 
deshalb nichts hörst, weil der Ton in Sekundenbruchteilen wieder neu 
startet.

Autor: cyberlink (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
da jetzt mein quellcode fertig ist (mini-synthesizer mit tastern) würde 
ich mich jetzt mal an den Anschluss meines Keyboards machen. Also dass 
der AVR MIDI-Daten sendet und das Keyboard sie über den MIDI-IN Port 
empfängt. Auf wikipedia hab ich folgende Anschlussbelegung gefunden:
http://de.wikipedia.org/wiki/Bild:StandardMIDIInterface.gif

Diese ist aber offensichtlich für den Gameport, der sicher wieder einen 
anderen Signalpegel hat. Midi hat ja einen Signalpegel von 5 Volt (0) 
oder 0 Volt (1). Das ist genau der UART Pegel des AVR, nur negativ.

Wie bekommt man so etwas am einfachsten (kleiner Bauteileaufwand, 
Bastelkistenteile) hin? Vielleicht mit zwei Optokopplern?
Das IC in der Wikipediaschaltung (falls das mit dem AVR funktionieren 
würde) müsste ich nämlich erst bestellen.

Ich hoffe, ihr könnt mir helfen

mfg
cyberlink

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR TXD über 220 Ohm an die MIDI-Buchse (Ausgang) und den anderen Pol 
der MIDI-Buchse über 220 Ohm an Vcc. Vom externen Keyboard an die 
MIDI-Buchse (Eingang) über 220 Ohm an die Anode der LED eines 
Optokopplers (CNY17/1 reicht) und deren Kathode zum anderen Pol der 
Buchse, dessen Emitter an Masse, Kollektor an AVR RXD und einen PullUp 
von 470 Ohm an Vcc. Das war´s.

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Thomas Korthoff (thomas47058)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ist schon ein altes Thema. Ich mach deshalb keinen neuen Thread auf, in 
der Hoffnung, dass das trotzdem jemand liest.

Ich bin gerade dabei einen MIDI Controller zu basteln. Noch befindet 
sich alles im Aufbau. Ich würd gerne aus Testzwecken einzelne MIDI 
Messages an den PC senden.

Der Aufbau ist folgender:
uC: atmega8
taktgeber quarz: 12 MHz
Fuses gesetzt (low: FF, high: C9)
MIDI Schnittstelle gebaut und verkabelt nach Plan (Pin4 der Buchse über 
220 ohm an TXD, Pin2 an GND, Pin5 über 220 an Vcc 5V)
programmiert mit Codevision

Mit MidiOX prüfe ich, was am PC ankommt. Leider tut sich rein gar 
nichts. Ich weiß nicht, ob es am Code liegt, oder am uC... ich bin 
ratlos.

Hier der Code in abgespeckter Form. Könnt ihr irgendwo einen Fehler 
entdecken? Hab ich vergessen notwendige Details zu erwähnen? Ich wäre 
für eure Hilfe sehr sehr dankbar.

Chip type           : ATmega8
Program type        : Application
Clock frequency     : 12,000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

// Standard Input/Output functions
#include <stdio.h>


unsigned char buffer;

void putchar_midi_on()
{
    
        while ( !( UCSRA & (1<<5)) );
        buffer = 0x91;
        UDR = buffer ;

        while ( !( UCSRA & (1<<5)) );
        buffer = 0x50;
        UDR = buffer ;

        while ( !( UCSRA & (1<<5)) );
        buffer = 0x64;
        UDR = buffer ;

}

void putchar_midi_off()
{
        while ( !( UCSRA & (1<<5)) );
        buffer = 0x81;
        UDR = buffer ;

        while ( !( UCSRA & (1<<5)) );
        buffer = 0x50;
        UDR = buffer ;

        while ( !( UCSRA & (1<<5)) );
        buffer = 0x64;
        UDR = buffer ;
}


void main(void)
{

[...]

// Port D initialization 
PORTD=0xFF;
DDRD=0xFF;

[...]

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 31250
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x17;

[...]

while (1)
      {
      
      if(!(PINC&0b00000001)) //Button an pinc0
      {
       putchar_midi_on();
       
       PORTD&=~(0b00000100); //Kontroll LED an
       delay_ms(100);
       PORTD|=0b00000100; //Kontroll LED aus
      //LEDs dienen nur temporär zum Überprüfen, ob die Fkt aufgerufen wird
      }
      
      if(!(PINB&0b00000100)) //Button an pinb2
      {        
       putchar_midi_off();
       
       PORTD&=~(0b00000100);
       delay_ms(100);
       PORTD|=0b00000100; 
      
      };
}
}

Autor: Thomas Korthoff (thomas47058)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weiß keiner eine lösung? hier nochmals die bitte drüber zu sehen.

besten dank!

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als erstes würde ich am MIDI-Ausgang Deines Controllers eine LED 
anschließen und gucken, ob sie blinkt. Dann wäre noch interessant, wie 
Du Deinen MIDI-Ausgang mit dem PC verdrahtet hast.

Autor: Phil J. (sunflower_seed)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.embedds.com/diy-midi-interface-for-usb/

Guck mal hier, ich habe die Orginale Internetseite nicht mehr gefunden.
Aber vielleicht hilft dir der Code zu dem projekt weiter
http://www.avrfreaks.net/index.php?module=Freaks%2...

Autor: Thomas Korthoff (thomas47058)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo und vielen Dank für die Antworten.

@travelrec, dass daten fließen, habe ich mit nem multimeter gemessen. 
ich weiß, das ist nicht die genaueste Methode, aber es hat gereich um 
festzustellen, dass was passiert am Ausgang. An die MIDI (DIN) Buchse 
habe ich ein einfaches MIDI Kabel angeschlossen, welches dann zur 
seriellen Schnittstelle meiner Soundkarte führt, als Adapter sozusagen. 
Soundkarte ist die Terratec EWX 24/96. Die haben damals einen "Gameport" 
mitgeliefert als "Midi In". Mein MIDI Keyboard tut's auch einwandfrei, 
daran liegts also nicht.

@phil, vielen Dank für den Beispiel Code. Nachdem ich drüber gesehen 
habe, hab ich, abgesehen vom Umfang, keinen Unterschied zu meinem Code 
entdeckt... leider. Hm... ich frag mich, ob ich das mit der 
Bitübertragung richtig eingestellt habe. 8 Daten Bits, 1 Stop Bit, kein 
Parity Bit ist doch korrekt, oder? Was ist mit dem Startbit? Und wieso 
steht im Beispielcode etwas von Stop Bit Generation?:
void SUART_putchar( u8 val )    // send byte
{
  while( stx_count );      // until last byte finished
  stx_data = ~val;  // invert data for Stop bit generation
  stx_count = 10;      // 10 bits: Start + data + Stop
}

Das verwirrt mich. Was hat es damit auf sich? Hab auch in Büchern nix 
dazu gefunden.

Vielleicht liegt es daran, dass etwas fehlt bei der Übertragung, oder 
etwas falsch interpretiert wird...

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moment mal: benutzt Du nun eine Hardware- oder Software-UART? Bei der 
Hardware-UART mußt Du nur Baudratenregister und Steuerregister passend 
setzen und nacheinander die richtigen Bytes in das UDR-Register 
schreiben. Die Baudrate muß natürlich stimmen. Den Rest mit Start und 
Stop-Bit macht die Hardware.

Autor: Mark M. (mom-jovi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas P. schrieb:
> 8 Daten Bits, 1 Stop Bit, kein Parity Bit ist doch korrekt, oder? Was
> ist mit dem Startbit?

Ich weiß, es ist ein altes Thema. Aber ich beschäftige mich gerade auch 
damit. Erwartet MIDI tatsächlich ein Stop Bit?
Nach dem hier: 
http://de.wikipedia.org/wiki/Musical_Instrument_Di...
werden doch nur bloße Bytes gesendet, oder? Die Unterscheidung 
Status-/Datenbyte erfolgt mit dem ersten Bit eines Bytes.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark M. schrieb:
> Nach dem hier:
> http://de.wikipedia.org/wiki/Musical_Instrument_Di...
> werden doch nur bloße Bytes gesendet, oder?

Das hat damit nichts zu tun. Es geht um die grundlegende serielle 
Übertragung, Start- und Stopbit gehören zu deren Framing, das um jedes 
übertragene Byte gepackt wird.

Darum muss man sich als Programmierer nicht kümmern, das erledigt die 
UART-Hardware ganz von selbst.

Autor: Mark M. (mom-jovi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. Firefly schrieb:
> Mark M. schrieb:
>> Nach dem hier:
>> http://de.wikipedia.org/wiki/Musical_Instrument_Di...
>> werden doch nur bloße Bytes gesendet, oder?
>
> Das hat damit nichts zu tun. Es geht um die grundlegende serielle
> Übertragung, Start- und Stopbit gehören zu deren Framing, das um /jedes/
> übertragene Byte gepackt wird.
>
> Darum muss man sich als Programmierer nicht kümmern, das erledigt die
> UART-Hardware ganz von selbst.

Aber hier geht es doch darum, MIDI-Bytes an einen MIDI-Eingang zu 
senden. Und ich habe gedacht, dass MIDI eben kein Framing hat/braucht. 
Oder versteht es UART mit Start- und Stop-Bits? Steht das irgendwo?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark M. schrieb:
> Und ich habe gedacht, dass MIDI eben kein Framing hat/braucht.

Doch, tut es. Das ist eine ganz stinknormale UART-Übertragung, so, wie 
es asynchrone serielle Schnittstellen tun. Es "versteht" nicht nur 
Start- und Stopbits, es benötigt sie zwingend.

Wäre die serielle Schnittstelle des PCs in der Lage, die korrekte 
Baudrate zu erzeugen, müsste man nur von RS232-Pegeln auf die 
MIDI-Stromschnittstelle umsetzen und könnte direkt mit MIDI-Hardware 
kommunizieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.