Hallo Leute,
Ich hab eine Frage zum Programmablauf...
Ich habe einen LDR am Analogeingang des Arduino Uno.
Dann noch 3 Leds am Digitalport 3,4,5.
Je nach Lichtstärke werden die Leds geschaltet.
Das heist : Led dunkel port 3
Led mittel port 4
Led hell port 5
Mit case 0, case 1, case 2, werden jeweils die leds dementsprechend geschaltet.
Ich habe aber noch zusätzlich die rc switch libarie für funksteckdosen mit im programm.
Soll bedeuten wenn die "led dunkel" eingeschaltet wird hab ich danach die Anweisung im Programm für die funksteckdose dass diese eingeschaltet werden soll.
Das ganze funktioniert auch mit den leds und der funksteckdose einwandfrei!
Mein eigentliches Problem ist das der 433 mhz sender dauerhaft sendet solang das programm die dunkelkeit erkennt ich wollte gern das es jedoch nur nach Änderung der helligkeit 1 mal kurz sendet und die leds umschalter und nicht dauerhaft im loop sendet.
// Lichterkennung (Helligkeit) je nach Helligkeit werden 3 Ausgänge geschaltet und über die serielle Schnittstelle ausgegeben.
// + Schalten der Funksteckdosen bei Helligkeitsänderung.
const int sensorMin =200;
const int sensorMax = 800;
#define Leddark 5 // Led dunkel
#define Ledmedium 4 // Led mittel
#define Ledbright 3 // Led hell
// Sender ist am Arduino Pin #10 angeschlossen
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
pinMode(Leddark, OUTPUT);
pinMode(Ledmedium, OUTPUT);
pinMode(Ledbright, OUTPUT);
mySwitch.enableTransmit(10);
}
void loop() {
int sensorReading = analogRead(A0); // Sensor am analog port 0 lesen
int range = map(sensorReading, sensorMin, sensorMax, 0, 3); // Umwandeln in 4 Bereiche
switch (range) { // Bereich erkennen
case 0: // es ist dunkel
Serial.println("Es ist dunkel!");
mySwitch.switchOn("11001", 2);
digitalWrite(Leddark, HIGH);
digitalWrite(Ledmedium, LOW);
digitalWrite(Ledbright, LOW);
delay(60000);
break;
case 1:
// zwischenwert ohne Angabe
digitalWrite(Leddark, LOW);
digitalWrite(Ledmedium, LOW);
digitalWrite(Ledbright, LOW);
break;
case 2: // es ist mittel
Serial.println("Es ist mittel!");
mySwitch.switchOff("11001", 2);
digitalWrite(Ledmedium, HIGH);
digitalWrite(Leddark, LOW);
digitalWrite(Ledbright, LOW);
delay(60000);
break;
case 3: // es ist hell
Serial.println("Es ist hell!");
mySwitch.switchOff("11001", 2);
digitalWrite(Ledbright, HIGH);
digitalWrite(Leddark, LOW);
digitalWrite(Ledmedium, LOW);
delay(60000);
break;
}
}
Die Pausen bei den case Anweisungen ( delay (60000) ) hab ich jetzt nur als "Notlösung" genommen dann sendet das 433mHz Modul wenigstens nur einmal alle 60 Sekunden aber normal sollten da so ca 5-10 Sekunden stehen.
Ich wollte ja nur das es bei einem Wechsel 1 mal sendet.
Also von hell auf dunkel (switch on -> für die Funksteckdosen).
Vom Wechsel von dunkel auf hell ( switch off -> für die Funksteckdosen).
Und die Led s sollten jeweils dauerhaft den jeweiligen helligkeitszustand anzeigen.
Schau einfach mit einer If-Abfrage ob sich dein zustand geändert hat wenn ja gehst du in dein case wenn nicht machst du nix
// Lichterkennung (Helligkeit) je nach Helligkeit werden 3 Ausgänge geschaltet und über die serielle Schnittstelle ausgegeben.
// + Schalten der Funksteckdosen bei Helligkeitsänderung.
const int sensorMin =200;
const int sensorMax = 800;
int old_range;
#define Leddark 5 // Led dunkel
#define Ledmedium 4 // Led mittel
#define Ledbright 3 // Led hell
// Sender ist am Arduino Pin #10 angeschlossen
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
pinMode(Leddark, OUTPUT);
pinMode(Ledmedium, OUTPUT);
pinMode(Ledbright, OUTPUT);
mySwitch.enableTransmit(10);
}
void loop() {
int sensorReading = analogRead(A0); // Sensor am analog port 0 lesen
int range = map(sensorReading, sensorMin, sensorMax, 0, 3); // Umwandeln in 4 Bereiche
if old_range != range {
old_range = range;
switch (range) { // Bereich erkennen
case 0: // es ist dunkel
Serial.println("Es ist dunkel!");
mySwitch.switchOn("11001", 2);
digitalWrite(Leddark, HIGH);
digitalWrite(Ledmedium, LOW);
digitalWrite(Ledbright, LOW);
delay(60000);
break;
case 1:
// zwischenwert ohne Angabe
digitalWrite(Leddark, LOW);
digitalWrite(Ledmedium, LOW);
digitalWrite(Ledbright, LOW);
break;
case 2: // es ist mittel
Serial.println("Es ist mittel!");
mySwitch.switchOff("11001", 2);
digitalWrite(Ledmedium, HIGH);
digitalWrite(Leddark, LOW);
digitalWrite(Ledbright, LOW);
delay(60000);
break;
case 3: // es ist hell
Serial.println("Es ist hell!");
mySwitch.switchOff("11001", 2);
digitalWrite(Ledbright, HIGH);
digitalWrite(Leddark, LOW);
digitalWrite(Ledmedium, LOW);
delay(60000);
break;
}
}
}
Wenn ich den Sketch von "circuit99" Kompilieren will kommt immer eine Fehlermeldung:
In function 'void loop()':
error: expected (' before 'old_range' error: expected }' at end of input
Da ich noch Anfänger bin und einige Zusammenhänge nicht verstehe weis ich leider nicht was das Problem ist!?
Ps. Gibt es eine Seite oder ein Tutorial indem die einzelne Befehle genau Beschrieben sind?
Nur als Bsp. :
Jetzt in meinem Fall wurde mir von euch ja die Änderung mit if vorgeschlagen :
if old_range != range { // was bedeutet das Ausrufezeichen vor dem = ?
old_range = range; // muss ich das "range" durch irgendetwas ersetzen? oder is das schon die fertige Funktion?
switch (range) {
Sorry für die vielen Fragen
Ich habe schon einiges durch testen und die Google Suche herausgefunden aber manche Sachen versteht man wohl erst besser
wenn man es erklärt bekommt.
Prinzipiell sollte das Programm nur die Switchanweisung ausführen, wenn sich range geändert hat. Lass dir mal vor dem if mit serial.println(range) und serial.println(old_range) die Werte ausgeben. Ich vermute das sich der Wert ständig ändert und des halb laufend das Signal gesendet wird. Oder des stimmt etwas mit den geschweiften klammern nicht. Die Switchanweisung muss im if-Block stehen, nicht danach.
Die 60 Sekunden kommen natürlich von dem delay, das habe ich nicht geändert.
Was heißt bei dir einmal senden? du willst ja sicher jeden Tag an und ausschalten
Dein Ansatz war schon richtig. Du musst anstatt der map-Funktion deine Switchcase-Variable mit if-Anweisungen festlegen. Ich weiß jetzt nicht, was für werte dein Sensor liefert aber du kannst es z.b. so machen:
if (ldr_value < 200) range =0; //dunkel
if (ldr_value > 400 && ldr_value < 600) range =1; //mittel
if (ldr_value > 800) range = 2; // hell
if (old_range != range) {
old_range = range;
switch (range) {
case 0:
case 1:
case 2:
}
}
Damit sollte es eigentlich funktionieren. Mit einer Mittelwertbildung von ldr_value kannst du die Funktion nochmals stabilisieren. Das Prinzip ist hier unter dem Stichwort Glätten (Smoothing) erklärt.
Es gibt noch eine Art der Glättung in dem der neuer gelesene Wert nur einen kleinen Einfluss auf den gelesenen Wert hat.
Nur so geschiebener Code
Wertaktuell=analogRead(A0); // Aktuellwert Einlesen
X=Wertneu*10; // Neuerwert nur 10% Einfluss auf den alten
Y=Wertalt*90; // Wert aus dem Vorherigien Zyklus auf 90%
Wertneu=X+Y/100; // Beide Werte addieren und Neuen Wert Bilden
Wertalt=Wertneu; // Für den nächsten Zyklus ist der neue (aktueller gesmoother Wert)
Mit den Faktoren 0.1 (neuer) und 0.9 (alter Wert) kannst du den Einfluss des gelesenen Wertes ändern. X,Y,Wertneu müssen vom typ long sein.
So verbringt man keine Zeit in einer for Schleife.