Hallo zusammen, Ich habe ein kleines Problem mit dem Empfang von MIDI Daten über einen Atmega 8 mit Bascom Gegeben: Atmega 8 und Midi-In auf PD0 über Opto nach MIDI-Standard. Übertragung 31250 Baud wie vorgeschrieben. In Bascom so konfiguriert: $regfile = "m168def.dat" $hwstack = 32 $swstack = 10 $framesize = 40 $PROG &HFF , &HCF , &HDF , &HF9 '$crystal = 7372800 $crystal = 8000000 $baud = 31250 Nun sende ich von einer Midi-Schnittstelle (am PC) ein paar Bytes an den µC welcher mir den Inhalt der Bytes dann über 8 LEDs anzeigen soll: Sende (Hx): 01 02 03 04 05 06 Aber es werden aber nur die 01 02 und 03 UND das letzte Byte angezeigt, ausgegeben. Sende ich: 01 02 03 04 05 06 07 08 09 0A dann wird ebenfalls wieder 01, 02 und 03 und das letzte Byte angezeigt. Alles dazwischen scheint nicht vorhanden zu sein. Um ein Problem mit dem MIDI-Interface aus zu schliessen habe ich einen zweiten µC genommen welcher auch senden kann (gleicher µC, gleicher Quarz etc) und siehe da, wenn ich die einzelnen Bytes mittels printbin 01, printbin 02 ... raus gebe habe ich den gleichen Effekt. Die ersten drei Bytes und das letzte werden angezeigt, was dazwischen liegt nicht. MIDI-Interface scheidet also aus. Wenn ich jetzt aber beim Sender das Programm erweitere und nach jedem printbin ein waitms 1000 schreibe, also so: printbin 01 waitms 1000 printbin 02 waitms 1000 .... dann bekomme ich alle Bytes übertragen und auch vollständig und korrekt angezeigt. Nun habe ich auf Empfängerseite seite ebenfalls ein waitms 1000 mit rein genommen: If Ischarwaiting() = 1 Then bRx = WaitKey() waitms 1000 end if Aber ohne Erfolg, bringt nichts, gleiches fehlerhaftes Verhalten. Hat jemand eine Idee was ursächlich sein könnte für das Problem ? Timing, Baud, Quarz, Fuse Bits (Divide by 8 is disabled, CLOCK Output disabled und 001111 Ext. Cyrstal Osc gesetzt) ? Habe sowohl 7,372800 MHz als 8 MHz Quarze versucht mit dem identischen Ergebnis. Was mir noch aufgefallen ist: wenn ich Config Serialin = Buffered , Size = 20 setze, dann geht auch nichts. Und im Moment habe ich keine Idee wo ich noch weiter suchen oder schrauben kann... Grüße, dmun
die Unart buffered laufen lassen und ischarwaiting kann sich beißen ... hatt ich jedenfalls mal. also weitms einfügen ist generell Müll. Der Controller macht dann einfach garnichts. Also was die Behandlung der UART in Bscom angeht kann ich nur empfehlen die Highlevelbefehle von Bascom zu meiden. Nen Sendepuffer und UTXC-Interrupt sowie URXC-Interrupt und Empfangspuffer sind nicht zu schwierig. Dann packst Du Deinen Empfang in den URXC-Interrupt und die Anzeige in die Mainloop
:
Bearbeitet durch User
So ganz klar ist das Problem noch nicht beschrieben: Sendet der PC die 8 Byte hintereinanderweg? Dann folgen die Bytes einander mit 0,32 ms Abstand. - So schnell kann man nicht gucken! - Aber wie siehst du die ersten 3 Byte? Mit Sendepause von 1000 ms hat man natürlich eine Sekunde Zeit jedes Byte zu sehen. Wofür soll denn die Pause beim Empfänger dienen?
Hallo, ja, de Bytes werden hinter einander gesendet und für die LEDs dann eine Zeit X ein und dann wieder ausgeschaltet. Somit kann man sehen was gesendet wird bzw. der Inhalt der Bytes. Beispiel: If Ischarwaiting() = 1 Then bRx = WaitKey() Out1 = bRx.0 Out2 = bRx.1 Out3 = bRx.2 Out4 = bRx.3 Out5 = bRx.4 Out6 = bRx.5 Out7 = bRx.6 Out8 = bRx.7 waitms 500 Out1 = 0 Out2 = 0 Out3 = 0 Out4 = 0 Out5 = 0 Out6 = 0 Out7 = 0 Out8 = 0 waitms 500 end if Es ist ganz egal ob es in Summe 8 Byte oder 4 Byte oder 12 Byte sind. das Muster ist immer identisch: die ersten drei Bytes und das Letzte Byte werden angezeigt und das ist im Moment nicht nachvollziehbar bzw. unlogisch. Grüße dmun
Probier das ganze mal komplett ohne Warten, mit einer LED pro Wert:
1 | If Ischarwaiting() = 1 Then |
2 | bRx = WaitKey() |
3 | Select Case bRx |
4 | Case 1: Out1 = 1 |
5 | Case 2: Out2 = 1 |
6 | Case 3: Out3 = 1 |
7 | Case 4: Out4 = 1 |
8 | Case 5: Out5 = 1 |
9 | Case 6: Out6 = 1 |
10 | Case 7: Out7 = 1 |
11 | Case 8: Out8 = 1 |
12 | End Select |
13 | End If |
Derek W. schrieb: > If Ischarwaiting() = 1 Then > bRx = WaitKey() > waitms 1000 > end if Wieso "WaitKey()", mit "If Ischarwaiting() = 1 Then" wird abgefragt ob ein Zeichen vom UART abgeholt werden kann. Derek W. schrieb: > ja, de Bytes werden hinter einander gesendet Alle Waits müssen raus, ansonsten kann der UART sowas nicht empfangen. Die empfangenen Bytes in einem Array speichern, z.B. mit 16 Stellen. Jacko schrieb: > Sendet der PC die 8 Byte hintereinanderweg? Dann folgen > die Bytes einander mit 0,32 ms Abstand. $hwstack = 64 Dim Empfang(16) as Byte Config Com1 = 31250 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 index = 1 Do If Ischarwaiting() = 1 Then ' Zeichen lesen Empfang(index) = Inkey() ' Byte aus dem Uart holen incr index if index = 17 then index = 1 End If Ein Wait von 100µsec wäre hier noch als Zählschritt für einen Anzeigetimer zulässig. Jetzt nacheinander die neuen Bytes aus dem Array holen und zum Beispiel für x mal 100µsec anzeigen. loop Besser wäre die Verwendung des CTC-Timers für die Anzeigezeiten. Gruß Alex
So, jetzt aber. Habe jetzt das Programm nach dem $baud... um folgende zwei Zeilen ergänzt $baud = 31250 Config Serialin = Buffered , Size = 10 Enable Interrupts und nun tut es wie es soll. Verstehe nicht wirklich wieso in diesem Fall noch Enable Interrupts gesetzt werden muss, aber so ist es. @Alex: die Waits sind nur drin gewesen um die Anzeige sichtbar zu machen und WaitKey oder InKey ist meiner Meinung nach dem IsCharWaiting() egal, würde es fehlen, dann würde die Sache anders aussehen. Aber jetzt geht alles wie es soll und ich kann das eigentliche Programm umsetzen. Danke und Grüße dmun
So ganz verstehe ich noch nicht, wie du alle 3 ersten Bytes sehen kannst. AVR-BASIC ist nicht so mein Metier, wahrscheinlich hat man da öfter solche Überraschungen... Es liegt vielleicht am Buffering, dass nicht so richtig klappt, wenn mehr als 3 Byte kommen. Letztendlich wird das letzte Byte angezeigt. OK. Andererseits - willst du MIDI machen?, oder MIDI-Bytes angucken? Wer MIDI für Musik nutzen will, kann DELAY und WAIT überhaupt nicht brauchen: Die Instrumente müssen SOFORT auf die Befehle reagieren, sonst spielt ein Instrument ein paar Sekunden später, als das andere... Wer MIDI parallel zum Musikablauf sichtbar machen will, muss mehr, als 8 LEDs nehmen! Selbst ein Bildschirm mit 25 Zeilen / 80 Zeichen ist in 0,64 s vollgeschrieben, wenn die Musik richtig abgeht... Aber ERKENNEN kann man in 0,64 s auch NICHT viel...
Derek W. schrieb: > Was mir noch aufgefallen ist: wenn ich Config Serialin = Buffered , Size > = 20 setze, dann geht auch nichts. Enable INTERRUPT setzt den Pufferbetrieb in Gang Kurt
:
Bearbeitet durch User
Derek W. schrieb: > Um ein Problem mit dem MIDI-Interface aus zu schliessen habe ich einen > zweiten µC genommen welcher auch senden kann (gleicher µC, gleicher > Quarz etc) und siehe da, wenn ich die einzelnen Bytes mittels printbin > 01, printbin 02 ... raus gebe habe ich den gleichen Effekt. Die ersten > drei Bytes und das letzte werden angezeigt, was dazwischen liegt nicht. > MIDI-Interface scheidet also aus. Hallo Derek, bei solchen Gelegenheiten bin ich froh, dass ich über ein Oszilloskop oder einen Logic-Aanlyzer verfügen kann. Das würde dir bei deiner Fehleranalyse sehr helfen. Du könntest auch die genauen zeitlichen Verläufe überwachen. Ich hatte damals nicht bedacht, dass meine Midi-Signale invertiert ausgegeben wurden. Der LA hatte meinen Fehler dann offenbart.
Wenn das erste und letzte Byte richtig angezeigt werden, ist Invertierung wohl nicht das Problem. Logic Analyzer und Scope würden auch nur zeigen, dass da kein passendes Konzept für MIDI-Übertragung vorliegt. Und LESEN muss man, was Logic Analyzer und Scope liefern, auch können... Also: Derek White (dmun) - was willst du eigentlich machen?
Guten Morgen, alles gut, Leute. Die LEDs dienten nur zur Anzeige der übertragenen Bytes um zu sehen was kommt und was nicht. Hat mit dem eigentlichen Programm nichts zu tun, welches auch zwischenzeitlich fast fertig ist und jetzt genau das macht, was erwartet wird. Grüße dmun
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.