Pages: [1]   Go Down
Author Topic: Nach Zustandswechsel nur 1 mal senden  (Read 1197 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

du muss post das am deutsch forum
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vielen Dank,
ok hier der code (bin Anfänger  smiley  )

Code:
// 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 Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink



Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
// 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 Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
#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 Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 21
Posts: 1125
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
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 das Denkmal, manchmal die Taube!

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Super smiley-wink

Vielen Dank!

Es geht jetzt einwandfrei smiley

Gruß Marc
Logged

Pages: [1]   Go Up
Jump to: