Hallo, sorry, ich steh wirklich an. ich versuche mit Peter Fleury's UART Lib Midi Daten in einem Array zu speichern. mich interessieren Sysex cmds, mit denen ich einen status setze und NoteOn/Off, die dann je nach eben genannten statusbits weiterverarbeitet werden. irgendwie funktioniert mein code nicht. mittels debug-noteOn (eine idee von mir einen ton unterschiedlicher höhe in verschiedenen subprocedures auszugeben) hat auch nix gebracht. offenbar hakts bei der zusammenstellung der midi commandos. die idee: loop(unendlich) ist das zeichen ein sysex oder noteon oder noteoff speichere es in array an pos 0 ist das zeichen nur midi daten erhöhe index im array und speichere das zeichen im array ist das cmd ein noteon/off und sind alle datenbytes (=2) angekommen bearbeite noteon/off ist das cmd ein sysex und sind alle datenbytes (immer 6) da bearbeiter sysex endloop kann mir jemand helfen?? mein hauptprogramm: int main(void) { u08 c; // currently received Byte u08 byteCount; // number of Bytes received u08 cmdType; // type of the midi command u08 chan; // midi channel u08 mididata[5]={0};// midi command collector // ------------ INITIALISATION --------------------- hw_init(); c=NONE; byteCount = 0; cmdType=NONE; chan=NONE; for(;;) { // -------- CHECK IF UART 1 MIDI DATA IS INCOMMING ---------- c = (unsigned char)uart1_getc(); // c is int not byte! if ( c & UART_NO_DATA ) { ; } else { // interpret midi stuff if (c & 0x080) { // is it a command? if ((c & MIDI_SYSEX) || (c & MIDI_NOTEON) || (c & MIDI_NOTEOFF)) { byteCount=0; mididata[0] = c; } if (c & MIDI_EOX) { byteCount++; //do not handle midi EOX } } else { // normal midi data received byteCount++; mididata[byteCount] = c; // add incomming data } // if myByte - else } // if c & uartnodata - else // -------- INTERPRET MIDI STUFF --------------------------- if (byteCount==2) { if (mididata[0] & MIDI_NOTEON) handle_NOTE(mididata); if (mididata[0] & MIDI_NOTEOFF) handle_NOTE(mididata); /*debug if ((mididata[0] & MIDI_CHANNEL_MASK)==0) { // add 1 to channel and send it back uart1_putc(mididata[0]+1); uart1_putc(mididata[1]); uart1_putc(mididata[2]); }debug*/ } if (byteCount==5) { if (mididata[0] & MIDI_SYSEX) handle_SYSEX(mididata); } } // for // ------------- MAIN LOOP END ------------------------- } //void main
> c = (unsigned char)uart1_getc(); // c is int not byte! c ist nicht int. c ist bei dir ein u08, also wohl ein Byte. Allerdings liefert die Funktion uart1_getc() einen int. Warum wohl könnte das so sein? Das liegt daran, dass die Funktion auch die Möglichkeit haben möchte, eine Art 'Status' über den Returnwert zu liefern. Also einen Returnwert der kein Zeichen ist, sondern eine Aussage darüber treffen soll, wie der Empfang insgesamt abgelaufen ist. Da aber in einem empfangenen Byte grundsätzlich jedes der 256 möglichen BItmuster vorkommen kann, reicht ein Returnwert in der Größe eines Bytes nicht aus. Daher ist der Returnwert ein int. Nur leider wirfst du sofort diese zusätzliche Information weg :-) > if ( c & UART_NO_DATA ) { Daher kannst du das hier auch nicht auswerten. Die Information UART_NO_DATA ist durch das runtercasten auf einen unsigned char schon längst in die ewigen Bit-Jagdgründe eingegangen. Hast du dir denn die Doku auf http://homepage.hispeed.ch/peterfleury/group__pfleury__uart.html zu dieser Library nicht angesehen? Da steht bei uart_getc() (und uart1_getc()) eindeutig, wie sich die Return-Werte auf High-Byte und Low-byte verteilen.
ok, danke für den hinweis. ich hab den code jetzt geändert. blöder fehler. aber es scheint noch ein problem zu geben, nicht einmal der debug-ton wird gespielt... for(;;) { // -------- CHECK IF UART 1 MIDI DATA IS INCOMMING ---------- i = uart1_getc(); // attention: i is int not a byte! if ( i & UART_NO_DATA ) { ; } else { // interpret midi stuff if ( c & UART_FRAME_ERROR ) { /* Framing Error detected, i.e no stop bit detected */ } if ( c & UART_OVERRUN_ERROR ) { } if ( c & UART_BUFFER_OVERFLOW ) { } c = i & 0x00FF; // Mask-out high byte if (DEBUG) debug(c); // spielt einen midi ton in höhe "c" if (c & 0x080) { // is it a command? if ((c & MIDI_SYSEX) || (c & MIDI_NOTEON) || (c & MIDI_NOTEOFF)) { byteCount=0; mididata[0] = c; if (DEBUG) debug(48); } if (c & MIDI_EOX) { byteCount++; //do not handle midi EOX } } else { // normal midi data received byteCount++; mididata[byteCount] = c; // add incomming data } // if myByte - else } // if c & uartnodata - else // -------- INTERPRET MIDI STUFF --------------------------- if (byteCount==2) { if (mididata[0] & MIDI_NOTEON) handle_NOTE(mididata); if (mididata[0] & MIDI_NOTEOFF) handle_NOTE(mididata); } if (byteCount==5) { if (mididata[0] & MIDI_SYSEX) handle_SYSEX(mididata); } } // for
Funktioniert denn die Debugausgabe alleine? Möglicherweise ist es ja ein Hardwarefehler oder die Baudrate stimmt nicht oder die Fusebits sind falsch gesetzt oder...
Muss das so sein, dass hier else { // normal midi data received byteCount++; mididata[byteCount] = c; // add incomming data der increment des byteCount unter Kommentar steht. Laut deiner algorithmischen Zusammenfassung ganz am Anfang sollte der Inkrement eigentlich erfolgen. Weiter seh ich mir das nicht an. Code wie deiner, unlogisch und nicht konsequent eingerückt, offensichtliche Fehler (wie zb, dass c benutzt wird um Framing Errors festzustellen noch bevor c einen Wert bekommen hat), all das führt meistens immer nur zu einem: Code der nicht funktioniert und dem gewaltigen Schrei nach Hilfe. Mach erst mal deine Hausaufgaben.
hallo, hab das eingesehen und die state machine komplett überarbeitet. _asche über mein haupt_ das neue teil funktioniert jetzt folgendermaßen: loop get integer from uart if integer available remove conrtol stuff from data (=c) if c=midi command then if c = noteON or c =noteOFF state=waitfornote if c = sysex state=waitforvendorid else //data is not a command but simply midi data if c war noteOn or noteOFF hole noten state=waitforVelocity if c war ... und so weiter ist besser lesbar und funktionert (vor allem) fängt aboluten müll ab und erlaubt wirklich kontrolle über den aktuellen zustand. danke für eure geduld und hilfe! tolles forum. PS einrückungsfehler sind aufgrund copy-paste passiert - auch hier werde ich in zukunft wohl lieber attachments benutzen. lg MArtin
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.