Bitte geben Sie einen Grund für die Verwarnung an
Der Grund erscheint unter dem Beitrag.Bei einer weiteren Verwarnung wird das Mitglied automatisch gesperrt.
Midifizierung eines pneumatischen Spieltisches
Ja die Abtastfrequenz habe ich auch im Verdacht, denn an anderer Stelle hat die künstliche Verlangsamung des Loop-Durchlaufs auch Besserung gebracht (hatte am Anfang "Ghosting" obwohl Dioden-Matrix). Immerhin hat der Arduino Uno 16 MHz, und mit diesem Controller (oder ähnlichen Chips) werden viele Midifizierungen gemacht. Der Controller, der in meinem geschlachteten Keyboard drin war, hat 40 MHz. Der Arduino Due hingegen hat 84 MHz.
Ich denke also, dass ich hier und da noch ein paar Bremsklappen einbauen bzw. die vorhandenen etwas weiter ausfahren muss.

Midi-Beiträge nach Arduino - Midi-Programmierung verschoben.
@Bkoeln
Durch Zufall gefunden, weil ich selbst etwas anderes gesucht habe. Hier gibt es alte Manuale, Tonumfang bis f, wie deine. Vielleicht interessant für dich?
https://www.orgelbau-weise.de/orgelverka...lklaviatur.html

Hallo ihr Freunde der Virtuellen Orgel,
nach längerer Abstinenz melde ich mich mal wieder. Ich hoffe dass ich jetzt endlich Zeit finde mein Projekt weiterzubauen.
Im Moment befasse ich mich mit der Programmierung eines Arduino , was andere hier ja auch schhon gemacht haben. Nicht weil ich es unbedingt brauche sondern einfach weil es mich reizt sowas selbst steuern zu können.
Bin gespannt was ich alles so finde hier .
Bis dahin liebe Grüße
Bernd

Hi Soubasse
Danke für die Begrüßung.
Habe erst mit arduino angefangen und das meiste am Simulator ausprobiert. Da klapptauch alles bestens.
Habe mich sinpirieren lassen von der Hardware die bei mir eingebaut ist.
Eigentlich mache ich das Ganze nur um selbst einentsprechendes Programm schreiben zu können. Bin jetzt seit einer Guten Woche dran.
Das Programm soll 8 Kanäle (Decoder) abfragen und da jeweils eine 8x8 Matrix..
Es läuft auf einem Uno. Habe auch noch Nano zur Auswahl. Der wird es wahrscheinlich am Ende sein.
Gestern habe ich das mal auf denunziert geflasht.
In der praktischen Anwendung prallen leider die Kontakte.
Das sieht so aus dass Note on und Note off sofort hintereinander ausgegeben werden. Beim loslassen dann nochmal Note off.. Ich habe nicht nicht verstanden an welcher Stelle das Programm stolpert. Wahrscheinlich brauche ich noch ein anderes delay.
GRUß
BERND
#113

Zitat von Bkoeln im Beitrag #111
Wahrscheinlich brauche ich noch ein anderes delay.
Ein längeres Delay kann eine Lösung sein, oder auch eine routine zum entprellen. Es kommt eben darauf an. Teile soch gerne mal deinen code. Und keine Angst, niemand hier wird etwas kritisieren, sondern wir geben nur Tipps.

Hallo, danke für eure Ermutigung.
ich schicke unten mal den Arduino-Sketch...übrigens mein erster nachdem ich mich eine Woche überhaupt mit dem Arduino beschäftige.
Bin weder Programmierer noch Elektroniker, aber beides hat mich schon immer fasziniert.
Die Print Befehle sind nur für den Simulator. In dem läuft die Sache genauso wie sie soll
// Definiere die Pins für die Diodenmatrix
const int inputPins[] = {2, 3, 4, 5}; // Eingabepins für die Matrix (4 Zeilen)
const int outputPins[] = {10, 11, 12}; // Ausgangspins für Clock (3 Spalten) Später 3-8 decodiert für 8 Leitungen
const int chanelPins[] = {13, A0,A1}; // Ausgangspins für Chanel(3 Spalten)
// Array zur Speicherung des Status der Noten (gedrückt oder nicht)
bool notePressed[8][8][8] = {false};
// Array für die Notenwerte
int Noten[8][8] {
{36,37,38,39,40,41,42,43},
{44,45,46,47,48,49,50,51},
{52,53,54,55,56,57,58,59},
{60,61,62,63,64,65,66,67},
{68,69,70,71,72,73,74,75},
{76,77,78,79,80,81,82,83},
{84,85,86,87,88,89,80,91},
{92,93,94,95,96,97,98,99}};
bool currentState;
int col = 0;
int row = 0;
int note = 0;
int chan = 0;
void setup() {
// Serielle Kommunikation mit 31250 Baud für MIDI
Serial.begin(31250);
// Setze die Eingabepins als INPUT
for (int i = 0; i < 4; i++) {
pinMode(inputPins[i], INPUT_PULLUP); // Verwende den Pull-Up-Widerstand
}
// Setze die Ausgangspins als OUTPUT
for (int i = 0; i < 3; i++) {
pinMode(outputPins[i], OUTPUT);
digitalWrite(outputPins[i], HIGH); // Setze sie initial auf LOW
}
// Setze die Kanäle
for (int i = 0; i < 3; i++) {
pinMode(chanelPins[i], OUTPUT);
digitalWrite(chanelPins[i], LOW); // Setze sie initial auf LOW
}
}
void loop() {
// Durchlaufe jeden Kanal
for (chan = 0; chan < 8; chan++) {
// Umrechnung der Zahl auf 3 Bit und Ausgabe auf die Ausgänge
int bitA = chan & 0b001; // Least Significant Bit (LSB)
int bitB = chan & 0b010; // Middle Bit
int bitC = chan & 0b100; // Most Significant Bit (MSB)
// Setze die Ausgänge je nach Bitwert (0 oder 1)
digitalWrite(chanelPins[0], bitA ? HIGH : LOW); // Pin A = LSB
digitalWrite(chanelPins[1], bitB ? HIGH : LOW); // Pin B = Middle Bit
digitalWrite(chanelPins[2], bitC ? HIGH : LOW); // Pin C = MSB
// Durchlaufe jede Spalte der Matrix
for (col = 0; col < 3; col++) {
digitalWrite(outputPins[col], LOW); // Aktiviere die aktuelle Spalte
delay(5);
// Überprüfe jede Zeile auf einen Tastendruck
for (row = 0; row < 4; row++) {
// if (digitalRead(inputPins[row]) == LOW) { // Taste gedrückt
currentState = digitalRead(inputPins[row]);// Wert der akt. Taste (True=High=inaktiv)
delay(5);
if (notePressed[chan][row][col] == currentState) { // Wenn Taste gedrückt und vorher nicht gedrückt
note = Noten[col][row]; //Abruf der MIDI-Note
if (currentState == LOW){ // Taste gedrückt
notePressed[chan][row][col] = true; //Speicherung des Notenwertes
//Serial.print(" Kanal: ");
//Serial.print(chan);
//Serial.print(" Note: ");
//Serial.print(note);
//Serial.print(" Taste gedrueckt: Zeile ");
//Serial.print(row);
//Serial.print(", Spalte ");
//Serial.println(col);
sendNoteOn(note); //Sende MIDI on
} else
{
// Taste losgelassen
(notePressed[chan][row][col] = false); // Speicherung des Noenwertes
//note = 36 + (4*col) + row;
//Serial.print(" Kanal: ");
//Serial.print(chan);
//Serial.print(" Note: ");
//Serial.print(note);
//Serial.print(" Taste losgelassen: Zeile ");
//Serial.print(row);
//Serial.print(", Spalte ");
//Serial.println(col);
}
sendNoteOff(note);
}
//delay(50); // Warte
}
digitalWrite(outputPins[col], HIGH); // Deaktiviere die aktuelle Spalte
}
digitalWrite(chanelPins[chan], LOW); // Deaktiviere KanalPin
}
}
// Funktion zum Senden eines Note On-Befehls
void sendNoteOn(byte note) {
Serial.write((0x90 + chan)); // Note On-Befehl für Kanal 1
Serial.write(note); // Note
Serial.write(0x7F); // Velocity (maximal)
}
// Funktion zum Senden eines Note Off-Befehls
void sendNoteOff(byte note) {
Serial.write(0x80 + chan); // Note Off-Befehl für Kanal 1
Serial.write(note); // Note
Serial.write(0x00); // Velocity (0)
}

#116

Ein Codeblock wäre ganz nützlich, da man den Code so kaum lesen kann.
Lief dein Programm schon einmal nativ auf einem Arduino?
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <MIDIUSB.h>
byte inputsManual1[] = {22,23,24,25,26,27,28,29}; //Deklariere inputs und outputs
#define inCountManual1 sizeof(inputsManual1)/sizeof(inputsManual1[0])
byte outputsManual1[] = {30,31,32,33,34,35,36,37};
#define outCountManual1 sizeof(outputsManual1)/sizeof(outputsManual1[0])
int layout[outCountManual1][inCountManual1] = { //layout grid for Manuals
//Manual 1+2 (8x8)
{48,47,46,45,44,43,42,41},
{56,55,54,53,52,51,50,49},
{64,63,62,61,60,59,58,57},
{72,71,70,69,68,67,66,65},
{80,79,78,77,76,75,74,73},
{88,87,86,85,84,83,82,81},
{97,96,95,94,93,92,91,89},
{105,104,103,102,101,100}
};
int keyDownManual1[outCountManual1][inCountManual1];
bool keyLongManual1[outCountManual1][inCountManual1];
/**** Funktionen für MIDI ***************************************************/
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
bool MidiButton(int pin, byte midisig, bool tasteAlt) { //Button-Pin, Noten-Nummer
bool taste = digitalRead(pin);
if(tasteAlt == HIGH && taste == LOW){
noteOnPedal(3, midisig, 127);
MidiUSB.flush();
tasteAlt = taste;
delayMicroseconds(500);
return tasteAlt;
}
if(tasteAlt == LOW && taste == HIGH){
noteOffPedal(3, midisig, 127);
MidiUSB.flush();
tasteAlt = taste;
delayMicroseconds(500);
return tasteAlt;
}
}
void noteOnPedal(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOffPedal(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
void setup(){
for(int i=0; i<outCountManual1; i++){ //declaring all the outputs and setting them high
pinMode(outputsManual1[i],OUTPUT);
digitalWrite(outputsManual1[i],HIGH);
}
//Serial.begin(9600); //establishing Serial link and initializing keyboard
//Serial.println("Connected");
}
//Main loop going through all the keys, then waiting 0.5ms
void loop() {
//Manuall 1
for (int i=0; i<outCountManual1; i++)
{
digitalWrite(outputsManual1[i],LOW); //setting one row low
delayMicroseconds(5); //giving electronics time to settle down
for(int j=0; j<inCountManual1; j++)
{
if(digitalRead(inputsManual1[j]) == LOW)
{
keyPressedManual1(i,j, 1); //calling keyPressed function if one of the inputs reads low
}
else if(keyDownManual1[i][j] != 0) //resetting the key if it is not pressed any more
{
resetKeyManual1(i,j, 1);
}
}
digitalWrite(outputsManual1[i],HIGH);
delayMicroseconds(500); //setting the row high and waiting 0.5ms until next cycle
}
}
// ==============
// == Manual 1 ==
// ==============
//if a key is pressed, this Funtion is called and outputs to serial the key location, it also sends the keystroke if not already done so
void keyPressedManual1(int row, int col, int kanal){
if(keyDownManual1[row][col]==0){ //if the function is called for the first time for this key
int kanal = 1;
noteOn(kanal, layout[row][col], 127);
MidiUSB.flush();
}
keyDownManual1[row][col]++;
}
void resetKeyManual1(int row, int col, int kanal){ //resetting the variables after key is released
keyDownManual1[row][col] = 0;
keyLongManual1[row][col] = false;
noteOff(kanal, layout[row][col], 127);
MidiUSB.flush();
}
Meine Lösung sieht so aus für die Tastenmatrix.
Also erstmal Respekt, soweit war ich nach wenigen Tagen noch lange nicht!
Deine Heransgehensweise ist gänzlich anders, als meine. Du prüfst quasi Taste für Taste durch, ob sie gedrückt ist, und je nachdem sendest du direkt einen NoteOn oder NoteOff Befehl. Ich scanne erst einmal alle Tasten durch und schreibe die HIGHs und LOWs in ein separates Array pro Manual/Pedal, anschließend sende ich gesammelt die Note-Befehle. Somit spare ich mir auch das Dreifach-Array noch mit dem MIDI-Kanal.
Zu deiner Herausforderung. Möglicherweise habe ich einen Ansatzpunkt gefunden.
Versuche mal die geschweifte Klammer erst nach dem NoteOff Befehl zuzumachen.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
...
sendNoteOn(note); //Sende MIDI on
} else
{
// Taste losgelassen
(notePressed[chan][row][col] = false); // Speicherung des Noenwertes
//note = 36 + (4*col) + row;
//Serial.print(" Kanal: ");
//Serial.print(chan);
//Serial.print(" Note: ");
//Serial.print(note);
//Serial.print(" Taste losgelassen: Zeile ");
//Serial.print(row);
//Serial.print(", Spalte ");
//Serial.println(col);
sendNoteOff(note);
}
}
//delay(50); // Warte
}
...
Unten im Spoiler findest du als Beispiel noch meinen Code. Entprellen mach ich nicht über Delay, sondern über millis().
Das Wichtigste sind stabile Pin-Zustände. Dass du mit INPUT_PULLUP arbeitest ist gut, das sorgt für ein stabiles HIGH und LOW. Genauso wichtig ist es, nach jedem Scan die Row erst auf HIGH zu setzen und dann von OUTPUT nach INPUT zu schalten. Das Schalten nach HIGH hatte ich erst nicht drin. Tatsächlich war das ursächlich für unkontrollierte "Geistertöne", weil da ab und zu ein Pin zwischen HIGH und LOW hin- und hergeflattert ist.
Zum Entprellen und delay bzw. millis(). Delay hält dir das gesamte Programm an. Hast du also ein paar Delays drin, addieren sich die Zeiten komplett auf für einen Loop-Durchlauf. Das bringt dir irgendwann spürbare Verzögerungen ein. Bei Millis merkt sich das Programm nur einen Zeitstempel und läuft aber weiter. Bei jedem Durchlauf wird der Zeitstempel verglichen und eine Aktion erst nach Ablaufen ausgeführt. So kannst du parallel weiterscannen und verlierst keine Zeit mit warten.
"Nachteil" von millis: Hier zählt einfach bei Einschalten des Arduinos eine Zahl von 0 an hoch. Ich weiß jetzt nicht mehr genau, ob sie bei Erreichen der Höchstzahl, die die Variable fassen kann, einfach von vorn anfängt oder ob die Variable dann "voll" ist und der Zeitstempel-Vergleich nicht mehr funktioniert. JEDOCH: bis dahin vergehen etwas mehr als 2 Tage. Wenn du also zwischendurch den PC mal ausgeschaltet hattest und der Arduino auch ausging, ist das kein Thema. Bei mir ist das so, deshalb messe ich dem keine Bedeutung bei.
Mein Komplettprogramm, das neben den Manualen und Pedalen auch noch 48 Pistons unter den Manualen scannt (hier auf Basis von verketteten Schieberegistern), braucht für einen Durchlauf 5ms. Also so lange, wie bei dir alleine eine Delay-Wartepause nach Tastendruck. Das illustriert aus meiner Sicht ganz gut den Vorteil von millis.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//#####MIDI-Kanäle definieren#####
int midichannelP = 0;
int midichannelI = 1; //das ergibt Kanal 2 für das 1. Manual
int midichannelII = 2; //das ergibt Kanal 3 für das 2. Manual
int midichannelIII = 3; //das ergibt Kanal 4 für das 3. Manual
int midichannelIV = 4; //das ergibt Kanal 5 für das 4. Manual
//#####Diodenmatrix für Manuale und Pedal#####
//Amount of Rows and Columns
const int rows = 8;
const int rowsP = 4; //Pedal hat 8x4 Matrix für 32 Tasten
const int cols = 8;
//row-Pins gemeinsam für alle
uint8_t rowpin[rows] = { 2, 3, 4, 5, 6, 7, 8, 9 }; //Pins an der Seite suchen
//col-Pins pro Manual
uint8_t colpinI[cols] = { 38, 40, 42, 44, 46, 48, 50, 52 };
uint8_t colpinII[cols] = { 39, 41, 43, 45, 47, 49, 51, 53 };
uint8_t colpinIII[cols] = { 22, 24, 26, 28, 30, 32, 34, 36 };
uint8_t colpinIV[cols] = { 23, 25, 27, 29, 31, 33, 35, 37 };
uint8_t colpinP[cols] = { 14, 15, 16, 17, 18, 19, 20, 21 };
//Entprellen der Tasten
unsigned long Delay = 10; //in Millisekunden
unsigned long DelayMikro = 10; //in Mikrosekunden
//Setup Key Data Arrays
byte keysI[rows][cols] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
};
byte keysII[rows][cols] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
};
byte keysIII[rows][cols] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
};
byte keysIV[rows][cols] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
};
byte keysP[rowsP][cols] = {
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 },
};
//Setup Key Press Arrays
byte lastI[rows][cols];
byte lastII[rows][cols];
byte lastIII[rows][cols];
byte lastIV[rows][cols];
byte lastP[rowsP][cols];
//deckungsgleich zum Tasten-Array die MIDI-Codes für NoteOn/Off
uint8_t keyToMidiMap[rows][cols] = { 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82, 83,
84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99,
};
//Entprellen der Tasten
unsigned long BounceIOn[rows][cols];
unsigned long BounceIOff[rows][cols];
unsigned long BounceIIOn[rows][cols];
unsigned long BounceIIOff[rows][cols];
unsigned long BounceIIIOn[rows][cols];
unsigned long BounceIIIOff[rows][cols];
unsigned long BounceIVOn[rows][cols];
unsigned long BounceIVOff[rows][cols];
unsigned long BouncePOn[rows][cols];
unsigned long BouncePOff[rows][cols];
void setup() {
//#####Setup Matrix Rows und Columns für 4 Manuale und Pedal#####
for (int i = 0; i <= 7; i++) {
pinMode(rowpin[i], INPUT);
pinMode(colpinI[i], INPUT_PULLUP);
pinMode(colpinII[i], INPUT_PULLUP);
pinMode(colpinIII[i], INPUT_PULLUP);
pinMode(colpinIV[i], INPUT_PULLUP);
pinMode(colpinP[i], INPUT_PULLUP);
}
}
void loop() {
//#####Manuale scannen#####
for (int i = 0; i <= 7; i++) {
pinMode(rowpin[i], OUTPUT);
digitalWrite(rowpin[i], LOW);
delayMicroseconds(DelayMikro);
//I. Manual scannen
for (int j = 0; j <= 7; j++) {
keysI[i][j] = digitalRead(colpinI[j]);
}
//II. Manual scannen
for (int j = 0; j <= 7; j++) {
keysII[i][j] = digitalRead(colpinII[j]);
}
//III. Manual scannen
for (int j = 0; j <= 7; j++) {
keysIII[i][j] = digitalRead(colpinIII[j]);
}
//IV. Manual scannen
for (int j = 0; j <= 7; j++) {
keysIV[i][j] = digitalRead(colpinIV[j]);
}
//Pedal scannen
if (i <= 3) {
for (int j = 0; j <= 7; j++) {
keysP[i][j] = digitalRead(colpinP[j]);
}
}
delayMicroseconds(DelayMikro);
digitalWrite(rowpin[i], HIGH); //neu eingefügt, 04.07.2024
pinMode(rowpin[i], INPUT);
delayMicroseconds(DelayMikro);
}
//#####gedrückte Tasten als MIDI-Befehle senden#####
for (int i = 0; i <= 7; i++) {
for (int j = 0; j <= 7; j++) {
//I. Manual
if (keysI[i][j] == LOW && lastI[i][j] == HIGH && ((millis() - BounceIOn[i][j]) > Delay)) {
noteOn(midichannelI, keyToMidiMap[i][j], 127);
lastI[i][j] = keysI[i][j];
BounceIOff[i][j] = millis();
}
if (keysI[i][j] == HIGH && lastI[i][j] == LOW && ((millis() - BounceIOff[i][j]) > Delay)) {
noteOff(midichannelI, keyToMidiMap[i][j], 0);
lastI[i][j] = keysI[i][j];
BounceIOn[i][j] = millis();
}
//II. Manual
if (keysII[i][j] == LOW && lastII[i][j] == HIGH && ((millis() - BounceIIOn[i][j]) > Delay)) {
noteOn(midichannelII, keyToMidiMap[i][j], 127);
lastII[i][j] = keysII[i][j];
BounceIIOff[i][j] = millis();
}
if (keysII[i][j] == HIGH && lastII[i][j] == LOW && ((millis() - BounceIIOff[i][j]) > Delay)) {
noteOff(midichannelII, keyToMidiMap[i][j], 0);
lastII[i][j] = keysII[i][j];
BounceIIOn[i][j] = millis();
}
//III. Manual
if (keysIII[i][j] == LOW && lastIII[i][j] == HIGH && ((millis() - BounceIIIOn[i][j]) > Delay)) {
noteOn(midichannelIII, keyToMidiMap[i][j], 127);
lastIII[i][j] = keysIII[i][j];
BounceIIIOff[i][j] = millis();
}
if (keysIII[i][j] == HIGH && lastIII[i][j] == LOW && ((millis() - BounceIIIOff[i][j]) > Delay)) {
noteOff(midichannelIII, keyToMidiMap[i][j], 0);
lastIII[i][j] = keysIII[i][j];
BounceIIIOn[i][j] = millis();
}
//IV. Manual
if (keysIV[i][j] == LOW && lastIV[i][j] == HIGH && ((millis() - BounceIVOn[i][j]) > Delay)) {
noteOn(midichannelIV, keyToMidiMap[i][j], 127);
lastIV[i][j] = keysIV[i][j];
BounceIVOff[i][j] = millis();
}
if (keysIV[i][j] == HIGH && lastIV[i][j] == LOW && ((millis() - BounceIVOff[i][j]) > Delay)) {
noteOff(midichannelIV, keyToMidiMap[i][j], 0);
lastIV[i][j] = keysIV[i][j];
BounceIVOn[i][j] = millis();
}
//Pedal
if (keysP[i][j] == LOW && lastP[i][j] == HIGH && ((millis() - BouncePOn[i][j]) > Delay)) {
noteOn(midichannelP, keyToMidiMap[i][j], 127);
lastP[i][j] = keysP[i][j];
BouncePOff[i][j] = millis();
}
if (keysP[i][j] == HIGH && lastP[i][j] == LOW && ((millis() - BouncePOff[i][j]) > Delay)) {
noteOff(midichannelP, keyToMidiMap[i][j], 0);
lastP[i][j] = keysP[i][j];
BouncePOn[i][j] = millis();
}
}
}
}

#120

Zitat von Soubasse im Beitrag #117
Ich scanne erst einmal alle Tasten durch und schreibe die HIGHs und LOWs in ein separates Array pro Manual/Pedal, anschließend sende ich gesammelt die Note-Befehle.
Ist das nicht theoretisch schlecht für die Latenz? Wenn ich fiktiv 60 Tasten Anfrage und dann für Veränderungen sende, dann ist doch die Latenz deutlich höher, als wenn ich bei einer Veränderung unmittelbar diese Sende. Auf der anderen Seite dauert es dann bis zum erneuten erkennen der seinen Taste dann auch wieder länger und das Ergebnis müsste bei beiden Varianten ähnlich sein. Wobei die Lösung mit weniger code wohl schneller sein müsste...
Du hast das sich bestimmt getestet wie ich dich einschätzen oder?
- Hauptwerk
- Hauptwerk-Konfiguration, Diskussion
- Hauptwerk-Samplesets
- GrandOrgue
- GrandOrgue-Konfiguration, Diskussion
- GrandOrgue-Samplesets
- Sweelinq
- Sweelinq-Konfiguration, Diskussion
- Sweelinq-Samplesets
- Sonstige Orgelsoftware
- Organteq
- Sonstige Sampler
- Hardware
- Spieltische und Selbstbau
- Zubehör (PCs, Monitore, Interfaces etc.)
- Klangabstrahlung
- Musikalisches
- Noten, Einspielungen, Konzerte
- Sonstige Musikthemen
Jetzt anmelden!
Jetzt registrieren!