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.
Arduino - Programmierung
![avatar](https://files.homepagemodules.de/b912600/avatar-4dd921d0-2.jpg)
Beiträge ab #107 aus Midifizierung eines pneumatischen Spieltisches hierher verschoben.
Ich kenne mich mit Arduino nicht aus, aber wenn du in einer Schleife ein Sleep einbaust, werden dann noch Signale verarbeitet?
Jetzt mal mit einem ggf. unrealistischen Wert: 200ms Pause, nach 100ms kommt ein Signal an - wird das nach dem Ablauf der 200ms verarbeitet oder ignoriert?
Kommt drauf an. Man kann Verzögerungen zweierlei Art einbauen: Delay (in Milli- oder Mikrosekunden) und millis() bzw. micros(). Beides führt zu Verzögerung, jedoch unterschiedlich. Ein Delay hält das komplette Programm für die angegebene Zeit an. Millis ist eher ein Zeitstempel, den man an bestimmten Punkten des Programms auslesen kann. So kann man z.B. definieren, dass eine bestimmte Aktion nur ausgeführt wird, wenn das letzte Mal mehr als 100 Millisekunden her ist. Der Vorteil bei dieser Vorgehensweise ist, dass bei Nichterfüllung der Bedingung (letztes Ereignis länger als 100ms her) das Programm trotzdem weiter ausgeführt wird. Das Programm kommt in der Schleife immer wieder an dieser Bedingung vorbei, bis sie erfüllt ist.
Mit Delays im Millisekunden-Bereich arbeite ich bei MIDI wenig, da das natürlich auch Latenz verursacht. Je nach Anwendungsfall mache ich es dann über millis(). Beim Delay im Mikrosekundenbereich ist es natürlich nicht so dramatisch. Gefühlt gebe ich damit allgemein der Hardware etwas Zeit, sich zu sortieren. Keine Ahnung, wie schnell sonst so ein Loop bei 84 MHz durchläuft. Auch das könnte man mit millis() genau messen.
Bei dem ersten geschilderten Fehler (Quinte f0/c1 hat auch cis1 mit gespielt oder Oktave C und c0 hat das GIS mitgespielt) hatte ich schon so einen Verdacht und habe nach bestimmten Einzelschritten der 8x8 Matrix-Abfrage µs-Delays eingebaut, was das Problem behoben hat.
![avatar](https://files.homepagemodules.de/b912600/avatar-4dd921d0-2.jpg)
Ich würde dir grundsätzlich Recht geben, dachte ich auch erst. Ich hatte dann zum Test den alten, originalen Mikrocontroller wieder an die Platine gesteckt und per USB betrieben, da war der Fehler weg. Musste also Software sein. Beim Analysieren meines Codes und vergleichbarer anderer ist mir als Unterschied halt die Verzögerung nach bestimmten Schritten aufgefallen. Ich habe es einfach probiert und diese (einzige) Änderung hat den Fehler beseitigt.
![avatar](https://files.homepagemodules.de/b912600/avatar-4dd921d0-2.jpg)
Das ist mein Problem, ich will das auch immer gern verstehen. Momentan habe ich es aber noch nicht verstanden. Ich kann erstmal nur beobachten. Und momentan sagt die Beobachtung, dass der erste bemerkte Fehler nachhaltig weg ist.
Ich halte es auch nicht für ganz unlogisch, dass es so ist. Immerhin findet bei der Matrix-Abfrage ein superschneller Wechsel zwischen High- und Low-Zuständen statt, der ausgelesen und in ein Array geschrieben wird. Kann doch sein, dass auch so ein µC bisschen Rüstzeit zwischen den Arbeitsschritten braucht (das Werkzeug weglegen, Handschuhe ausziehen, Hebel auf HIGH stellen, Handschuhe wieder an, Werkzeug in die Hand, gucken wo es blinkt und dann den Zustand ins Array meißeln).
![avatar](https://files.homepagemodules.de/b912600/avatar-4dd921d0-2.jpg)
![avatar](https://files.homepagemodules.de/b912600/avatar-4dd921d0-2.jpg)
"Kann doch sein, dass auch so ein µC bisschen Rüstzeit zwischen den Arbeitsschritten braucht"
Nein, braucht es nicht. Je schneller er das macht, desto besser. Das was ich nicht weiß ist, ob ein Signal entprellt werden muss, d.h,. das z.B. ein NoteOn nicht mehrfach ausgelöst wird. Dazu baut man dann eine kleine Verzögerung ein, wodurch das verhindert wird.
Ein weiterer Grund für eine eingebaute Verzögerung kann sein, das die Hardware geschont wird, weil eine Abfrage von mehreren tausend Mal in einer Sekunde keinen Sinn macht (die Hardware läuft auf Hochtouren). Aber da weiß ich nicht genau, wie das System bzw. die Hardware/Software-Library "tickt".
@Montre
Danke für das Angebot! Ich komme evtl. darauf zurück. Vorher probiere ich noch das eine oder andere, hatte heute noch eine andere Idee wo ich einen Fehler gemacht haben könnte.
@Bkoeln
Könnte das hier für dich interessant sein?
https://www.gebrauchtorgeln.de/2_manualk...1-8-1105-0.html
#10
![avatar](https://files.homepagemodules.de/b912600/avatar-f9e7f889-14.jpg)
Man sollte immer eine kurzes Unterbrechung einbauen. Zum einen braucht die Elektronik ja einen Moment um zu schalten, aber auch Dioden oder ähnliches brauchen eine gewisse Zeit. Wobei wir da im Bereich Microsekunden reden. Meine Abfrage der Matrix schaut z.B so aus:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//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);
}
}
Ich gebe ihm immer 5 Microsekunden. Es ist wohl nicht zwingend notwendig, aber es bietet der CPU ja auch Zeit mal zu schlafen. Allgemein ist in einer Schleife vor einem erneuten durchlaufen eine kleine Unterbrechung ganz sinnvoll. Es spart Strom und die CPU läuft nicht immer auf voller Last, was auch die Temperatur senkt und somit indirekt die Lebensdauer wohl nicht negativ beeinflusst.
Ich hatte beim Programmieren ein absurdes Problem. Mein Arduino hatte alle Tasten die gedrückt oder losgelassen wurden korrekt erkannt, aber am Rechner kam kein Midi Signal an. Nach vielen Stunden Debuggen habe ich nur gesehen, dass alles korrekt läuft. Die Ursache war die midiusb Bibliothek. Ich habe ein Senden der Daten gefordert mit einem flush. Dieser bewirkt, dass die Daten sofort gesendet werden, ohne noch auf weitere Daten zu warten. Aber genau auf meinem Arduino Due war die Besonderheit, dass der Controller eine bestimmte Zeitspanne braucht um wieder etwas über USB zu senden. Daher wurden NoteON/OFF dann nicht gesendet mit dem Ergebnis, dass ein Ton nicht gespielt wurde oder hängen blieb. Ein entfernen des flush Befehls hat das Problem gelöst. Dadurch kann es zwar ein paar Microsekunden dauern bevor alles gesendet wird, aber das ist wohl unerheblich :)
Lange Rede kurzer Sinn: Manchmal liegt das Problem an einer Stelle, an die man nicht denkt oder niemals vermuten würde.
Ich habe testweise nochmal den originalen Controller des Keyboards angesteckt, da läuft alles fehlerfrei, was Hänger anbelangt. Ich kann also Hardware ausschließen, es muss am Code liegen.
Ich verwende bei der Abfrage folgenden Code, der alle HIGH und LOW Status in ein 8x8 Array schreibt. Danach gibt es eine kombinierte For-Schleife, die den Array-Inhalt als MIDI NoteOn/Off sendet.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pinMode(col1, INPUT_PULLUP);
pinMode(col2, INPUT_PULLUP);
pinMode(col3, INPUT_PULLUP);
pinMode(col4, INPUT_PULLUP);
pinMode(col5, INPUT_PULLUP);
pinMode(col6, INPUT_PULLUP);
pinMode(col7, INPUT_PULLUP);
pinMode(col8, INPUT_PULLUP);
//der folgende Absatz kommt dann acht Mal, die Variable DelayMS habe ich auf 10 (mit 5 gab es mehr Schwierigkeiten)
pinMode(row1, OUTPUT);
digitalWrite(row1, LOW);
delayMicroseconds(DelayMS);
keysA[0][0] = digitalRead(col1);
keysA[0][1] = digitalRead(col2);
keysA[0][2] = digitalRead(col3);
keysA[0][3] = digitalRead(col4);
keysA[0][4] = digitalRead(col5);
keysA[0][5] = digitalRead(col6);
keysA[0][6] = digitalRead(col7);
keysA[0][7] = digitalRead(col8);
pinMode(row1, INPUT);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for (int row = 0; row <= 7; row++) {
for (int col = 0; col <= 7; col++) {
if (keysA[row][col] == LOW && lastA[row][col] == HIGH) {
noteOn(midichannel, keyToMidiMap[row][col], 127);
MidiUSB.flush();
lastA[row][col] = keysA[row][col];
//delay(Delay);
}
if (keysA[row][col] == HIGH && lastA[row][col] == LOW) {
noteOff(midichannel, keyToMidiMap[row][col], 0);
MidiUSB.flush();
lastA[row][col] = keysA[row][col];
//delay(Delay);
}
}
}
Midiflush habe ich auch probiert rein- und rauszumachen. Hatte gar keinen Einfluss.
Mit der Delay-Variable in Mikrosekunden habe ich herumexperimentiert. Die wenigstens Schwierigkeiten habe ich mit 10 µs, mehr oder weniger als das sorgen für mehr Hänger. Ganz ohne Delay habe ich sogar Ghosting.
Ich hatte dann noch so einen Veracht, ob es am Arduino Due liegen kann. Der macht ja manches anders, als ein Uno oder Mega (andere Spannung, anderer Prozessor, schnellere Taktrate, etc.). Habe gelesen, dass der digitalWrite Befehl für irgendwelche Schwierigkeiten beim Due sorgen soll. Aber wenn das so wäre, dann hätte @Christian_Hofmann ja auch Probleme damit haben müssen. Du nutzt doch einen Due oder?
Ich wollte das ganze vlt. noch einmal altmodisch mit einem Mega und einem DIN-Kabel probieren. Vielleicht hilft ja das komplett andere Setting.
#12
![avatar](https://files.homepagemodules.de/b912600/avatar-f9e7f889-14.jpg)
@Montre Ich kenne deinen Code nicht, ich vermute, dass du in den Funktionen noteon und noteoff ein sendMIDI einfach ausführst oder? Versuche mal hinter den sendMIDI direkt ein delayMicroseconds(300); zu setzen und entferne zusätzlich einmal alles flush aus deinem Code (auskommentieren). Schau dann einmal ob es funktioniert. Das hat zumindest bei mir so funktioniert.
Ich habe dir mal meinen Code angehängt wie er aktuell läuft. Er ist zwar etwas durcheinander, da er neben zwei Manualen mit Matrix auch ein Pedal mit Matrix und ein weiteres ohne abruft. Aber vielleicht findest du da etwas hilfreiches.
Inzwischen nutze ich bei neuen Projekten lieber den Raspberry Pi Pico, zum einen ist er mit 5 Euro sehr viel günstiger, zum anderen lässt er sich mit Python sehr viel angenehmer Debuggen. Die Arduinos sind da leider alle ganz mies in dieser Disziplin... Ohne teure spezielle Hardware und sehr viel Fachwissen ist man eigentlich auf die Textausgabe über die Konsole angewiesen. Man kann nciht einfach mal zur Laufzeit in die Variablen und so schauen.
![avatar](https://files.homepagemodules.de/b912600/avatar-4dd921d0-2.jpg)
#14
![avatar](https://files.homepagemodules.de/b912600/avatar-f9e7f889-14.jpg)
Danke für deine Tipps @Christian_Hofmann. Das probiere ich heute Abend mal aus, ich weiß nur nicht, ob es hilft. Gefühlt lasse ich die Taste ja schneller los, als der NoteOff Befehl gesendet werden kann oder aber zwei Tasten (v.a. f1 und g1) blockieren sich da irgendwie gegenseitig.
Hier der gesamte Code, den ich verwende (ja ich weiß, man kann über Schleifen noch viel mehr zusammenfassen). Da ist noch ein bisschen zum Testen auskommentiert, ist also nicht final. In dieser Gestalt verursacht er aber momentan die wenigsten Probleme.
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
// Name: Arduino Mega Midi Controller Mega side.
// Created: May 10, 2021
// Last Edited: Mar 26, 2022
// Author: Larason2
// Acknowledgements: Bald Engineer, Amanda Ghassaei, jeffb42, GrumpyMike, John Main, Ghost, RIP Tutorial, Arduino tutorials.
// Includes Midi Through, wiring for pistons, improved debounce.
//für Arduino Due und MIDIUSB-Bibliothek angepasst
#include "MIDIUSB.h"
//Setup Key Data Arrays
byte keysA[8][8] = { {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},
};
//Setup Key Press Arrays
byte lastA[8][8];
//deckungsgleich zum Tasten-Array die MIDI-Codes für NoteOn/Off
uint8_t keyToMidiMap[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, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99,
};
//MIDI Kanal
int midichannel = 3; //das ergibt Kanal 4 für das 3. Manual
//Entprellen der Tasten
unsigned long Delay = 10; //in Millisekunden
unsigned long DelayMS = 10; //in Mikrosekunden, 10 ging so recht und schlecht
unsigned long BounceAOn[8][8];
unsigned long BounceAOff[8][8];
//row-Pins
int row1 = 22;
int row2 = 24;
int row3 = 26;
int row4 = 28;
int row5 = 30;
int row6 = 32;
int row7 = 34;
int row8 = 36;
//col-Pins
int col1 = 23;
int col2 = 25;
int col3 = 27;
int col4 = 29;
int col5 = 31;
int col6 = 33;
int col7 = 35;
int col8 = 37;
//Sequenzer
bool key2Alt = LOW;
bool key3Alt = LOW;
bool key4Alt = LOW;
bool key5Alt = LOW;
int seq1 = 2;
int seq2 = 3;
int seq3 = 4;
int seq4 = 5;
//Variablen Schweller OW
int pinOW = A0;
int MapOW;
int LastMapOW = 127; //ganz auf
int LastPotOW = 980; //ganz auf bei ca. 980-1000, 1023 werden nicht erreicht
const unsigned long repeat = 50; // Zeit in ms, die gewartet wird, bis die Schweller-Schleife erneut durchläuft
unsigned long lastrepeatOW; // gespeicherte millis-Zeit des letzten Schweller-Durchlaufs
int DiffMapOW = 4; //Differenzwert zwischen Ist und Soll, ab dem keine weitere Schweller-Bewegung mehr stattfindet, quasi Entprellwert
int DiffOW = 5; //Wert, um den der MIDI-Wert beim Schweller addiert/subtrahiert wird
int PotT = 40; //Entprellwert Schweller
int CCchanOW = 4; //Kanal 5 für Schweller OW
int channel;
int controller = 11; //Controller Nummer, 11=Expression Pedal
int value;
/** 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);
}
void sendControlChange (byte channel, byte controller, byte value) {
midiEventPacket_t event = {0x0B, 0xB0 | channel, controller, value};
MidiUSB.sendMIDI(event);
}
bool MidiButton(int pin, byte midisig, bool keyAlt) { //Button-Pin, Noten-Nummer
bool key = digitalRead(pin);
if (pin == seq1 || pin == seq2 || pin == seq3 || pin == seq4) {
if (keyAlt == LOW && key == HIGH) {
noteOn(3, midisig, 64);
MidiUSB.flush();
keyAlt = key;
delay(Delay);
return keyAlt;
}
if (keyAlt == HIGH && key == LOW) {
noteOff(3, midisig, 64);
MidiUSB.flush();
keyAlt = key;
delay(Delay);
return keyAlt;
}
}
else {
if (keyAlt == HIGH && key == LOW) {
noteOn(3, midisig, 64);
MidiUSB.flush();
keyAlt = key;
delay(Delay);
return keyAlt;
}
if (keyAlt == LOW && key == HIGH) {
noteOff(3, midisig, 64);
MidiUSB.flush();
keyAlt = key;
delay(Delay);
return keyAlt;
}
}
}
/****************************************************************************/
void setup() {
//Initialize Row Pins Keyboard A (Reihe sind unten jeder 2. Pin)
pinMode(row1, INPUT);
pinMode(row2, INPUT);
pinMode(row3, INPUT);
pinMode(row4, INPUT);
pinMode(row5, INPUT);
pinMode(row6, INPUT);
pinMode(row7, INPUT);
pinMode(row8, INPUT);
//Initialize Column Pins Keyboard A (Spalten sind die oberen Kontakte)
pinMode(col1, INPUT);
pinMode(col2, INPUT);
pinMode(col3, INPUT);
pinMode(col4, INPUT);
pinMode(col5, INPUT);
pinMode(col6, INPUT);
pinMode(col7, INPUT);
pinMode(col8, INPUT);
pinMode(pinOW, INPUT); //Schweller OW
pinMode(seq1, INPUT_PULLUP);
pinMode(seq2, INPUT_PULLUP);
pinMode(seq3, INPUT_PULLUP);
pinMode(seq4, INPUT_PULLUP);
}
void loop() {
key2Alt = MidiButton(seq1, 100, key2Alt); //Sequenzer-Taste
key3Alt = MidiButton(seq2, 101, key3Alt); //Sequenzer Taste
key4Alt = MidiButton(seq3, 102, key4Alt); //Sequenzer Taste
key5Alt = MidiButton(seq4, 103, key5Alt); //Sequenzer Taste
pinMode(col1, INPUT_PULLUP);
pinMode(col2, INPUT_PULLUP);
pinMode(col3, INPUT_PULLUP);
pinMode(col4, INPUT_PULLUP);
pinMode(col5, INPUT_PULLUP);
pinMode(col6, INPUT_PULLUP);
pinMode(col7, INPUT_PULLUP);
pinMode(col8, INPUT_PULLUP);
pinMode(row1, OUTPUT);
digitalWrite(row1, LOW);
delayMicroseconds(DelayMS);
keysA[0][0] = digitalRead(col1);
keysA[0][1] = digitalRead(col2);
keysA[0][2] = digitalRead(col3);
keysA[0][3] = digitalRead(col4);
keysA[0][4] = digitalRead(col5);
keysA[0][5] = digitalRead(col6);
keysA[0][6] = digitalRead(col7);
keysA[0][7] = digitalRead(col8);
pinMode(row1, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row2, OUTPUT);
digitalWrite(row2, LOW);
delayMicroseconds(DelayMS);
keysA[1][0] = digitalRead(col1);
keysA[1][1] = digitalRead(col2);
keysA[1][2] = digitalRead(col3);
keysA[1][3] = digitalRead(col4);
keysA[1][4] = digitalRead(col5);
keysA[1][5] = digitalRead(col6);
keysA[1][6] = digitalRead(col7);
keysA[1][7] = digitalRead(col8);
pinMode(row2, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row3, OUTPUT);
digitalWrite(row3, LOW);
delayMicroseconds(DelayMS);
keysA[2][0] = digitalRead(col1);
keysA[2][1] = digitalRead(col2);
keysA[2][2] = digitalRead(col3);
keysA[2][3] = digitalRead(col4);
keysA[2][4] = digitalRead(col5);
keysA[2][5] = digitalRead(col6);
keysA[2][6] = digitalRead(col7);
keysA[2][7] = digitalRead(col8);
pinMode(row3, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row4, OUTPUT);
digitalWrite(row4, LOW);
delayMicroseconds(DelayMS);
keysA[3][0] = digitalRead(col1);
keysA[3][1] = digitalRead(col2);
keysA[3][2] = digitalRead(col3);
keysA[3][3] = digitalRead(col4);
keysA[3][4] = digitalRead(col5);
keysA[3][5] = digitalRead(col6); //Problemton f1
keysA[3][6] = digitalRead(col7);
keysA[3][7] = digitalRead(col8); //Problemton g1
pinMode(row4, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row5, OUTPUT);
digitalWrite(row5, LOW);
delayMicroseconds(DelayMS);
keysA[4][0] = digitalRead(col1);
keysA[4][1] = digitalRead(col2);
keysA[4][2] = digitalRead(col3);
keysA[4][3] = digitalRead(col4);
keysA[4][4] = digitalRead(col5);
keysA[4][5] = digitalRead(col6);
keysA[4][6] = digitalRead(col7);
keysA[4][7] = digitalRead(col8);
pinMode(row5, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row6, OUTPUT);
digitalWrite(row6, LOW);
delayMicroseconds(DelayMS);
keysA[5][0] = digitalRead(col1);
keysA[5][1] = digitalRead(col2);
keysA[5][2] = digitalRead(col3);
keysA[5][3] = digitalRead(col4);
keysA[5][4] = digitalRead(col5);
keysA[5][5] = digitalRead(col6);
keysA[5][6] = digitalRead(col7);
keysA[5][7] = digitalRead(col8);
pinMode(row6, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row7, OUTPUT);
digitalWrite(row7, LOW);
delayMicroseconds(DelayMS);
keysA[6][0] = digitalRead(col1);
keysA[6][1] = digitalRead(col2);
keysA[6][2] = digitalRead(col3);
keysA[6][3] = digitalRead(col4);
keysA[6][4] = digitalRead(col5);
keysA[6][5] = digitalRead(col6);
keysA[6][6] = digitalRead(col7);
keysA[6][7] = digitalRead(col8);
pinMode(row7, INPUT);
//delayMicroseconds(DelayMS);
pinMode(row8, OUTPUT);
digitalWrite(row8, LOW);
delayMicroseconds(DelayMS);
keysA[7][0] = digitalRead(col1);
keysA[7][1] = digitalRead(col2);
keysA[7][2] = digitalRead(col3);
keysA[7][3] = digitalRead(col4);
keysA[7][4] = digitalRead(col5);
keysA[7][5] = digitalRead(col6);
keysA[7][6] = digitalRead(col7);
keysA[7][7] = digitalRead(col8);
pinMode(row8, INPUT);
//delayMicroseconds(DelayMS);
pinMode(col1, INPUT);
pinMode(col2, INPUT);
pinMode(col3, INPUT);
pinMode(col4, INPUT);
pinMode(col5, INPUT);
pinMode(col6, INPUT);
pinMode(col7, INPUT);
pinMode(col8, INPUT);
//delayMicroseconds(DelayMS);
//gedrückte Tasten als MIDI-Befehle senden
for (int row = 0; row <= 7; row++) {
for (int col = 0; col <= 7; col++) {
if (keysA[row][col] == LOW && lastA[row][col] == HIGH) {
noteOn(midichannel, keyToMidiMap[row][col], 127);
MidiUSB.flush();
lastA[row][col] = keysA[row][col];
//delay(Delay);
}
if (keysA[row][col] == HIGH && lastA[row][col] == LOW) {
noteOff(midichannel, keyToMidiMap[row][col], 0);
MidiUSB.flush();
lastA[row][col] = keysA[row][col];
//delay(Delay);
}
}
}
/*
//gedrückte Tasten als MIDI-Befehle senden
for (int row = 0; row <= 7; row++) {
for (int col = 0; col <= 7; col++) {
if (keysA[row][col] == LOW && lastA[row][col] == HIGH && ((millis() - BounceAOn[row][col]) > Delay)) {
noteOn(midichannel, keyToMidiMap[row][col], 127);
MidiUSB.flush();
lastA[row][col] = keysA[row][col];
BounceAOff[row][col] = millis();
//delay(Delay);
}
if (keysA[row][col] == HIGH && lastA[row][col] == LOW && ((millis() - BounceAOff[row][col]) > Delay)) {
noteOff(midichannel, keyToMidiMap[row][col], 0);
MidiUSB.flush();
lastA[row][col] = keysA[row][col];
BounceAOn[row][col] = millis();
//delay(Delay);
}
}
}
*/
//Schweller OW
int CurOW = analogRead(0);
if (CurOW > 980) CurOW = 980;
if (CurOW < 100) CurOW = 100;
MapOW = map(CurOW, 100, 980, 0, 127);
//Schweller 2. Manual (Oberwerk)
if (abs(MapOW - LastMapOW) >= DiffMapOW) {
if (millis() - lastrepeatOW >= repeat) {
if (MapOW < LastMapOW) {
LastMapOW = LastMapOW - DiffOW;
if (LastMapOW < 0) LastMapOW = 0;
if (abs(MapOW - LastMapOW) <= DiffMapOW) LastMapOW = MapOW;
sendControlChange(CCchanOW, controller, LastMapOW); // Set the value of controller 10 on channel 0 to 65
}
if (MapOW > LastMapOW) {
LastMapOW = LastMapOW + DiffOW;
if (LastMapOW > 127) LastMapOW = 127;
if (abs(MapOW - LastMapOW) <= DiffMapOW) LastMapOW = MapOW;
sendControlChange(CCchanOW, controller, LastMapOW); // Set the value of controller 10 on channel 0 to 65
}
lastrepeatOW = millis();
}
}
}
Ich wollte evtl. mal noch eine andere Art der Programmierung versuchen. Es gibt da noch die Keypad Library, die auf Matrizen ausgelegt ist.
- 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!