Datalogging: Datum als Dateiname

Hallo zusammen,

als Arduino-Einsteiger kämpfe ich etwas mit der C++ Programmierung und bräuchte nun euere Hilfe.

Vorwort: Ich bin dabei, wie anfangs viele, mit Sensoren zu spielen um daraus eine heimische Wetterstation für den Garten zu bauen. Nach rund 3 Wochen intensiver Experimente konnte ich schon einige Fortschritte erzielen. Aus verschiedenen Projekten analysierte ich die Sketche und wandelte sie um. Versuchte gleich ein paar eigene Ideen umzusetzen, die ich in anderen Beispielen nicht fand.
Das Resultat sind einzelne Sketche, die irgendwann zu einem migriert werden. An dieser Stelle bin ich gerade und kämpfe mich mühsam durch.

Nun hänge ich an einer Stelle und blicke nicht weiter.

Die Fehlermeldung lautet: no match for 'operator=' (operand types are 'String' and 'void')
bei: logFilename = getDateshortrev();

void prepareLogfileDay() {
  // one logfile per day
  logFilename = getDateshortrev();
  logFilename += ".txt";
  dataFile = SD.open(logFilename, FILE_WRITE);
  dataFile.println(logHeader);  // Header schreiben
  dataFile.close();
}

void getDateshortrev() {
  // Datum ermitteln und als String zurueckgeben
  // short und reverse (yymmdd)
  String revDate;
  String sY, sM, sD;
  DateTime now = RTC.now();
  sY = String(now.year());
  sM = String(now.month());
  sD = String(now.day());
  revDate = sY + sM + sD;
  return revDate;
}

Habt ihr eine Idee, woran es hier klemmt?

Als Anlage ist noch der komplette Sketch. Nicht erschrecken, wie erwähnt Migration aus allen einzelnen noch im Gange. Ich wäre echt dankbar, wenn jemand bischen Zeit und Lust hat drüberzuschauen und mir die gravierendsten Fehler(punkte) nennen könnte.

Danke schon mal

Datalogger_sensor_a0-a3.ino (17.5 KB)

Hallo,

dein "void getDateshortrev()" ist eine Funktion, die keinen Rückgabewert liefern soll. Unten ist aber ein "return" und versucht zu liefern - DAS kollidiert ...

Damit willkommen im Forum
Rudi

Danke RudiDL5,

irgendeine innere Stimme sagte mir, das vorhergehende String will einen String haben...

String getDateshortrev() {

und siehe da, er hat es geschluckt. Vorläufig, Ergebnis noch nicht getestet.

Tja, wenn ich es noch verstehen könnte.

Daraus resultierend kommt gerade eine andere Frage hoch, falls erlaubt:
Wie frage ich es ab (also die definierten Datum/Zeit-Formate), wenn ich keinen String nutze? Sondern einen int, oder was anderes aus der großen unbekannten Variablen-Galerie. :confused:

Eigentlich wollte ich mit dem Arduino spielen, bischen Elektronik schnuppern und lernen, nicht einen C/C++ Lehrgang absolvieren :frowning:

nicht einen C/C++ Lehrgang absolvieren

Programmierer ist nicht ohne Grund ein Ausbildungsberuf.

Ich schätze 3 bis 4 Jahre, bis man halbwegs fit ist.
Plus 1/2 Jahr für jede neue Sprache/Spezialgebiet.

Zusätzlich: Erfahrungen sammeln.

Ja, so ca nach 10 Jahren kann man richtig gut sein.

... man sollte öfters auf seine innere Stimme bzw. auf sein Bauchgefühl hören - dann passt es oft recht gut :wink:

Es ist nahezu egal, WAS du wo zurück gibst - du musst es nur genau so weiter verarbeiten wie vorgegeben. Ggf. kannst du nach Rückgabe auch diverse Konvertierungen durchführen um die Daten in ein anderes Format zu bringen. Das kommt alles auf die Anwendung an.

Wie auch immer - einen "vollständigen Lehrgang" brauchst du für ein paar "Spielereien" nicht wirklich absolvieren... Jedoch ist ein gewisses Basiswissen dennoch notwendig. Je mehr du davon im Laufe der Zeit sammelst - um so bessere "Spielchen" gelingen dir. Vor 3 Jahren hatte ich vom Arduino Null Ahnung - was ich HEUTE alles damit mache will ich gar nicht erzählen. Man muss nur bereit sein, hin und wieder etwas hinzuzulernen.

Schau mal hier, vielleicht hilft dir das dabei:

https://de.wikibooks.org/wiki/C%2B%2B-Programmierung

Rudi

PS: Ich stimme combie übrigens zu und ergänze noch: Wenn man das alles durch rein privates "learning by doing" macht (oder machen muß weil die Umstände es so ergaben) ... dauert es noch wesentlich länger; vielleicht x 3 oder so

mratix:
...

Tja, wenn ich es noch verstehen könnte.
...

Moin mratix,

ich bin auch noch nicht so lange dabei, aber so habe ich es kapiert. Vielleicht hilft es dir auch!?

Eine ganz normale VOID() - Methode gibt nix zurück ! Sondern arbeitet nur ihren Inhalt ab.

void blinken(){
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
}

Du kannst aber auch Parameter mit übergeben, dann wird in diesem Beispiel das Ganze ein bisschen flexibler. Aber da es eine VOID() - Methode ist, gibt diese auch nichts zurück.

void blinken(int pin, int dauer) {
  digitalWrite(pin, HIGH);
  delay(dauer);
  digitalWrite(pin, LOW);
  delay(dauer);
}

Diese Funktion könntest du dann so z.B. aufrufen ...

blinken(2, 1000);

Dann wird Pin 2 jede Sekunde auf HIGH und danach auf LOW geschalten.

Beim nächsten Beispiel ist die Methode keine VOID, sondern eine Mehtode, die einen Rückgabewert liefert. In diesem Fall ein int.

int summe(int a, int b){
int ergebnis = a+b;
return ergebnis;
}

Wenn du dann die Funktion z.B. so aufrufst ...

int meinErgebnis = summe(5, 3);

dann sollte meinErgebnis = 8 sein.

Ich hoffe ich hab´ alles richtig erklärt :wink:

Ein guter Anfang!

Diese Funktion könntest du dann so z.B. aufrufen ...

void blinken(2, 1000);

Da sollte man das void weg lassen.

Jetzt musst du nur noch Funktionen von Methoden unterscheiden lernen....
Denn du spricht offensichtlich über Funktionen, nicht über Methoden.

@combie

Danke ... zu schnell getippt. Habe es oben korrigiert.
Aber der Wille zu helfen war da, kann nur besser werden :smiley:

combie:
... Jetzt musst du nur noch Funktionen von Methoden unterscheiden lernen....
Denn du spricht offensichtlich über Funktionen, nicht über Methoden.

Da sprichst du allerdings was an :sunglasses:
Den Unterschied hab ich wirklich noch nicht genau verstanden.

Mach dir nichts draus!

DaleCarnegie:
Lernen ist ein aktiver Prozess. Wir lernen, indem wir es tun.

@RudiDL5 Danke, das Buch habe ich mir heruntergeladen. Jetzt fehlt nur noch der Upload ins Hirn :wink:

@dfence, woow Dankeeee

da hast du ja richtig leckere Beispiele zusammengeschrieben. Damit kann ich was anfangen und fleißig üben.

Die void Methode war mir irgendwie klar, dass sie nur einen Arbeitsabschnitt darstellt. Nur kenne ich gerademal eine handvoll Befehle, um mehr zu machen.

Und warum immer ein leeres () steht, frage ich mich schon die ganze Zeit. Was man dort eintragen könnte, damit es einen Sinn ergibt und etwas komplexer wird.

Angefangen habe ich heute mit Arrays, das klappt schon mal gut. Und das nächste schreit schon nach Doppel-Arrays. Wir wollen ja Werte, Parameter hin und herschieben, irgendwelche Abläufe erstellen um letztendlich Daten zu verarbeiten/produzieren.

Aber das kommt schon mit der Zeit... Auf jeden Fall bleibe ich weiter am Ball. 2 Urlaubswochen habe ich schon an das herum-Arduino'n verbraten, spielt keine Rolle wann die Wetterstation fertig wird :slight_smile:

Auf jeden Fall danke auch Allen, für die restlichen Beiträge und die Hilfestellung.

void ist einfach nur ein Datentyp und bedeutet "nichts". Es gibt Anfänger die denken dass sei eine Art Anweisung und nennen Funktionen plötzlich "voids". Das führt zu nichts gutem.

Funktionen sehen so aus:
[Rückgabewert] [Name] ([Parameter])

Wenn man nichts zurück gibt es es eben void.

Wenn man keine Parameter hat kann man da auch void schreiben. Das wird in C gemacht, weil es da einen Unterschied zwischen () und (void) gibt. Tatsächlich ist es in C wesentlich besser wenn man void explizit angibt, weil es dann für den Compiler klar ist dass die Funktion keine Parameter hat. () bedeutet da dass die Funktion eine unbekannte Zahl an Paramtern hat.
In C++ (das ist die Sprache die hier verwendet wird) ist jedoch beides identisch. Man sieht manchmal auch (void), aber i.d.R. ist die Parameterliste einfach leer wenn man nichts übergibt.

Es verbessert dein Verständnis auch wenn du nicht alles als "Befehl" versteht. C/C++ ist weit komplexer als das. Es gibt Schüsselwörter, Datentypen, Operatoren, Funktionen, etc. Die werden unterschiedlich behandelt und folgen unterschiedlichen (aber klar definierten) Regeln.
Wenn man weiß wie die Dinge heißen kann man im Internet auch einfacher nach Hilfe dazu suchen. Der Unterschied zwischen Funktionen und Methoden ist da z.B. auch relevant. Wir wissen was du meinst (und grundlegend sind sie sehr ähnlich), aber wenn du im Internet nach Hilfe zu Methoden suchst ist das etwas leicht anderes als Hilfe zu Funktionen.

@Serenify Danke, das muss ist noch durchkauen, etwas später.

Nach etwas umbauen habe ich einen kleinen dummen simplen Fehler:

void readSensorsA() {
^
exit status 1
'pinSensorA' was not declared in this scope

Variable pinSensorAxyz ist doch global definiert. Ich habe gerade keinen Plan was er da nicht mag und drehe im Kreis.

Das Konstrukt sieht im Moment so aus:

#define pinSensorA0 0 // analog Temperatursensor
const int sensorA0 = 0; // ex pinTemp // spaeter fuer Poti, Taster o.ä.

void readSensorsA() {
  // get values from sensorA0..A3
  for (int i = 0; i < 4; i++) {
    int valA[i] = analogRead(pinSensorA[i]); // schreibe Werte in valA1..3
    delay(100); // warte auf Messwert
    // hier erhaltene Messwerte pro Sensor berechnen/umrechnen/mappen
    writeValueslast()
  }
}

void buildLogStringA() {
  String dataString = "";  // make a string for assembling the data
  for (int i = 0; i < 4; i++) {
    dataString += (getDatelong()); // Datum hinzufuegen
    dataString += (sepData); // Separator hinzufuegen
    dataString += (getTimelong()); // Uhrzeit hinzufuegen
    dataString += (sepData); // Separator hinzufuegen
    dataString += ("SensorA")sensorA[i]); // Sensorname hinzufuegen
    dataString += (sepData); // Separator hinzufuegen
    dataString += (sensorA[i]); // Sensornummer hinzufuegen
    dataString += (sepData); // Separator hinzufuegen
    dataString += (sensorT[i]); // Sensortyp hinzufuegen
    dataString += (sepData); // Separator hinzufuegen
    dataString += (valA[i]); // Messwert hinzufuegen
    dataString += (sepData); // Separator hinzufuegen
    dataString += (unit[u]); // Einheit hinzufuegen
    // array aus sensorA[i] -> sensorT[t] <- unit[u] {unit[T]emp,unit[L]ight,unit[H]umidity,unit[P]ressure,unit[R]ain}

    // return dataString;
    logData = dataString; // fertige Datenzeile uebergeben
    writeDatatoLogfile()
    dataString = ""; // clear string for new input
  }
}

void writeDatatoLogfile() {
  // dataFile.println(dataString);  // Datenzeile schreiben
  dataFile.println(logData);  // Datenzeile schreiben
  dataFile.close();
  Serial.println(logData);
}

Bitte helft mir. Fett dank.

Datalogger_sensor_a0-a3.ino (19.3 KB)

Der Fehler ist vermutlich woanders.

Hast du noch mehr #define davor ?

#define pinSensorA0 0 // analog Temperatursensor
#define pinSensorA1 1 // analog LM393 Photoresistormodul
#define pinSensorA2 2 // analog LDR Photoresistor
#define pinSensorA3 3 // analog LM393 Soil Moisture Sensor

....

  for (int i = 0; i < 4; i++) {
    int valA[i] = analogRead(pinSensorA[i]); // schreibe Werte in valA1..3

glaube nicht, dass Du das pinSensorA so mit den Nummern ergänzen kannst

denke dass musst du anders lösen.

Grüße
Jörg

müsste doch so gehen:

for (int i = 0; i < 4; i++) {
   int valA[i] = analogRead(i); // schreibe Werte in valA1..3

pinSensorA gibt es gar nicht. Und genau darüber beschwert sich der Compiler. "not declared in this scope" bedeutet dass eine Variable nicht bekannt ist

So geht es:

const byte pinSensorA[] = { 0, 1, 2, 3 };

for (int i = 0; i < 4; i++) {
   int valA[i] = analogRead(pinSensorA[i]);

Das Array ist hier zwar theoretisch nicht nötig, aber wenn es mal andere Pins sein sollen, kann man das so bequem machen

RudiDL5:
PS: Ich stimme combie übrigens zu und ergänze noch: Wenn man das alles durch rein privates "learning by doing" macht (oder machen muß weil die Umstände es so ergaben) ... dauert es noch wesentlich länger; vielleicht x 3 oder so

Das sehe ich anders. Wenn man es lernen will, lernt man's umso schneller. Gerade dann kann „learning by doing“ ein echter Turbo sein.

Gruß

Gregor

echter Turbo sein.

Veto: Mag sicherlich stimmen wenn man dabei zufällig in die richtige Richtung geht. Wenn man aber irgendwie ohne echten Plan von einer in die andere Sache stolpert, kann man sich auf lange Sicht gesehen mächtig verrennen ... fängt wieder bei Null an und muss so einiges über den Haufen werfen :wink:

Moin zusammen,

bin ja schon kräftig am Doing, zu Lasten von Learning :slight_smile:

Der Punkt mit #define war tatsächlich ein Tippfehler, Vorhaben war folgendes:

#define pinSensorA0 sensorA0;

Als Folgefehler kam das vertauschte:

const int pinSensorA0 = 0;
// durch
const int sensorA0 = 0;

daher das Gemecker der fehlenden Variable.

Die elegante Ausführung:

const byte pinSensorA[] = { 0, 1, 2, 3 };

gefällt mir besser. Danke für den Hinweis.

Langsam komm ich aus dem Karussel nicht raus. An jeder Ecke und Stelle quitscht etwas. Bin schon echt am Überlegen einen anderen Kurs einzuschlagen, Reset und neues Dokument.

Zur Verteidigung:

  • Die erste Version des "Projektes" hatte nur 2-3 analoge Sensoren, ein soweit funktionierendes LCD-Output und simples Reporting.
  • Die zweite Version hatte 3-6 digitale Sensoren, kein Output, funktionierte noch besser, allerdings nur kleine Probleme mit den Messwerten (pure Mathematik/Formelspielerei).
  • Die dritte Version war der Ansatz Datenlogging und Speicherung von Messdaten einzuführen. Noch bevor das richtig lief begann ich schon irgendwelche Ideen als draft zu implementieren.

Dann entschied ich mich für das daily-Logfile, von dort an begann das Chaos. Weder das Logging tut mehr, noch die Sensoren... Nun funktioniert gar nichts mehr :slight_smile:

So, liebe Gemeinde. Was würdet ihr an meiner Stelle machen?
-> zurück zu V1 und fertigstellen
-> zurück zu V2, Matheprobleme fixen, visuellen Output neu schreiben
-> zurück zu V3 und das Logging von Beginn sauber schreiben
-> irgendein fertiges Wetter-Projekt klauen und umschreiben?
-> oder was ganz anderes

Achja, bräuchte dringend ein anderes IDE. Das Arduino-Ding-Editor ist nicht zu ertragen... Da kann gedit/vim mehr. Was habt ihr im Einsatz?

Gruß aus dem verregnetem München

Achja, bräuchte dringend ein anderes IDE. Das Arduino-Ding-Editor ist nicht zu ertragen... Da kann gedit/vim mehr.

Scheinst nicht sehr Windows-affin zu sein. Sonst wäre das VisualMicro plugin was.