Führende Null bei Sekunde

Hallo,
ich versuche, bei der Uhrzeitausgabe mit der RTClib.h library der Sekunde eine führende "0" zu verpassen, wenn int Sekunde < 10 ist. Es funktioniert aber nicht.
Hier der Teil-sketch und die Serial.print-Ausgabe:

void loop () {

DateTime now = rtc.now();
  Serial.print(now.day(), DEC);
  Serial.print(".");
  Serial.print(now.month(), DEC);
  Serial.print('.');
  Serial.print(now.year(), DEC);

  int yearday = DayOfYear(now.year(), now.month(), now.day());

Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');

  String sec = String(now.second(), DEC);
  String Null = "0";

  if ((now.second(), DEC) < 10) {
    sec = Null + sec;
  }

  Serial.print (sec);
  Serial.print("  ");
  Serial.println(yearday);
  
delay(1000);
}


6.9.2023  21:39:59  249
6.9.2023  21:40:0  249
6.9.2023  21:40:1  249
6.9.2023  21:40:2  249
6.9.2023  21:40:3  249
6.9.2023  21:40:4  249
6.9.2023  21:40:5  249
6.9.2023  21:40:6  249
6.9.2023  21:40:7  249
6.9.2023  21:40:8  249
6.9.2023  21:40:9  249
6.9.2023  21:40:10  249

Was ist falsch an dem Code, dass die if-Anweisung offensichtlich ignoriert und die Null der Sekunde nicht voran gestellt wird?
Danke, und Gruss Minima

if (now.second() < 10) {

Wobei das ganze Konstrukt völlig sinnfrei ist.
Warum musst Du da nen String draus machen?
Dir wird ddas gleiche bei Minute und stunde wiederfahren....

Sorry, aber ich befinde mich erst am Beginn meiner Programmierer-Karriere ...
Wie sähe dieser Teil meines sketches denn aus, wenn ihn ein Profi geschrieben hätte?
Danke, und Gruss Minima

Ob es ein Profi so machen würde, kann ich Dir nicht sagen, aber ich würde es so schreiben:

/*
  Forum: https://forum.arduino.cc/t/fuhrende-null-bei-sekunde/1165965
  Wokwi: https://wokwi.com/projects/305979285237137984

*/
#include "RTClib.h"

RTC_DS1307 rtc;

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

  if (! rtc.begin()) {
    Serial.println("RTC nicht gefunden");
    Serial.flush();
    while (true) {
      // DoNothing
    };
  }
}

char buffer[80];

void loop () {
  DateTime now = rtc.now();
  sprintf(buffer, "%02d.%02d.%04d %02d:%02d:%02d", now.day(), now.month(), now.year(), now.hour(),now.minute(), now.second());
  Serial.println(buffer);
  delay(1000);
}

Auf Wokwi testen: https://wokwi.com/projects/375151781556240385

Du müsstest nur noch Dein yearday einbauen. Der sprintf-Befehl dazu sähe so aus:

sprintf(buffer, "%02d.%02d.%04d %02d:%02d:%02d  %03d", now.day(), now.month(), now.year(), now.hour(),now.minute(), now.second(),yearday);

Eine Erläuterung dazu findest Du hier:

https://www.kriwanek.de/index.php/de/arduino/sprachreferenz/393-sprintf-ausgabeformatierung

In Kürze zum obigen Sketch:

  • Im sprintf-Befehl steht an zweiter Stelle ein sogenannter Format(ierungs)string.
  • In diesem String steht für jede auszugebende Variable ein %-Zeichen mit nachfolgenden Formatangaben.
  • Die zugehörigen Variablen stehen hinter dem Formatstring in genau der Zahl und Reihenfolge der %-Zeichen.
  • In z.B. "%02d" bedeutet
    • das "d", dass an dieser Stelle eine Dezimalzahl ausgegeben werden soll
    • die 2 zweistellig,
    • die 0 zwischen % und 2, dass führende Stellen mit Nullen aufgefüllt werden sollen

Bei "%04d" für die Jahreszahl kann man die 0 natürlich auch weglassen.

Die anderen Zeichen (Leerzeichen, Punkte, Doppelpunkte und ggf. auch weiterer Text) werden an den entsprechenden Stellen im Ergebnis beibehalten.

Man muss nur dafür sorgen, dass der Puffer (hier "buffer" genannt) ausreichend Platz für die maximale Zeilenlänge vorhält. buffer ist hier mit 80 Zeichen vorgegeben.

Ich nenne mich nciht Profi, aber....
Wenn Du das einfach auf dem SerMon ausgeben willst:


byte lastSecond=60;

void loop ()
{
  DateTime now = rtc.now();
  byte mySecond = now.second();
  if (lastSecond != mySecond)
  {
    printDateAndTime();
    lastSecond = mySecond;
  }
}

void printDateAndTime()
{
  vorNull(now.day());
  Serial.print('.');
  vorNull(now.month());
  Serial.print('.');
  Serial.print(now.year());
  Serial.print('\t');
  vorNull(now.hour());
  Serial.print(':');
  vorNull(now.minute());
  Serial.print(':');
  vorNull(now.second());
  Serial.println();
}

void vorNull(const byte zahl)
{
  if (zahl < 10)
  { Serial.print(0); }
  Serial.print(zahl);
}

Bitte gewöhne Dir an vollständigen Code zu posten.
Das wird sonst eine sinnlose frickelei, wenn ich mich hier verhaue und Du das nicht kompilieren kannst.

wat'n dat?
grafik
:slight_smile:

Ich hab mich extra nicht an das snprintf rangewagt - ich wollt ja schon streaming ins Spiel bringen, aber ich glaub langsam anfangen ist auch nicht schlecht...

Ja, das sieht sehr professionell aus. Ich habe bis dahin noch einen langen Weg vor mir ...
Aber jeder fängt mal an ...
Herzlichen Dank für Deine Hilfe, weiss ich zu schätzen :heartbeat:
Gruss MInima
P.S.
Dein sketch hat auf Anhieb funktioniert. Danke nochmals.

DankeSchön für Deine Hilfe, der Code sieht so erst einmal viel besser aus ...
Ich werde ihn mal Schritt für Schritt analysieren und ausprobieren, bin ja noch Lehrling ...
Gruss Jenny

Moin @my_xy_projekt,

hoffe, dass es Dir gut geht :wink:

Ich habe oben noch ein paar kurze Erläuterungen angehängt. Diese Art der Ausgabe ist sicher erst einmal etwas "lernintensiv", aber über kurz (bei manchen eher lang) die eleganteste Art für Ausgaben.

@minima-123: Das ist leichter umzusetzen, als es auf den ersten Blick aussieht. Wenn man es nicht häufig nutzt, hilft es, sich die Tabelle mit den Formatangaben irgendwo abzulegen (oder einen Link darauf). Viel Spaß und Erfolg weiterhin! Mit @my_xy_projekt hast Du auf jeden Fall eine Super-Unterstützung!

Gruß
ec2021

Uff.
Das beantwortet aber meine Frage nicht :slight_smile:

Ansonsten weisst ja... Der Erklärbär tut wasserkann ...

Beim Kompilieren kommt die Fehlermeldung:
"'now' was not declared in this scope"
Wie muss ich "now" denn deklarieren?

Hier noch der vollständige sketch:

#include "RTClib.h"
#include <DTutils.h>

RTC_DS3231 rtc;

void setup () {

  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // rtc.adjust(DateTime(2023, 9, 6, 20, 23, 0));
}

byte lastSecond=60;

void loop ()
{
  DateTime now = rtc.now();
  byte mySecond = now.second();
  if (lastSecond != mySecond)
  {
    printDateAndTime();
    lastSecond = mySecond;
  }
}

void printDateAndTime()
{
  vorNull(now.day());
  Serial.print('.');
  vorNull(now.month());
  Serial.print('.');
  Serial.print(now.year());
  Serial.print('\t');
  vorNull(now.hour());
  Serial.print(':');
  vorNull(now.minute());
  Serial.print(':');
  vorNull(now.second());
  Serial.println();
}

void vorNull(const byte zahl)
{
  if (zahl < 10)
  { Serial.print(0); }
  Serial.print(zahl);
}

Gib mal deinen kompletten Sketch, damit ich sehe, was Du da machst.

Off Topic

Frage: Wat'n dat?
Antwort: Stilisierter Monitor ...

Das kommt davon, wenn man eine global erforderliche Variable in der loop() deklariert...;-))

#include "RTClib.h"
//#include <DTutils.h>

RTC_DS3231 rtc;

void setup ()
{
  Serial.begin(9600);
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1)
    {
      delay(10);
    }
  }
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // rtc.adjust(DateTime(2023, 9, 6, 20, 23, 0));
}

byte lastSecond = 60;
DateTime now;
void loop ()
{
  now = rtc.now();
  byte mySecond = now.second();
  if (lastSecond != mySecond)
  {
    printDateAndTime();
    lastSecond = mySecond;
  }
}

void printDateAndTime()
{
  vorNull(now.day());
  Serial.print('.');
  vorNull(now.month());
  Serial.print('.');
  Serial.print(now.year());
  Serial.print('\t');
  vorNull(now.hour());
  Serial.print(':');
  vorNull(now.minute());
  Serial.print(':');
  vorNull(now.second());
  Serial.println();
}

void vorNull(const byte zahl)
{
  if (zahl < 10)
  { Serial.print(0); }
  Serial.print(zahl);
}

Ich hab das nur blind übernommen...
Aber war genauso schnell mit der Lösung :slight_smile:
Und ich mach hier noch was anderes...

Danke, Dein sketch funktioniert super.
Herzlichen Dank, Du hast mir sehr weiter geholfen.
Gruss Minima
P.S. Eine Frage noch:
Warum wurde oben in meinem ersten Teil-Sketch die if-Anweisung ignoriert?
Danke

Hier der Teil, um den es geht:

  String sec = String(now.second(), DEC);
  String Null = "0";

  if ((now.second(), DEC) < 10) {
    sec = Null + sec;
  }

  Serial.print (sec);
  Serial.print("  ");
 

du solltest eigentlich sein Sketch als Lösung markieren, nicht dein Dankeschön.

Sorry, ist geschehen. Danke für den HInweis.

Ob ich ein Profi bin, lasse ich lieber andere entscheiden.
Aber was ich weis:
Ich bin faul, darum nutze ich auch gerne Dinge, welche schon fertig sind.

#include <RTClib.h>

void setup() 
{
  Serial.begin(9600);
 
  DateTime dateTime(F(__DATE__),F(__TIME__));
  char buffer[50] {"DDD, DD MMM YYYY hh:mm:ss"};
  Serial.println(dateTime.toString(buffer));
}

void loop() 
{

}

Ausgabe:

Wed, 06 Sep 2023 23:37:34