Boolean verändern

Guten Tag Leute,
Ich versuche mit dem Soundsensor aus dem Elegoo Kit(https://www.amazon.de/Elegoo-MEGA2560-Ultimate-Deutschem-Mikrocontroller/dp/B01II76PDM/ref=asc_df_B01II76PDM/?tag=googshopde-21&linkCode=df0&hvadid=310638483583&hvpos=1o3&hvnetw=g&hvrand=14196419511820095427&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1004611&hvtargid=pla-565110404541&psc=1&th=1&psc=1&tag=&ref=&adgrpid=63367893073&hvpone=&hvptwo=&hvadid=310638483583&hvpos=1o3&hvnetw=g&hvrand=14196419511820095427&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1004611&hvtargid=pla-565110404541) und einem WeMos D1 Mini(ESP8266 ESP-12 NodeMcu Lua WeMos D1 WIFI Mini CH340G Development Board Antenna M | eBay) ein kleines Projekt für ein SmartHome(SmartZimmer wohl eher). Der Funktionsaufbau ist eigentlich recht simpel. Ein mal klatschen schaltet rot einer RGB LED an, zweimal klatschen grün und dreimal klatschen blau. Nun scheitert es bei mir schon beim zweimal klatschen. Das Problem scheint zu seien, dass der Boolean "klatschen" nicht umgeschrieben wird. Der Sketch ist jetzt natürlich nicht der beste, da ich gerademal ein fortgeschrittener Anfänger bin, aber ich hoffe ihr könnt es nachvollziehen.

PS: Der Sketch ist auch noch unten angehängt.

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");
   }
 }
}

Gruß Denis :slight_smile:

Klatschprogramm.ino (1.43 KB)

if(Klatscher = true)

Diese Anweisung wird immer zu true ausgewertet

if(Klatscher = false)

Diese Anweisung wird immer zu false ausgewertet

Bemerke:
Unabhängig davon, welchen Wert Klatscher vorher hat.

Hallo,

was combie Dir sagen wollte:

if( katscher == true)

muss es sein

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

schau dir das nochmal in der Hilfe der IDE an

Heinz

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.

Gruß Denis

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.

Gruß Tommy

Hi

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.

MfG

Hallo,

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!!! :slight_smile: ). 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.

Gruß Denis :slight_smile:

Probier mal anstatt
sound = !digitalRead(soundIn);
das:
sound = digitalRead(soundIn);

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?

Gruß Denis

Hallo Denis

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.

Heinz

Komisch. Ich hab genau den gleichen nur bei mir tut er nicht das, was er bei mir tut.

Hallo,

was ist denn mit der LED auf dem Sensor, macht die was sie soll?

bei dem StarterSet sind auch Beispliele bei für jeden Sensor, kau die mal durch

Heinz

Denis_W:
Komisch. Ich hab genau den gleichen nur bei mir tut er nicht das, was er bei mir tut.

Ich glaube, das ist ein Widerspruch in sich. :wink:

Tommy56:
Ich glaube, das ist ein Widerspruch in sich. :wink:

Hab mich verschrieben :slight_smile:

Rentner:
Hallo,

was ist denn mit der LED auf dem Sensor, macht die was sie soll?

bei dem StarterSet sind auch Beispliele bei für jeden Sensor, kau die mal durch

Heinz

Das werde ich nochmal. Nochmal danke für die Hilfe.

Gruß Denis