Arduino Forum

International => Deutsch => Topic started by: Ak-Nak47 on Mar 18, 2012, 10:29 pm

Title: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 18, 2012, 10:29 pm
Hallo Zusammen,

ich bin neu hier und habe mich hier im Forum etwas eingelesen und habe schnell gemerkt das hier viele Spezialisten unterwegs sind. Hat mich sehr gefreut zu sehen mit wie viel Leidenschaft hier Leute geholfen wird. Ich denke ich bin mit meiner Frage hier gut aufgehoben.

Ich will einen (später mehrere) Poti an die Analogen Pins anschließen und das Signal des Potis als Midi dann wieder ausgeben. Ich will mir einen kleinen eigenen Sequenzer bauen und benötige hier ein paar Potis. Ich will dann über USB die Musik Software Abelton ansteuern.

Ich bin auf Arduino gestossen und blutiger Anfänger, mit einigen wenigen Befehlen kann ich etwas anfanegn, aber das wars auch schon. Über die bereitgestellten examples konte ich ein wenig testen mit led´s und potis jedoch finde ich keinen vernünftigen Weg um ein Potisignal in ein Midi umzuwandeln und auch auszugeben, ich habe da keine chance.

Kann mir jemand bei meinem Problem behiflich sein?

Über jede hilfreiche Antwort freue ich mich.

Vielen Dank.

Grüße
Ak-NAK47
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 19, 2012, 07:26 am
Hilfreich wäre sicher erstmal ein MIDI-Shield, das Du bei diversen Händlern findest (ca 16 Euro). Damit hast Du dann schonmal die passenden MIDI-Schnittstellen. Außerdem sind diese dann per Optokoppler galvanisch von der restliche Hardware getrennt.
Es gibt auch eine MIDI-Lib für den Arduino mit dem Du z.b. Noten auf verschiedenen Kanälen erzeugen kannst.
Der erste Schritt wäre sicher erstmal das Auslesen der Potis. Dazu gibt es ein einfaches Beispiel:
http://arduino.cc/en/Tutorial/AnalogReadSerial (http://arduino.cc/en/Tutorial/AnalogReadSerial)
Die Midi-Lib gibt es hier:
http://arduino.cc/playground/Main/MIDILibrary (http://arduino.cc/playground/Main/MIDILibrary)
Ansonsten finden sich im Palyground diverse MIDI Projekte:
http://arduino.cc/playground/Main/InterfacingWithHardware#Output (http://arduino.cc/playground/Main/InterfacingWithHardware#Output)
Ich hoffe das hilft Dir erstmal weiter.
Mario.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 19, 2012, 04:41 pm
Hallo,

was möchtest Du denn mit dem(den) Poti(s) überhaupt eingeben? Die Note(n)?
Da in MIDI 128 Noten sein können, kannst Du als erstes die Eingabe am Analogpin von 0-1023 auf 0-127 umsetzen:
Code: [Select]
byte note = map(analogRead(A0), 0 , 1023, 0, 127);

Dann kannst Du die Note mit der MIDI-library verwenden:
Code: [Select]
sendNoteOn (byte note, byte velocity, byte channel)
mit note = 0-127; velocity = 0-127 und channel = 1-16

oder Du machst es gleich selbst:
Code: [Select]
Serial.write(144);        // Note On auf Kanal 1 - 159 wäre dann Kanal 16
Serial.write(note);       // Die Note vom Poti
Serial.write(velocity);   // Attack von 0-127, wobei 0 als Note Off interpretiert wird


Bei Omni kannst Du das ganze in eine Schleife packen:
Code: [Select]
for (byte i = 0; i < 16; i++)  // for-Schleife von i = 0 bis i = 15
{
 Serial.write(144 + i);
 Serial.write(note);
 Serial.write(velocity);
}


Die MIDI-library kann übrigens nicht auf Omni senden! Da müsstest Du wieder eine Schleife verwenden.
Beim Poti reichen 470 Ohm um mit den 5V vom Arduino 0-1023 am anlogen Eingang "lesen" zu können.

Übersicht der MIDI messages:
http://www.midi.org/techspecs/midimessages.php (http://www.midi.org/techspecs/midimessages.php)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 19, 2012, 06:27 pm
Hallo,

ersteinmal danke für die Antworten.
Die 1. Antwort muss ich erstmal checken und durchlesen bzw. einlesen.

@mime

Also die Potis will ich später individuell in der Software zuweisen. Dabei will ich mit den Potis Lautstärken regeln, oder links und rechts kontrollieren, oder Effekte rauf- und runterschrauben. Grob gesagt regeln. :-)

Wie muss ich das mit den Codes verstehen? Ich lese ersteinmal den Wert aus dem Poti aus (gibt es ja scho ein exaple in der Software wenn ich das richtig gesehen habe und dann benutze ich einen deiner Code Beispiele indem ich die einfach i den Code einbinde? Ist das richtig so? Es tut mir leid ich bin da wirklich neu in diesem Gebiet, doch wilig die Materie zu verstehen und zu lernen. Brauche da aber wie im 1. Post erwähnt ein wenig support.

Wäre nett weitere tips zu lesen.

Viele Grüße
Ak-Nak47
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 19, 2012, 07:08 pm
Ja, Du kannst das kopieren.
Mal kurz im Telegramm-Stil:
Poti auslesen:
Code: [Select]
wert = analogRead(A0); // mit den Pins A0 - A5
http://arduino.cc/en/Reference/AnalogRead (http://arduino.cc/en/Reference/AnalogRead)
Damit erhälst Du einen Wert zw. 0 und 1023 (10 Bit-Analog-Digital-Wandler)
Diesen Wertebereich kannst Du mit dem map-Befehl verändern. Sagen wir Du willst die Lautstärke in Prozent von Null bis 100:
Code: [Select]
lautstaerke = map(wert, 0, 1023, 0, 100);
http://arduino.cc/en/Reference/Map

Du kannst auch beides zusammenfassen:
Code: [Select]
lautstaerke = map(analogRead(A0), 0, 1023, 0, 100);

Nicht vergessen in "void setup()" die Variablen zu deklarieren. Z.B.:
Code: [Select]
byte lautstarke;
http://arduino.cc/en/Reference/Byte (http://arduino.cc/en/Reference/Byte)

Wenn Du das dann via USB an Ableton senden willst:
in "void setup()"
Code: [Select]
Serial.begin(38400);
und im "loop" z.B.
Code: [Select]
Serial.write(lautstaerke);
http://arduino.cc/en/Reference/Serial
(http://arduino.cc/en/Reference/Serial)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 19, 2012, 07:41 pm
Also jetzt nicht lachen. Das müsste dann im Programm so aussehen:
Oder habe ich mich jetzt voll verzettelt?

Code: [Select]

wert = analogRead(A0); // mit den Pins A0 - A5

lautstaerke = map(wert, 0, 1023, 0, 100);


void setup(byte lautstarke)

Serial.begin(38400);

void loop()
Serial.write(lautstaerke);
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: sth77 on Mar 19, 2012, 08:40 pm
Es geht in die richtige Richtung. ;)
Du hast aber noch nicht verinnerlicht, wozu die setup- und die loop-Funktion sind. So gehört die Abfrage des Potiwertes natürlich in die loop, der Wert soll ja dauernd abgefragt, gewandelt und übertragen werden.
Die Syntax ist natürlich auch wichtig, Anweisungen in diesen beiden Funktionen müssen in geschweiften Klammern stehen.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 19, 2012, 08:42 pm
Nicht ganz.
1. Bibliotheken einbinden
2. Variablen und ev. Pins deklarieren
3. setup
4. loop

also so rum:
Code: [Select]

byte lautstaerke;  // Variable für die Lautstärke

void setup() {
 pinMode(A0, INPUT);  // Pin als Eingang deklarieren
 Serial.begin(38400);
}

void loop() {
 lautstaerke = map(analogRead(A0), 0, 1023, 0, 100);
 Serial.print("Lautst");
 Serial.write(227);  // Serial.print(byte(227)); geht auch
 Serial.print("rke: ");
 Serial.print(lautstaerke);
 Serial.println(" [%]"); // println erzeugt nach der Ausgabe eine neue Zeile
}


Das Ergebnis kannst Du Dir dann im seriellen Monitor der IDE anschauen.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 19, 2012, 08:58 pm
Ich würde Dir empfehlen erstmal mit den Grundlagen anzufangen. Dazu ist die Arduino-Webseite schon recht informativ. http://arduino.cc/en/Tutorial/HomePage (http://arduino.cc/en/Tutorial/HomePage)
Es finden sich auch im Netz recht viele Tutorials, teilweise auch in deutscher Sprache.

Die Arduino-Umgebung abstrahiert schon einen sehr großen Teil der eigentlich notwendigen Schritte, um ein Programm auf einen µController zu bekommen. Ganz ohne Programmierung kommt man aber nicht aus.

1.) C/C++ ist die Programmiersprache, mit der Dein Arduino programmiert wird. Die Sprache ist nicht speziell für den Arduino entwickelt, vielmehr handelt es sich um eine weit verbreitete und recht systemnahe Sprache. Unabhängig vom Arduino finden sich recht viele Tutorials im Netz dazu. Diese Grundlagen sind wichtig, damit Du auch mit dem Arduino voran kommst.

2) Grundlegende Programmier-Konzepte solltest Du Dir aneignen, wenn nicht schon vorhanden. Also Schleifen, Vergleiche (Bedingte Ausführung von Programmteilen), Variablen, Datentypen, Funktionen usw.

3) Ein wenig Elektrotechnik ist auch wichtig. Hier reicht am Anfang aber erstmal das Schulwissen aus dem Physikunterricht (Widerstände, Reihenschaltung, Parallelschaltung, Ohmsches Gesetzt). Der Rest kommt nach und nach mit den einzelnen Projekten.

Das Forum hier ist auf jeden Fall immer ein guter Anlaufpunkt, wenn Du nicht weiter kommst. Je genauer Du beschreiben kannst was Du machen willst und was genau nicht klappt, um so besser kann Dir geholfen werden. Und das Beispiel vom "mime" sollte Dir auch erstmal weiterhelfen.

Viel Erfolg, Geduld und nur nicht gleich aufgeben :-)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 19, 2012, 09:38 pm
Vielen Dank für euren Support. Wirklich Danke.

Ja ich muss mich hier noch kräftig reinarbeiten, das ist nicht einfach wie ich sehe und merke aber mit Ehrgeiz ist das machbar. Im Moment bin ich noch sehr motiviert bei der Sache.

@mime

Danke, ich sehe da habe ich noch einiges vergessen, die geschweiften klammern hatte ich zu spät bemerkt das ich diese vergessen hatte. Ich werde den Code auf jeden Fall ausprobieren.

@sth77

Wie gesagt ich habe hier gerade mal eine LED über Arduino zum blinken gebracht, das war es auch schon. :-) Aber ich taste mich ran.

@mkl0815

Danke für die Tipps und die Links, ich lese mich da rein. Das Problem ist das sehr viele Tutorials und Beispiele für einen Anfänger wie mich sehr schwer zu verstehen sind. Mir fehlt da einiges an Know-How. Aber mit der Zeit wird das auch mehr werden vom Wissen her. :) Hoffe ich jetzt einfach mal.


Aber jetzt wollte ich den Code auf mein Arduino uploaden und es kommt folgender Fehler:

Binary sketch size: 4548 bytes (of a 30720 byte maximum)
avrdude: stk500_getsync(): not in sync: resp=0x00
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

Keine Ahnung was das jetzt wieder ist, eigentlich hat es immer funktioniert. Ich habe ein Arduino Duemilanove mit Atmega 328 und nen FDTI Chip.

Was mache ich hier falsch?

Viele Grüße
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 19, 2012, 09:40 pm
Okay der Fehler hat sich erledigt, hatte den falschen Port gewählt. Muss den irgendwie verstellt haben...! Ich berichte neues wenn ich den Code geteste habe und werde dazu einige Fragen stellen wenn ich da nicht ganz durchsteige.  :-)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 19, 2012, 10:25 pm
Also den Code habe ich wie folgt:

Code: [Select]
byte lautstaerke;  // Variable für die Lautstärke

void setup() {
 pinMode(A0, INPUT);  // Pin als Eingang deklarieren
 Serial.begin(38400);
}

void loop() {
 lautstaerke = map(analogRead(A0), 0, 1023, 0, 100);
 Serial.print("Lautst");
 Serial.write(227);  // Serial.print(byte(227)); geht auch
 Serial.print("rke: ");
 Serial.print(lautstaerke);
 Serial.println(" [%]"); // println erzeugt nach der Ausgabe eine neue Zeile
}


Erkennen tut er es als MIDI jetzt weist er aber wahrlos irgendetwas im Abelton zu. Ich würde den jetzt gerne so konfigurieren: Serial.write(velocity);

Ich würde den Code jetzt fogendermaßen schreiben:

Code: [Select]
byte velocity;  // Variable für die Lautstärke

void setup() {
 pinMode(A0, INPUT);  // Pin als Eingang deklarieren
 Serial.begin(38400);
}

void loop() {
 velocity = map(analogRead(A0), 0, 1023, 0, 100);
 Serial.print("Lautst");
 Serial.write(velocity);  // Serial.print(byte(227)); geht auch
 Serial.print("rke: ");
 Serial.print(velocity);
 Serial.println(" [%]"); // println erzeugt nach der Ausgabe eine neue Zeile
}
}


doch wie weise ich nun einen Attack von 0-127 im code zu?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 20, 2012, 03:39 am

Erkennen tut er es als MIDI jetzt weist er aber wahrlos irgendetwas im Ableton zu. Ich würde den jetzt gerne so konfigurieren: Serial.write(velocity);

Ich merke, Du hast den Code nicht verstanden ;)
Bevor Du versuchst Ableton Live zu steuern, solltest Du Dir wirklich erstmal einige Grundlagen aneignen.

Code: [Select]
Serial.write(227);  // Serial.print(byte(227)); geht auch
Diese Zeile gibt ein "ä" im seriellen Monitor der IDE aus. Da man Umlaute nicht direkt ausgeben kann, habe ich das Wort "Lautstärke" in drei Teile zerlegen müssen - diese Ausgabe war nur für den seriellen Monitor gedacht, nicht für Ableton Live, deshalb kann das Programm damit nicht viel anfangen ;)

Da die velocity rein zu quetschen macht also keinen Sinn.
Eine Variable kannst Du so zuweisen:
Code: [Select]
byte velocity = 100;
Byte reicht hier, da velocity nur Werte zw. 0 und 127 haben kann, für größere (oder negative), ganze Zahlen muss man dann int oder long benutzen.
Schau Dir mal die verschiedenen Variablentypen wie byte, int , long... an.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 20, 2012, 03:54 pm
Hier hast Du zwei Beispiele die mit Ableton Live funktionieren. Da ich nicht weiss ob Du mehr als ein Poti hast, verwenden sie nur eines. Ich hoffe die Kommentare helfen Dir beim Verstehen der Programme.
Im ersten Beispiel kannst Du die Note mit dem Poti variieren:
Code: [Select]
/* Variablendeklaration */
byte note;  // Variable für die Note deklarieren
byte velocity = 127;  // Variable für Attack deklarieren und ihr den Wert 127 zuweisen

/* Setup wird nur einmal, nach dem Starten des Mikrokontrollers, ausgeführt */
void setup() {
  pinMode(A0, INPUT);   // Pin A0 als Eingang deklarieren
  Serial.begin(38400);  // Serielle Schnittstelle mit 38400 Baud starten
  // 38400 Baud weil diese am nächsten an 31250 Baud, der MIDI-Geschwindigkeit sind
}

/* Loop wird solange immer wieder ausgeführt wie der Mikrokontroller Strom hat */
void loop() {
  note = map(analogRead(A0), 0, 1023, 0, 127);
  // Note vom analogen Eingang 0 einlesen und den Wertebereich auf 0-127 'umbiegen'

/* Note On */
  Serial.write(144);       // 'note on' auf Kanal 1 senden
  Serial.write(note);      // Note senden
  Serial.write(velocity);  // Attack senden

  delay(500);              // 500 ms warten

/* Note Off */
  Serial.write(128);       // 'note off' auf Kanal 1 senden
  Serial.write(note);      // Note senden
  Serial.write(velocity);  // Attack senden
}


Und im zweiten velocity:
Code: [Select]
/* Variablendeklaration */
byte note = 69;  // Variable für die Note deklarieren und ihr den Wert 69 zuweisen
// 69 = A3; Kammerton A mit 440 Hz
byte velocity;  // Variable für Attack deklarieren

void setup() {
  pinMode(A0, INPUT);
  Serial.begin(38400);
}

void loop() {
  velocity = map(analogRead(A0), 0, 1023, 0, 127);

/* Note On */
  Serial.write(144);       // 'note on' auf Kanal 1 senden
  Serial.write(note);      // Note A3 senden
  Serial.write(velocity);  // Attack senden

  delay(500);

/* Note Off */
  Serial.write(128);       // 'note off' auf Kanal 1 senden
  Serial.write(note);      // Note A3 senden
  Serial.write(velocity);  // Attack senden
}
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 20, 2012, 06:44 pm
Hi mime,

also verstanden habe ich nicht alles aber zumindest verstehe ich jetzt das void setuo und void loop, das ist schon mal sehr hilfreich. :-)

Habe das auch gleich mal probiert und komm da irgendwie nicht ganz dahinter. Also mit einem Poti reicht mir das mal zum probieren.

Jetzt nochmal zum Code. Die Kommentare helfen mir auch ganz gut beim Weg zum "Verstehen". Du sendest sozusagen immer die Note mit. Das erkennt Abelton auf jeden Fall und wenn ich an dem Poti drehe ändert er die Note auch.

Wenn ich aber den Poti im Abelton z.B. einem Fader zuweisen will passiert nichts. Die Frage die sich mir jetzt stellt ist: Muss ich denn diese 69 Note mitsenden? Und was genau hat es mit der 69 auf sich?

Vielen Dank für deine Hilfe. Kann mich da gar nicht oft genug bedanken. Find es klasse das es Leute gibt die einem so sehr weiterhelfen.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: sth77 on Mar 20, 2012, 08:20 pm
Als Nichtmusiker knn ich dir nur empfehlen, dich strikt an das MIDI-Protokoll zu halten:
http://de.wikipedia.org/wiki/Musical_Instrument_Digital_Interface
Dort sollte alles erklärt sein, bei der Umsetzung auf dem Arduino hilft man dir natürlich weiterhin gern.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 20, 2012, 08:54 pm
Also ich glaube mit dem Code funktioniert mein Vorhaben nicht so wie ich mir das dachte. Also ich weiss jetzt nicht ob ich mit dem was ich jetzt vorschlage richtig liege.

Also ich will den Poti benutzen um im Abelton Fader regeln zu können z.B. von Lautstärke 0 - 100. Oder einen Effektpegel regulieren. Diesen Poti will ich i Abelton frei zuweisen können.

Müsste ich dazu nicht den Wert des Potis auslesen und diesen Wert sozusagen wieder al Midi Signal über USB ans Abelton senden?

Im Grunde sind die Codes von dir mim schon der richtige Ansatz aber wenn ich den Code richtig verstehe schickt er "nur" einen Ton ans Abelton, diesen Ton kann ich dann mittels Poti verändern. Oder?

Jedoch sollte ich doch mit dem vom Analogen Pin ausgelesenen Wert (vom Poti) nehmen und als Midi Signal so weiter geben?

Ist dieser Ansatz / Gedanke richtig?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 20, 2012, 09:44 pm

Also ich glaube mit dem Code funktioniert mein Vorhaben nicht so wie ich mir das dachte.

Das sind auch nur zwei Beispiele wie man ein Poti abfragt und eine MIDI-Nachricht senden kann.


Müsste ich dazu nicht den Wert des Potis auslesen und diesen Wert sozusagen wieder al Midi Signal über USB ans Abelton senden?

Richtig

Im Grunde sind die Codes von dir mim schon der richtige Ansatz aber wenn ich den Code richtig verstehe schickt er "nur" einen Ton ans Abelton, diesen Ton kann ich dann mittels Poti verändern. Oder?

Richtig

Jedoch sollte ich doch mit dem vom Analogen Pin ausgelesenen Wert (vom Poti) nehmen und als Midi Signal so weiter geben?
Ist dieser Ansatz / Gedanke richtig?

Ja, ist er.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 20, 2012, 09:56 pm
Ich werd das mal soooooo zusammenbasteln wie ich meine das es hinhauen könnte. :-) IIch würde mich freuen wenn du da dann drüber schauen könntest.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 20, 2012, 10:49 pm
Code: [Select]
const int analogInPin = A0; 

int sensorValue = 0;       
int outputValue = 0;

void setup() {
  Serial.begin(38400);
}

void loop() {
  // auslesen des Wertes aus de Analogen Eingan
  sensorValue = analogRead(INPUT);
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  analogWrite(analogInPin, outputValue);
 
  Serial.write(outputValue);
 
  delay(10);
 
}


Habe mich jetzt an den vorgegebenen Examples aus der Arduino Software und den Beispielen hier etwas zusammengeschustert. Bin mir noch nicht im klaren darüber was ich gemacht habe, aber kann man den Ansatz als "geht in die richtige Richtung" bezeichnen oder eher als "total daneben" ?

Viele Grüße
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 21, 2012, 08:43 am

Habe mich jetzt an den vorgegebenen Examples aus der Arduino Software und den Beispielen hier etwas zusammengeschustert.

Zusammengeschustert ist das richtige Wort dafür.

Bin mir noch nicht im klaren darüber was ich gemacht habe,

Das sieht man, wenn Du Dir nicht die Mühe machst die Sprache zu lernen und die Funktion der einzelnen Befehle zu lernen, wirst Du nicht weit kommen. Du hast ein Beispiel mit einer LED benutzt, dessen Helligkeit über einen Sensor (Poti) geregelt wird, richtig?
Die Helligkeit einer LED hat aber nun so gar nichts mit dem MIDI-Protokoll zu tun.

Du kannst nicht irgend etwas senden und erwarten das Ableton Live das als MIDI versteht, wenn Du Dich nicht an das MIDI-Protokoll hältst. Das habe ich Dir weiter oben schon verlinkt.
Im Grunde ist es recht einfach:
Eine MIDI-Nachricht besteht aus ein bis drei Bytes.
Beispiele für ein Byte lange Kommandos sind z.B.
clock = 248
start = 250
stop = 252
Beispiele für drei Byte lange Kommandos hatten wir ja schon, z.B. 'note on' und 'note off'.
Nehmen wir als Beispiel 'note on':
Im ersten Byte wird der Befehl 'note on' und der Kanal, für den dies gilt, gesendet:
'note on' ist als 1001 definiert (diese vier Bit heissen im MIDI-Jargon 'first nibble' oder 'most-significant nibble'), jetzt hängen wir noch vier Bit für den Kanal dran ('least-significant  nibble'). Nehmen wir Kanal 11, da wir bei Null mit dem Zählen beginnen, müssen wir tatsächlich 10 und nicht 11 verwenden. 10 in binärer Schreibweise ist 1010. Damit erhalten wir (binär) für das Kommando 'note on' auf Kanal 11: 10011010 (dezimal 154).

Das zweite Byte in diesem Kommando ist die Note. MIDI kennt 128 Noten (0 - 127); das der Kammerton A die MIDI Notennummer 69 hat wissen wir ja schon.

Das dritte Byte ist 'velocity', der Anschlag. Dieser kann Werte von 0-127 annehmen. Da wir richtig in die (eine) Taste hauen wollen, nehmen wir 127.

Somit haben wir jetzt die drei Bytes für das komplette Kommando "Note A3 auf Kanal 11 mit vollem Anschlag AN":
154 69 127
In Arduino wäre das dann:
Code: [Select]
Serial.write(154);
Serial.write(69);
Serial.write(127);


Und genauso wird für alle anderen Befehle, wie 'polyphonic aftertouch', 'control change', 'pitch wheel change', und wie sie alle heissen, verfahren.
Die Lautstärke z.B. versteckt sich hinter 'control change' ('first nibble' 1011). "Ändere etwas auf Kanal 11" wäre also 1011 + 1010 = 10111010 (dezimal 186) [Achtung, das ist natürlich keine Addition.]
Was ändere ich? Da schaue ich wieder bei midi.org und sehe: 'channel volume' ist definiert als 00000111 (dezimal 7). Worauf ändere ich die Lautstärke? Auf das, was der Arduino vom Poti einliest (mögliche Werte wieder 0-127).
Code: [Select]
Serial.write(186);              // control change auf Kanal 11
Serial.write(7);                // Ändere die Lautstärke...
Serial.write(meinWertVomPoti);  // ... auf meinWertVomPoti


Auf midi.org steht das alles in Binär, Hexadezimal und Dezimal; damit brauchst Du Dich also noch nicht einmal groß rumschlagen, nachlesen reicht. Ich wollte es, wegen dem grundsätzlichen Verständnis, aber einmal erklären.
Eigentlich ist das MIDI-Protokoll total simpel. Wenn Dir das, auf diese Art, zu kompliziert ist, würde ich Dir die Verwendung der MIDI-Bibliothek empfehlen, diese hat mkl0815 freundlicherweise bereits verlinkt.
Da vereinfacht sich die Sache zu 'sendControlChange (byte ControlNumber, byte ControlValue, byte Channel)'.
Für obiges Beispiel also
Code: [Select]
sendControlChange(7, meinWertVomPoti, 11);
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 21, 2012, 10:28 am
In Deinem Programm stecken, unabhängig von der MIDI-Kommunikation noch diverse Fehler. Ich bezweifle das Du das Programm überhaupt ohne Fehler compilieren kannst.
Hast Du das mal probiert? Am besten lernt man immer noch, wenn man versucht die Fehler selbst zu finden und zu beheben. Erst wenn man damit nicht weiter kommt, sollte man fragen.
Zu Deinem Programm:
Code: [Select]

  // auslesen des Wertes aus de Analogen Eingang
  sensorValue = analogRead(INPUT);

Was ist INPUT, das ist nirgendwo definiert. Hier sollte sicher "analogInPin" stehen.
Code: [Select]
 
analogWrite(analogInPin, outputValue);

Warum willst Du nochmal einen Wert auf dem Eingangspin ausgeben?  Das macht keinen Sinn. Abgesehen davon ist "analogWrite()" eine Funktion die nur für PWM-Pins Sinn macht, da Du damit das Tast-Verhältnis des PWM-Signals setzen kannst.

Der Rest ist erstmal syntaktisch korrekt, an der Semantik musst Du aber definitiv noch arbeiten.
Wenn Du es geschafft hast, die korrekten MIDI-Daten an Deinen Rechner zu senden, solltest Du das sicher nicht alle 10ms machen, sondern nur dann, wenn sich der Wert auch geändert hat. Ziel sollte es immer sein nur so viele Daten zu übertragen, wie nötig, nicht so viele wie möglich.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: sth77 on Mar 21, 2012, 11:27 am
Wie gesagt, du musst dir überlegen, wie die MIDI-Kommunikation eigentlich funktioniert, zumindest den groben Rahmen. Wenn die Erläuterungen von mime (zumindest halbwegs) verstanden hast, du aber eine leichtere, eingängige Lösung suchst, dann kannst du die bereits verlinkte MIDI-Bibliothek verwenden. Soweit ich das beurteilen kann, lässt diese vom Funktionsumfang keine Wünsche übrig.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 21, 2012, 02:42 pm

In Deinem Programm stecken, unabhängig von der MIDI-Kommunikation noch diverse Fehler. Ich bezweifle das Du das Programm überhaupt ohne Fehler compilieren kannst.


Doch es läßt sich compilieren und es sendet auch Daten an den Computer. Da er sich aber offenbar überhaupt nicht mit dem MIDI-Protokoll beschäftigt hat, sendet sein Programm quer durch allerlei MIDI-Kommandos und Kanäle irgendetwas, manchmal auch für MIDI-Geräte/Programme unverständlichen Kram. Das hat mich auch erstaunt.

14:31:31.105   To MIDI Monitor (Untitled)   Active Sense      
14:31:31.115   To MIDI Monitor (Untitled)   Active Sense      
14:31:31.125   To MIDI Monitor (Untitled)   Stop      
14:31:31.136   To MIDI Monitor (Untitled)   Continue      
14:31:31.145   To MIDI Monitor (Untitled)   Start      
14:31:31.156   To MIDI Monitor (Untitled)   Invalid      1 bytes
14:31:31.167   To MIDI Monitor (Untitled)   Invalid      1 bytes
14:31:31.177   To MIDI Monitor (Untitled)   Clock      
14:31:31.187   To MIDI Monitor (Untitled)   Clock      
14:31:31.197   To MIDI Monitor (Untitled)   Invalid      1 bytes
14:31:31.208   To MIDI Monitor (Untitled)   Clock      
14:31:31.217   To MIDI Monitor (Untitled)   Invalid      1 bytes
14:31:31.228   To MIDI Monitor (Untitled)   Tune Request      
14:31:31.248   To MIDI Monitor (Untitled)   Invalid      1 bytes
14:31:31.270   To MIDI Monitor (Untitled)   Invalid      2 bytes
14:31:31.290   To MIDI Monitor (Untitled)   Invalid      1 bytes
14:31:31.352   To MIDI Monitor (Untitled)   SysEx      1 bytes
14:31:31.659   To MIDI Monitor (Untitled)   Note Off   13   122   0



Soweit ich das beurteilen kann, lässt diese vom Funktionsumfang keine Wünsche übrig.

Man kann Omni wohl nur empfangen, was ihm nicht viel nützen wird, da er ja senden will.
(Omni heisst nichts anderes als "auf allen 16 Kanälen", statt nur auf einem Kanal)
Aber diese kleine Restriktion ließe sich leicht mit einer For-Schleife, die einmal durch alle 16 Kanäle rattert, umgehen.
Mir persönlich ist die "mach es selbst"-Methode lieber, da weiss man was das Programm tatsächlich macht (und was man selbst macht). Aber das ist vielleicht Geschmackssache. So oder so muß man sich mit dem MIDI-Protokoll beschäftigen, wenn ich nicht weiss, was ich tue, hilft mir auch keine library weiter.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 21, 2012, 03:01 pm
Es Funktioniert durch Zufall, weil INPUT in der Arduino.h der IDE definiert wird. Ansonsten würde es Fehler geben beim Compilieren.
Allerdings mit 0x0, also dem Wert 0.
Es wird also ein analogRead(0) aufgerufen. Das bringt aber nix, denn "A0" ist mit 14 definiert.
Damit wird also nicht das Poti ausgelesen.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 21, 2012, 03:17 pm
Frag mich nicht warum es überhaupt geht, wundert mich auch sehr. Aber ich habe es ja ausprobiert, siehe oben, es sendet halt irgendetwas und das Ergebnis ändert sich auch, wenn ich am Poti drehe. Nur halt völlig wahl- und sinnlos. Schon erstaunlich.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 21, 2012, 03:56 pm
*rofl*  :smiley-eek:
Code: [Select]

int analogRead(uint8_t pin)
{
        uint8_t low, high;

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
        if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
        if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#else
        if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

Das ist aus /hardware/arduino/cores/arduino/wiring_analog.c (IDE Libs)
Es funktioniert, weil für den Arduino der A0 Eingang auf Pin 14 gemappt wird. Da wir einen ATmega328 (bzw.168) haben, gibt es nur digitale 13 Pins und die IDE verwendet Pin14 als ersten Analogen. Daher funktioniert das Programm auch, denn da das INPUT als 0x0 definiert ist und das als Parameter übergeben wird, wird tatsächlich der erste analoge Eingang ausgewertet.
Würde man korrekterweise die 14 (oder A0) übergeben, würde aus dann genau der folgende Code ausgeführt:
Code: [Select]
if (pin >= 14) pin -= 14; // allow for channel or pin numbers

Und es würde auch wieder "0" heraus kommen.
Wir haben es also mit einem "falschen Fehler" zu tun.  :)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 21, 2012, 06:28 pm
Ich seh schon ich will mit dem Kopf durch die Wand.  :) Doch der Beton ist härter als ich dachte. Das ist halt absolutes Neuland für mich. Hauptberuflich bin ich Konstrukteur i Sondermaschinenbau und das hier soll der ausgleich zu täglichen Mechanik sein.

Ich will euch auf keinen Fall verrückt machen, ich probiere jetzt einfach ma weiter und lass euch meine Ergebnisse hier auf dem Board, wäre nett wenn ihr sie weiter ausdiskutiert.   :smiley-eek-blue:
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 21, 2012, 07:39 pm
...scheiße ich muss passen, ich krieg das irgendwie nicht hin. weiss gar net wo ich anfangen soll...! *arghhh*
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 21, 2012, 08:57 pm
Also wieder ein wenig geschuster und es tut auf jedenfall das was es tun sollte im abelton.

Code: [Select]
void setup()
{               
Serial.begin(38400);
}

int THRESHOLD=2;
int maxPin;
int knobFunction(const int pin, int divisor)
{
  static int prevRead[6] = {0, 0, 0, 0, 0, 0};   
  int output = analogRead(pin)/4;    
  if (abs(output - prevRead[0])  >= THRESHOLD)
    {prevRead[pin] = output;}
  else
    {output = prevRead[pin];}
  return output/2;
}

void loop () {
  static int lastmaxVal = 0;
  int maxVal = knobFunction(0, 4);
  if(maxVal != lastmaxVal)
  {
    Serial.println(maxVal);
    lastmaxVal = maxVal;
   
Serial.write(186);              // control change auf Kanal 11
Serial.write(7);                // Ändere die Lautstärke...
Serial.write(maxVal);       // ... auf meinWertVomPoti
  }



Jetzt habe ich aber noch 3 Dinge die ich nicht ganz kapiere oder nicht nachvollziehen kann:

1. Senden tut er das Signal nur wenn ich am Poti drehe, das ist so in Ordnung. Im Abelton zeigt er aber ständig ein Empfangs-Signal an. Ich gehe davon aus das liegt daran das das Tool Serial_MIDI_Converter dafür verantwortlich ist. Oder?

2. Im Serialmonitor zeigte vor meiner "schusterei" einen Wert von 0-127 an, so hat er es aber nicht im Abelton erkannt, dann habe ich die Serial.write Befehle eingefügt. Dann hat er im Serialmonitor beim drehen des potis einen "Mischwert" angzeigt z.B.: 87 und eine Zeile darunter ºW (so was ähnliches). Ich gehe davon aus das im Code die Zeile Serial.println(maxVal); dafür verantwortlich ist das er beide Werte anzeigt?

3. Um das Signal ans Abelton zu übergeben benutze ich das Tool Serial_MIDI_Converter, gibt es eine Möglichkeit das ganze auch ohne dieses Tool benutzen zu müssen?

Viele Grüße.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 21, 2012, 10:07 pm
Das ständige Senden liegt einfach daran, das Du innerhalb von loop() ein
Code: [Select]
  static int lastmaxVal = 0;
stehen hast. Damit wird bei jedem Durchlauf von loop die Variable neu erzeugt und auf 0 gesetzt.
Damit ist das "  if(maxVal != lastmaxVal)" aber immer erfüllt und es wird jedesmal gesendet.
Wenn Du das noch aus der Loop rausnimmst, sollte es passen.
Mario.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 21, 2012, 10:22 pm
Er sendet nicht ständig, sondern nur, wenn sich das Signal um THRESHOLD verändernd hat ;)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 21, 2012, 10:52 pm

2. Im Serialmonitor zeigte vor meiner "schusterei" einen Wert von 0-127 an, so hat er es aber nicht im Abelton erkannt, dann habe ich die Serial.write Befehle eingefügt. Dann hat er im Serialmonitor beim drehen des potis einen "Mischwert" angzeigt z.B.: 87 und eine Zeile darunter ºW (so was ähnliches). Ich gehe davon aus das im Code die Zeile Serial.println(maxVal); dafür verantwortlich ist das er beide Werte anzeigt?

mit Serial.println(maxVal); schickst Du ja auch nur irgendwas über die Leitung, was nicht dem MIDI-Protokoll entspricht.
Bei mir sieht das dann so aus:
+10.037 - Error: got nonsense MIDI data: 35300d0a
+10.047 - Error: got nonsense MIDI data: 35310d0a
+10.057 - Error: got nonsense MIDI data: 35320d0a
+10.067 - Error: got nonsense MIDI data: 35330d
+10.069 - Error: got nonsense MIDI data: 0a
usw. Also das musst Du rauskommentieren, das kannst Du zum debuggen in der IDE nehmen, aber für Live musst Du es löschen/auskommentieren.
Die °A °B und sonstige seltsame Symbole kommen von den drei Zeilen in denen Du die MIDI-Nachricht schickst.


3. Um das Signal ans Abelton zu übergeben benutze ich das Tool Serial_MIDI_Converter, gibt es eine Möglichkeit das ganze auch ohne dieses Tool benutzen zu müssen?

Nur wenn Du Hardware hast, die dir MIDI zu USB umsetzt und Du z.B. ein MIDI-Shield für den Arduino hast.


Die Variable 'divisor', welche Du mit der Funktion 'knobFunction' übergibst, wird überhaupt nicht verwendet, dann kannst Du sie auch komplett rauswerfen. (kostet nur unnötig Speicher)

Code: [Select]
int output = analogRead(pin)/4; hier wird durch 4 und
Code: [Select]
return output/2; hier noch mal durch 2 dividiert - eine Division reicht ;)
Code: [Select]
int output = analogRead(pin)/8;
...
return output;

Multiplikationen und Divisionen sind für Mikrokontroller sehr aufwendig, deshalb solltest Du eine entfernen, dann wird der Code flotter (und 10 Bytes kürzer).
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Mar 22, 2012, 01:24 pm

Er sendet nicht ständig, sondern nur, wenn sich das Signal um THRESHOLD verändernd hat ;)

Stimmt, das liegt aber daran, das die Funktion knobFunction den gleichen Fehler macht und das Array "prefRead" immer wieder neu definiert und damit wenn der Wert sich nicht ändert eine "0" zurückliefert. Damit ist aber im loop die Bedingung wieder erfüllt. Wieder ein falscher Fehler :-)
Der Code ist alles andere als optimal, das macht es unheimlich schwierig Bugs von echten Fehlern zu unterscheiden ...
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 22, 2012, 01:56 pm

Stimmt, das liegt aber daran, das die Funktion knobFunction den gleichen Fehler macht und das Array "prefRead" immer wieder neu definiert und damit wenn der Wert sich nicht ändert eine "0" zurückliefert. Damit ist aber im loop die Bedingung wieder erfüllt. Wieder ein falscher Fehler :-)
Der Code ist alles andere als optimal, das macht es unheimlich schwierig Bugs von echten Fehlern zu unterscheiden ...

Nein, die Variablen sind ja als "static" definiert:
Variables declared as static will only be created and initialized the first time a function is called.

edit: Ich finde den Code aber auch verwirrend.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 22, 2012, 05:42 pm
Okay danke für die Verbesserungen und Tips. Habe das jetzt auch verändert mit der division und dem Serial.print.

Wenn ich jetzt mehrere Potis anschießen will also im Eingang 0, 1, 2, 3 usw. wie muss ich das im code einbinden bzw. ansteuern?

Grüße
Ak-Nak47
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 22, 2012, 06:33 pm
Als erstes möchte ich Dir vorschlagen vernünftige Namen zu vergeben, also nicht so etwas wie poti1, poti2 .... in ein paar Wochen weisst Du sonst u.U. selbst nicht mehr was was ist. Also vielleicht so etwas wie lautPoti...oder was immer Dir einleuchtend erscheint.

Du kannst den Pin jedesmal in die Befehle schreiben:
meinWert = analogRead(A0);

Oder, was bei größeren Programmen besser ist, auf eine Variable legen. Das hat den großen Vorteil, daß Du, wenn Du die Hardware änderst, nicht den ganzen Code abklappern musst um A0 in Irgendetwas zu ändern, sondern nur diese eine Variable ändern musst.

Beispiel:
Code: [Select]

/* Variablen */
int volume, int balance;

/* Pinbelegung */
const int volumePot = A0;
const int balancePot = A1;
// u.s.w.
void setup() {
  ....
}
void loop(){
....
}


Oder meintest Du, wie die Funktion 'knobFunction' mit mehreren Potis funktioniert?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 22, 2012, 06:41 pm
ja ich meinte wie ich diese funktion die ich jetzt auf den einen poti habe auch für mehrere angeschlossene potis benutze kann, wo genau binde ich die potis im code ein?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 22, 2012, 07:24 pm
Das ist in der Funktion schon eingebaut. Du übergibst ihr den Pin an dem das Poti hängt.

static int prevRead[6] = {0, 0, 0, 0, 0, 0};
In dieser Zeile wird ein Array 'prevRead' erzeugt, darin speichert die Funktion sechs Werte für die sechs analogen Eingänge. Also 'prevRead[0]' ist dann der Wert von A0 u.s.w..
int output = analogRead(pin)/8;
Hier wird der Eingang 'pin' ausgelesen, 'pin' ist die Variable, die Du der Funktion übergeben musst. Das sieht man auch an der Zeile:
int knobFunction(const int pin)
In der Klammer steht der Parameter der übergeben wird.

Code: [Select]
/* Variablen */
int volume, lastVolume, balance, lastBalance;
int threshold = 2;

/* Pinbelegung */
int volumePot = A0;
int balancePot = A1;

void setup() {
  Serial.begin(38400);
}

void loop(){
/* Read and send volume */
  volume = knobFunction(volumePot);
  if(volume != lastVolume) {
    lastVolume = volume;
    //Serial.print("volume: ");
    //Serial.println(volume);
    Serial.write(186);
    Serial.write(7);
    Serial.write(volume);
  }
/* Read and send balance */
  balance = knobFunction(balancePot);
  if(balance != lastBalance) {
    lastBalance = balance;
    //Serial.print("balance: ");
    //Serial.println(balance);
    // irgend etwas tun
  }
}

int knobFunction(const int pin)
{
  static int prevRead[6] = {0, 0, 0, 0, 0, 0};   
  int output = analogRead(pin)/8;    
  if (abs(output - prevRead[0])  >= threshold)
    {prevRead[pin] = output;}
  else
    {output = prevRead[pin];}
  return output;
}
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 22, 2012, 08:03 pm
Balance fällt auch wieder unter 'control change'.
Kanal ist nun auch eine Variable (die habe ich wieder auf Byte gesetzt um RAM zu sparen), somit kannst Du den Kanal einfach ändern. Wenn Du einen Taster hast, dann z.B. mit dem.

Code: [Select]
/* Variablen */
byte volume, lastVolume, balance, lastBalance;
byte channel = 1;     // Hier Kanal festlegen (1 bis 16)
int threshold = 2;

/* Pinbelegung */
const int volumePot = A0;   // Poti für die Lautstärke
const int balancePot = A1;  // Poti für die Balance

void setup() {
  Serial.begin(38400);
}

void loop(){
/* Lies und sende Lautstärke */
  volume = knobFunction(volumePot);
  if(volume != lastVolume) {
    lastVolume = volume;
    //Serial.print("volume: ");
    //Serial.println(volume);
    Serial.write(175 + channel);  // Sende 'control change' auf Kanal 'channel'
    Serial.write(7);              // ändere Lautstärke auf...
    Serial.write(volume);         // den Wert der Variablen 'volume'
  }
/* Lies und sende Balance */
  balance = knobFunction(balancePot);
  if(balance != lastBalance) {
    lastBalance = balance;
    //Serial.print("balance: ");
    //Serial.println(balance);     
    Serial.write(175 + channel);  // Sende 'control change' auf Kanal 'channel'
    Serial.write(8);              // ändere Balance auf...
    Serial.write(balance);        // den Wert der Variablen 'balance'
   }
}

/* Funktionen */
int knobFunction(const int pin)
{
  static int prevRead[6] = {0, 0, 0, 0, 0, 0};   
  int output = analogRead(pin)/8;    
  if (abs(output - prevRead[0])  >= threshold)
    {prevRead[pin] = output;}
  else
    {output = prevRead[pin];}
  return output;
}


Das ist ein bißchen schizophren, Variablen & Co englisch und Kommentare deutsch  :smiley-roll:
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 22, 2012, 09:08 pm
Okay also verstehen tu ich das was du gepostet hast auf jeden Fall. Komisch irgendwie leuchtet das jetzt besser ein als vorher. Klasse. Danke.

Jetzt habe ich auf dem Arduino ja nur 6 analoge Eingänge, jetzt habe ich die Möglichkeit des "Multiplexen" i wie fern muss ich hier jetzt verfahren. Angenommen ich würde gerne 16 Potis verwenden? Muss ich dazu im Code das Multiplexen berücksichtigen? Ich gehe mal davon aus das ich das muss.

Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 22, 2012, 09:19 pm

Angenommen ich würde gerne 16 Potis verwenden? Muss ich dazu im Code das Multiplexen berücksichtigen? Ich gehe mal davon aus das ich das muss.


Ja sicher, Du kannst nicht erwarten das die Hardware wie von Zauberhand von alleine funktioniert.
Hier ist ein Beispiel wie man 16 Potis demultiplexen kann, also genau das, was Du machen willst:
http://bildr.org/2011/02/cd74hc4067-arduino/ (http://bildr.org/2011/02/cd74hc4067-arduino/)

Der Chip kostet 84 Cent, ist also nicht wirklich teuer.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 22, 2012, 09:22 pm
Ja eigentlich das was ich will, muss nur gucken wie viele digitale ich noch frei habe. das könnte sehr sehr eng werden. :-) Nicht schlecht.

Woher kannst du diesen ganzen Stuff? Hast du das gelernt oder hast du beruflich damit zu tun?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: sth77 on Mar 22, 2012, 09:28 pm

Ja eigentlich das was ich will, muss nur gucken wie viele digitale ich noch frei habe. das könnte sehr sehr eng werden. :-) Nicht schlecht.


Naja, 4 digitale Ausgänge sind ja auch nicht die Welt. Was soll denn noch aufgebaut werden, dass du solch einen Verschleiß an Pins hast? ;)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 22, 2012, 09:31 pm
Das will ich noch nicht verraten, es ist noch ein langer weg bis dorthin. vieles haben wir testen können aber wir sind noch a m entwicken, aber ich werde es hier natürlich posten, keine frage. Im CAD System habe ich alles designt jetzt sollte ich mich langsam ans doing machen aber mir fehlt da ausreichend zeit (leider).
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 23, 2012, 08:20 pm

Woher kannst du diesen ganzen Stuff? Hast du das gelernt oder hast du beruflich damit zu tun?

Nein und nein.
Ich bin über Umwege und durch 'Zufall' vor ungefähr 4 Jahren über den Arduino gestolpert und bin einfach sehr begeistert von der ganze Sache, Hardware, IDE und vor allem der Idee dahinter.
Arduino macht alle, wenn sie bereit sind etwas Schweiß zu investieren, zu "Ingenieuren". Die Lernkurve ist nicht wirklich steil und es macht einfach Spaß.
Deshalb habe ich die ganze Zeit versucht Dich dazu zu bringen, daß Du Dich mehr damit beschäftigst. Du wirst eine Menge Spaß mit dem Arduino haben, da bin ich mir ziemlich sicher, und nebenbei wirst Du einiges lernen. ;)

Es gibt ein Zitat von Kung-tse (bei uns auch Konfuzius genannt) das sehr schön zum ganzen Projekt 'Arduino' passt:

Was du mir sagst, das vergesse ich.
Was du mir zeigst, daran erinnere ich mich.
Was du mich tun lässt, das verstehe ich.

Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 23, 2012, 08:31 pm
Ja das ist wirklich ein zutreffendes Zitat. Mir macht diese ganze Sache viel Spaß es kostet mich natürlich unheimlich viel Nerven, da ich mehr der Typ bin der mit dem Kopf durch die Wand will. Ja ich denke auch das das eine Tolle Sache ist mit dem Arduino man kann so einiges damit anstellen.

Klar denke ich mir "da hast du dir als Einsteiger aber viel vorgenommen" aber ich denke alles ist machbar wenn wann es will.

Ich finde es ganz gut nicht alles vorgekaut zu bekommen und an dieser Stelle nochmals vielen Dank für den Support.

Eine Frage habe ich im Moment aber noch:

Wenn ich das Mux Breakout benutze, dann benötige ich weiterhin das Serial_Midi_Converter oder? Wenn ich habe das MuxShield benutze brauche ich dieses Tool nicht mehr?

Grüße
AK-NAK47
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 23, 2012, 08:59 pm
Doch Du brauchst das Tool weiterhin, die Mux-Hardware hat doch nichts mit der Kommunikation zw. Arduino und Computer/Ableton Live zu tun.
An der Software kommst Du nur mit einem MIDI-zu-USB-Adapter vorbei, was natürlich nur geht, wenn der Arduino über MIDI-Hardware verfügt.

http://www.thomann.de/de/midi-interfaces.html (http://www.thomann.de/de/midi-interfaces.html)
http://www.musikhaus-korn.de/de/MIDI-USB-1X1-INTERFACE-Kabel.html (http://www.musikhaus-korn.de/de/MIDI-USB-1X1-INTERFACE-Kabel.html)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 23, 2012, 09:03 pm
Das heisst wenn ich einen Mux verwende und das Tool nicht benutzen will benötige ich ein Midi / USB Interface.

Ich weiss nicht ob du das Gerät Arduinome kennst, da kommen die Signale allerding über die Digitalen Eingänge des Arduinos. Ich denke das macht den Unterschied.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 23, 2012, 09:56 pm
Hab mir Arduinome mal kurz angeschaut. OK, sie schicken Daten über USB, was aber hängt am anderen Ende? Also was läuft auf dem Computer an dem das Teil hängt.
Ob die Daten von den digitalen I/Os oder den analogen PINs kommen ist aber für die Kommunikation wieder egal.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 23, 2012, 11:18 pm
Ja da hast du recht um ein Arduinome mit eine Software wie Abelton laufen zu lassen benötigt man das tool arduinome serial, ich gehe jetzt davon aus das hinter dieser exe datei bzw. diesem tool selbiges wie beim midi_converter verbirgt, oder zumindest etwas sehr ähnliches.

Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 23, 2012, 11:41 pm
Es gäbe noch die Möglichkeit, wenn Du einen Uno hast, den 8U2 mit einer MIDI-Firmware zu flashen.
http://arduino.cc/playground/Main/InterfacingWithHardware#USB
Da sind gleich zwei und hier noch eine:
http://hunt.net.nz/users/darran/weblog/52882/Arduino_UNO_MIDI_USB_version_02.html (http://hunt.net.nz/users/darran/weblog/52882/Arduino_UNO_MIDI_USB_version_02.html)
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 23, 2012, 11:55 pm
Ja das könnte unter umständen funktionieren.
Da das duemilanove sowieso abdankt könnte man auch auf das von dir genannte uno board setzen. Das sieht vielversprechend aus und ich benötige kein zusatz tool.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 24, 2012, 12:01 am
Bedenke aber, daß Du den Uno dann nicht mehr über die IDE/USB programmieren kannst. Du musst dann jedesmal den 8U2 flashen, oder den M328 über ISCP statt USB flashen. Und Du brauchst natürlich einen Programmer.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 24, 2012, 12:04 am
Ich sehe schon, irgendwas ist immer.  :)

Ich brauch da ne möglichst simple lösung für die idee...! Zumindest eine die für mich machbar ist.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 24, 2012, 12:54 am
Für die Entwicklung kannst Du das Programm ja weiter verwenden, oder ist das so schlimm? Und wenn alles fertig ist, flasht Du den 8U2 auf MIDI und brauchst es nicht mehr.
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mime on Mar 24, 2012, 11:03 am
Ich hab noch mal am Code gewerkelt.
* Kanal dann doch wieder 0 - 15
* Funktion um MIDI Nachricht zu senden
* Vordefinierte Konstanten für einiges, was man so senden kann

Code: [Select]
/* Variablen */
byte volume, lastVolume, balance, lastBalance;
byte channel = 0;     // Hier Kanal festlegen (0 - 15)
int threshold = 2;

/* MIDI Nachrichten */
/* Status Bytes = erstes Byte */
const byte polyphonicAftertouch = 0xA0;
const byte controlChange = 0xB0;
const byte programChange = 0xC0;
const byte channelAftertouch = 0xD0;
const byte pitchWheelControl = 0xE0;
/* Ein-Byte-Nachrichten */
const byte midiStart = 0xFA;       
const byte midiContinue = 0xFB;
const byte midiStop = 0xFC;

/* Daten Bytes = zweites Byte */
const byte ccChannelVolume = 0x07;  // Control change channel volume
const byte ccBalance = 0x08;        // Control change balance

/* Pinbelegung */
const int volumePot = A0;   // Poti für die Lautstärke
const int balancePot = A1;  // Poti für die Balance

void setup() {
  Serial.begin(38400);      // MIDI Baud-Rate 31250
}

void loop(){
/* Lies und sende Lautstärke */
  volume = knobFunction(volumePot);
  if(volume != lastVolume) {
    lastVolume = volume;
    //Serial.print("volume: ");
    //Serial.println(volume);
    sendMidiMessage(controlChange, ccChannelVolume, volume);
  }
/* Lies und sende Balance */
  balance = knobFunction(balancePot);
  if(balance != lastBalance) {
    lastBalance = balance;
    //Serial.print("balance: ");
    //Serial.println(balance);
   sendMidiMessage(controlChange, ccBalance, balance);   
   }
}

/* Funktionen */
int knobFunction(const int pin)
{
  static int prevRead[6] = {0, 0, 0, 0, 0, 0};   
  int output = analogRead(pin)/8;    
  if (abs(output - prevRead[0])  >= threshold)
    {prevRead[pin] = output;}
  else
    {output = prevRead[pin];}
  return output;
}

void sendMidiMessage (byte statusByte, byte dataByte, byte valueByte ) {
  Serial.write(statusByte + channel);
  Serial.write(dataByte);
  Serial.write(valueByte);
}
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Mar 25, 2012, 09:54 pm
hi mime,

konnte bislang nicht den code ausprobieren, sieht aber edel aus.  :)
Morge das erste was ich nach der Arbeit ausprobieren werde. Coole Sache.

Hast du sonst irgendwas mit Musik zu tun?

Grüße
Ak-Nak47

Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Apr 24, 2012, 08:14 pm
Hi,

habe jetzt 6 potis angeschlossen, wollte den Code ändern so dass auf jeden Poti "ccChannelVolume" gesetzt wird. Irgendwie nimmt er das aber nicht...!

Der gegebene Code sieht folgendermaßen aus:

Code: [Select]
/* Pinbelegung */
const int volumePot = A0;   // Poti für die Lautstärke
const int balancePot = A1;  // Poti für die Balance


Nun müsste ich wenn ich jeden Poti als "volumePot" haben will den Code do so ändern:

Code: [Select]
/* Pinbelegung */
const int volumePot = A0;   // Poti für die Lautstärke
const int volumePot= A1;  // Poti für die 2 Lautstärke


oder wenn es möglich ist:

Code: [Select]
/* Pinbelegung */
const int volumePot = A0;A1;A2; ...   // Poti für die Lautstärke


Oder bin ich verkehrt?


Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on Apr 24, 2012, 08:31 pm
Code: [Select]

Code:
/* Pinbelegung */
const int volumePot = A0;   // Poti für die Lautstärke
const int volumePot= A1;  // Poti für die 2 Lautstärke

oder wenn es möglich ist:

Code:

/* Pinbelegung */
const int volumePot = A0;A1;A2; ...   // Poti für die Lautstärke

So geht es leider nicht. "VolumePot" ist eine Variable, also ein Platzhalter für EINEN Wert.
Eigentlich stehen die Werte A0 und A1 ... nur für bestimmte Pin-Nummern des Arduino.
Was Du machst ist folgendes:

1) Merke Dir, das volumePot für das erste analog Pin steht.
2) Merke Dir, das volumePot für das zweite analog Pin steht
...
Was soll sich Dein Programm denn nun merken? Das erste oder das zweite Pin?

Du kannst entweder ein Array nehmen:
Code: [Select]
int volumePot[3]= { A0 , A1, A2};
//zugriff über index des array - achtung zählung beginnz bei 0
... analogRead(volumePot[0]);
...  analogRead(volumePot[1]);
...  analogRead(volumePot[2]);


oder Du definierst Dir 3 verschiedene Variablen
Code: [Select]

int volumePot1= A1;
int volumePot2= A2;
int volumePot3= A3;
//zugriff über einzelne Variable
... analogRead(volumePot1);
...  analogRead(volumePot2);
...  analogRead(volumePot3);

Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on Apr 24, 2012, 11:01 pm
Dann müsste es folgendermaßen aussehen:

Code: [Select]
/* Variablen */
byte volume, lastVolume, balance, lastBalance;
byte channel = 1;     // Hier Kanal festlegen (1 bis 16)
int threshold = 2;

/* Pinbelegung */
const int volumePot[6] = { A0 , A1, A2, A3, A4, A5};   // Poti für die Lautstärke
const int balancePot = A6;  // Poti für die Balance

void setup() {
  Serial.begin(38400);
}

void loop(){
/* Lies und sende Lautstärke */
  volume = knobFunction(volumePot);
  if(volume != lastVolume) {
    lastVolume = volume;
    //Serial.print("volume: ");
    //Serial.println(volume);
    Serial.write(175 + channel);  // Sende 'control change' auf Kanal 'channel'
    Serial.write(7);              // ändere Lautstärke auf...
    Serial.write(volume);         // den Wert der Variablen 'volume'
  }
/* Lies und sende Balance */
  balance = knobFunction(balancePot);
  if(balance != lastBalance) {
    lastBalance = balance;
    //Serial.print("balance: ");
    //Serial.println(balance);     
    Serial.write(175 + channel);  // Sende 'control change' auf Kanal 'channel'
    Serial.write(8);              // ändere Balance auf...
    Serial.write(balance);        // den Wert der Variablen 'balance'
   }
}

/* Funktionen */
int knobFunction(const int pin)
{
  static int prevRead[6] = {0, 0, 0, 0, 0, 0};   
  int output = analogRead(pin)/8;    
  if (abs(output - prevRead[0])  >= threshold)
    {prevRead[pin] = output;}
  else
    {output = prevRead[pin];}
  return output;
}


Kanns jetzt gerade nicht ausprobieren, aber so sollte es doch gehen?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: Ak-Nak47 on May 01, 2012, 11:29 am
Irgedwie funktioniert das nicht   =(....warum?
Title: Re: Poti an analogen Pin als MIDI ausgeben
Post by: mkl0815 on May 01, 2012, 12:09 pm
Du definierst knobFunction() mit einem Parameter "const int pin" also einem Integer als Wert. Es wird aber in Deinem Code die Variable volumePot übergeben, die aber kein Integer ist, sondern ein Array von mehreren Integern. Statt knobFunction(volumePot) muss es also heissen knobFunction(volumePot[0]) für den ersten Wert,  knobFunction(volumePot[1]) für den zweiten Wert usw.

Außerdem brauchst Du in Deinem loop() vermutlich eine Schleife, die durch die einzelnen Werte des Arrays durchgeht. Da Du Dir mit "lastVolume" den vorherigen Wert merkst, sollte das vermutlich dann auch ein Array werden, sonst vergleichst Du plötzlich den lastVolume mit unterschiedlichen Ergebnissen der verschiedenen Eingänge die in volumePot[] definiert sind.
Mario.