DS3231 mit Tastern stellen

Hallo,

ich habe ein Frage, wie ich am besten die Uhrzeit nachstellen kann mit Hilfe von 3 Tastern. Die Zeit soll nach der Änderung ebenfalls auch in den DS3231 geschrieben werden.

Taster sind wie folgt angeschlossen
Pin 1 = Ground
Pin 2 = I/O 10,11,12

Problem ist, er schaltet nur bedingt so weiter wie gewünscht.

#include <DS3232RTC.h>		// http://github.com/JChristensen/DS3232RTC
#include <Streaming.h>		// http://arduiniana.org/libraries/streaming/
#include <Time.h>			// http://playground.arduino.cc/Code/Time
#include <Wire.h>			// http://arduino.cc/en/Reference/Wire
#include <FastSPI_LED2.h>	// https://code.google.com/p/fastspi/
#include <Bounce.h>			// http://playground.arduino.cc/code/bounce

#define NUM_LEDS 60			// Anzahl an Leds am WS2812 Strip
#define RGBORDER GRB		// RGB Anordnung vom WS2812 Strip
#define DATA_PIN 6			// DIN Pin Arduino
CRGB leds[NUM_LEDS];

#define BUTTON0 10			// Anpassung Stunde
Bounce bounceHour = Bounce(BUTTON0, 5);

#define BUTTON1 11			// Anpassung Minute
Bounce bounceMinute = Bounce(BUTTON1, 5);

#define BUTTON2 12			// Anpassung Sekunde
Bounce bounceSecond = Bounce(BUTTON2, 5);


void setup()
{
	Serial.begin(115200);

	Serial << F("************************************") << endl;
	Serial << F("* Chronos WS2812B   Letztes Update *") << endl;
	Serial << F("* von sschultewolter    16.12.2013 *") << endl;
	Serial << F("************************************") << endl;

	setSyncProvider(RTC.get);

	Serial << F("Sync");
	if (timeStatus() != timeSet) Serial << F(" nicht erfolgreich!") << endl << F("DS3232RTC nicht verbunden?") << endl;
	else Serial << F(" erfolgreich!") << endl;
	Serial << endl;

	FastLED.addLeds<WS2812B, DATA_PIN, RGBORDER>(leds, NUM_LEDS);
	memset(leds, 0, NUM_LEDS * 3);

	pinMode(BUTTON0, INPUT_PULLUP);
	pinMode(BUTTON1, INPUT_PULLUP);
	pinMode(BUTTON2, INPUT_PULLUP);
}


// Führende Nullen ausgeben
void print2digits(int val, char delim) {
	if (val < 10) Serial << '0';
	Serial << _DEC(val);
	if (delim > 0) Serial << delim;
	return;
}


void loop() {
	byte saturation = 255;
	byte brightness = 100;

	time_t t;
	tmElements_t tm;
	
	memset(leds, 0, NUM_LEDS * 3);
	
	if (bounceHour.update() && bounceHour.read() == false) {
		if (hour() >= 23) tm.Hour = 0;
		else tm.Hour++;
		Serial << F("Stunde + 1") << endl;

		t = makeTime(tm);
		RTC.write(tm);
		setTime(t);
	}

	if (bounceMinute.update() && bounceMinute.read() == false) {
		if (minute() >= 59) tm.Minute = 0;
		else tm.Minute++;
		Serial << F("Minute + 1") << endl;

		t = makeTime(tm);
		RTC.write(tm);
		setTime(t);
	}

	if (bounceSecond.update() && bounceSecond.read() == false) {
		if (second() >= 59) tm.Second = 0;
		else tm.Second++;
		Serial << F("Sekunde + 1") << endl;

		t = makeTime(tm);
		RTC.write(tm);
		setTime(t);
	}

	// Uhrzeit auf dem Seriellen Monitor ausgeben
	static unsigned long lastTime;
	if (millis() - lastTime > 1000) {
		lastTime = millis();
		print2digits(hour(), ':');
		print2digits(minute(), ':');
		print2digits(second(), ' ');
		Serial << endl;
	}

	setHourLeds(0, saturation, brightness);
	setMinuteLeds(85, saturation, brightness);
	setSecondLeds(170, saturation, brightness);

	FastLED.show();
}

Was verstehst Du unter bedingt? Daß er zäh reagiert oder nicht immer oder zahlen überspringt?
Sicher mußt Du nicht bei jedem Loop-Durchlauf die LED aktualisieren sondern nur bei jeder neuen Sekunde.
Grüße Uwe

Hallo Uwe, der Sketch ist stark verkleinert. Habe ihn auf das nötigste heruntergefahren. memset und fastLED.show sind normalerweise nicht in der loop. Lasse diese nur nach einer Änderung neusetzen.

Mir geht es um das nachjustieren der Zeit. Die Anzeige der Leds verhält sich identisch mit der Seriellen Ausgabe. Die Zeiten werden mehr oder weniger zufällig aufaddiert. Ab und zu klappt es bei Minuten, dass er immer um 1 hochzählt. Bei Stunden geht das wieder nicht, da geht er mal 3h hoch, oder auch weit mehr.

Du solltest nicht nur kontrollieren ob der Taster gedrückt ist sondern entweder wie lange( nach x Zeit läuft das incrementieren automatisch ) oder ob er losgelassen wurde (also pro drücken um 1 incrementieren).

Mit dem vereinfachten Sketch sollten wir vereinfachte Fehler finden??? :wink: :wink: :wink: oder stellt sich der Fehler auch beim geposteten Sketch ein?

Grüße Uwe

Fehler kommt genau so vor. Nen funktionierenden Sketch reinstellen und Fehlerfinden mag zwar spannend sein, aber wäre eine unendliche Aufgabe. Hier ein Auszug des Monitors

Port open
************************************
* Chronos WS2812B   Letztes Update *
* von sschultewolter    16.12.2013 *
************************************
Sync erfolgreich!

03:14:44 
03:14:45 
03:14:46 
03:14:48 
03:14:49 
03:14:50 
03:14:51 
Minute + 1
17:34:47 
17:34:48 
Minute + 1
17:35:47 
17:35:48 
Minute + 1
Minute + 1
08:01:00 
Minute + 1
Minute + 1
08:03:00 
08:03:01

sschultewolter:
03:14:51
Minute + 1
17:34:47

Die Variable tm ist in der loop überhaupt nicht auf bestimmte Werte initialisiert, wenn Du darauf zugreifst.

Wie soll ich das genau verstehen, jurs?

sschultewolter:
Wie soll ich das genau verstehen, jurs?

Erklärung "nicht initialisiert" am Beispiel Deiner loop-Funktion:

void loop() {
	byte saturation = 255;
	byte brightness = 100;

	time_t t;
	tmElements_t tm; // ==> hier wird "tm" deklariert und bekommt zufällige Luft-Werte zugewiesen
	
	memset(leds, 0, NUM_LEDS * 3);
	
	if (bounceHour.update() && bounceHour.read() == false) {
		if (hour() >= 23) tm.Hour = 0;
		else tm.Hour++;  // Hier wird der Luftwert in tm.Hour um 1 erhöht. 
		Serial << F("Stunde + 1") << endl;

		t = makeTime(tm); // und aus dem Luftwert eine Zeit gebildet
		RTC.write(tm);  // und der frei aus der Luft gegriffene und ggf. erhöhte Wert als Zeit in die Uhr geschrieben

"tm" bekommt nirgends etwas sinnvolles zugewiesen, bevor Du damit Vergleiche anstellst und zu irgendwas 1 dazuzählst.

Um ein definiertes Programmverhalten zu bekommen, müßte zunächst mal was an tm zugewiesen werden, bevor Du mit dem, was in tm drin ist, etwas machen kannst. Z.B. die Zeit aus der RTC-Uhr auslesen und an tm zuweisen.

EDIT: Oops. Hatte ich glaube ich falsch gelesen

Was aber schief gehen könnte ist das:

if (hour() >= 23) tm.Hour = 0;
		else tm.Hour++;

Das tm struct musst du ja per Hand erst mal mit breakTime() mit der aktuellen Zeit füllen. Wer weiß was da drin steht wenn du einfach so tm.Hour++ machst.

Also erst mal den aktuellen time_t von der RTC holen und dann das struct mit der aktuellen Zeit beschreiben.

Hallo Serenfly,

dein Beitrag ist hilfreicher als der ganze Playground bzgl. RTC. Wurde nirgendswo wirklich auf breakTime hingewiesen

	time_t t = now();
	tmElements_t tm;
	breakTime(t, tm);

	if (bounceHour.update() && bounceHour.read() == false) {
		if (hour(t) >= 23) tm.Hour = 0;
		else tm.Hour++;
		Serial << F("Stunde++") << endl;

		t = makeTime(tm);
		RTC.write(tm);
		setTime(t);
	}

	if (bounceMinute.update() && bounceMinute.read() == false) {
		if (minute(t) >= 59) tm.Minute = 0;
		else tm.Minute++;
		Serial << F("Minute++") << endl;

		t = makeTime(tm);
		RTC.write(tm);
		setTime(t);
	}

	if (bounceSecond.update() && bounceSecond.read() == false) {
		if (second(t) >= 59) tm.Second = 0;
		else tm.Second++;
		Serial << F("Sekunde++") << endl;

		t = makeTime(tm);
		RTC.write(tm);
		setTime(t);
	}

So geht es nun so wie es soll :wink: Hab ich in dem Teil des Scriptes noch etwas, was etwas überflüssig oder verbessert werden kann bzgl. der Zeit Abfrage und der Zeit setzen.

Gruß Stefan

Ja. Die Time Lib ist etwas kompliziert. Ich hatte auch einige Zeit gebraucht bis ich das alles kapiert habe. makeTime/breakTime sind auch etwas verwirrend benannt und leicht zu verwechseln.

Hier steht was dazu:
http://www.pjrc.com/teensy/td_libs_Time.html

Ist aber sehr leicht zu übersehen, bzw. wenn man es nicht kennt schlecht in den Kontext der ganzen Lib einzuordnen.

Aber musst man nicht erst inkrementieren und danach abfragen ob man zu hoch ist?

Wenn ich vorher inkrementiere, kann die Zeit überspringen! Wobei, für Minuten und Sekunden könnte ich es wie du meinst, machen.

Wenn ich das mit Stunden nach deiner Anmerkung mache, springe ich in den nächsten Tag. Ist nicht gewünscht.