Hallo zusammen,
ich bastele gerade an einem MidiController mit Teensy 3.2 zur Ausgabe von Midi NoteON / Off Befehlen.
Die Stromversorgung läuft über USB.
Mit einem Poti an A1 lässt sich ein Schwellwert einstellen. Definiert ist der als (VoltageA1>1) und entspricht dem Anschlag einer Saite.
Um das besser simulieren zu können hängt zwischen Poti Schleifer und A1 noch ein Taster (mit 10 K und 40nF gegen GND).
Zusätzlich wird mit einen Spannungsteiler an A0 der Widerstand gemessen und über switchcase in Midi Noten (= Bund Position der Greifhand) umgerechnet .
Grundsätzlich funktionieren damit zumindest mal die einzelnen Schaltpunkte .
Sketch:
/*
Teensy 3.2 (72 MHz,USB Type Midi, Optimize = Faster),
IDE 1.8.12
Stromversorgung per USB
Spannungsteiler an A0 und GND fest angeschlossen !
Poti an A1 für Schwellwert (mit Taster am Schleifer).
*/
const int channel = 1; // Midikanal
float Quellspannung = 3.28;// gemessene Spannung !
const int PinA0 = 0; // Hier ist der Spannungsteiler angeschlossen
const int PinA1 = 1; // Poti Anschluss für Schwellwert (wird später durch Pickup für H Saite ersetzt)
int WertA1; // speichert die gemessene Spannung
float voltageA1; // Schwellwert für Note On / Off
int Velocity_H; //Midiwert für Lautstärke zZ per Poti an A1(später per Pickup)
int MidiOffsets[5] = {0, 5, 10, 15, 20}; // Zugriff auf 1. Wert mit MidiOffsets[0];
int R1 = 3270.0; //Wert des bekannten Messwerts(3,3k; nachgemessen = 3270)
long MesswertA0;
long MesswertA1;
float SpannungR2; //Spannung über dem zu messenden Widerstand
float Widerstand = 0;
int midineu = 0 ;
int midiold = 0 ;
void setup() {
Serial.begin(115200);
}
void loop() {
WertA1 = analogRead(A1);
voltageA1 = WertA1 * (Quellspannung / 1024);
//for (int i = 0; i < 5; i++) {
// MesswertA1 += analogRead(PinA1);
//}
// MesswertA1 = trunc(MesswertA1 / 5);
Serial.print(" Spannung an A1 beträgt ");
Serial.println(voltageA1);// voltageA1
//int Velocity_H = map(voltageA1, 0, 1023, 0, 127);
//Velocity_H = map(WertA1, 0, 1023, 0, 127);
//Serial.print(" Midiwert ist ");
//Serial.println(Velocity_H);
//5 Messungen am Spannungsteiler machen und Mittelwert bilden
MesswertA0 = 0;
//for (int i = 0; i < 5; i++) {
MesswertA0 += analogRead(PinA0);
// }
//MesswertA0 = trunc(MesswertA0 / 5);
//Spannung berechnen
SpannungR2 = (Quellspannung / 1024) * MesswertA0;
//Serial.print("Spannung ueber R2 betraegt ");
//Serial.print(SpannungR2, 2);
//Serial.println(" Volt!");
//Berechnung: (R2 = R1 * (U2/U1))
Widerstand = R1 * (SpannungR2 / (Quellspannung - SpannungR2));
Serial.print("Der Widerstand hat ");
Serial.print(Widerstand, 2);
Serial.println(" Ohm.");
Serial.println();
delay(250); // Verzögerung zum Lesen der Anzeige, fliegt sonst raus!
//Umrechnung Widerstand => MidiNote
switch (int(Widerstand))
{
case 2844 ... 3857 : midineu = 24; break; // 3,3 (theoretischer Mittelwert)
case 6186 ... 7186 : midineu = 25; break; // 6,6
case 9495 ... 10578 : midineu = 26; break; // 9,9
case 12847 ... 13765 : midineu = 27; break; //13,2
case 16000 ... 17000 : midineu = 28; break; //16,5
case 19300 ... 20500 : midineu = 29; break; //19,8
case 22876 ... 23876 : midineu = 30; break; //23,1
case 25943 ... 27208 : midineu = 31; break; //26,4
case 29148 ... 30474 : midineu = 32; break; //29,7
case 31827 ... 33727 : midineu = 33; break; //33,0
case 35734 ... 37204 : midineu = 34; break; //36,3
case 39280 ... 40839 : midineu = 35; break; //39,6
case 42229 ... 43868 : midineu = 36; break; //42,9
case 45612 ... 47350 : midineu = 37; break; //46,2
case 49533 ... 50533 : midineu = 38; break; //49,5
case 52198 ... 54147 : midineu = 39; break; //52,8
case 56197 ... 57197 : midineu = 40; break; //56,1
case 58418 ... 60592 : midineu = 41; break; //59,4
case 60810 ... 63077 : midineu = 42; break; //62,7
case 64765 ... 66000 : midineu = 43; break; //66,0
case 66300 ... 68500 : midineu = 44; break; //69,3
case 70858 ... 73554 : midineu = 45; break; //72,6
case 74329 ... 75329 : midineu = 46; break; //75,9
case 78139 ... 81187 : midineu = 47; break; //79,2
case 82000 ... 93000 : midineu = 23; break; //89,2 (25. Widerstand = 10K "leere" H Saite)
default: midineu = 0; break;
}
if (voltageA1 < 1 ) {
usbMIDI.sendNoteOff(midiold, 0, 1);
//midineu = 0;
//midiold = 0;
midiold = midineu;
}
if (voltageA1 > 1) {
usbMIDI.sendNoteOn(midineu, 127, 1); // midineu = Midi Note, 127 = Lautstärke, 1 = Kanalnr
midiold = midineu;
}
}
Im Moment wird Note Off leider als "Dauerfeuer" gesendet wenn A1>1 ist (wenn A1< 1 kommt absichtlich nix).
Wenn über den Spannngsteiler eine neue Midinote errechnet wird kommt Note On auch als Dauerfeuer solange der entsprechende Widerstand ausgewählt ist.
Note On / Off sollten jeweils nur 1 x gesendet werden (wie bei einem Keyboard) solange sich A0 oder A1 nicht ändern.
Wie lässt sich das umsetzen ?
Würde mich über Eure Tipps freuen !
Grüsse