Go Down

Topic: Fragen zum Design einer LED Uhr (Read 790 times) previous topic - next topic

Igotcha

Oct 25, 2013, 03:05 pm Last Edit: Oct 25, 2013, 03:07 pm by Igotcha Reason: 1
Hallo zusammen,

das ist mein erster Post hier und ich möchte eine Frage zum technischen Design einer RGB LED Stripe Uhr stellen.

Ich habe eine 60 RGB LED Strip in eine Ziffernuhr eingebaut, so dass die Striche, die die Minuten und Stunden markieren jeweils durch eine LED beleuchtet werden. Die Ansteuerung der LEDs ist kein Problem.

Ich möchte jetzt gerne eine DS1307 RTC verbauen, aus folgenden Gründen:

  • batterigepufferte Uhrzeit

  • Nutzung des Sekunden-Interrupts zum Aktualisieren der LEDs


Die LED-Uhr soll über 3 Taster eingestellt werden können:

  • Anzeigemodus der LEDs

  • Stunden

  • Minuten


Im Moment baue ich das Ganze prototypisch mit einem UNO auf und möchte später die Uhr mit Batterien betreiben.

Meine Frage bezieht sich jetzt darauf, ob die Stromversorgung per Batterie dazu ausreicht bzw. was ich dazu nehmen sollte und, wenn das Ganze läuft, ob ich mit dieser Konfiguration auf einen ATTiny84A switchen kann (um zusätzlich Strom zu sparen).?

jurs


Meine Frage bezieht sich jetzt darauf, ob die Stromversorgung per Batterie dazu ausreicht


Rechne es Dir aus, Du benötigst die Batteriekapazität in "Ah" und die Stromaufnahme Deiner Schaltung in "A" oder wahlweise auch die Batteriekapazität in "mAh" und die Stromaufnahme in "mA". Dann rechnest Du:

Ungefähre Batterielaufzeit in Stunden = Batteriekapazität geteilt durch Stromaufnahme

Un schon weißt Du, ob ein Batteriewechsel alle halbe Stunde, alle 2 Stunden oder sogar erst alle 5 oder 10 Stunden fällig ist. Oder wie oft auch immer dabei herauskommt.

sschultewolter

Hallo igotcha,

nehme lieber ein DS3231 RTC Modul. Die DS1307 laufen ungenau und bei der Kostendifferenz macht ein angleichen wenig Sinn.
Den Sekunden-Interupt brauchst du nicht zwingend zum aktualisieren der Leds. Wenn doch, ist auf den mir bekannten I2C RTC Modulen mit DS3231 ein Ausgang der ein Rechteck-Signal ausgibt (INT/SQW), welches mit 1Hz arbeitet.

Das mit der Batterie solltest du dir aus dem Kopf schlagen. Das wird nicht klappen. Ob nun ein Mega oder ein kleiner Attiny angeschlossen ist, spielt kaum eine Rolle, da beide mit Abstand die kleinsten Verbraucher sind.

Wenn du keine Autobatterie in der Uhr verschwinden kannst, steht dir keine ausreichende Kapazität zur Verfügung.
Keinen technischen Support über PN!

Serenifly

Ja, Batterie ist bei den Mengen LEDs aussichtslos.

Und es reicht eigentlich wenn du auf dem Arduino per millis() überprüfst ob eine Sekunde vergangen ist und dann updatest. So super-genau muss da nicht sein.

Udo Klein

Ein Uno hat üblicherweise einen Resonator und keinen Quarz --> nach 5-30 Minuten ist der schon locker eine Sekunde nebendran. DS1307 ist besser aber auch nicht das Gelbe vom Ei. DS3231 ist deutlich besser.
Check out my experiments http://blog.blinkenlight.net

Serenifly

Ich meinte nach einer Sekunde die RTC auslesen. Statt den RTC-Interrupt zu verwenden. Da ist es egal wie weit die daneben liegt, solange man mitbekommt, dass eine Sekunde vergangen ist.

Es gibt auch ne Lib die erst mal die Arduino-Zeit nimmt und sich nach einem einstellbaren Intervall mit der RTC synchronisiert.

Udo Klein

Die RTCs können alle ein 32768 Hz Signal erzeugen. Das kann man auch per Timer zählen lassen --> keine sonstige Kommunikation mit dem Chip erforderlich.
Check out my experiments http://blog.blinkenlight.net

Rabenauge

Warum so kompliziert, wenns nur um eine Uhr geht?
Meine rufen einfach im Hauptprogramm ständig die Echtzeit ab und wenn eine Sekunde vergangen ist (der vorherige Sekundenwert wird einfach gespeichert), wird aktualisiert.
Ausser ner Variablen braucht es da keinen Zauber weiter..

------------
Grüssle, Sly

Udo Klein

Du meinst außer einer Library die zum Chip passt und einer Variablen? Hängt davon ab was man einfacher findet.
Check out my experiments http://blog.blinkenlight.net

Rabenauge

Ich find einfach die Vorgehensweise, irgendwo her nen Interrupt zu nehmen, nur damit die Anzeige rechtzeitig aktualisiert wird, zu umständlich..den braucht es nicht.

------------
Grüssle, Sly

Igotcha

Danke für eure Antworten, hier ist das Ergebnis: http://e-realm.de/arduino-rgb-led-uhr/

Ich habe mich für die einfache Variante der regelmäßigen Abfrage der Echtzeit in der loop entschieden, funktioniert problemlos.

Aber: Jetzt habe ich ein anderes Problem und muss wieder auf das Thema Interrupt zurückkommen. Ich habe noch einen DS18B20 Temperatursensor verbaut, um temperaturabhängig die Status-LED ändern zu können.

Die Temperatur frage ich auch in der loop ab, aber der DS18B20 reagiert ja nicht sofort, sondern mit einer Verzögerung von 0,5-1 Sekunde - das bringt mir natürlich meine Sekundenanzeige in diesem Moment ins Stocken.

Jetzt kann man natürlich sagen, man muss die Temperatur ja auch nicht jede Sekunde abfragen. Muss man auch nicht, aber egal in welchem Intervall ich abfrage, es stockt eben immer durch die Auslesezeit und ich hätte gerne eine "schöne" Lösung  ;)

Schön wäre es, wenn man jetzt die Temperaturabfrage per Interrupt steuern könnte (z.B. alle 5 Minuten) und das Auslesen NICHT in der loop erfolgt, sondern in der Interruptroutine der Temperaturwert ausgelesen und an eine Variable übergeben wird, die wiederum in der loop verarbeitet wird. Beim Googlen habe ich aber nur etwas über Hardwareinterrupts gefunden, also wenn Sensoren o.ä. eine Änderung ausgeben, dass dann reagiert wird und nicht, dass zyklisch softwareseitig etwas abgefragt / durchgeführt wird.

Serenifly

Du willst es eigentlich eher anders herum. Die Sekundenanzeige in einem Interrupt, so dass sie andere Funktionen die gerade ausgeführt werden unterbrechen kann. Dann kannst du deine Temperatur immer noch alle x Minuten auslesen (das kann man einfach mit millis() zählen), aber die Anzeige sollte theoretisch immer noch regelmäßig aktualisiert werden. Es sei denn die DS18B20 Lib blockiert das...

Dafür reicht msTimer2:
http://playground.arduino.cc/Main/MsTimer2

Oder wenn du es ganz perfekt mit der RTC synchronisieren willst, eben doch den SQW-Ausgang des RTC-Moduls mit 1Hz (siehe Register 7) nehmen. Das muss aber nicht unbedingt sein.


Igotcha


Du willst es eigentlich eher anders herum. Die Sekundenanzeige in einem Interrupt, ...

Oder wenn du es ganz perfekt mit der RTC synchronisieren willst, eben doch den SQW-Ausgang des RTC-Moduls mit 1Hz (siehe Register 7) nehmen. Das muss aber nicht unbedingt sein.


Ja, da hast Du eigentlich recht  ;)

Und dann wäre ich wieder bei meiner Ausgangsfrage  :)

Ich werde mich morgen mal dransetzen und den SQW des DS1307 nutzen. Muss dazu aber Pin2 umlöten, da ich da momentan einen Taster dran habe.

Igotcha

So, RTC Hardware Interrupt läuft, jetzt habe ich nur noch ein kleines Codeproblem.

Eingerichtet ist der Interrupt in setup() mit:
Code: [Select]

RTC_DS1307 rtc;

void setup() {
pinMode(2, INPUT);                  
digitalWrite(2, HIGH);                
attachInterrupt(0, DisplayIntTime, FALLING);
... mehr Code
}


Meine Interruptroutine sieht wie folgt aus, die auch funktioniert, sofern ich den DateTime-Aufruf weglasse:

Code: [Select]

void DisplayIntTime()
{
  Serial.println(" Interrupt");
  // Uhrzeit aus RTC lesen
 DateTime t = rtc.now();

... weitere Code
}


Ich konnte eingrenzen, dass die DateTime-Zeile dazu führt, dass nichts mehr ausgeführt wird. Lösche ich die Zeile, dann funktioniert alles bestens (z.B. die serielle Ausgabe). In der ursprünglichen Fassung mit dem rtc.now()-Aufruf in der Loop funktionierte auch alles.

Ich vermute, es liegt an der Deklaration von "t", aber auch eine Deklaration mit volatile für t vor dem setup() führt nicht zum gewünschten Ergebnis.

Habt ihr dazu eine Idee zu?

Serenifly

#14
Oct 29, 2013, 08:08 pm Last Edit: Oct 29, 2013, 08:15 pm by Serenifly Reason: 1
Wahrscheinlich braucht die I2C Kommunikation das Interrupt-System. Und auf dem AVR können sich Interrupts nicht gegenseitig unterbrechen (außer man macht es per Hand. Aber das Normalverhalten ist dass sie blockieren).

Setze mal in der ISR nur eine bool-Variable und frage in der loop ab ob diese gesetzt ist. Dann weist du dass du updaten musst.

Go Up