int red = 16;
int green = 14;
int blue = 12;
const int soundIn = 13;
int sound;
boolean Klatscher = false; // sagt aus, ob einmal geklatscht oder zweimal geklatscht wurde
boolean statusRed = false;
boolean statusGreen = false;
boolean statusBlue = false;
void setup() {
Serial.begin(9600);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
pinMode(soundIn, INPUT);
}
void loop() {
sound = digitalRead(soundIn);
if(!sound) {
Serial.println("1. Klatscher");
Klatscher = true;
delay(100);
for(int i;i<300;i++) { // wenn einmal geklatscht, für 300 Millisekunden abfragen ob nochmal geklatscht wurde
Serial.println("For"); // nur zu debug zwecken
delay(1);
sound = digitalRead(soundIn);
if(!sound) {
Serial.println("2. Klatscher");
Klatscher = false;
delay(100);
}
}
if(Klatscher = true) { // wenn nur einmal geklatscht wurde, dann rot an oder aus, jenachdem wie der Status ist
Serial.println("Nur ein Klatscher");
statusRed = !statusRed;
digitalWrite(red, statusRed);
Serial.println("Rot an");
}
else if(Klatscher = false) { // und hier das gleiche nur mit grün
Serial.println("Zweimal geklatscht");
statusGreen = !statusGreen;
digitalWrite(green, statusGreen);
Serial.println("Gruen an");
}
}
}
Das doppelte = macht einen Vergleich der beiden Werte links und rechts
Das einfache ist eine Zuweisung , der linke Teil bekommt den Wert des rechten Teils zugewiesen
Erstmal danke für die schnelle Antwort.
Ich habe jetzt ein doppeltes = an den beiden Stellen eingefügt, aber jetzt ignoriert der Sketch die 300 Millisekunden Wartezeit. Also z.B. klatsche ich einmal wird nicht auf das zweite klatschen gewartet sondern die rote led sofort angeschaltet.
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
So ist er auch auf portablen Geräten lesbar. Das kannst Du auch noch nachträglich ändern.
Du kannst aber so definiert das Klatschen erkennen?
Hätte Da so meine Bedenken - spätestens nach der 300ms Wartezeit - wenn Du bei 280ms bereits geklatscht hast, ist's Essig, bei 320ms ebenso.
Erfasse den Klatsch-Sensor IMMER.
Wenn ein Klatschen erkannt wurde und das letzte Klatschen weniger als eine Sekunde her ist ... +1, sonst =1.
Wenn eine Sekunde kein Klatschen erkannt wurde =0
So hast Du den Wert der zusammenhängenden Klatscher mit maximal einer Sekunde Pause.
ich hab mal versucht den Fehler in Deinem Sketch zu finden, habs aber dann aufgegeben, weil das letztlich mit dem delay in der for Schleife nix Richtiges werden kann. Delay macht eine Pause und es geht nichts anderes mehr, aber das hast Du ja sicher bereits selbst gemerkt und bist darum auf die for schleife gekommen. For Schleifen sind ebenfalls meist schlecht, weil alles was ausserhalb der Schleife steht natürlich während der Schleife ebenfalls nicht bearbeitet wird. Das gilt auch für do und while auch das sind Schleifen , wird aber häufig von Anfängern vergessen.
If Abfragen sind da viel besser geeignet da sie keine Schleife bilden.
Ich hab jetzt mal einen anderen Ansatz verfolgt, der sinniger Weise mit millis() arbeitet. Da ich keinen Klatschschalter habe, hab ich einen Taster verwendet zum probieren.
Zur Funktion
Wird ein Signal vom Taster erkannt wird zunächst eine Flankenerkennung gemacht. Damit wird die aktuelle Laufzeit in eine Variable abgelegt und ein Zähler erhöht. Innerhalb einer Sekunde wird durch weitere Signale der Zähler erhöht. Ist die Sekunde abgelaufen erfolgt die Auswertung des Zählers und Ansteuerung der LED mittels select Case. Nach 10 s werden alle LED ausgeschaltet und es kann von vorne beginnen.
Es gibt da sicher noch geschicktere Lösungen, mir ging es aber darum das es möglichst einfach für Dich bleibt damit du es verstehen kannst.
Grüß Heinz
/* Ein Taster steuert 2 LED an. Einmal tasten rot zwei mal
* grüne LED ein. Die Tastfolge wird für eine Sekunde
* angenommen, danach werden die LED ensprechend der Anzahl Signale
* angesteuert. Nach 10s werden die LED wieder aus geschaltet.
* Hardware UNO
*/
const byte soundIn = 2;// Eingang Soundschalter
const byte rot = 4; // LED rot
const byte grn = 5; // LED grün
bool sound, merker;
byte Klatschcounter = 0;
unsigned long klatschzeit; // Zeitpunkt erste Klatschen erkannt
unsigned long Erkennungszeit = 1000; // 1 sekunde
unsigned long aus = 10000; // nach 10s alles wieder aus
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(soundIn, INPUT_PULLUP); // nur bei Taster erforderlich
pinMode(rot, OUTPUT);
pinMode(grn, OUTPUT);
klatschzeit = millis();
}
void loop() {
// put your main code here, to run repeatedly:
sound = !digitalRead(soundIn); // Eingang lesen
delay(10);// entprellen nur bei Taster erforderlich
if (!sound )merker = false; // Merker reset
if (sound && !merker) { // Flanke erkannt
merker = true;
if (Klatschcounter == 0) { // Erkennung Zeit starten
klatschzeit = millis(); // erstes klatschen erkannt
}
if (millis() - klatschzeit <= Erkennungszeit) { // Klatschzähler erhöhen
Klatschcounter = Klatschcounter + 1;
}
Serial.print(Klatschcounter); Serial.print("\t");// anzeige auf Monitor
Serial.println(millis() - klatschzeit);
}
if (millis() - klatschzeit > Erkennungszeit) { // Zeit abgelaufen
switch (Klatschcounter) {
case 1:
// LED ansteuern
digitalWrite(rot, HIGH);
digitalWrite(grn, LOW);
break;
case 2:
digitalWrite(rot, LOW);
digitalWrite(grn, HIGH);
break;
}
if (millis() - klatschzeit >= aus) { // nach 10s ausschalten
Klatschcounter = 0;
digitalWrite(grn, LOW);
digitalWrite(rot, LOW);
}
}
}
Also erstmal vielen Dank für die Antworten. Ich habe jetzt deinen Sketch ausprobiert ebenfalls mit Taster und es funktioniert einwandfrei (VIELEN DANK!!! ). Nun versuche ich das selbe mit dem Soundsensor statt dem Taster. Dafür habe ich den pinMode auf INPUT gestellt und das Programm hochgeladen. Leider hat es gar nicht funktioniert. Dazu muss man sagen, dass der Soundsensor bei "Stille" ein HIGH ausgibt und bei erkanntem Ton (z.B Klatschen) ein LOW. Könntest du mir sagen was ich noch an deinem Sketch ändern muss. Vielen Dank im vorraus.
So. Ich habe jetzt beides nochmal ausprobiert und bin zum entschluss gekommen, dass es am Sensor liegt. Der Sensor gibt nämlich nur ein LOW aus, wenn er einen längeren Ton erfasst (100-200 ms). Wisst ihr, wie man das lösen kann?
ich weiß nicht was Du für einen Sensor hast, ich hab von ELEGO einen Sensor der nennt sich Big Sound. Hat ein Mikofon drauf mit einem Analogausgang und eine Digitalausgang. Mit einem Spindelpoti kann man die Empfindlichkeit für den Digitalausgang einstellen. Dazu gibt es eine kleine LED auf dem Sensor die den Zustand des Ausgangs anzeigt.
Ich hab jetzt mal das Poti nach rechts gedreht bis die LED angeht und dann ein Stück zurück, das sie sicher wieder aus ist. Wenn Man jetzt klatscht geht die LED sofort kurz an.
Da der Sensor HIGH ausgibt hab ich noch das Inverieren des Eingangs rausgenommen.
sound = digitalRead(soundIn); // Eingang lesen
Leider ist es nun so das der Sensor den Ausgang bei einem Klatscher nicht nur einmal einschaltet sondern mehrfach und es zu Zählerstanden von 4-8 kommen kann. Um das auszufiltern hab ich nach dem Addieren des Zählers noch delay(50ms) eingebaut. Das ist jetzt also eigendlich ein bischschen quick & durty, für den Fall aber ok.
damit hat´s dann eigendlich geklappt.
Man könnte sicher auch den Anlogeingang einlesen und damit arbeiten.