So ein bisschen sollte man schon das Prinzip einer Programmiersprache verstehen.
sorry, bin ja dabei es besser zu verstehen, aller Anfang ist schwer. Es prasseln im Moment nur so viele Informationen auf einen ein, da muss man erst mal durchsteigen wenn man gerade damit anfängt.
Ich habe es jetzt hinbekommen, dank euch
so sieht der code jetzt aus, das mit der + 11 ist ein perfekter Hinweis
die Ausgabe von DeepSleep_Time ist auf dem Display mit Sekunden, diese brauche
ich nicht. Bin im Netz auf der suche wie man es ändern kann.
Schaue gerde nach den Funktionen strptime() und strftime
das Partial update einzubauen, mal sehen ob ich es schaffe.
const char* DeepSleep_Time ist ein beliebiger Text. Da du weißt, dass er ein Datum/Uhrzeit enthält, kannst du es zwar mit viel Mühe in eine Uhrzeit wandeln, die du dann wiederum in allen möglichen Formaten in Text wandeln kannst, aber eigentlich willst du nur ein paar Buchstaben davon ausschneiden. Da ist strncpy das was du suchst.
Wenn dir der Trick mit +11 gefällt, interessiert es dich wohl auch, wie man in C / C++ Texte abschneidet, wenn sie nicht const sind:
char* DeepSleep_Time = DeepSleep["Time"]; // ohne const !
DeepSleep_Time+16 = 0; // Endekennung setzen
Serial.println(DeepSleep_Time + 11); // jetzt nur noch die Buchstaben 11 .. 15
Dein JsonObject DeepSleep ist übrigens eine sehr gute Idee zur besseren Lesbarkeit des Codes. Glückwunsch !
wenn ich das von Dir vorgeschlagene einfüge kommt eine Fehlermeldung bei
DeepSleep_Time+16 = 0; // Endekennung setzen
Compilation error: lvalue required as left operand of assignment
Ich hoffe es richtig das ich const char* rausneheme und dann das von Dir char* //ohne const einsetze ?
Ich habe im Netz schon gesucht, aber das ist glaube noch zu kompliziert für mich.
Am Anfang kommt einem alles schwierig vor, d.h. man muss viel nachlesen und ausprobieren. Aber das wird mit der Zeit. Ein guter Tipp wäre noch ein C++ Buch (schau mal z.B. hier im Forum).
Zum konkreten Thema: "Substring extrahieren" hätte ich noch diese Anmerkung. Es gibt viele Wege um das zu zu tun, also z.B. das Zerlegen wie ich oben erwähnt hab, oder der quick-and-dirty-Hack von oben.
char* DeepSleep_Time = DeepSleep["Time"]; // ohne const !
DeepSleep_Time[16] = 0; // Endekennung setzen
Serial.println(DeepSleep_Time + 11); // jetzt nur noch die Buchstaben 11 .. 15
Ja das funktioniert, der Compiler ist happy und die Firmware wird für diesen speziellen Fall wohl auch funktionieren. Als Anfänger würde ich es so nicht lösen. Nicht ohne Grund wird vom ArduinoJson Assistant ein const char* DeepSleep_Time = DeepSleep["Time"]; vorgeschlagen. Das soll nämlich zeigen, dass der Speicher quasi dem JsonObject DeepSleep gehört. Also Hände weg! An dem soll nicht gefummelt werden, d.h. lesen aber nicht schreiben. Wie gesagt im obigen Beispiel ist es sicher unkritisch, aber man könnte sich auch vorstellen dass die Daten vielleicht noch an einer anderen Stelle benötigt werden, und dann hast du mit dem 0-Einfügen den String kaputt gemacht. Als Anfänger würde ich solche Hacks vermeiden, weil man irgendwann später wegen solcher Nebeneffekte saublöde Fehler sucht. Eine saubere Lösung wäre aus meiner Sicht z.B. eine lokale Variable char StundeMinute[6]={0}; anlegen und dann per strncpy() Funktion die 5 Zeichen aus dem DeepSleep_Time String zu kopieren. Dann hast du die Zeit mit Stunde und Minute mundgerecht für die Ausgabe. Also ungefähr so als alternative Lösung:
Hi Andreas,
es klappt super mit deiner Lösung, bei den anderen Vorschlägen kamen leider immer wieder Fehler, trotzdem danke an euch.
Kannst Du mir evtl. noch erläutern was die [6]={0} bedeuten ?
Es wird ein char Array für 6 byte mit dem Bezeichner „StundeMinute“ definiert, bei dem alle 6 Speicherstellen mit dem Wert 0 initialisiert werden. Lässt man = {0} weg, ist der Inhalt des Speichers zufällig und kann auch andere Werte enthalten.
Wie Kai-R beschrieben hat, wird die Variable StundeMinute[] beim Anlegen gleich initialisiert, d.h. mit 0en gefüllt.
Ich habe vor vielen Jahren mit der Programmierung in "C" begonnen und erst später kam "C++" dazu. In C werden die Variablen jeweils am Block-Anfang deklariert. Aus dieser Zeit hab ich mir angewöhnt alle Variablen beim Anlegen gleich mit sinnvollen Werten zu füllen. Nicht initialisiert Variablen können ganz blöde Effekte auslösen. Wenn du also mal so eine Warnung wie diese hier siehst warning C4700: uninitialized local variable 'x' used, dann unbedingt ernst nehmen!
Da wären wir schon beim nächsten Ratschlag: Einfach alle Warnungen ernst nehmen! Warnungen behandle ich genau so wie errors. Bei vielen Libs sieht man Warnungen, das finde ich persönlich schlampig programmiert.
Stimmt. Ich habe diese Angewohnheit auch beibehalten, ich finde das ist der beste Platz dafür. Falls ich mal eine Variable suchen muss, schau ich immer zuerst am Blockanfang.
Da komme ich doch glatt noch zu den best-practice Vorschlägen #3 ... #5
#3 Kleine Funktionsblöcke anstreben.
Wenn ich mehrfach blättern muss um an das Ende einer Funktion zu kommen, dann stimmt was nicht. Dann versuche ich immer das Problem in kleinere Blöcke und Funktionen (gerne auch mal als inline deklariert) zu zerlegen. Zusätzlich halte ich den Source-Code gerne kompakt, d.h. keine überflüssigen Leerzeilen und die öffnende { am ende des Funktionskopf oder genau hinter for(), if() usw. Das ist vielleicht nicht jedermanns Geschmack aber mir ist ein gescheiter Kommentar lieber.
#4 Bei Zählvariablen statt i, j, k besser ic, jc, kc verwenden
Ich hab mir angewöhnt für Zähler-Variablen (z.B. für for() Schleifen) immer int ic statt int i zu schreiben. Falls man doch mal was mit Suchen-Ersetzen ändern möchte, dann geht das einfacher als mit i und j
#5 setup() und loop() immer am Ende
Das mache ich damit ich setup() und loop() gleich finde. Ein Nebeneffekt ist, dass dann die Funktionen bekannt sind und man nicht extra Prototypen deklarieren muss. Warum die Arduino IDE ohne Prototypen auskommt ist mir ein Rätsel, denn alle C++ Compiler, die ich in den Fingern hatte, möchten vor dem Aufruf von Funktionen wissen wie die Funktion aussieht, so z.B. auch in der Entwicklungsumgebung vs-code + platformio.
Die baut sie sich selbst.
Frag dich auch, wie die IDE Dateien mit der Endung .ino übersetzt kriegt, ohne dass die mit #include <Arduino.h> anfangen. Und ohne makefile.
Und wie es kommt, dass Funktionen in andern .ino Dateien gefunden werden, globale Variable aber nicht immer.
Muss ja wohl so sein, dass noch ein Tool vorab drüber läuft und das eigentliche c++ Sourcefile generiert. Das Nachforschen (also wie genau die Arduino IDE das im Hintergrund macht) hab ich beiseite gelegt, denn ehrlich gesagt hab ich schon vor langer Zeit auf VS-code + platformio gewechselt.
Hi@all,
ich danke euch für die Hilfe und Tipps, damit habe ich es jetzt zum laufen gebracht wie ich es mir gedacht hatte.
Ich denke ich werde bestimmt immer noch bei weiteren Objekten mal Hilfe benötigen.
Es ist super das ihr hier den Anfänger auch Hilfestellungen und Lösungen gebt und nicht nur sagt lies mal hier und da.
Werde bestimmt noch einiges probieren und testen.