Ich habe ganz frisch mit dem Arduino und dem Programmieren angefangen. Das Board ist ein Uno R3. Ich möchte einen ganz primitiven Bewegungsmelder bauen, bei welchem eine Leuchtdiode angeht wenn der PIR etwas detektiert. Die LED ist am digitalen Pin 13 und der PIR an Pin 2. Im Netz finde ich viele Beispiele, die alle ähnlich aussehen, doch mir ist es nicht ganz klar. Auf der Recherche basierend sieht mein Sketch wie folgt aus:
int ledPin = 13;
int inputPin = 2;
int pirState = LOW;
int val = 0;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
Serial.begin(9600);
}
void loop()
{
val = digitalRead(inputPin);
if (val == HIGH)
{
digitalWrite(ledPin, HIGH);
delay(150);
if (pirState == LOW)
{
Serial.println("Motion detected!");
pirState = HIGH;
}
}
else
{
digitalWrite(ledPin, LOW);
delay(300);
if (pirState == HIGH)
{
Serial.println("Motion ended!");
pirState = LOW;
}
}
}
Wenn ich das Programm nun auf das Board aufspiele und danach in der IDE auf den seriellen Monitor gehe, dann erscheint dort ein "Motion detected!". Ich komme also in den ersten Block der If-Bedingung, weil pirState = LOW. Das scheint zu funktionieren, doch von einem Bewegungsmelder erwarte ich, dass er sich wieder deaktiviert und die LED neu ansteuert, wenn sich ein Objekt davor bewegt.
ArduinoFreshling:
... Was muss ich machen um dies zu erreichen? ...
Meiner Erfahrung nach ist es am hilfreichsten, bei solchen Fragen einen Programmablaufplan (PAP) dessen zu zeichnen, was man erreichen möchte. Wenn Du es im PAP so formuliert hast, wie es sein soll, ist die Umsetzung nur noch etwas Fleißarbeit.
Bei den meisten PIR kann man per Jumper konfigurieren, ob sie einmalig eine detektierte Bewegung melden sollen, oder während der gesamten* Dauer.
Dann ist der Sketch so aufgebaut, dass er nur die Zustandsänderungen meldet. Also Detected und Ended.
Sonst bekommst Du ja alle paar Millisekunden eine Nachricht per Serieller Schnittstelle zugeschickt.
*Die gesamte Dauer ist natürlich dennoch endlich, da der PIR nur Zustandsveränderungen wahrnimmt. Steht jemand davor und bewegt sich nicht sonderlich viel, so meldet er Ended.
Das kann man aber etwas entprellen:
const int pirPin = 12; //D6 the digital pin connected to the PIR sensor's output
const int ledPin = LED_BUILTIN;
//the time when the sensor outputs a low impulse
uint32_t lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 60000;
boolean lockLow = true;
boolean takeLowTime;
void PirCheck() {
if(digitalRead(pirPin) == HIGH){
digitalWrite(ledPin, LOW);
if(lockLow){
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
PirActive();
delay(50);
}
takeLowTime = true;
}else {
digitalWrite(ledPin, HIGH);
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
PirInactive();
delay(50);
}
}
}
der Frage nach dem typ des PIR oder einem Link auf das Kaufangebot wäre hilfreich.
Die HC-SR501 haben z.B. die Angewohnheit nach PowerOn oder bei Änderungen der Potis erstmal ewig zu brauchen bis sie überhaupt das erste Mal abschalten. Einschalten unbewegt auf eine Fläche richten wo sich nichts bewegt und abwarten. Es kann durchaus 2-3 Minuten dauern bis er überhaupt das erste Mal auf aus geht.
Sorgt schnell für Frust weil man Fehler in der Schaltung oder im Programm sucht.
Besser erstmal nur einen TEstsketch machen, der direkt eine LED einschaltet wenn Pin2 auf H geht und die wieder ausmacht wenn es L ist. Damit erstmal klären das und wie der PIR überhaupt anspricht.