Beleuchtungssteuerung für einen Leuchttum

noiasca: so als Grundgerüst mit unsyncronisierter Top-Leuchte

// Lighthouse with 8 LEDs and one top PWM
// https://forum.arduino.cc/index.php?topic=711838
// by noiasca

define DEBUG_UART 1

const uint8_t pwmPin = 3; // UNO PWM pins 3, 5, 6, 9, 10, 11 const uint8_t ledPin[] = {2, 4, 5, 6, 7, 8, 9, 10}; const size_t totalNoLeds = sizeof(ledPin);

uint32_t currentMillis = 0;

void doRunning()                              // switch on / off one LED after the other {  static uint8_t actual = totalNoLeds - 1;    // start with the last LED  static uint32_t previousMillis = 0;  const uint8_t myIntervall = 5;              // intervall in seconds    if (currentMillis - previousMillis >= myIntervall * 1000UL)  {    previousMillis = currentMillis;    digitalWrite(ledPin[actual], LOW);    actual++;    if (actual >= totalNoLeds) actual = 0;    digitalWrite(ledPin[actual], HIGH);

if DEBUG_UART

   Serial.print("actual Pin=");    Serial.println(ledPin[actual]);

endif

 } }

void doPWM() {  static uint32_t previousMillis = 0;  const uint16_t myIntervall = 10;             // speed of PWM  static int8_t dir = 1;                       // direction upwards(1) or downwards (-1)  static uint8_t newPwm;

 if (millis() - previousMillis >= myIntervall)  {    previousMillis = millis();    if (dir == 1 && newPwm >= 254)        // end of scale      dir = -1;                           // go downwards    if (dir == -1 && newPwm <= 54)        // lower end of pwm scale      dir = 1;                            // go upwards    newPwm += dir;    analogWrite(pwmPin, newPwm);

if DEBUG_UART

   Serial.print("newPwm=");    Serial.println(newPwm);

endif

 } }

void setup() {

if DEBUG_UART

 Serial.begin(115200);

endif

 for (uint8_t i = 0; i < totalNoLeds; i++) {    pinMode(ledPin[i], OUTPUT);  }  pinMode(pwmPin, OUTPUT); }

void loop() {  currentMillis = millis();  doPWM();                  // check, if PWM needs to be changed  doRunning();              // check, if one of the running LEDs need to be changed  // do what ever you want unblocked here }

Grundgerüst? Das ist genau die Funktion die ich brauche vielen dank, jetzt muss ich es nur noch verstehen. :D

einfach mit dem Finger Zeiler für Zeile durchgehen. aufkommende Fragen notieren.

Bei der aller letzten schließenden Klammer die Fragen googeln. Wenn google nichts bringt - hier fragen.

Hallo Tim, das wäre mein Vorschlag mit MobaTools und weichem Überblenden der Minuten-Leds:

#include 

const byte ledPins[] = { 2,3,4,5,6,7,8,9 }; // muss byte sein wg. sizeof
const byte ledZahl = sizeof(ledPins);
const byte fadePin = 10;
MoToTimebase minuteTime;        // Zeitbasis für die Minuten-Leds
MoToTimebase fadeTime;          // Zeitbasis für die einzelne Fade-Led

MoToSoftLed minuteLeds[ledZahl];
MoToSoftLed fadeLed;

byte minuteIx = 0;          // aktive Minuten-Led

void setup() {
    // Minuten-Leds initiieren:
    for ( byte i=0; i= ledZahl ) minuteIx = 0;
        minuteLeds[minuteIx].on();      // nächste Led einschalten
    }
    // Fade-Led umschalten
    if ( fadeTime.tick() ) fadeLed.toggle();

}

(deleted)

timsieberg: Mein Schwiegervater hat sich einen Leuchtturm für den Garten gebaut, den er gerne beleuchtet haben möchte.

Hat der Leuchtturm ein Vorbild? Hat Dein Schwiegervater einen Bezug zu diesem Vorbild?

Wenn "ja" sollte der Leuchtturm, wie schon angedeutet, nicht einfach nur blinken, sondern die Blinkfolge des Vorbilds nachahmen. Wer sich einen Leuchtturm baut, legt da wahrscheinlich Wert drauf, vermute ich mal.

Hast Du ein Foto?

Hier ein Bild des Leuchtturms, den Turm gibt es nicht mehr.

Vielen danke erstmal für eure Antworten, das hat mir schon sehr weitergeholfen. Jetzt habe ich gestern nochmal mit ihm telefoniert.

Er möchte es jetzt gerne wie folgt haben: - Einschalten bei Dämmerung Habe einen passenden Lichtsensor. Ich habe bei den Programmen von noiasca und MicroBahner auch hinbekommen, dass die LED´s erst angehen, wenn ein bestimmter Wert-X unterschritten ist. Leider ist es jetzt so, dass sobald der Wert-X wieder überschritten wird also Tag, das Programm gestoppt wird und nicht weiterläuft. Wird der Wert wieder unterschritten, wird das Programm an der Stelle fortgesetzt.

Als "Leuchtfeuer" sollte die LED sehr hell sein und sich "drehen": Habe jetzt an eine 230V G9 LED-Lampe gedacht die dauerhaft über ein Relaismodul eingeschaltet wird. Mithilfe eines Schrittmotors, soll dich der "Spiegel" mit ca. 1U/min um die LED drehen, sodass eine Art Lichtkegel erscheint. Dies soll natürlich unabhängig von der Fensterbeleuchtung laufen. Auch hier soll bei Überschreiten von Wert-X die Lampe und der Motor ausgehen.

ce4936b4-d994-40d6-8f1c-6f3eff91ac8a.jpg|768x1024

timsieberg: Hier ein Bild des Leuchtturms,

Gruß an den Schwiegervater, meine Hochachtung!

Da lohnt sich jede Anstrengung für eine gute Beleuchtung!

timsieberg: den Turm gibt es nicht mehr.

Du meinst in der Realität, weshalb es für die Blinkfolge kein Vorbild gibt?

timsieberg: Leider ist es jetzt so, dass sobald der Wert-X wieder überschritten wird also Tag, das Programm gestoppt wird und nicht weiterläuft. Wird der Wert wieder unterschritten, wird das Programm an der Stelle fortgesetzt.

Du benötigst eine Hysterese: Bei Wert X einschalten, bei Wert Y ausschalten, wobei X "dunkler" ist als Y.

timsieberg: Als "Leuchtfeuer" sollte die LED sehr hell sein ...

Nach meinen Erfahrungen besser nicht. Niemand möchte nachts im Garten mit Sonnenbrille sitzen 8)

Ich habe zwei Leuchttürme, die mit Kühlschrankbirnen 230 V 5 W betrieben wurden. Ich habe die dann auf 12 V 15 W umgerüstet, was mir aber zu hell war, weshalb ich sie auf 12 V 5 W rediziert habe. Bei LEDs verhält es sich dann noch etwas anders.

timsieberg: Habe jetzt an eine 230V G9 LED-Lampe ...

Die 230 V sind mir für Gartenbeleuchtung zu gefährlich, ein Kabel mit 12 V kann man gefahrlos durchhacken.

timsieberg: Mithilfe eines Schrittmotors, soll dich der "Spiegel" mit ca. 1U/min um die LED drehen, sodass eine Art Lichtkegel erscheint. Dies soll natürlich unabhängig von der Fensterbeleuchtung laufen.

Mechanik im Garten ist beispielsweise wegen Frost nicht ganz unproblematisch. Außerdem genügt ein kleiner DC-Getriebemotor für den gleichmäßigen Antrieb, da wird ja nichts positioniert.

agmue: Du meinst in der Realität, weshalb es für die Blinkfolge kein Vorbild gibt?

Ja genau.

agmue: Du benötigst eine Hysterese: Bei Wert X einschalten, bei Wert Y ausschalten, wobei X "dunkler" ist als Y.

Ok, werde ich mal probieren, jetzt ist es so: eingebaut in den Sketch von noisca. sensorWert = analogRead(eingang); Serial.print("Sensorwert = " ); Serial.println(sensorWert); if (sensorWert < 30){ {currentMillis = millis(); doPWM(); doRunning(); Einschaltung funktioniert, Wenn der Wert überschritten wird funktioniert es ja auch, nur nicht richtig es geht nicht aus sondern stoppt nur.

agmue: Nach meinen Erfahrungen besser nicht. Niemand möchte nachts im Garten mit Sonnenbrille sitzen 8) Ich habe zwei Leuchttürme, die mit Kühlschrankbirnen 230 V 5 W betrieben wurden. Ich habe die dann auf 12 V 15 W umgerüstet, was mir aber zu hell war, weshalb ich sie auf 12 V 5 W rediziert habe. Bei LEDs verhält es sich dann noch etwas anders. Die 230 V sind mir für Gartenbeleuchtung zu gefährlich, ein Kabel mit 12 V kann man gefahrlos durchhacken

Die 230V hat er schon verlegt ;-). Okay das mit der Helligkeit werde ich mal im Hinterkopf behalten. Ärger bekommt wenn dann er mit den Nachbarn.

agmue: Mechanik im Garten ist beispielsweise wegen Frost nicht ganz unproblematisch. Außerdem genügt ein kleiner DC-Getriebemotor für den gleichmäßigen Antrieb, da wird ja nichts positioniert.

Bekomme ich Getriebemotoren mit so kleiner Übersetzung? Das Getriebe ist ja auch Mechanik, aber ich verstehe was du meinst.

Leider ist es jetzt so, dass sobald der Wert-X wieder überschritten wird also Tag, das Programm gestoppt wird und nicht weiterläuft. Wird der Wert wieder unterschritten, wird das Programm an der Stelle fortgesetzt.

bezogen auf das "Leider": das hättest du programmatisch aber auch anders machen können.

Kleingetriebe findet man sicher im Modellbau. Den Motor hat mir google ausgespuckt: https://at.rs-online.com/web/p/dc-getriebemotor/8347644/.

Andererseits wer sowas baut, der baut sich dann auch eine Untersetzung von 1,5 auf 1, oder 4 auf 1 ... sogesehen alles lösbar.

edit: es ist ja jetzt dein Sketch aber so hätte ich das nicht gemacht.

Mach dir eine globale Funktion die ein istNacht = true oder false zurückgibt und frag das in den Funktionen doRunning bzw. doPWM ab. bei false schaltest du explizit die LEDs ab, bei true führst du durch so wie jetzt auch.

Einschaltung funktioniert, Wenn der Wert überschritten wird funktioniert es ja auch, nur nicht richtig es geht nicht aus sondern stoppt nur.

Das zeigt dein Code-Schnipsel leider nicht.

Zusätzlich ist evtl. sinnvoll, eine Verzögerung einzubauen, damit nicht eine kurze Helligkeitsänderung gleich den Leuchtturm an- bzw. abschaltet.
(Zum Testen kann man diese Verzögerung ja kürzer einstellen als hinterher im echten Betrieb)

doch zeigt es.

er stoppt das currentMillis update - kein wunder dass es "stehen bleibt". Er muss halt auch abschalten.

Toll, was du aus

if (sensorWert < 30){
{currentMillis = millis();
doPWM();                  
doRunning();

herauslesen kannst :)

Ich hatte ja meine Gründe weswegen das im loop steht und nicht in den do Funktionen. Ich wäre aber nie auf die Idee gekommen, dass das jemand zum Anhalten missbrauchen würde. :o

noiasca: Ich hatte ja meine Gründe weswegen das im loop steht und nicht in den do Funktionen. Ich wäre aber nie auf die Idee gekommen, dass das jemand zum Anhalten missbrauchen würde. :o

So jetzt hat es Funktioniert, void doRunning() { static uint8_t actual = totalNoLeds - 1; static uint32_t previousMillis = 0; const uint8_t myIntervall = 2; // Schenlligkeit Fenster in Sekunden sensorWert= analogRead(eingang); Serial.print ("Helligkeit= "); Serial.println (sensorWert); if (sensorWert < 30){ if (currentMillis - previousMillis >= myIntervall * 1000UL) { previousMillis = currentMillis; digitalWrite(ledPin[actual], LOW); actual++; if (actual >= totalNoLeds) actual = 0; digitalWrite(ledPin[actual], HIGH);

if DEBUG_UART

Serial.print("actual Pin="); Serial.println(ledPin[actual]);

endif

} } else { digitalWrite(ledPin[actual], LOW); } } So funktioniert es, jetzt werde ich noch schauen das ich die var global vergebe.

nö, keine global. mach dir eine Funktion die dir das Ergebnis aufbereitet.

ungeprüft:

bool isDark (void)
{
  bool result = true;
  if (analogRead(eingang) < 30) result = false  
  return result;
}

dann kannst mal bei Lust immer noch eine Hysterese (an einer zentralen Stelle) einbauen

vieleicht so:

bool isDark (void)
{
  static bool result = true;
  if (analogRead(eingang) < 30) result = false;
  else if (analogRead(eingang) > 60) result = true;
  return result;
}

noiasca: bool isDark (void) {  bool result = true;  if (analogRead(eingang) < 30) result = false    return result; }

Danke werde ich mal reinbasteln ist auf alle fälle kürzer.

noiasca: dann kannst mal bei Lust immer noch eine Hysterese (an einer zentralen Stelle) einbauen

vieleicht so:

bool isDark (void)
{
  static bool result = true;
  if (analogRead(eingang) < 30) result = false;
  else if (analogRead(eingang) > 60) result = true;
  return result;
}

Ob eine Hysterese hier so sinnig ist weiß ich nicht, ich denke es ist besser ein zeit einzusetzen WertX muss Y Sekunden unterschritten sein dann ist Dunkel. Andersrum genau so WertX muss Y Sekunden überschritten sein dann Tag. Nicht das mal ein Scheinwerfer eines Autos etc. draufscheint und dann geht alles aus. Wie seht ihr das?

kannst auch machen. Auch das bringst du in dieser Funktion unter. Einfach zweiteilig machen. Einmal bei "Flankenänderung" den Zeitstempel merken, und im zweiten Teil dann auf millis-previousMillis prüfen.

noiasca: kannst auch machen. Auch das bringst du in dieser Funktion unter. Einfach zweiteilig machen. Einmal bei "Flankenänderung" den Zeitstempel merken, und im zweiten Teil dann auf millis-previousMillis prüfen.

und welche variable frage ich dann ab in der if um das doRunning zu beenden?

timsieberg: Wie seht ihr das?

Wäre das so schlimm? Du baust kein Atomkraftwerk ::)

Man kann es immer beliebig kompliziert machen und Zeit und Hysterese kombinieren. Du kannst auch den gleitenden Mittelwert zusammen mit der Hysterese verwenden, wäre so mein Tipp.

du fragst keine Variable ab sondern die Funktion return't das Ergebnis.

statt deinem

if (sensorWert < 30){

machst ein

if (isDark()){

oder

if (isDark() == true){

wie es dir halt besser gefällt.