Datenlogger für Versuchsbienenstand

Vielen Dank thewknd,

Ich habe die Sensoren von den Pins 10, 11, 12 abgesteckt und auch aus dem Programm entfernt.
Die SD-Karte ist in einem Adafruit Data Logging Shield, das Huckepack auf dem Arduino sitzt.
Ich hoffe das nutzt tatsächlich die von dir angegebenen Pins.

Jetzt schreibt er alle 20 Sekunden (also bei jedem Intervall) "DHTxx test!" auf den Serial Monitor.
Sonst nichts.
Vorher hat er das nur am Anfang einmal geschrieben und dann halt alle 20 sek die Messwerte.

Hier der Code wie er jetzt aussieht:

#include "DHT.h"
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

#define DHT2PIN 2 // what pin we're connected to
#define DHT3PIN 3
#define DHT4PIN 4 
#define DHT5PIN 5 
#define DHT6PIN 6 
#define DHT7PIN 7 
#define DHT8PIN 8 
#define DHT9PIN 9 




#define DHT2TYPE DHT22   
#define DHT3TYPE DHT22
#define DHT4TYPE DHT22 
#define DHT5TYPE DHT22
#define DHT6TYPE DHT22
#define DHT7TYPE DHT22
#define DHT8TYPE DHT22
#define DHT9TYPE DHT22





RTC_DS1307 rtc;

const int chipSelect = 10;

File dataFile;

// Initialize DHT sensor
DHT dht2(DHT2PIN, DHT2TYPE);
DHT dht3(DHT3PIN, DHT3TYPE);
DHT dht4(DHT4PIN, DHT4TYPE);
DHT dht5(DHT5PIN, DHT5TYPE);
DHT dht6(DHT6PIN, DHT6TYPE);
DHT dht7(DHT7PIN, DHT7TYPE);
DHT dht8(DHT8PIN, DHT8TYPE);
DHT dht9(DHT9PIN, DHT9TYPE);



void setup() {
  Serial.begin(9600); 
  
  #ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); 
#endif
  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");}
  
  Serial.println("DHTxx test!");
 
  dht2.begin();
  dht3.begin();
  dht4.begin();
  dht5.begin();
  dht6.begin();
  dht7.begin();
  dht8.begin();
  dht9.begin();



  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(chipSelect, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1) ;
  }
  Serial.println("card initialized.");
  
  // Open up the file we're going to log to!
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (! dataFile) {
    Serial.println("error opening datalog.txt");
    // Wait forever since we cant write data
    while (1) ;
  }}


void loop() {
  // Wait a few seconds between measurements.
  delay(20000);
  
   DateTime now = rtc.now();


  float h2 = dht2.readHumidity();

  float t2 = dht2.readTemperature();
  
  float h3 = dht3.readHumidity();

  float t3 = dht3.readTemperature();
  
    float h4 = dht4.readHumidity();

  float t4 = dht4.readTemperature();
  
  float h5 = dht5.readHumidity();
  
  float t5 = dht5.readTemperature();
  
    float h6 = dht6.readHumidity();
  
  float t6 = dht6.readTemperature();
  
  float h7 = dht7.readHumidity();

  float t7 = dht7.readTemperature();
  
    float h8 = dht8.readHumidity();

  float t8 = dht8.readTemperature();
  
  float h9 = dht9.readHumidity();
 
  float t9 = dht9.readTemperature();
  

  
   Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h2) || isnan(t2)) {
    Serial.println("Failed to read from DHT sensor 2!");
    return;
  }

  Serial.print("Humidity 2: "); 
  Serial.print(h2);
  Serial.print(" %\t");
  Serial.print("Temperature 2: "); 
  Serial.print(t2);
  Serial.println(" *C ");
  
  dataFile.print("Humidity 2: "); 
  dataFile.print(h2);
  dataFile.print(" %\t");
  dataFile.print("Temperature 2: "); 
  dataFile.print(t2);
  dataFile.println(" *C ");
  
   if (isnan(h3) || isnan(t3)) {
    Serial.println("Failed to read from DHT sensor 3!");
    return;
  }

  Serial.print("Humidity 3: "); 
  Serial.print(h3);
  Serial.print(" %\t");
  Serial.print("Temperature 3: "); 
  Serial.print(t3);
  Serial.println(" *C ");
  
     if (isnan(h4) || isnan(t4)) {
    Serial.println("Failed to read from DHT sensor 4!");
    return;
  }

  Serial.print("Humidity 4: "); 
  Serial.print(h4);
  Serial.print(" %\t");
  Serial.print("Temperature 4: "); 
  Serial.print(t4);
  Serial.println(" *C ");
  
  if (isnan(h5) || isnan(t5)) {
    Serial.println("Failed to read from DHT sensor 5!");
    return;
  }

  Serial.print("Humidity 5: "); 
  Serial.print(h5);
  Serial.print(" %\t");
  Serial.print("Temperature 5: "); 
  Serial.print(t5);
  Serial.println(" *C ");
  
  if (isnan(h6) || isnan(t6)) {
    Serial.println("Failed to read from DHT sensor 6!");
    return;
  }

  Serial.print("Humidity 6: "); 
  Serial.print(h6);
  Serial.print(" %\t");
  Serial.print("Temperature 6: "); 
  Serial.print(t6);
  Serial.println(" *C ");
  
   if (isnan(h7) || isnan(t7)) {
    Serial.println("Failed to read from DHT sensor 7!");
    return;
  }

  Serial.print("Humidity 7: "); 
  Serial.print(h7);
  Serial.print(" %\t");
  Serial.print("Temperature 7: "); 
  Serial.print(t7);
  Serial.println(" *C ");
  
  if (isnan(h8) || isnan(t8)) {
    Serial.println("Failed to read from DHT sensor 8!");
    return;
  }

  Serial.print("Humidity 8: "); 
  Serial.print(h8);
  Serial.print(" %\t");
  Serial.print("Temperature 8: "); 
  Serial.print(t8);
  Serial.println(" *C ");
  
  if (isnan(h9) || isnan(t9)) {
    Serial.println("Failed to read from DHT sensor 9!");
    return;
  }

  Serial.print("Humidity 9: "); 
  Serial.print(h9);
  Serial.print(" %\t");
  Serial.print("Temperature 9: "); 
  Serial.print(t9);
  Serial.println(" *C ");
  
}

Andreas_R:
Leider funktioniert es aber immer noch nicht.
Könnte sich das bitte nochmal jemand anschauen?

Gab's jetzt eine Projektverlängerung, oder was?

In Reply #1 hast Du vor einer Woche geschrieben:

Andreas_R:
Hilfe! Wir müssen das heute fertig bekommen, damit wir noch genügend Daten sammeln können bevor die Saison vorbei ist!
:cold_sweat:

Also ich habe mich an dem vor einer Woche gestarteten Thread eigentlich nur wegen der völlig inakzeptablen Deadline "heute fertig" nicht daran beteiligt. Jetzt sehe ich, dass eine Woche vergangen ist und ihr es immer noch nicht am Laufen habt.

Also wie lange habt ihr denn jetzt wirklich Zeit, um das zum Funktionieren zu bekommen?

Wenn Du vor einer Woche geschrieben hättest "in einer Woche soll es laufen", häte ich ja virtuelle Hilfe angeboten. Aber die extreme Deadline von ein paar Stunden, dass es noch am selben Tag laufen soll, also das fand ich extrem abschreckend.

Im übrigen fallen mir an Eurem Code zwei Dinge auf:

  1. nicht unnötig RAM-Speicher verbrauchen:
    Wenn ihr nur einen UNO mit 2 KB RAM habt und darauf eine fette Library wie "SD" verwenden wollt, die alleine schon über 1 KB RAM wegfrißt, dann müßt ihr in Eurem Programm RAM-Speicher sparen. Eine Maßnahme dazu wäre beispielsweise, dass man String-Konstanten im Flash-Speicher hält und nicht im RAM, indem man bei der Ausgabe von Textkonstanten per print/println mit dem F-Makro macht. Also beispielsweise statt:
Serial.println("Failed to read from DHT sensor 2!");

Besser weil RAM-sparender:

Serial.println(F("Failed to read from DHT sensor 2!"));
  1. Wenn stets fast gleiche Dinge zu tun sind, Funktionen und for-Schleifen nutzen!
    Wenn ihr ein Dutzend Sensoren abfragen und den Wert ausgeben lassen möchtet, dann schreibt man nicht zwölfmal "Programmcode für alles" hin, sondern dann macht man eine Programmschleife oder eine Funktion, die EINEN Sensor behandelt. Und über eine Zählvariable oder einen Funktionsparameter wird eine Nummer von 1 bis 12 übergeben, die vorgibt, welcher Sensor gerade dran ist, abgefragt und behandelt zu werden. Das verringert einerseits die Komplexität des Programms und macht es andererseits bei Änderungen leichter wartbar: Wenn sich zum Beispiel der Code zur Abfrage des Sensors ändern soll, braucht man dann nämlich nicht 12 Stellen im Programm ändern, sondern nur eine einzige.

Also letzte Woche war der Kollege da, bei dem der Versuchsbienenstand steht.
Wäre das da fertig geworden, dann hätte er es mitnehmen können und wir hätten vielleicht noch genug Daten sammeln können um damit begründete Aussagen treffen zu können.

Die Versuchsbienenvölker würden es am Versuchsstand nicht über den Winter schaffen, deshalb werden die vorher kostenlos an Jungimker (v.a. Studenten die mit Imkerei anfangen möchten) abgegeben, damit sie evtl. eine Chance haben.

Wir haben jetzt noch ein paar Wochen Zeit, solange die Bienen noch fliegen, um zumindest einen kleinen Vorversuch zu starten.
So könnten wir testen ob sich die Sensoren unter realen Bedingungen bewähren, ob die Bienen sie etwa zubauen und was man dagegen tun könnte.
Evtl. lässt sich anhand der Messwerte auch abschätzen inwiefern unsere Arbeitshypothese zutrifft und ob es sich lohnt nächstes Jahr eine große Versuchsreihe zu starten, die mit erheblichem finanzellen Aufwand verbunden wäre.

Wie lange dafür jetzt noch Zeit ist lässt sich schwer sagen, weil das vor allem von der Witterung abhängt. Ein goldener Oktober wäre perfekt, aber wenn es weiter nur regnet und kälter wird werden wir den Versuchsbienenstand bald auflösen müssen.

Wir haben jetzt beschlossen dieses Wochenende noch einmal zu versuchen das mit der SD-Karte hinzubekommen. Wenn es nicht klappt werden wir den PC mit ins Feld stellen und mit dem Serial Monitor "loggen". Das ist natürlich alles andere als ideal.

Es sollte halt erst mal provisorisch funktionieren, aber Hauptsache es funktioniert.

Wenn wir dann ein paar Werte, vielleicht von 3-4 Wochen haben und hoffentlich abschätzen können ob sich das rentiert und überhaupt in der Praxis realisierbar ist, werden wir über den Winter an den Details arbeiten, das Programm schön machen und alles ordentlich und in entsprechender Anzahl bauen damit wir das nächstes Jahr in einem Maßstab machen können der erforderlich ist um stichhaltige Aussagen treffen zu können.

Glaubst du das mit dem RAM ist der Grund warum es nicht klappt?
Oder ist das nur eine Sache die man schon machen sollte aber nicht unbedingt muss? Würde ja dann auch erst bei der Serienversion genügen.

Andreas_R:
Wir haben jetzt noch ein paar Wochen Zeit, solange die Bienen noch fliegen, um zumindest einen kleinen Vorversuch zu starten.

OK, das hört sich schon mal anders an als "es muss heute funktionieren".

Andreas_R:
So könnten wir testen ob sich die Sensoren unter realen Bedingungen bewähren, ob die Bienen sie etwa zubauen und was man dagegen tun könnte.

Eure Messungen und ob die Erfassung mit genau diesen Sensoren besonders sinnvoll ist mal zunächst außen vor gelassen: Wenn ihr das Programm entsprechend modular und mit einer vernünftigen Struktur aufbaut, wäre es kein Problem, die Sensoren später gegen andere auszutauschen.

Messt ihr zum Vergleich auch die Außentemperatur und die Außenluftfeuchte nach halbwegs meteorologischen Standards (z.B. im gut durchlüfteten Schatten, 2 m über Grasboden, fernab von soliden Gebäuden)?

Andreas_R:
Es sollte halt erst mal provisorisch funktionieren, aber Hauptsache es funktioniert.

Tja, wenn etwas zuverlässig und wie gewünscht funktioniert, ist man fertig.
Das ist das Ziel.

Andreas_R:
Wenn wir dann ein paar Werte, vielleicht von 3-4 Wochen haben und hoffentlich abschätzen können ob sich das rentiert und überhaupt in der Praxis realisierbar ist, werden wir über den Winter an den Details arbeiten, das Programm schön machen

Nein, das Programm muß von Anfang an schön gemacht werden.
Funktionell und sauber strukturiert.
Und dabei immer an die zur Verfügung stehenden Ressourcen wie z.B. RAM-Speicher denken!
Nur dann ist ein Programm überhaupt "leicht wartbar" und Du in einigen Monaten überhaupt noch in der Lage, daran Änderungen vorzunehmen, ohne Dich in wirren Datenstrukturen und Programmlogiken zu verheddern.

Andreas_R:
Glaubst du das mit dem RAM ist der Grund warum es nicht klappt?

Wenn Deinem Programm der RAM-Speicher ausgehl, dann läuft es nicht. In dem Programm, das Du gepostet hast, wird RAM-Speicher ohne Ende für gar nichts verbraten. Wie Du einen großen Teil RAM-Speicher durch Verwendung des F-Makros bei print/println einsparen kannst, habe ich in meinem letzten Posting geschrieben. Ob das "notwendig" oder gar "hinreichend" ist, um Dein Programm funktionieren zu lassen, keine Ahnung, das müßte ich selbst mal gründlich testen, bevor ich dazu etwas sagen kann. Bisher kann ich nur sagen, dass ihr Euch um einen möglicherweise zu hohen RAM-Verbrauch Eures Programm offenbar überhaupt keine Gedanken gemacht habt und dass es wahrscheinlich sehr notwendig ist, den RAM-Verbrauch im Auge zu behalten.

Andreas_R:
Oder ist das nur eine Sache die man schon machen sollte aber nicht unbedingt muss?

Nein, sobald Du "fette" Libraries wie die SD-Kartenlibrary verwendest, die selbst bereits reichlich RAM verbrauchen und Du gleichzeitig für das Arduino-Board UNO mit dem geringsten RAM-Speicher handelsüblicher Arduino-Boards programmierst, ist das für nicht-triviale Programme eigentlich eher ein "muss" als ein "nice to have", bei Ausgaben von Textkonstanten das F-Makro zu verwenden.

Ich schaue mal, ob ich sonst noch etwas finden kann.
Leider verwendet ihr ja reichlich Drittanbieter-Libraries, so dass man Euren Sketch nicht mal eben durchkompilieren lassen kann, ohne sich vorher erstmal alle diese Drittanbieter-Libraries zu suchen, herunterzuladen und zu installieren.

Ok, dann fangen wir nochmal von vorne an und machen das ordentlich.

Die DHT22 Sensoren haben wir jetzt schon da, die waren nicht so billig. Was stört an denen? Wir fanden es eigentlich recht praktisch, dass die gleichzeitig Temperatur und Luftfeuchte messen. Uns interessiert v. a. die Luftfeuchte, die Temperatur muss aber sinnvollerweise auch gemessen werden.
Das Gehäuse hat auch eine Öse, mit der man die gut im Bienenstock anschrauben könnte.

Andreas_R:
Ok, dann fangen wir nochmal von vorne an und machen das ordentlich.

So schlimm ist das gar nicht. Im Prinzip müßte man als erstes nur mal die Sensorpins und -messwerte in Arrays unterbringen und die Programmlogik auf eine for-Schleife umstellen statt alles nacheinander mit eigenem Code abzuarbeiten. Ich schaue mir das mal an.

Im übrigen liegt es bei einem UNO-Board tatsächlich am RAM-Speicher, der Dir beim Programmieren ausgegangen ist.

Ich habe das Programm gerade mal auf einen MEGA2560 gezogen, der 8 KB RAM hat, als Drittanbieter-Library habe ich nur die DHT-Library verwendet, die RTC-Library und alle Bezüge darauf auskommentiert, und das am nackten Board betriebene Programm zeigt mir an:

Free RAM: 5810
DHTxx test!
Initializing SD card...Card failed, or not present

Wenn auf einem MEGA-Board mit 8 kB RAM also 81024 Bytes noch 5810 Bytes frei sind, dann benötigt Dein Programm ca. 81024-5810 = 2382 Bytes RAM. Das liegt deutlich über den 2 KB RAM, die ein UNO hat. Du benötigst für Dein Programm also DRINGEND das F-Makro bei allen print/println Ausgaben von Textkonstanten.

Aber wie gesagt: Die ganze Sensorerfassung und Datenausgabe auf eine for-Schleife umschreiben, dann werden es schon viel weniger Textkonstanten, die im Programm eingebaut werden müssen. Und dann geht es vielleicht doch wieder ohne F-Makros.

Über die Sensoren können wir dann ein anderes mal diskutieren. Nachdem Du diese teuer gekauft hast, wirst Du ja auch genau diese erstmal verwenden wollen und Dein Programm mit genau diesen Sensoren zum Laufen bekommen. Vielleicht bewähren sie sich ja.

Also einen Mega 2560 hätte ich auch da.
Den wollten wir ursprünglich verwenden, weil man da mehr Sensoren anschließen kann.
Weil aber das Adafruit Datalogging Shield nicht genau drauf passt (die Abstände zwischen den Buchsenleisten sind etwas anders und manche Anschlüsse sind wo anders), hab ich stattdessen einen UNO genommen, der hier rumlag.
Das erschien mir einfacher als die Anschlüsse alle einzeln zu verkabeln, wo doch das Shield als praktische Huckepack-Lösung gedacht ist.
Wobei, muss man da eigentlich alle Anschlüsse verkabeln oder sind die meisten nur durchgeführt?

Nachtrag: Diese F-Sache, ist das wirklich so einfach, dass ich nur um jeden print-Befehl noch (F...) drum mach?

Jup

Dann mach ich das doch mal...

So einfach ist das doch nicht: 'F' was not declared in this scope.
Ich muss dem also erklären was F ist.
Wie mach ich das?

Andreas_R:
So einfach ist das doch nicht: 'F' was not declared in this scope.
Ich muss dem also erklären was F ist.
Wie mach ich das?

Das machst Du nur mit TEXTKONSTANTEN, also feststehendem Text, den Du ausgibst.
Das funktioniert nicht mit Variablen.

Beispiel:

Serial.println(F("Ich bin eine Textkonstante"));

Bevor Du damit loslegst, wartest Du aber am besten erstmal ab: Ich vereinfache Dir Deine Programmstruktur erstmal und stelle auf Arrays und for-Schleifen um.

Nachfrage: Hast Du denn jetzt alles zum Testen da? RTC? Ein paar Sensoren? SD-Karte?
Oder steht das irgendwo bei irgendwem in der Imkerei und Du mußt ohne testen und entwickeln?

Das ist alles hier bei mir!

Andreas_R:
Das ist alles hier bei mir!

Alles klar, optimale Voraussetzungen!

Jetzt habe ich mal grob über das Ausgabeformat drübergeschaut, dass Du auf Serial ausgeben läßt.

Das schaut ja ungefähr so aus (Temperaturwerte sind nur Zufallszahlen):

Humidity 0: 91.00 %	Temperature 0: 47.00 *C	
Humidity 1: 4.00 %	Temperature 1: -3.00 *C	
Humidity 2: 17.00 %	Temperature 2: 24.00 *C	
Humidity 3: 14.00 %	Temperature 3: -14.00 *C	
Humidity 4: 86.00 %	Temperature 4: -30.00 *C	
Failed to read from DHT sensor 5
Humidity 6: 74.00 %	Temperature 6: -34.00 *C	
Humidity 7: 53.00 %	Temperature 7: -14.00 *C

Wie und womit möchtest Du das auswerten, wenn auf auf SD-Karte geschrieben wird?

Normalerweise würde sich zur Aufzeichnung eher ein solches Format eigenen:

  • Eine Zeile pro Datensatz
  • Ein Datensatz besteht aus Datum, Zeit, und 12x Sensorwerten Humidity/Temperature
    (alle Werte mit einem Trennzeichen getrennt, z.B. Semikolon oder Tabulatorzeichen)

Solche Dateien könntest Du dann relativ einfach weiterverarbeiten, z.B. mit MS-Excel oder anderen Programmen.

Soll ich Dir die Ausgabe gleich so umstellen, dass alle Werte eines Datensatzes in einer Zeile ausgegeben werden?
(Zusammengehörende Werte stehen dann spaltenweise untereinander)
Was meinst Du?

Ja das wäre perfekt.
Auswertung wird mit Excel erfolgen.
Mir ist noch aufgefallen dass bei der Version, die nur auf Serial Monitor ausgibt das, bei einem Fehler nicht weiter geht.
Also angenommen Sensor 5 geht kaputt, dann schreibt er noch einmal "Failed to read from DHT sensor 5", dann ist aber Schluss.
Das wäre blöd, falls die Bienen doch mal ein Kabel abnagen.

Andreas_R:
Ja das wäre perfekt.
Auswertung wird mit Excel erfolgen.

OK, also schreibt man am besten ein Format, das sich in Excel besonders leicht importieren läßt. Also beispielsweise TAB-Seperated ASCII-Text.

Muss ich mal schauen, irgendwo muß ich noch eine Excel Starter-Edition auf einem PC haben. Ich glaube, auf deutschen Excel-Versionen mit Lokaleinstellung Deutschland importiert man Gleitkommazahlen besser mit Dezimalkomma als mit Dezimalpunkt. damit sie problemlos als Zahlen importiert werden? Muss ich mal ausprobieren.

Andreas_R:
Mir ist noch aufgefallen dass bei der Version, die nur auf Serial Monitor ausgibt das, bei einem Fehler nicht weiter geht.

Mit Fehlerbehandlung kann man sich wahrscheinlich länger beschäftigen als mit der Programmierung einer Prototypen-Firmware.

Als wichtigen Parameter müßte man noch wissen:
Wie oft sollen Daten aufgezeichnet werden? Jede Viertelstunde? Alle Fünf Minuten? Jede Minute? Häufiger?

Ggf. muß man sich nämlich Gedanken über das Kaputtschreiben von SD-Kartensektoren machen. Mal angenommen, ein SD-Kartensektor kann 100000 mal beschrieben werden und Du schreibst einmal pro Sekunde Daten in eine Datei, die dazu jedesmal geöffnet, beschrieben und geschlossen wird, dann wird bei jedem Schließen der Datei der FAT-Sektor mit der Dateigröße neu beschrieben. In dem Fall wäre der FAT-Sektor bereits nach etwas über einem Tag kaputtgeschrieben.

Zwar hat eine SD-Karte immer "Ersatzsektoren", die der Kartencontroller für kaputtgeschriebene Sektoren als Ersatz in das Dateisystem einblenden kann, aber diese stehen nur begrenzt in nicht allzu großer Anzahl zur Verfügung. Wenn alle Ersatzsektoren verbraucht und ebenfalls kaputtgeschrieben sind, ist die Karte defekt und unbrauchbar.

Also wie oft sollen die Daten auf Karte geschrieben werden?

Das wäre dann auch eine Frage des Datenumfangs, mit dem Du zu hantieren hast. Mal angenommen, Du machst eine Aufzeichnung einmal pro Minute, dann bekommst Du 1440 Datensätze pro Tage = ca.30*1440 = 43200 Datensätze pro Monat zum Auswerten. Bei einer Aufzeichnung alle 10 Minuten wäre es nur ein Zehntel der Datenmenge.

Hast Du Dir schon überlegt, wie viele Daten Du wie oft erzeugen und aufzeichnen möchtest?
Alle Daten in eine einzige Datei?
Oder die Daten jeden Tag oder jede Woche oder jeden Monat in eine neue Datei?

Zu den Schreibzyklen noch eine Anmerkung: beim FAT-Dateisystem, das bei SD-Karten verwendet wird, gibts ein Inhaltsverzeichnis, was auch jedes Mal neu geschrieben wird. Das ist auch eine Schwachstelle. Denn die MFT wird halt bei jeder Datei wieder geändert. Deshalb wurde bei SSD's auch das wearleveling eingeführt, wo der Controller den logischen Blöcken, die das Betriebssystem und das Dateisystem "sehen" pysische Speicherzellen im Austausch untergeschoben werden, so das die MFT eben bei 1000x ändern nicht 1000x in die selbe Zelle geschrieben wird. Die Reservesektoren sind dann Stufe zwei. Deshalb sollte man eine SSD auch nie bis zum Rand füllen, denn für dieses Rotationsverfahren werden nur freie Zellen genutzt. Gibt es davon wenig, sind die Wenigen halt schneller wieder dran.

Gruß Gerald

Also als Intervall für die Aufzeichnung sollte eigentlich eine ganze oder halbe Sunde genügen.
Das kann man ja später noch einstellen und z.B. mal einen Tag oder eine Woche mit höherer Auflösung aufzeichnen.
Im Normalbetrieb müsste aber eine Stunde passen, das Klima im Bienenstock hat eine gewisse Trägheit.
Wir könnten sicherheitshalber die SD-Karten regelmäßig austauschen wenn abzusehen ist, dass die z.B. nur drei Monate durchhalten dann entsorgen wir die halt nach zwei Monaten Laufzeit.
Das brauchen ja keine großen Karten sein, die kosten ja inzwischen nicht mehr viel.
Die Daten sollen alle in eine Datei.
Es wird so sein, dass die Karte ca. einmal pro Woche ausgetauscht wird. Das ist dann besser so, Datum und Uhrzeit stehen ja immer bei jedem Datensatz dabei.

Jetzt ist es ja noch so, dass an die Pins 0,1,10,11,12,13 keine Sensoren angeschlossen werden können. Wir haben aber 12 Sensoren, könnte man die vier, die vorher auf 1,10,11,12 angeschlossen waren noch auf den analogen Pins unterbringen?

Ich gehe jetzt ins Bett, vielen herzlichen Dank soweit schonmal und gute Nacht.

Ja, die analogen Pins kann man auch als digitale I/Os verwenden. Entweder mit A0, A1, etc. entsprechend oder mit Zahlen > 13. Auf dem UNO ist A0 = 14, A1 = 15, etc. Auf dem Mega ist A0 = 54. Also immer 1 mehr als der höchste nummerierte Pin.

Andreas_R:
Also als Intervall für die Aufzeichnung sollte eigentlich eine ganze oder halbe Sunde genügen.

OK, das ist ja sehr entspannt. Bei stündlichem Schreibvorgang wären das 24 Schreibvorgänge pro Tag oder ca. 30*24= 720 pro Monat, damit würde es über 100 Monate dauern, bis der erste Sektor kaputtgeschrieben ist, wenn Du über 100 Monate lang immer in dieselbe Datei schreibst. Überhaupt kein Problem.

Ich schlage mal vor: Viertelstündlich schreiben, macht 424= 96 Schreibvorgänge pro Tag und ca. 3096= 2880 Schreibvorgänge pro Monat. In einen FAT-Sektor von 512 Bytes passen 32 Dateieinträge a 16 Bytes, also alle 32 Dateien wird in einen anderen FAT-Sektor geschrieben. Wenn Du nun jeden Monat in eine andere Log-Datei schreibst, finden maximal ca. 32*2880 Schreibvorgänge im selben FAT-Sektor statt = 92160 Schreibvorgänge für den am stärksten belasteten FAT-Sektor.

Das sollte eine hochwertige SD-Karte noch schaffen, ohne dabei defekt zu werden oder Ersatzsektoren zu verwenden, so dass Du die Karte damit viele Jahre lang beschreiben kannst, bis sie voll ist (Voraussetzung: Keine bereits geschriebenen Dateien löschen).

Andreas_R:
Jetzt ist es ja noch so, dass an die Pins 0,1,10,11,12,13 keine Sensoren angeschlossen werden können. Wir haben aber 12 Sensoren, könnte man die vier, die vorher auf 1,10,11,12 angeschlossen waren noch auf den analogen Pins unterbringen?

Du kannst die Pins A0 bis A5 auf dem UNO auch als digitale Pins verwenden.

Über das zu schreibende Datenformat habe ich mir folgende Gedanken gemacht:
Wenn die Daten in Excel weiterverarbeitet werden sollen, dann wäre ein Datenformat praktisch, das sich ruckzuck und ohne Aufwand in Excel importieren läßt. Beim Datenimport beachtet Excel offenbar die Ländereinstellungen des PCs, so dass auf einem auf "Deutschland/Deutsch" eingestellten PC das Datumsformat "dd.mm.yyyy" verwendet wird und für Zahlen mit Nachkommastellen das Komma und nicht der Dezimalpunkt als Trennzeichen erwartet wird.

Ich habe mal eine Musterdatei als Textdatei mit Zufallsdaten gemacht und versucht, diese dann in Excel zu importieren und zu verarbeiten. Probiere bitte mal aus, ob Du mit so einer "test.txt" Datei auch etwas anfangen und diese leicht in Excel öffnen und die Daten verarbeiten kannst!

Diese test.txt Datei sollte so vorbereitet sein, dass Du beim Excel Import-Wizard auf einem PC mit "Deutsch" Einstellung nur die Standardvorgaben bestätigen mußt, und schon wird die Datei ohne weitere Einstellungen direkt geöffnet bzw. importiert. Funktioniert das bei Dir?

test.txt.txt (4.55 KB)