Show Posts
Pages: 1 2 [3] 4 5 ... 211
31  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 14, 2014, 09:25:29 am
Ja, vergießen mit 2k Harz ist auch meine Lieblingslösung bei meinem U-Boot-Projekt (ach Gott, das verstaubt im Keller, weil keine Zeit...)
Wo keine Luft ist kommt auch kein Wasser hin.

Allerdings könnte es bei einem SD-Datenlogger dann schwierig werden, die SD-Karte zum Auslesen zu entfernen, wenn die Platine in Elektronik-Vergußmasse eingegossen ist.

Die Alternative, um Platinen beim Einsatz im Außenbereich gegen rauhe Bedingungen und zeitweise entstehendes Kondenswasser abzuhärten ist die Lackierung der bestückten Boards mit Speziallacken.

Bei Conrad gibt es für den Zweck zum Beispiel Sprühdosen mit "PLASTIK 70", einem hochisolierenden Schutzlack, der Korrosionserscheinungen an Elektronikplatinen im Außenbereich verhindert. Den SD-Kartenschacht müßte man vor dem Einsprühen aber wohl abkleben, wenn man so einen Sprühlack verwendet.

Über mögliche LED-Lichteffekte, die den Betriebszustand des Datenloggers nach außen signalisieren, habe ich auch nochmal nachgedacht. Also wenn man eine grüne und eine rote LED verwendet, könnte man es zum Beispiel so machen:

Grüne LED:
- wird nach erfolgreichem setup() auf "Pulsschlag" geschaltet, 1s an, 1s aus wenn das Programm läuft
- zeigt einige Sekunden lang dauer-grün während die Sensoren ausgelesen werden
Das regelmäßige Ein- und Ausschalten der grünen LED signalisiert dann, dass das Programm läuft und nicht hängt oder abgestürzt ist.

Rote LED:
- wird nach erfolgreichem setup() auf "aus" geschaltet und leuchtet danach nur im Fehlerfall
- rotes Blinken ==> Sensoren sind ausgefallen
- rotes Dauerlicht ==> SD-Karte oder RTC-Uhr funktioniert nicht
Das rote Blinken bei ausgefallenen Sensoren könnte man von der Anzahl der ausgefallenen Sensoren abhängig machen. Zum Beispiel bei 12 Sensoren macht man eine 3-Sekunden Blinkperiode und steuert diese Periode wie folgt:
- 1 Sensor ausgefallen ==> 250 ms rot an, 2750 ms aus
- 2 Sensoren ausgefallen ==> 500 ms rot an, 2500 ms aus
- 3 Sensoren ausgefallen ==> 750 ms rot an, 2250 ms aus
- 4Sensoren ausgefallen ==> 1000 ms rot an, 2000 ms aus
etc.
D.h. je mehr Sensoren ausgefallen sind, desto länger bleibt die rote LED an.

So könnte man dann mit einer kurzen Sichtkontrolle der LEDs jederzeit kontrollieren, ob noch alles wunschgemäß läuft.
32  International / Deutsch / Re: DCF77 – macht keinen Spaß on: September 14, 2014, 08:49:40 am
Ich finde NTP zu störanfallig: mein Arduino holt sich 1 mal am Tag die Zeit übers Internet, wenn aber keine Daten verfügbar sind,  dann bleibt der komplette Sketch stehen und ich muss Reset drücken  smiley-sad

Das kann eigentlich gar nicht angehen. Bei NTP sendest Du ein UDP-Paket und schaust eine Sekunde später nach, ob Du ein UDP-Paket zurückbekommen hast. Wenn Du nichts zurückbekommen hast, machst Du nichts, wenn Du was zurückbekommen hast, hast Du eine neue Zeit.

Hänger mit Stehenbleiben des gesamten Sketches stelle ich eher bei HTTP-Anwendungen fest, wenn Verbindungen aufgebaut, Daten bei stehender Verbindung ausgetauscht und die Verbindung dann wieder beendet wird.

Vlt hat aber auch mein Netshield ne Macke.... manchmal wird die SD-Karte beim starten nicht erkannt, oder der Arduino bekommt keine  IP-Adresse (trotz fester Zuweisung). Teilweise läuft der Sketch auch tagelang und es kann plötzlich nicht mehr von der SD-Karte gelesen werden

Im Endeffekt kommt es auch auf das Programm an: Wenn die Hardware nicht optimal anstesteuert wird, können Probleme auftreten. In Bezug auf NTP stelle ich zum Beispiel auch hier im deutschsprachigen Forum fest, dass die Leute dazu neigen, Code aus dürftigsten Programmbeispielen direkt zu übernehmen und extrem fehlerträchig zu programmieren.

Das fängt dann damit an, dass NTP-Server nicht über den Namen angesprochen werden, sondern nur über die IP-Nummer, die sich jederzeit ändern kann, wenn der Server neu aufgesetzt oder eine andere Hardware ans Internet angeschlossen wird. Und das geht damit weiter, dass als NTP-Server irgendein dubioser Server einer Frickler-Organisation in Übersee eingetragen wird statt in Deutschland die zuverlässigen Server der Physikalisch-Technischen Bundesanstalt in Braunschweig zu verwenden, die wir mit Steuergeld bezahlen, damit sie die amtliche Zeit zuverlässig und genau verbreiten.

Ich stelle jetzt jedenfalls auf DCF um, denke mal dass ich damit besser fahre.

Auch da kommt es auf die Software an, und wie gut diese mit dem verwendeten DCF-Modul harmoniert. Fast alle im Internet verbreiteten Codes zur DCF-Auswertung harmonieren nur mit solchen Modulen gut, die ein tiefpassgefiltertes Signal ausgeben, wie das Modul von Pollin. Mit Modulen wie dem Conrad-DCF-Modul, das ein ungefiltertes Signal ausgibt, kommen nur wenige DCF-Auswertungen gut klar, sobald das Signal gestört wird, wie zum Beispiel der Code von Udo.
33  International / Deutsch / Re: Wie setze ich die dauer einer action? on: September 14, 2014, 05:58:46 am
Und da hänge ich fest. Aktuell benutze ich den befehl delay(20000), LCD geht dann auch für 20 sec an aber die Sensordaten aktualisieren sich auch 20 sec. lang nicht da der loop ja wartet. Wegen der Sensordaten(Temp,Luftdruck...) weiter nicht schlimm, aber wenn eine Uhr dazu soll geht das so nicht.

Ja, "delay" ist ein Befehl zum Blockieren der Programmausführung für eine bestimmte Zeit.

Für Programme, die nicht blockiert werden sollen, ist delay völlig ungeeignet.

Meine Frage; wie bestimme ich die dauer von lcd.backlight() ohne die anzeige der Sensordaten damit zu beeinflussen?

Ohne delay natürlich. Am besten deklarierst Du Dir oberhalb der loop-Funktion sowas in der Art:
Code:
#define BACKLIGHTDURATION 20000L  // Anzahl Millisekunden Einschaltzeit
boolean backlightOn=false;
unsigned long backlightOnTime=0;  // Einschaltzeitpunkt in Millisekunden
Und in der loop behandelst Du es dann ungefähr so (ungetestet hingeschrieben):
Code:
void loop() {
  // Irgendwas an Code
  if (backlightOn && millis()-backlightOnTime>BACKLIGHTDURATION)
  {
    lcd.noBacklight(); //backlight Off
    backlightOn=false;
  }
  else if (!backlightOn && digitalRead(inputPin))
  {
    lcd.backlight(); // backlight on
    backlightOn=true;
    backlightOnTime=millis();
  }
  // Noch irgendwas anderes an Code
}

Funktioniert's?
34  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 13, 2014, 01:01:13 pm
Wenn's nach mir geht, dann hätte ich gerne zwei LEDs, eine grüne und eine rote.
Wenn alles perfekt ist, dann leuchtet die grüne andauernd.

Eine dauergrüne LED zeigt nur wenig brauchbares an. Dafür brauchst Du keinen IO, die hängst Du am besten mit Vorwiderstand gleich an 5V und dann leuchtet sie dauernd, solange das Board mit Spannung versorgt wird. Quasi eine Spannungskontrolle.

Dauergrün würde ja auch leuchten, wenn
- das Programm in einer Endlosschleife festhängt
- das Programm schon lange abgestürzt ist
- die loop-Funktion aus anderen Gründen überhaupt nicht mehr aufgerufen wird oder nicht durchläuft
Mehr als eine grobe Kontrolle der Betriebsspannung kann das nicht sein.

Mit Blinksignalen der verschiedensten Art läßt sich etwas anfangen.

Wenn einer oder mehrere Sensoren nicht senden, dann leuchtet die grüne andauernd und die rote blinkt.
Wenn keine Aufzeichnung mehr möglich ist (alle Sensoren i.A. oder SD funktioniert nicht), dann leuchtet die rote andauernd.
Dann könnte man schon bei der regelmäßigen Kontrolle der Völker erkennen ob es ein Problem gibt und dann nachschauen woran das liegt.

Könnte man machen. Braucht einen I/O-Pin.
Soll ich dafür mal einen Vorschlag machen?

Funktioniert der gepostete Code mit Deiner SD-Karte?

Das Ding muss halt monatelang im Freien stehen. Da ist mir eine übertriebene Dichtheit lieber als dass es bei starkem Regen irgendwo reinsuppt.

Es ist ein Irrglaube, Gehäuse möglichst "dicht" zu machen, damit es keine Schäden durch Feuchtigkeit gibt. Am billigsten und extrem gut funktioniert es im Freien, ein Gerät "regengeschützt" anzubringen (kleine Überdachung, die für Trockenheit sorgt) und ein stinknormales "undichtes" Gehäuse zu verwenden, möglicherweise sogar mit Lüftungsschlitzen.

Die meisten selbstgebauten elektronischen Gerät im Freien geben nämlich wegen Kondenswasser in schlecht durchlüfteten Gehäusen den Geist auf, weil irgendjemand meint, das Gehäuse müsse "dicht" gemacht werden. Stattdessen mus es nur regengeschützt angebracht werden in einem stinknormalen "undichten" 08/15 Gehäuse.

In das Gehäuse kommt aber noch ein Beutel Silica Gel oder anderes Trockenmittel (ich hätte Calciumchlorid da).

Das Silica-Gel als Trocknungsmittel reißt es in einem geschlossenen Gehäuse natürlich wieder raus: Wenn die Luftfeuchte im Innern bei Abkühlung ansteigt, kann das Trocknungsmittel die überschüssige Luftfeuchte aufnehmen. Dazu wäre es allerdings vorteilhaft, das Gehäuse nicht nur "wasserdicht" sondern sogar "luftdicht" zu haben, und das Trocknungsmittel bei Bedarf auszutauschen, wenn seine Wasseraufnahmefähigkeit erschöpft ist. Eine relativ teure und nicht ganz wartungsfreie Angelegenheit.

Ansonsten gilt eher: Regenschutzdach von oben, Sensorgehäuse mit guter Durchlüftung darunter angebracht.
35  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 13, 2014, 11:43:40 am
Noch mehr Funktionen?
Ich denke das reicht jetzt erst Mal für den Prototypen.
Die Karte über Serial auslesen ist nicht nötig,
OK, dann habe ich das nur mal so weit eingebaut, wie ich es zum Debuggen brauchte. Es gibt derzeitig nur ein einziges serielles Kommando und das sieht so aus: Egal was über Serial gesendet wird (leere Zeile reicht aus) wird die gerade aktuelle Datei ausgelesen und am Bildschirm angezeigt (mit ein paar Matschzeichen am Dateiende).

Wenn Du das deaktivieren möchtest, kommentiere den Aufruf von " handleSerialCommand();" in der loop einfach aus!

ChipSelect Deiner SD-Karte ist wohl Pin-10?
Ich hatte mit dem SD-Kartenschacht auf einem Ethernet-Shield getestet, da ist es Pin-4.

Hier mein Code, wie gesagt, mit Sensoren konnte ich nicht testen:
Code:
#include "DHT.h"
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

#define LOGWAITTIME 20 // Anzahl der Sekunden zwischen zwei Log-Einträgen
#define CHIPSELECT 10  // ChipSelect-Pin der SD-Karte, 4 bei Ethernet-Shield

DHT dhtSensoren[]={ // hier die Sensoren mit ihren Pins eintragen
  DHT(2, DHT22),
  DHT(3, DHT22),
  DHT(4, DHT22),
  DHT(5, DHT22),
  DHT(6, DHT22),
  DHT(7, DHT22),
  DHT(8, DHT22),
  DHT(9, DHT22),
};

#define ANZAHLSENSOREN sizeof(dhtSensoren)/sizeof(dhtSensoren[0])

#define RTC_I2C_ADDRESS 0x68

byte bcdToDec(byte val)  // Hilfsfunktion zum Lesen/Schreiben der RTC
{ // Convert binary coded decimal to decimal number
  return ( (val/16*10) + (val%16) );
}

void rtcReadTime(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
{ // aktuelle Zeit aus RTC auslesen
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0);  // Reset the register pointer
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  // A few of these need masks because certain bits are control bits
  sekunden    = bcdToDec(Wire.read() & 0x7f);
  minuten     = bcdToDec(Wire.read());
  stunden     = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  /*wochentag   = */bcdToDec(Wire.read());
  tage        = bcdToDec(Wire.read());
  monate      = bcdToDec(Wire.read());
  jahre       = bcdToDec(Wire.read())+2000; 
}


int freeRam () { // ermittelt freien RAM-Speicher
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

char* floatFormatKomma(float f, int decimals, char* str)
{ // Gleitkommazahl zwischen -999 und 999 mit Dezimalkomma formatieren
  // Zielpuffer str muss groß genug sein!
  if (abs(f)>999) strcpy(str,"???.?");
  else dtostrf(f,decimals+1,decimals,str);
  char* c=strchr(str,'.');
  if (c!=NULL) c[0]=',';
  return str;
}

void setup() {
  Serial.begin(9600);
  Serial.print("Free RAM: ");Serial.println(freeRam());
 
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin();
#endif
  Serial.println(F("DHT22-Sensoren initialisieren..."));
  for (int i=0;i<ANZAHLSENSOREN;i++) dhtSensoren[i].begin();
  Serial.print(F("SD-Karte initialisieren... "));
  pinMode(SS,OUTPUT);
  pinMode(CHIPSELECT, OUTPUT);
  delay(1);
  if (!SD.begin(CHIPSELECT)) {
    Serial.println(F("Kartenfehler oder SD-Karte nicht vorhanden"));
    // don't do anything more:
    while (1) ;
  }
  Serial.println(F(" OK"));
}

boolean timeToLogEntries(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
{ // gibt true zurück, wenn es wieder Zeit ist, einen Datensatz zu loggen
  static long lastSecond;
  rtcReadTime(jahre,monate,tage,stunden,minuten,sekunden);
  long thisSecond=stunden*3600L+minuten*60+sekunden;
  if (lastSecond/LOGWAITTIME != thisSecond/LOGWAITTIME)
  {
    lastSecond=thisSecond;
    return true;
  }
  else return false;
}

void logEntries(int jahre, int monate, int tage, int stunden, int minuten, int sekunden)
{ // Einen Datensatz loggen und auf Serial und in Datei ausgeben
  char str[18];
  snprintf(str,sizeof(str),"%04d",jahre); // Verzeichnisname = Jahreszahl
  SD.mkdir(str);  // legt das Jahresverzeichnis an, falls es nicht existiert
  snprintf(str,sizeof(str),"%04d/%04d_%02d.txt",jahre,jahre,monate);
  File file=SD.open(str, FILE_WRITE);
  if (!file) Serial.print(F("Error "));
  Serial.print(F("Writing File "));
  Serial.println(str);  // Dateiname mit vollständigem Pfad
  snprintf(str,sizeof(str),"%02d.%02d.%04d ",tage, monate, jahre);
  Serial.print(str);
  if (file) file.print(str);
  snprintf(str,sizeof(str),"%02d:%02d\t",stunden,minuten);
  Serial.print(str);
  if (file) file.print(str);
  for(int i=0;i<ANZAHLSENSOREN;i++)
  {
    float humidity=dhtSensoren[i].readHumidity();
    float temperature=dhtSensoren[i].readTemperature();
    if (isnan(humidity) || isnan(temperature))
    {
      Serial.print(F("***\t***\t"));
      if (file) file.print(F("***\t***\t"));
    }
    else
    {
      floatFormatKomma(humidity,1,str);
      Serial.print(str);
      if (file) file.print(str);
      Serial.print('\t');
      if (file) file.print('\t');
      floatFormatKomma(temperature,2,str);
      Serial.print(str);
      if (file) file.print(str);
      Serial.print('\t');
      if (file) file.print('\t');
    }
  }
  Serial.println();
  if (file) file.println();
  if (file) file.close();
}

void handleSerialCommand()
{ // Funktion zum Debuggen: Gibt die aktuelle Datei auf Serial aus
  char str[18];
  byte buf[64];
  if (!Serial.available()) return;
  int jahre,monate,tage,stunden,minuten,sekunden;
  rtcReadTime(jahre,monate,tage,stunden,minuten,sekunden);
  snprintf(str,sizeof(str),"%04d/%04d_%02d.txt",jahre,jahre,monate);
  Serial.println();
  File file=SD.open(str, FILE_READ);
  if (!file) Serial.print("Error ");
  Serial.print("Reading File ");
  Serial.println(str);
  while (file.available())
  {
    file.read(buf,sizeof(buf));
    Serial.write(buf,sizeof(buf)); // sizeof(buf));
  }
  Serial.println();
  Serial.println();
  file.close();
  while (Serial.available()) Serial.read();
}


void loop() {
  delay(1000); // In diesem Abstand wird geprüft, ob neue Werte zu loggen sind
  int jahre,monate,tage,stunden,minuten,sekunden;
  if (timeToLogEntries(jahre, monate, tage, stunden, minuten, sekunden))
    logEntries(jahre, monate, tage, stunden, minuten, sekunden);
  handleSerialCommand();
}

das Ganze kommt in ein wasserdichtes Gehäuse und es wird eher schwierig da während dem Betrieb ein USB-Kabel anzuschließen.

Vorsicht mit "wasserdichten" Gehäusen, das kann bei Kondenswasserbildung zu ganz üblen Korrosionsschäden führen! Das wäre ggf. nochmal genauer zu diskutieren.

Die Uhr einstellen ist auch überflüssig, die wird ja soweit genau gehen dass sie eine Saison lang ungefähr stimmt. Eine Minute hin oder her ist egal. Und weil wir eh nur im Sommer messen können muss man auch keine Winterzeit einstellen können.

Alles klar, also ohne Zeiteinstellung.
Spart Arbeit bei der Funktion "handleSerialCommand();"

Wünschenswert wäre vielleicht noch eine kleine Statusanzeige per blinkender LED außen am Gerät.
So ungefähr wie:
- langsames Blinken ==> alles in Ordnung, Programm läuft fehlerfrei
- schnelles Blinken ==> Kartenfehler, kann nicht auf SD-Karte schreiben
- lang und kurz abwechselnd Blinken ==> Sensorfehler, mindestens ein Sensor liefert keine Werte
Damit man von außen ggf. direkt erkennen kann, ob eine Störung vorliegt oder ob das Programm wie gewünscht funktioniert.
36  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 13, 2014, 09:21:57 am
Auf dem Serial Monitor wird das so ausgegeben:

Das sieht doch schon mal sehr gut aus!

- RTC ist richtig angeschlossen und funktioniert
- RTC ist richtig gestellt
- DHT22-Sensoren sind richtig angeschlossen und funktionieren

An den protokollierten Daten müßte man jetzt eigentlich nur noch ändern, dass anstelle des Dezimalpunktes ein Dezimalkomma ausgegeben wird. Und dann die Daten in Datei auf SD-Karte wegschreiben.

761 Bytes RAM-Speicher sind noch frei, die man im Programm verbraten kann, das sollte locker reichen.

Was brauchst Du denn noch an Zusatzfunktionen?

Soll man sich die protokollierten Daten zwecks Debugging auch von der Karte auslesen und auf Serial anzeigen lassen können, damit man zum Debuggen nicht immer die Karte entnehmen und umständlich am PC auslesen muss? Ich glaube, das wäre zum Debuggen ganz praktisch.

Soll man die RTC-Uhr auch über den Seriellen Monitor direkt vom Programm aus neu stellen können?
37  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 13, 2014, 08:40:31 am
Jurs, das funktioniert perfekt!

Das hört sich ja schon mal gut an.

Ich hätte vielleicht noch erwähnen müssen, dass das Ganze bei mir auf einem Mac ist, also auch eine Excel-Version für Mac.
Die Auswertung wird dann wahrscheinlich auf einem Windows PC erfolgen.

Das sollte kein Problem sein. Ich habe das gepostete Datenformat getestet mit einer "Windows Starter-Edition" von MS-Excel. Sollte dann soweit OK sein. Und das Datenformat der Textdatei kann man ggf. später natürlich auch noch ändern. Aber man muß natürlich erstmal etwas haben, das man ausgeben möchte.

Bevor die Textdatei ausgegeben wird, habe ich nun aber erstmal die Programstruktur geändert, so dass
a) RAM-Speicher gespart wird und
b) Die Sensoren reihum in einer for-Schleife abgefragt werden
c) und ein paar Dinge mehr

Beispielsweise habe ich die RTClib rausgeschmissen und lese die RTC direkt mit einer eigenen Funktion aus.

Anbei mal ein Sketch zum Testen.
Ich habe momentan hier keine DHT22-Sensoren angeschlossen, bei mir erscheint anstelle der Luftfeuchte- und Temperaturwerte nur die Fehlerausgabe "***" an den Stellen, wo Werte nicht ausgelesen werden können (also eigentlich überall.

Das sollte mit dem Testprogramm funktionieren:
- Ausgabe auf Serial (aber noch KEINE Ausgabe in Datei)
- lauffähig auf UNO-Board (weil ausreichend RAM-Speicher eingespart wird)
- vorprogrammierter Zeitabstand zum Testen: 20 Sekunden (definiert in LOGWAITTIME)

Zum Aufzeichnungszeitpunkt sollte ausgegeben werden:
- Dateiname, in den die Daten geschrieben würden
- ein Datensatz mit allen ausgelesenen Sensorwerten

Läuft das bei Dir soweit?
Code:
#include "DHT.h"
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

#define LOGWAITTIME 20

DHT dhtSensoren[]={ // hier die Sensoren mit ihren Pins eintragen
  DHT(2, DHT22),
  DHT(3, DHT22),
  DHT(4, DHT22),
  DHT(5, DHT22),
  DHT(6, DHT22),
  DHT(7, DHT22),
  DHT(8, DHT22),
  DHT(9, DHT22),
};

#define ANZAHLSENSOREN sizeof(dhtSensoren)/sizeof(dhtSensoren[0])

float humidity[ANZAHLSENSOREN];
float temperature[ANZAHLSENSOREN];

// RTC_DS1307 rtc;

#define RTC_I2C_ADDRESS 0x68

byte bcdToDec(byte val)  // Hilfsfunktion zum Lesen/Schreiben der RTC
{ // Convert binary coded decimal to decimal number
  return ( (val/16*10) + (val%16) );
}

void rtcReadTime(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
{ // aktuelle Zeit aus RTC auslesen
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0);  // Reset the register pointer
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  // A few of these need masks because certain bits are control bits
  sekunden    = bcdToDec(Wire.read() & 0x7f);
  minuten     = bcdToDec(Wire.read());
  stunden     = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  /*wochentag   = */bcdToDec(Wire.read());
  tage        = bcdToDec(Wire.read());
  monate      = bcdToDec(Wire.read());
  jahre       = bcdToDec(Wire.read())+2000; 
}


const int chipSelect = 10;

File dataFile;

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void setup() {
  Serial.begin(9600);
  Serial.print("Free RAM: ");Serial.println(freeRam());
 
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin();
#endif
/*
  rtc.begin();
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");}
*/ 
  Serial.println("DHTxx test!");
  for (int i=0;i<ANZAHLSENSOREN;i++) dhtSensoren[i].begin();
return;   // Eingefügt: Keine SD-Kartenfunktion in dieser Testversion

  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) ;
  }
}

boolean timeToLogEntries(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
{
  static long lastSecond;
  rtcReadTime(jahre,monate,tage,stunden,minuten,sekunden);
  long thisSecond=stunden*3600L+minuten*60+sekunden;
  if (lastSecond/LOGWAITTIME != thisSecond/LOGWAITTIME)
  {
    lastSecond=thisSecond;
    return true;
  }
  else return false;
}

void logEntries(int jahre, int monate, int tage, int stunden, int minuten, int sekunden)
{
  char str[18];
  snprintf(str,sizeof(str),"%04d\\%04d_%02d.txt",jahre,jahre,monate);
  Serial.println(str);  // Das wäre die Datei, in die die Daten geschrieben werden
  snprintf(str,sizeof(str),"%02d.%02d.%04d ",tage, monate, jahre);
  Serial.print(str);
  snprintf(str,sizeof(str),"%02d:%02d\t",stunden,minuten);
  Serial.print(str);
  for(int i=0;i<ANZAHLSENSOREN;i++)
  {
    float humidity=dhtSensoren[i].readHumidity();
    float temperature=dhtSensoren[i].readTemperature();
    if (isnan(humidity) || isnan(temperature))
      Serial.print("***\t***\t");
    else
    {
      Serial.print(humidity,1);
      Serial.print('\t');
      Serial.print(temperature,2);
      Serial.print('\t');
    }
  }
  Serial.println();
}


void loop() {
  delay(1000); // In diesem Abstand wird geprüft, ob neue Werte zu loggen sind
  int jahre,monate,tage,stunden,minuten,sekunden;
  if (timeToLogEntries(jahre, monate, tage, stunden, minuten, sekunden))
    logEntries(jahre, monate, tage, stunden, minuten, sekunden);
}

Du kannst ja mal eine Testausgabe aus Deinem seriellen Monitor herauskopieren und hier posten.
38  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 13, 2014, 06:15:44 am
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 4*24= 96 Schreibvorgänge pro Tag und ca. 30*96= 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).

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?
39  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 12, 2014, 02:52:30 pm
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.

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?
40  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 12, 2014, 12:17:35 pm
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):
Code:
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?
41  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 12, 2014, 11:47:01 am
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:
Code:
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?
42  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 12, 2014, 10:09:20 am
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:
Code:
Free RAM: 5810
DHTxx test!
Initializing SD card...Card failed, or not present

Wenn auf einem MEGA-Board mit 8 kB RAM also 8*1024 Bytes noch 5810 Bytes frei sind, dann benötigt Dein Programm ca. 8*1024-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.
43  International / Deutsch / Re: Arduino mit Pegelwandler an 1.8V on: September 12, 2014, 09:31:59 am
vor allem verstehe ich

Quote
beide versorgen "sich selbst" mit Strom

nicht. wie ist das gemeint?

gruß stefan

Für mich ist das eindeutig, was er meint:

Er hat einen Arduino mit 5V TTL-Serial.
Und er hat irgendwas anderes mit 1.8V TTL-Serial.

Nur beim Arduino kommt er an die Stromversorgungs-Pins 5V und 3.3V heran, und das andere Gerät ist für ihn eine Black-Box, bei der er nur an GND, RX und TX rankommt, aber nicht an die 1.8V Versorgungsspannung.
44  International / Deutsch / Re: Datenlogger für Versuchsbienenstand on: September 12, 2014, 09:28:22 am
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".

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)?

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.

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.

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.

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.
45  International / Deutsch / Re: Arduino als Lichtorgel on: September 12, 2014, 07:32:46 am
Meine Frage ist jetzt eigentlich - wie kann man dem ­Arduino sagen wann Bass/Mittel/Hochtöne kommen? Zum Beispiel ein Mikrofon oder eine extra Schaltung zusammen löten oder einfach direkt einen Lautsprecher anzapfen.

Entweder schickst Du Dein Audiosignal über verschiedene Frequenzweichen und bekomst das eine Audiosignal aufgeteilt in ein Tieftonsignal, ein Mitteltonsignal und ein Hochtonsignal.
http://de.wikipedia.org/wiki/Frequenzweiche

Oder Du machst ein digitales Signal Processing und wertest das Signal digital aus. Da der Arduino ein bisschen langsam ist für schnelles Audio-Processing hoher Frequenzen, kannst Du zum Beispiel einen kleinen Baustein namens MSGEQ7 verwenden. Der ist eigentlich dafür da, um Signale für einen 7-Band Equalizer auszugeben, aber da der für 5V Betrieb geeignet ist, kannst Du ihn für diverse Basteleien am Arduino verwenden, wenn Du die Signalstärke für 7 Frequenzen ermitteln möchtest.

Pages: 1 2 [3] 4 5 ... 211