Drum-kit: Piezo und Led

Hallo Leute,

ich habe mit ein Drumkit gebaut, welches über piezos angesteuert wird. Ich benutze “Ardrumo” um mir die Signale über USB in MIDI umzuwandeln (sodass ich kein Midikabel benötige). Die Töne lege ich dann in garageband fest.
So sieht das Programm aus:

#define LEDPIN 13 // status LED pin
#define PIEZOTHRESHOLD 5 // analog threshold for piezo sensing
#define PADNUM 6 // number of pads

int val;
void setup() {

pinMode(LEDPIN, OUTPUT);
Serial.begin(57600); // set serial output rate
}
void loop() {

for(int i = 0; i < PADNUM; i++) {

val = analogRead(i);
if( val >= PIEZOTHRESHOLD ) {
digitalWrite(LEDPIN,HIGH); // indicate we’re sending MIDI data
Serial.print(i);
Serial.print(",");
Serial.print(val);
Serial.println();
digitalWrite(LEDPIN,LOW);
}
}
}

Dazu sollen beim Anspielen der piezos LEDs aufleuchten. Dies habe ich auch in folgendem Sketch geschrieben:

int sensorPin1 = A0;
int sensorPin2 = A1;
int sensorPin3 = A2;
int sensorPin4 = A3;

int ledPin1 = 13;
int ledPin2 = 12;
int ledPin3 = 8;
int ledPin4 = 7;

int sensorValue = 0;

void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
}

void loop() {

sensorValue = analogRead(sensorPin1);
digitalWrite(ledPin1, HIGH);
delay(sensorValue);
digitalWrite(ledPin1, LOW);

sensorValue = analogRead(sensorPin2);
digitalWrite(ledPin2, HIGH);
delay(sensorValue);
digitalWrite(ledPin2, LOW);

sensorValue = analogRead(sensorPin3);
digitalWrite(ledPin3, HIGH);
delay(sensorValue);
digitalWrite(ledPin3, LOW);

sensorValue = analogRead(sensorPin4);
digitalWrite(ledPin4, HIGH);
delay(sensorValue);
digitalWrite(ledPin4, LOW);
}

Beide einzelnen Sketche funktionieren getrennt sehr gut, aber wenn ich beide zu einem frickle, dann funktioniert es nicht gut, das heißt das beim Anspielen des Drumpads zwar die LED leuchtet aber der Ton erst später oder gar nicht kommt. Insgesamt reagiert alles sehr verzögert und nicht präzise.

Sollte man alles lieber in einer Schleife abhandeln? Hierbei benötige ich Hilfe, denn dies is mein erstes Arduino-Projekt.

Delay() blockiert die Abarbeitung des Codes. Als Ersatz siehe http://arduino.cc/en/Tutorial/BlinkWithoutDelay Grüße Uwe

Vielen Dank für den Tip, das mit dem delay macht natürlich Sinn. Ich bekomme es aber nicht hin, das Beispie: blink without delay so umzuschreiben, das es auf meinen analogen Input reagiert.

Update:
Ich habe den Code folgendermaßen umgeschrieben:

#define PIEZOTHRESHOLD 45  // analog threshold for piezo sensing

#define PADNUM 4          // number of pads

int sensorPin1 = A0;  
int sensorPin2 = A1;  
int sensorPin3 = A2;
int sensorPin4 = A3;

int ledPin1 = 13;     // status LED pin
int ledPin2 = 12;
int ledPin3 = 8;
int ledPin4 = 7;

int sensorValue = 0;

int drum1; 
int drum2;
int drum3;
int drum4;

void setup() {

 pinMode(ledPin1, OUTPUT);  
 pinMode(ledPin2, OUTPUT);  
 pinMode(ledPin3, OUTPUT); 
 pinMode(ledPin4, OUTPUT); 

  Serial.begin(57600);   // set serial output rate

}



void loop() {



  // Loop through each piezo and send data

  // on the serial output if the force exceeds

  // the piezo threshold

  for(int i = 0; i < PADNUM; i++) {

sensorValue = analogRead(sensorPin1);
if( sensorValue >= PIEZOTHRESHOLD ) {
digitalWrite(ledPin1,HIGH);  // indicate we're sending MIDI data
Serial.print(i);
Serial.print(",");
Serial.print(sensorValue);
Serial.println();
digitalWrite(ledPin1,LOW);
}

sensorValue = analogRead(sensorPin2);
if( sensorValue >= PIEZOTHRESHOLD ) {
digitalWrite(ledPin2,HIGH);  // indicate we're sending MIDI data
Serial.print(i);
Serial.print(",");
Serial.print(sensorValue);
Serial.println();
digitalWrite(ledPin2,LOW);
}

sensorValue = analogRead(sensorPin3);
if( sensorValue >= PIEZOTHRESHOLD ) {
digitalWrite(ledPin3,HIGH);  // indicate we're sending MIDI data
Serial.print(i);
Serial.print(",");
Serial.print(sensorValue);
Serial.println();
digitalWrite(ledPin3,LOW);
}

sensorValue = analogRead(sensorPin4);
if( sensorValue >= PIEZOTHRESHOLD ) {
digitalWrite(ledPin4,HIGH);  // indicate we're sending MIDI data
Serial.print(i);
Serial.print(",");
Serial.print(sensorValue);
Serial.println();
digitalWrite(ledPin4,LOW);
}
  }

}

Nun werden die LEDs getrennt angesprochen. Das Problem welches nun auftritt, ist das beim Anschlag eines Piezos die Töne von allen 4 Pads abgespielt werden. Der liegt vielleicht darin das ich jeweils 4 For-schleifen benutze, wie kann ich dem Abhilfe verschaffen?

bin delber noch nicht so lange dabei aber ich könnte mir vorstellen das du das folgendermaßen hin bekommst:

sensorValue = analogRead(sensorPin[i]);
if( sensorValue >= PIEZOTHRESHOLD ) {
digitalWrite(ledPin[i],HIGH);  // indicate we're sending MIDI data
Serial.print(i);
Serial.print(",");
Serial.print(sensorValue);
Serial.println();
digitalWrite(ledPin[1],LOW);
}

Du müßtest nur sensorpin und ledpin auch zu arrays machen
so hast du aber nur noch eine if die entsprechend der pads-anzahl aufgerufen wird

ich hoffe ich liege nicht falsch…

Gruß
Thorsten

Ja es funktioniert! :slight_smile:
Gute Idee mit den Arrays und vielen Dank.