Go Down

Topic: Propleme beim Zeitgesteuerten Dimmen einer LED (Read 1 time) previous topic - next topic

Bruzzzler89

Hallo an alle,

vorweg möchte ich sagen dass ich was den Arduino angeht ein absoluter Anfänger bin :) 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 :)

Grüße Bruzzzler

Code: [Select]
#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
}
}

michael_x

Quote
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.

Quote
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.

Bruzzzler89

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

michael_x

#3
Mar 21, 2013, 12:27 pm Last Edit: Mar 21, 2013, 12:31 pm by michael_x Reason: 1
Fertige Lösungen macht jurs gerne ;)

Ich meckere lieber über anderer Leute Fehler.   :P

Aber eigentlich bin ich doch ein netter Kerl :
Code: [Select]

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

Bruzzzler89

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

Doc_Arduino

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?
Tschau
Doc Arduino

michael_x

#6
Mar 21, 2013, 10:40 pm Last Edit: Mar 21, 2013, 10:42 pm by michael_x Reason: 1
Jetzt lass ihn doch erstmal machen, Doc  :)

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...
Quote
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  ;)


...  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 : http://www.dl8ma.de/Arduino/RTC_DS1307_LCD/

Eisebaer

hi,

Quote
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

Doc_Arduino

Hallo,

okay Michael, ich halte mich zurück.  ;) 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.  :)  Von daher denke ich, es hängt nur von der Betrachtungsweise ab, was wovon wie abhängt.
Tschau
Doc Arduino

Go Up