Hallo, ich habe es mitlerweile geschafft ein Midisignal von einen Fader an den Computer zu senden. Mit angehängtem "Schaltplan". Über den ADC Eingang am Atmega8 habe ich den Fader abgefragt. (Ich weiß das das nicht alzu genau ist. Reicht aber denkne ich aus.) Nun will ich aber das Midisignal was ich von einem PC aus sende, am Mikrocotnroller empfangen und den gesendeten Midi Wert (Byte1 soll in eine Variabel, Byte 2 soll in eine Variable und Byte 3 soll auch in eine Variable (Byte 3 = 0...127) Jetzt bin ich auf der Suche nach einem Codeschnipsel zum Einlesen dieser Mididaten mit einem Atmega8 Vielen Dank Gruß Fabi
Fabian Müller schrieb: > Jetzt bin ich auf der Suche nach einem Codeschnipsel zum Einlesen dieser > Mididaten mit einem Atmega8 Das kommt mir ein wenig komisch vor. Auf der einen Seite hast du selber Code geschrieben, der eine Midi Nachricht versendet, musst also wissen, dass das jeweils erste Byte in der Sequenz, welches das Kommando beinhaltet (das 'Statusbyte') dadurch erkennbar ist, dass es das Bit 7 auf 1 gesetzt hat. Weiters musst du logischerweise mit der UART umgehen können, denn sonst könntest du ja nichts wegsenden. Auf der anderen Seite bist du aber nicht in der Lage, von der UART empfangene Bytes wegzuholen, anhand des gesetzten Bit 7 das Kommandobyte zu erkennen und dann ganz einfach die nächsten Bytes mitzuzählen um zu wissen, welches Datenbyte welche Bedeutung hat. Jetzt bin ich wirklich verwirrt. Kann es sein, dass dein "ich habe es geschafft, das und das zu programmieren' in Wirklichkeit eher ein 'Ich habe es geschafft, den Code XYZ zu kopieren ohne ihn verstehen zu müssen' darstellt? Wenn ja, dann lass dir gesagt sein, dass das nicht funktioniert. MIDI ist nichts anderes als die Behandlung der UART. Kannst du mit der UART umgehen, dann hast du die technische Hürde erst mal gemeistert. Und der Rest ist gerade bei Midi die Auswertung eines erst mal äusserst simplen Protokolls, dessen Abarbeitung damit beginnt, das man nachsieht ob das Bit 7 im gerade empfangenen Byte auf 1 ist oder nicht. Und der Rest ist: Eine Zählervariable, die laufend um 1 erhöht wird (und auf jeden Fall bei Erhalt eines Kommandobytes auf 0 zurück gesetzt wird), so dass dir der Zähler sagt, mit welchem Byte in der Sequenz du gerade zu tun hast. Summa summarum: alles andere als Raketentechnik und für jemanden der Senden kann kein Problem.
:
Bearbeitet durch User
Fabian Müller schrieb: > Über den ADC Eingang am Atmega8 habe ich den Fader abgefragt. (Ich weiß > das das nicht alzu genau ist. Reicht aber denkne ich aus.) Der dürfte allemal reichen. Gehe mal davon aus, dass du den Fader von Hand einstellt. Bereits bei einer Auflösung von 8-Bit wären somit 255 verschiedene Stufen erkennbar. Denke kaum dass du mit deiner hand 255 verschiedene Schritte einstellen kannst, von demher ist das kein Problem. Zu deinem Problem: Laut deiner Beschreibung hast du genau das bereits gemacht, was du machen wolltest. Du versendest ein Byte von einem uC zum PC. Nun willst du das ganze blos in die andere Richtung machen. Kannst mir kaum erzählen, dass du lediglich den halben UART eines uC's verstanden hast und somit nur fähig bist zu Senden aber nicht zum Empfangen?
Hallo zusammen, vielen Dank für eure Antworten ! Habe jetzt das UART-Tutorial durchgearbeitet. Und mein Problem besteht einfach darin, wie ich den UAR so umrechnen kann, dass am Ende in Variable 1 der Midikanal steht, in Variable 2, Der Befehl und in Variable 3 der Value. Wäre dankbar wenn mir da jemand helfen könnte. Es wird nämlich ein so ein tolles Projekt. (Lichtmischpult) Werde dann auch eine BAuanleitung dafür verfassen. Code vom senden:
1 | #include <avr/io.h> |
2 | #include <avr/io.h> |
3 | #define F_CPU 1000000
|
4 | #define BAUD 31250
|
5 | #include <util/setbaud.h> |
6 | void adc_init (void){ |
7 | |
8 | ADMUX = 0xC0; |
9 | |
10 | |
11 | ADCSRA = 0x80; |
12 | |
13 | |
14 | ADCSRA |= 0x05; //Vorteiler 32 |
15 | |
16 | |
17 | ADCSRA |= (1<<6); |
18 | |
19 | while(ADCSRA & (1<<6)){}; |
20 | |
21 | uint16_t ergebnis = 0; |
22 | |
23 | ergebnis = ADCL; |
24 | ergebnis += (ADCH<<8); |
25 | |
26 | }
|
27 | |
28 | uint16_t adc_read (uint8_t kanal){ |
29 | |
30 | static uint8_t init = 0; |
31 | |
32 | if(init==0){adc_init(); init++;} |
33 | |
34 | ADMUX &= (0xE0); |
35 | |
36 | ADMUX |= (kanal&(0x1F)); |
37 | |
38 | ADCSRA |= (1<<6); |
39 | |
40 | |
41 | |
42 | while(ADCSRA & (1<<6)){}; |
43 | |
44 | uint16_t ergebnis = 0; |
45 | |
46 | ergebnis = ADCL; |
47 | ergebnis += (ADCH<<8); |
48 | |
49 | return ergebnis; |
50 | |
51 | }
|
52 | |
53 | int main(void){ |
54 | uint16_t schweller; |
55 | uint16_t alterWert; |
56 | |
57 | uart_init(); |
58 | adc_init(); |
59 | |
60 | alterWert = adc_read( 2 ) / 8; |
61 | |
62 | while( 1 ) |
63 | {
|
64 | schweller = adc_read( 2 ) / 8; |
65 | if( schweller != alterWert ) |
66 | {
|
67 | alterWert = schweller; |
68 | |
69 | uart_putc(schweller); |
70 | }
|
71 | }
|
72 | }
|
73 | |
74 | void uart_init(void){ |
75 | UBRRH = UBRRH_VALUE; |
76 | UBRRL = UBRRL_VALUE; |
77 | |
78 | #if USE_2X
|
79 | UCSRA |= (1 << U2X); |
80 | #else
|
81 | UCSRA &= ~(1 << U2X); |
82 | #endif
|
83 | UCSRB |= (1<<TXEN); |
84 | UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); |
85 | }
|
86 | |
87 | void uart_putc(unsigned char c){ |
88 | while (!(UCSRA & (1<<UDRE))){} |
89 | UDR = c; |
90 | }
|
91 | |
92 | void Sendmidicontrol(void){ |
93 | uart_putc(176); |
94 | uart_putc(100); |
95 | uart_putc(100); |
96 | }
|
Vielen Dank Gruß Fabi
:
Bearbeitet durch User
Fabian Müller schrieb: > Habe jetzt das UART-Tutorial durchgearbeitet. Sieht nicht so aus, als ob du viel davon verstanden hättest. Und von Midi offenbar auch nicht. > Und mein Problem besteht einfach darin, wie ich den UAR so umrechnen > kann, dass am Ende in Variable 1 der Midikanal steht, in Variable 2, Der > Befehl und in Variable 3 der Value. Du musst nichts 'umrechnen'. Du musst einfach nur die Bytes, die an der UART ankommen, entsprechend verteilen. Dazu benutzt du am besten den Empfang per Interrupt (siehe jedes UART Tutorial), zusammen mit der Kenntnis das * im MIDI 'Befehls-byte' das Bit 7 gesetzt ist. Das gibt dir die Information, dass hier der nächste Befehl anfängt. * danach nur noch Datenbytes kommen, die kein gesetztes Bit 7 haben
1 | volatile uint8_t Command; |
2 | volatile uint8_t Byte1; |
3 | volatile uint8_t Byte2; |
4 | |
5 | ISR( USART_RXC_vect ) |
6 | {
|
7 | static uint8_t byteCounter = 0; |
8 | |
9 | uint8_t nextByte = UDR; |
10 | |
11 | if( nextByte & 0x80 ) { // ist Bit 7 gesetzt, wenn ja dann |
12 | // ist das hier ein Kommando, in MIDI
|
13 | // nennt sich das ein Statusbyte
|
14 | Command = nextByte; |
15 | byteCounter = 0; |
16 | }
|
17 | |
18 | else { // Nope, war kein Kommando |
19 | // muss also ein Datenbyte sein
|
20 | // Die meisten MIDI Datenbytes kommen
|
21 | // in Pärchen, so dass nach dem Statusbyte
|
22 | // noch 2 Bytes kommen.
|
23 | if( byteCounter == 0 ) |
24 | Byte1 = nextByte; |
25 | else
|
26 | Byte2 = nextByte; |
27 | |
28 | // nach jeweils 2 Datenbytes ist damit
|
29 | // 1 Kommando abgeschlossen
|
30 | // mach was damit
|
31 | // Fehlt das Statusbyte, dann gilt das zuletzt
|
32 | // empfangene Kommando als zu wiederholen (nur halt
|
33 | // mit anderen Daten)
|
34 | if( byteCounter == 1 ) |
35 | ProcessMIDI( Command, Byte1, Byte2 ); |
36 | |
37 | byteCounter = 1 - byteCounter; |
38 | }
|
39 | }
|
> Es wird nämlich ein so ein tolles Projekt. (Lichtmischpult) > Werde dann auch eine BAuanleitung dafür verfassen. Sieh lieber zu, dass du erst mal die Basics lernst. Bis du genügend Wissen hast um eine sinnvolle Bauanleitung zu verfassen, rinnt noch viel Wasser die Donau hinunter, wenn dir dieser Trivialcode (der zugegebenermassen nicht ganz vollständig ist) schon Schwierigkeiten macht. Du brauchst niemanden mit einer möglichen Bauanleitung ködern. Das wäre so, wie wenn ich anbieten würde eine leicht verständliche Anleitung für Herzoperationen zu schreiben, nur weil ich es mit Anleitung geschafft habe ein Pflaster unfallfrei abzunehmen - das wird nichts. > ich habe es mitlerweile geschafft ein Midisignal von einen Fader an den Computer zu senden. Mit dem Sendecode aus deinem letzte Post? Das wage ich zu bezweifeln. Du sendest den Messwert per UART, das stimmt. Aber MIDI ist das noch lange nicht. Die Funktion Sendmidicontrol wird überhaupt nicht aufgerufen und selbst wenn sie aufgerufen werden würde, sendet die immer den gleichen Wert (100), der nichts mit dem Ergebnis vom ADC zu tun hat. Man kann das natürlich ändern, was für jeden Programmierer trivial ist. Allerdings hast du das bisher anscheinend nicht gemacht.
:
Bearbeitet durch User
Hallo, erstmal vielen Dank für deine Bemühungen. Ja, ok. Was kannst du denn für ein Tutorial empfehlen was wirklich von null (oder von so "LED-blink-Wissen" :)) aufbaut?? Hab da jetzt schonmal gegoogelt auch was gefunden, aber nicht so recht passendes. Such was für C. Am liebsten wäre mir eine PDF (Soll ausdruckbar sein). Vielen Dank Gruß Fabi
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.