Offline
Newbie
Karma: 0
Posts: 8
|
 |
« on: October 15, 2012, 08:43:20 am » |
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.
Wie mach ich das am einfachsten? Gruß Marc
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 28
|
 |
« Reply #1 on: October 15, 2012, 08:45:11 am » |
du muss post das am deutsch forum
|
|
|
|
|
Logged
|
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 71
Posts: 3486
|
 |
« Reply #2 on: October 15, 2012, 08:54:24 am » |
Wie mach ich das am einfachsten? Poste Deinen Code, dann können wir Dir vielleicht helfen. Ohne Code wird das wohl nichts werden.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 1
|
 |
« Reply #3 on: October 15, 2012, 10:47:51 am » |
Also ohne programm code ist das natürlich schwer zu beurteilen aber versuchs mal mit einer while schleife die du nur einmal durchlaufen lässt.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #4 on: October 17, 2012, 01:25:47 pm » |
Vielen Dank, ok hier der code (bin Anfänger  ) // 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;
}
}
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #5 on: October 17, 2012, 01:31:29 pm » |
Hab noch was vergessen! 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. Danke euch 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #6 on: October 17, 2012, 04:33:39 pm » |
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;
} } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #7 on: October 19, 2012, 07:09:01 am » |
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.
Gruß Marc
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #8 on: October 19, 2012, 07:36:48 am » |
Hab die Fehlermeldungen doch selbst beseitigen können....
if (old_range != range) { old_range = range; switch (range) {
So geht's zu kompilieren, allerdings macht das Programm das selbe wie mein Code es sendet alle 60 sek das Signal für den 433mHz Sender ...
??
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #9 on: October 19, 2012, 08:00:03 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #10 on: October 19, 2012, 08:17:59 am » |
Ja genau die Helligkeit ändert sich dauerhaft um einen kleinen Bereich. Gibt es keine Funktion die etwas nur einmal ausführen lässt? Ich hab jetzt mal was anderes Versucht: #define Leddark 5 // Led dunkel #define Ledmedium 4 // Led mittel #define Ledbright 3 // Led hell
int ldr = 0; //analog pin LDR int ldr_value = 0;
#include <RCSwitch.h> RCSwitch mySwitch = RCSwitch();
void setup() { Serial.begin(9600); mySwitch.enableTransmit(10); pinMode(Leddark, OUTPUT); pinMode(Ledmedium, OUTPUT); pinMode(Ledbright, OUTPUT); }
void loop() { ldr_value = analogRead(ldr) ; if (ldr_value > 600) digitalWrite(Leddark, LOW), mySwitch.switchOn("11001", 2);
if (ldr_value <500) digitalWrite(Leddark, HIGH), mySwitch.switchOff("11001", 2);
}
Leider auch hier das doofe dauer senden ;(
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #11 on: October 19, 2012, 09:11:02 am » |
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. http://creativecoding.uni-bayreuth.de/tools/arduino/arduino-patterns/Wenn das noch nicht geht musst du mit mills() arbeiten und zeitdifferenzen festlegen, in denen geschaltet werden darf.
|
|
|
|
|
Logged
|
|
|
|
|
AREA COLOGNE
Offline
God Member
Karma: 12
Posts: 840
I am 1 of 10 who understands binary
|
 |
« Reply #12 on: October 19, 2012, 09:39:14 am » |
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.
|
|
|
|
|
Logged
|
So ist das Leben: Manchmal bis du die Denkmal, manchmal die Taube!
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #13 on: October 19, 2012, 09:52:19 am » |
Super  Vielen Dank! Es geht jetzt einwandfrei  Gruß Marc
|
|
|
|
|
Logged
|
|
|
|
|
|