Propleme beim Zeitgesteuerten Dimmen einer LED

Hallo an alle,

vorweg möchte ich sagen dass ich was den Arduino angeht ein absoluter Anfänger bin :slight_smile: Nachdem ich erst ein wenig mit meinem UNO rumexperimentiert habe, wollte ich nun mein erstes Programm schreiben.

Das Programm sollte z.B. Um 8.00 Uhr eine LED Lampe langsam hochdimmen (so über ne halbe stunde) und um 18Uhr wieder langsam runter. Nachdem ich durch jede Menge googeln den Arduino dazu bekommen habe die Uhrzeit (DS1307) auf meinem LCD anzuzeigen, stellt sich jetzt das Problem, dass ich nicht weiß wie ich beim Dimmen die delay Funktion umgehe weil dann ja sonst meine Uhr während des Dimmens stehen bleibt.

Das zweite ist dass ich nicht weiß wie ich den dann hochgedimmten ausgang dann angeschalten lasse obwohl er ja jede sekunde den loop wiederholt und die Zeit abruft.

Wenn mir jemand helfen kann, freue ich mich :slight_smile:

Grüße Bruzzzler

#include "LCD4Bit_mod.h" 
#include "Wire.h"

int ledPin = 3;                                          // LED Pin setzen

#define DS1307_I2C_ADDRESS 0x68                          // I2C Adresse

char buffer[20] = "";                                    // Speicherbereich für Datenkonvertierung 

LCD4Bit_mod lcd = LCD4Bit_mod(2);                        // LCD-Display

/****************************************************************************************************
 * Konvertierung BCD-kodierter Dezimalzahl
 */
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

/****************************************************************************************************
 * Zeit und Datum aus DS1307 auslesen und konvertieren
 */
void getDateDs1307(int date[])
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);         // I2C-Kommunikation im Schreibmodus starten
  Wire.write(0x00);                                   // Registerzeiger auf 0 setzen
  Wire.endTransmission();                             // I2C-Kommunikation beenden 
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);            // I2C-Kommunikation im Lesemodus starten

  date[ 0 ] = bcdToDec(Wire.read() & 0x7f);        // Sekunden
  date[ 1 ] = bcdToDec(Wire.read());               // Minuten
  date[ 2 ] = bcdToDec(Wire.read() & 0x3f);        // Stunden
  date[ 3 ] = bcdToDec(Wire.read());               // Wochentag
  date[ 4 ] = bcdToDec(Wire.read());               // Tag
  date[ 5 ] = bcdToDec(Wire.read());               // Monat
  date[ 6 ] = bcdToDec(Wire.read());               // Jahr
}

/****************************************************************************************************
 */
void setup() {
  Wire.begin();                                      // I2C-Bus einrichten

    lcd.init();                                      // LCD-Anzeige initialisieren
  lcd.clear();
  lcd.printIn( "DS1307 - Uhr" ); 
 
  
}

/****************************************************************************************************
 */
void loop() {

  int datum[ 7 ];  

  getDateDs1307( datum );                            // Datum und Uhrzeit aus DS1307 holen

  lcd.cursorTo(2, 0);                                // Datum und Uhrzeit in 2. Zeile schreiben

  if( datum[ 4 ] < 10 )
    lcd.printIn( "0" );
  lcd.printIn( itoa( datum[ 4 ], buffer, 10 ) );
  lcd.printIn( "." );
  if( datum[ 5 ] < 10 )
    lcd.printIn( "0" );
  lcd.printIn( itoa( datum[ 5 ], buffer, 10 ) );
  lcd.printIn( "." );
  /*
if( datum[ 6 ] < 10 )
   lcd.printIn( "0" );
   lcd.printIn( itoa( datum[ 6 ], buffer, 10 ) );
   */
  lcd.printIn( "  " );

  if( datum[ 2 ] < 10 )
    lcd.printIn( "0" );
  lcd.printIn( itoa( datum[ 2 ], buffer, 10 ) );
  lcd.printIn( ":" );
  if( datum[ 1 ] < 10 )
    lcd.printIn( "0" );
  lcd.printIn( itoa( datum[ 1 ], buffer, 10 ) );
  lcd.printIn( ":" );
  if( datum[ 0 ] < 10 )
    lcd.printIn( "0" );
  lcd.printIn( itoa( datum[ 0 ], buffer, 10 ) );
  lcd.printIn( "  " );

/****************************************************************************************************
 Tageslichtsteuerung
*/

//Morgens
 
  if ( datum[ 2 ]  >= 10 )   // Stunde                   
  if ( datum[ 1 ] >= 2 )   // Minute
  if ( ledPin <1){
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(3, fadeValue);             
    delay(30);                            
  }
  }  
{
  delay(1000);                                    // grobes Sekundenraster für Anzeige
}
}

langsam hochdimmen (so über ne halbe stunde)

"ne halbe Stunde" sind also 1 von 256 Schritten alle 7 Sek.

Du arbeitest eh schon im Sekundentakt. Zähl doch einfach die Sekunden ab Rampenanfang und erhöhe fadeValue alle 7 sekunden um 1.

Mein Tip: nimm eher 8 sek. , nach einer halben Stunde bist du schon bei 225 ( 1800 / 8 ) und wirst keinen Helligkeitszuwachs mehr fesstellen.

Das zweite ist dass ich nicht weiß wie ich den dann hochgedimmten ausgang dann angeschalten lasse obwohl er ja jede sekunde den loop wiederholt und die Zeit abruft.

Bei 255 änderst fu fadeValue nicht mehr, dann bleibt deine LED den ganzen Tag an.

Ob du analogWrite(ledPin,fadeValue) wiederholst oder gar nicht ausführst, ist egal.
Der PWM Wert bleibt bis zum nächsten analogWrite / reset.

Fehlt noch, in setup den zur Uhrzeit passenden fadeValue zu initialisieren und analogWrite einmal einzustellen.

Hallo michael_x ,
Danke für deine schnelle antwort. Wie genau meinst du das? Kannst du mir das anhand des codes zeigen? :blush:

Fertige Lösungen macht jurs gerne :wink:

Ich meckere lieber über anderer Leute Fehler. :stuck_out_tongue:

Aber eigentlich bin ich doch ein netter Kerl :

void setLED(byte Stunde, byte Minute,  byte LEDpin)
{
/****************************************************************************************************
 Tageslichtsteuerung  8:30 hoch, 20:15 runter  ( runter muss später als hoch sein, d.h. Tageswechsel ist immer dunkel )
  Fade über 2040 Aufrufe ( ca. 30 Minuten, falls diese Funktion im Sekundentakt aufgerufen wird). 
  Ein einmal gestartetes Fading läuft immer erst zu Ende, hoch / runter Zeitpunkte müssen weit genug auseinander liegen ...
  Wird der Arduino innerhalb einer Fade-Periode gestartet, verzögert sich das Ganze oder fällt aus (wenn schon ein Stundenwechsel war) ...
*/
const byte UP_H = 8;
const byte UP_M = 30;
const byte DN_H = 20;
const byte DN_M = 15;

static int fadevalue = 255;  // default: Tag
static int fading = 0 ;  // 1 ... 2040 = up , -2040 ... -1 = down, 0 = fadevalue bleibt stehen  

if (fading != 0) 
{ // nur hier wird fadevalue verändert 
   if (fading < 0)  fadevalue = -(fading++) / 8; 
   else fadevalue = fading++ / 8;
   
   if (fadevalue == 0 || fadevalue == 255) fading = 0;   
}

analogWrite(LEDpin, fadevalue);
if (fading) return; // Fade-Start wurde schon erkannt


if ( Stunde < UP_H ) fadevalue = 0;
if ( Stunde > DN_H ) fadevalue = 0;
if ( Stunde == UP_H && Minute >= UP_M && fadevalue == 0)  fading = 8;
if ( Stunde == DN_H && Minute >= DN_M && fadevalue != 0)  fading = -2040;

analogWrite(LEDpin, fadevalue);

}
  
void loop() 
{
  ... Zeit von RTC ...
  ... LCD aktualisieren ...
  setLED(datum[2], datum[1], ledPin);
  delay(1000);                                    // grobes Sekundenraster für Anzeige und setLED
}

Edit: 1 Fehler gefixt, aber immer noch unkompiliert/ungetestet

Super danke. Muss jetzt noch ein bischen rumspielen und hoffe dass es dann geht aber danke für die super hilfe

Hallo,

möchte Du einfach "stur" die per PMW immer 1 hochzählen oder soll die Helligkeit laut unserem Augen Empfinden gleichmäßig heller werden?

Jetzt lass ihn doch erstmal machen, Doc :slight_smile:

Bisher ging es - nach meinemVerständnis - erstmal um eher Grundsätzliches. Wie man einen Arduino "ewig" laufen lässt, auch wenn das Programm fertig ist; wie man zwei delays ineinander verschachtelt oder doch nicht; und so Fragen eben...

Das zweite ist dass ich nicht weiß wie ich den dann hochgedimmten ausgang dann angeschalten lasse obwohl er ja jede sekunde den loop wiederholt und die Zeit abruft.

Ausserdem, bei der Vorgabe "ca. eine halbe Stunde" ist das wohl nicht so kritisch.

Also, Bruzzzler, wenn du merkst es geht im Prinzip, aber nach wenigen Minuten ist schon fast keine Steigerung mehr feststellbar, oder umgekehrt, beim Runterdimmen passiert erstmal fast gar nichts: da hätten wir noch eine Riesen-Verbesserung für dich :wink:

... oder such mal selbst, was hier vor kurzem über logarithmisch (war es nicht eigentlich eher exponentiell ?) und LED-Helligkeit diskutiert wurde. )

P.S. Wo hast du eigentlich getDateDs1307() gefunden ? Oder: Schön dass du ohne de dicke DS1307 Librqry auskommst ...
Edit: Google hilft : Echtzeit-Uhr mit DS1307 und LCD-Anzeige

hi,

P.S. Wo hast du eigentlich getDateDs1307() gefunden ? Oder: Schön dass du ohne de dicke DS1307 Librqry auskommst ...

gibt's im playground...

gruß stefan

Hallo,

okay Michael, ich halte mich zurück. :wink: Im Abstand von 30min wird man aber sowie kaum einen Unterschied ausmachen, denke ich. Aber wir wissen ja nicht was er vor hat mit dem halben Stunden Takt. Er wird sich schon melden ...

Zum rechnen brauchte ich keinen Logarithmus. Obwohl der Augeneffekt überall so beschrieben steht. Das ist aber glaube ich nur das Gegenteil vom Potenzieren. Schule liegt schon paar Jahre zurück. :slight_smile: Von daher denke ich, es hängt nur von der Betrachtungsweise ab, was wovon wie abhängt.