Poti an analogen Pin als MIDI ausgeben

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

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:

Die Midi-Lib gibt es hier:
http://arduino.cc/playground/Main/MIDILibrary
Ansonsten finden sich im Palyground diverse MIDI Projekte:
http://arduino.cc/playground/Main/InterfacingWithHardware#Output
Ich hoffe das hilft Dir erstmal weiter.
Mario.

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:

byte note = map(analogRead(A0), 0 , 1023, 0, 127);

Dann kannst Du die Note mit der MIDI-library verwenden:

sendNoteOn (byte note, byte velocity, byte channel)

mit note = 0-127; velocity = 0-127 und channel = 1-16

oder Du machst es gleich selbst:

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:

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:

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. :slight_smile:

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

Ja, Du kannst das kopieren.
Mal kurz im Telegramm-Stil:
Poti auslesen:

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

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:

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

http://arduino.cc/en/Reference/Map

Du kannst auch beides zusammenfassen:

lautstaerke = map(analogRead(A0), 0, 1023, 0, 100);

Nicht vergessen in "void setup()" die Variablen zu deklarieren. Z.B.:

byte lautstarke;

http://arduino.cc/en/Reference/Byte

Wenn Du das dann via USB an Ableton senden willst:
in "void setup()"

Serial.begin(38400);

und im "loop" z.B.

Serial.write(lautstaerke);

Also jetzt nicht lachen. Das müsste dann im Programm so aussehen:
Oder habe ich mich jetzt voll verzettelt?

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);

Es geht in die richtige Richtung. :wink:
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.

Nicht ganz.

  1. Bibliotheken einbinden
  2. Variablen und ev. Pins deklarieren
  3. setup
  4. loop

also so rum:

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.

Ich würde Dir empfehlen erstmal mit den Grundlagen anzufangen. Dazu ist die Arduino-Webseite schon recht informativ. 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.

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

  2. 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 :slight_smile:

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. :slight_smile: 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. :slight_smile: 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

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. :slight_smile:

Also den Code habe ich wie folgt:

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:

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?

Ak-Nak47:
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 :wink:
Bevor Du versuchst Ableton Live zu steuern, solltest Du Dir wirklich erstmal einige Grundlagen aneignen.

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 :wink:

Da die velocity rein zu quetschen macht also keinen Sinn.
Eine Variable kannst Du so zuweisen:

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.

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:

/* 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:

/* 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
}

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. :slight_smile:

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.

Als Nichtmusiker knn ich dir nur empfehlen, dich strikt an das MIDI-Protokoll zu halten:

Dort sollte alles erklärt sein, bei der Umsetzung auf dem Arduino hilft man dir natürlich weiterhin gern.

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?

Ak-Nak47:
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.

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

Richtig

Ak-Nak47:
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

Ak-Nak47:
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.

Ich werd das mal soooooo zusammenbasteln wie ich meine das es hinhauen könnte. :slight_smile: IIch würde mich freuen wenn du da dann drüber schauen könntest.

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