Frage wegen Datenlogger

Hallo
Ich brauche einen Datenlogger , um eine Temperatur an eine Warmwasserspeicher 60 Grad Celsius ( 400 Liter) zu Messen.
Das Problem ist , wenn ich mich am Morgen Waschen will ist das Wasser kalt., wenn ich dann in Keller den Warmwasserspeicher kontrolliere ist die Temperatur nur noch ca 25 Grad Celsius). Laut Hersteller des Warmwasserspeicher fällt die Temperatur aber Maximal um 5 Grad Celsuis Pro Nacht . Es wäre ja nicht mal aufgefallen , aber ich schalte jetzt aus Kostengründen die Heizung von ca 22.00 Uhr bis ca 7.00 Uhr komplett aus. Da noch eine andere Partei im Haus wohnt muss also da was Faul sein . Mir langt es wenn er alle 10 Miunten eine Messung macht daher brauche ich keine Uhr .
Daher habe ich mal ein Code geschrieben , der läuft auch aber er schreibt mit nichts in das Datalog.CSV File .
Wäre sehr Nett wenn mir da jemand helfen könnte.

Danke an alle

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#define ONE_WIRE_BUS 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const int chipSelect = 10; // CS PIN

void setup(){
  Serial.begin(9600);
  while (!Serial) 
    Serial.print("Initializing SD card...");
  sensors.begin();
  if (!SD.begin(chipSelect)); {
    Serial.println("Card failed, or not present");
    return; 
  }
  Serial.println("card initialized."); 
}

void loop(){
  File dataFile = SD.open("datalog.CSV", FILE_WRITE);{
    String dataString = " ";
    dataFile.println(dataString);
    sensors.requestTemperatures();
    if (dataFile) {
      Serial.println(sensors.getTempCByIndex(0));
      dataFile.close();
      delay(60000);
      Serial.println(dataString);
    } 
    else {
      Serial.println("error opening datalog.CSV");
    }
  }
}

Hallo,
irgentwie fehlt mir da ein wenig Dallas-Code: Hier mal das Original:

#include <OneWire.h>

#include <LiquidCrystal.h>

#include <Wire.h>



// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(10);  // on pin 10

void setup(void) {
  Serial.begin(19200);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(750);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius,1);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

Hier der original Datenlogger der Arduino SD Lib

/*
  SD card datalogger
 
 This example shows how to log data from three analog sensors 
 to an SD card using the SD library.
 	
 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 created  24 Nov 2010
 modified 9 Apr 2012
 by Tom Igoe
 
 This example code is in the public domain.
 	 
 */

#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  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(10, 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:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
}

Vielleicht hilft es Dir ja.
Gruß und Spaß
Andreas

Hallo,

guck Dir nochmal die einzelnen Bsp. an. Denn bei Dir fehlen Befehle zum schreiben auf die SD Karte.
Du müßtest allerdings Werte auf der seriellen Schnittstelle sehen, falls das hier so funktioniert wie gewünscht.
Serial.println(sensors.getTempCByIndex(0));

Ich kommentiere mal dein loop wie ich das verstehe, dann wird vielleicht einiges klarer.

String dataString = " ";
dataFile.println(dataString);
dataString enthält ein leeres Zeichen, also nichts

sensors.requestTemperatures();
das scheint nur ein nackter Funktionsaufruf zu sein ohne Variablenzuweisung führt demnach ins leere

if (dataFile) {
Serial.println(sensors.getTempCByIndex(0));
hier wird ein Wert auf die serielle Schnittstelle ausgegeben

dataFile.close();
Datei wird geschlossen und nichts ist bis hierher auf die SD Karte geschrieben wurden, außer vielleicht das leere Zeichen, sieht man dann jedoch nicht

delay(60000);

Serial.println(dataString);
das leere Zeichen von oben wird an die serielle Schnittstelle ausgegeben

Hallo Doc_Arduino
Danke für die schnelle Antwort.
Und da genau ist das Problem was ich nicht ganz Verstehe.
Wenn ich was in den String dataString = " "; schreibe das sehe ich auf der SD Karte.
Ich sehe dann aber nur den Text , aber nicht den Wert des DS 18S20 .
Wie schreibe ich auch den Wert des DS 18S20 rein .
Ein Beispiel wäre schön .

Danke

Du mußt den Wert auch in den Datastring schreiben.

z.B.:

    String dataString = "Temp= ";
    float AktTemp = 23.5;
    dataFile.print(dataString);
    dataFile.println(AktTemp);
    dataFile.close();

Hast du die Beispiele aus der SD-lib schon ausprobiert?

Ein Beispiel wäre schön

Das Hier macht natürlich für deinen Bedarf zu viel, und du musst auch lang klicken, bis du zum Download Link kommst :wink:

Hinweis: Die meisten Beispiele verwenden keine String Objekte!

Hallo guntherb
Ich habe jetzt den Code so abgeändert wie in deinem Beispiel.
Jetzt schreibt er mir zwar was rein ist der Begriff temp und die 23.5
Was mache ich jetzt noch falsch.

Danke für die Hilfe.

Anbei Code.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#define ONE_WIRE_BUS 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const int chipSelect = 10; // CS PIN

void setup()
{
  sensors.begin();
  Serial.begin(9600);
  while (!Serial) {
    ; 
  }
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
}  


void loop(){
  String dataString = "Temp= ";
  float AktTemp = 23.5;
  File dataFile = SD.open("datalog.CSV", FILE_WRITE);
  {
    dataFile.println(dataString);
    if (dataFile) {
      dataFile.println(AktTemp);
      dataFile.close();
      delay(1000);
      Serial.println(dataString);
    } 
    else {
      Serial.println("error opening datalog.CSV");
    }
  }
}

Hallo,

ich vermute du kopierst irgendwas aus den Bsp. zusammen und hoffst das es funktioniert. Das klappt aber so nicht. Skoby hat schon erwähnt das für den DS18S20 auch wenig Code fehlt um diesen auszulesen. Ich habe Dir Deine loop erklärt. Gunther hat ein Bsp. gebracht.

Befasse Dich bitte mit den Bsp. für den DS18S20. Lasse es auf der seriellen Schnittstelle ausgeben. Zum Schluss gezielt Deinen Sensor auslesen.

Warum Du immer nur Temp und 23.5 siehst?
Du gibts Temp und 23.5 fest aus. Das war nur ein Bsp. von Gunther.

man kann schreiben:
Serial.print(23.5);

man kann aber auch schreiben:
float celsius = 23.5;
Serial.print(celsius);

Erkennst Du den Unterschied?

Kleine Anmerkung zum Schluss. Wir wollen Dir damit auf die Sprünge helfen damit Du das Problem selbst erkennst. Dann ist der Lerneffekt größer. :slight_smile:

Vielleicht hilft dir ja auch das bei deinem Problem:

Conrad Temperaturlogger Baustein

Ich habe das Gefühl, dir geht es weniger um den Arduino als um die Lösung deines Warmwasserproblems

Hallo an alle

Das was guntherb sagt ist Richtig , ich habe das Zusammenkopiert weil ich eigentlich nur Programme für die Modelleisenbahn bzw Modellbau schreibe ( Belebtes Haus , Baustellenblitz, Adreaskreutze, Lauflicht u.s.w.).
Ich habe noch nie einenDatenlogger in Angriff genommen.
Weil mir da einfach da Wissen fehlt wie man sowas angeht
Ich habe mir auch das Buch von Michael McRoberts gekauft , 2010 Beginning Arduino.
Da ist ja auch ein Datenlogger drin , der geht aber leider nicht.
Wenn ich Project 37 Nachbaue das Läuft super, wenn ich aber Project 43 Nachbaue und den Code Kompillieren will
mault er immer an der DeviceAddress rum.

DeviceAddress insideThermometer = { 0x28, 0x94, 0xE2, 0xDF, 0x02, 0x00, 0x00, 0xFE };
Darauf habe ich mir ein Code gesucht wo man die DeviceAddress auslesen kann , und habe da die Ausgelesen Werte Eingetragen. Aber dann Mault er auch wieder Rot Markiert.
Danke

Dann laß doch den Arduino weg...und nimm dir einen ruhigen abend Zeit*.
Ggf ist das schneller und Ziel führender.

Kontrollier nach dem abschalten der Heizung alle ein bis zwei Stunden die Temperatur.
Ich würde fast wetten das du langsam aber stetig sinkende Temperaturen haben wirst.
Dann googelste mal nach einer "Schwerkraftbremse".
Entleert sich der Speicher von 22 bis 23 Uhr komplett, sprichste mal mit der anderen Partei

*geht natürlich auch tagsüber, aber dann muß sichergestellt sein das niemand Warmwasser entnimmt und es darf kein Ventil dazu geschlossen werden!

Hallo,

du könntest auch einfach mal den Wasserzähler morgens und abends kontrollieren. Um einen 400l. Speicher zu leeren muss man schon baden oder eine ganze Familie ausgiebig duschen. Das dürftest du am Wasserverbrauch sehen können.
.

Hallo,
also ganz ehrlich- einen "fertigen" Sketch zum sehr einfachen DatenLoggen
wirst Du hier nicht bekommen.
Ich weiß wirklich nicht, wo Du hier ein Problem hast. Wenn Du ModellEisenbahn
und ModellBau zusammenkopiert bekommst, dann ist es kein Problem mit den
beiden originalen Sketch´s das hin zu bekommen.
Nehme jeden Sketch für sich- erst den Dallas, die Werte läßt Du Dir über
die serielle am PC anzeigen. Dann den Datenlogger dazu kopieren.
In Deine DatenLoggerFile läßt Du Dir dann "celsius,1" schreiben. Das ist doch
nun wirklich nicht schwer.
Noch ein Tip: Lerne einmal die SchlüsselWörter, siehe "Reference".
Beispiel: "dataString" ist kein SchlüsselWort- Du kannst dafür auch "Egon"
schreiben. Das wird Dir sehr helfen, so einen Sketch zu verstehen.
Gruß und Spaß dabei
Andreas

Hallo
Habe es jetzt endlich Geschaft den Datenlogger zum Laufen zu Bringen. Ich stand mir selbst im Weg.
Habe nur noch 3 kleine Fragen.

1 Frage : Wie schaffe ich es hinter der Gradzahl im Logfile das Wort Grad zu Schreiben.
myFile.print("SENSOR 01 ");
myFile.println(sensors1.getTempCByIndex(0));
myFile.close();

z.b. SENSOR 01 23.56 GRAD
Habe schon alles Mögliche probiert , aber er setzt mir das Wort Grad entweder vor den Wert 23.56 oder dahinter.

2 Frage: Wie schaffe ich es das im Logfile eine Durchnummerierung
der Messungen zu bekommen.

z.b. 001 SENSOR 01 23.56 Grad

3 Frage: Mir ist aufgefallen das ein RTC Modul und ein GLCD 128/64 (KS0108 Controller) die gleiche
Pinbelegung habe Analog 4 und 5. Was kann man da machen wenn man auf einem GLCD 128/64
(KS0108 Controller) eine Uhr haben will aber es sind ja die gleichen Pins. Welche möglichkeit gibt es da .

Wäre für Tips Dankbar

Habe nur noch 3 kleine Fragen.

Die hast du wohl inzwischen schon selbst rausgefunden, sonst :

  1. Wo muss myFile.println(" GRAD"); wohl eingefügt werden ?

int i = 1;
myFile.println(i);
i++;
myFile.println(i);

Wenn es denn immer 3 Stellen mit führenden Nullen sein müssen

  char Nummer[4]; // 3 Zeichen + Endekennung
  sprintf(Nummer, "%03d", i); // wandelt eine Zahl in in dezimal-Darstellung mit führenden Nullen.
  myFile.print(Nummer);
  1. I2C ist ein Bus-System, alle Teilnehmer teilen sich die gleichen Pins. ( A4 / A5 beim UNO )
    Der Master sendet ein Adressbyte, die Slaves reagieren nur auf ihres.
    RTC haben traditionellerweise die Adresse 0x68.
    Bei anderen Devices sind Adressen oft per Brücken einstellbar.
    Ausserdem gibt es den I2CScanner- Sketch ...