MIDI Fehlersuche

Gast #3695230
Lesenswert?

Hallo,

ich baue gerade einen kleinen MIDI-Controller mit ATtiny2313. Paar 
Taster und entsprechend ein paar zu sendende Codes.

Getestet habe ich den Code mit 38400Bd/s über RS232, jetzt geändert auf 
31250Bd/s und die Stromschleife mit 2x 220 Ohm.

Übertragen möchte ich: B00000C000
Empfangen wird bei wiederholtem Tastendruck irgendwann 30C0


Relevanter Schaltungsausschnitt angefügt. Belegung im MIDI-Stecker ist 
korrekt, Masse aufgelegt (Senderseite halt). Indikator am Empfänger 
leuchtet auch bei jedem Tastendruck auf, es scheint also auf jeden Fall 
etwas anzukommen.


Das Programm (Taster-Abfragen gespart, ist trivial und funktioniert). 
UART sind Referenzfunktionen, funktioniert mit 38400 wie gesagt bestens.
1
#define F_CPU 4000000UL
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
#include "midifs.h"
7
#include "usart.h"
8

9
[...]
10

11
int main (void)
12
{
13
  CLKPR = 0x00;
14
  [...]
15
  USART_Init(31250);      // initialize USART with 31250 baud
16
  USART_Flush();        // flush USART receive buffer
17

18
  while (1) {
19
    if (iBtn1_counter > BTN_THRESHOLD && cBtn1 == 0)
20
    {
21
      USART_Transmit(0xB0);
22
      USART_Transmit(0x00);
23
      USART_Transmit(0x00);
24
      USART_Transmit(0xC0);
25
      USART_Transmit(0x00);
26
      cBtn1 = 1;
27
    }
28
    else if (iBtn1_counter < BTN_THRESHOLD && cBtn1 == 1)
29
      cBtn1 = 0;
30
    [...]
31
  }
32
}
33

34
void USART_Init( unsigned long baud )
35
{
36
  unsigned int ubrr_val = (unsigned int)((F_CPU/(baud*16L))-1);
37
  UBRRH = (unsigned char)(ubrr_val>>8);
38
  UBRRL = (unsigned char)ubrr_val;  
39
  UCSRB = (1<<TXEN);      // enable transmitter
40
  UCSRC = (3<<UCSZ0);      // 8 data, 1 stop
41
}
42

43
void USART_Transmit( unsigned char data )
44
{
45
  while ( !( UCSRA & (1<<UDRE)) )
46
    ;
47
  UDR = data;
48
}
49

50
void USART_Flush( void )
51
{
52
  unsigned char dummy;
53
  while ( UCSRA & (1<<RXC) ) dummy = UDR;
54
}
Angehängte Dateien:
Gast #3695266
Lesenswert?

Benutzt du einen Quarz?
Hast du den Taster entprellt?

Dass du einen dreipoligen Stecker eingezeichnet hast, ist wohl wegen der 
Einfachheit, oder?

Was passiert, wenn du nur ein Byte sendest? Kommt das an?
Gast #3695300
Lesenswert?

holger schrieb:
>>funktioniert mit 38400 wie gesagt bestens
>
> Mit -7.0% funktioniert es bei dir? Cool.

Nein. Es funktioniert damit, wenn ich statt MIDI an einen MAX232 gehe. 
War vielleicht unglücklich formuliert.

Dussel schrieb:
> Benutzt du einen Quarz?
Nein. Internen 4MHz RC. Ich weiß, nicht optimal, aber so empfindlich 
kenne ich die Signale eigentlich nicht.

> Hast du den Taster entprellt?
Ja. 50ms zum drücken, 100ms zum loslassen per Software.

> Dass du einen dreipoligen Stecker eingezeichnet hast, ist wohl wegen der
> Einfachheit, oder?
Meine Platine hat einen 3pol Stecker, die MIDI Einbaubuchse ist mit 5cm 
verdrillter "Flugleitung" angeschlossen.

> Was passiert, wenn du nur ein Byte sendest? Kommt das an?
Nein. Wobei ich vermute, dass es die Software (oder das Interface) 
schluckt, da kein gültiger Befehl.

Wenn ich kürzere Befehle wie C0 00 sende, passiert garnichts.
50 45 64 ergibt Empfängerseitig 80 10 10 (bei jedem Druck).


Ganz falsch kann es ja irgendwie nicht sein, es kommen hier zumindest 
die korrekte Anzahl an Bytes an, auch wenn mir der Zusammenhang noch 
fehlt...
Gast #3695347
Lesenswert?

npn schrieb:
> Dussel schrieb:
>> nexo schrieb:
>>> 50 45 64 ergibt Empfängerseitig 80 10 10 (bei jedem Druck).
>> Ist das Zufall, dass 0x50=80 ist?
>
> Ich denke ja, denn 0x45 und 0x64 sind garantiert nicht beide 10(dez).
Vielleicht wird ja der erste Wert noch richtig übertragen und danach 
stolpert die Übertragung. Zumindest enthält 0x45 die Folge 0001010. Je 
nachdem, wie das durcheinanderkommt, kann das als 10 interpretiert 
werden.


Mach mal zwischen die Übertragungen eine Pause von ein paar 
Millisekunden rein. Was passiert dann?
Gast #3695360
Lesenswert?

Ja, ich denke auch, dass das Zufall war.

Aber ein interessanter neuer Effekt:
Mit 8MHz intern es funktioniert es!

Muss man jetzt nicht zwingend verstehen, oder?
Einziger Unterschied war die F_CPU Angabe und die Fusebits.


Berechnung der Baudrate aus der Frequenz sieht korrekt aus, an der 
Formel kann es eig. nicht liegen (hat bei RS232 ja auch funktioniert)

Timer Interrupt zu langsam, und hat die Übertragung gestört? Hätte bei 
10MHz dann ja auch kein Problem sein dürfen...


Wenn ich jetzt direkt wie oben den kompletten Befehl absetze, macht mein 
Empfänger exakt, was er soll.
Persönliche Seite #3695531
Lesenswert?

nexo schrieb:
> Getestet habe ich den Code mit 38400Bd/s über RS232, jetzt geändert auf
> 31250Bd/s und die Stromschleife mit 2x 220 Ohm.

Wenn Du als Gegenstelle die serielle Schnittstelle eines PCs verwendest, 
bedenke, daß die keine 31250 Baud unterstützt. Das gibt die Hardware 
nicht her, die die Baudraten aus einem 1.8432-MHz-Takt und einem 16-fach 
Vorteiler ableitet.

Wenn Du am PC ein Midi-Interface verwendest, oder eine 
USB-Seriell-Bridge mit einem funktionierenden Devicetreiber*, dann 
kann das natürlich anders aussehen.



*) gemeint ist einer, der die Baudrate nicht anhand irgendwelcher 
Tabellen interpretiert, sondern unverändert an die USB-Hardware 
weiterreicht

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren