Schrijven waardes DS18B20 naar SD-card

Hallo allemaal,

Sinds korte tijd ben ik bezig met een datalogger die een keten van DS18B20 temperatuursensors moet gaan uitlezen en de waarden, tesamen met een timestamp van een RTC, gaat opslaan op een SD-kaart.

Alle losse onderdelen werken, babbelen over de seriele poort werkt ook, ik kan zien dat de waarden correct worden ingelezen en de seriele bus over gegooid worden.

Waarschijnlijk ben ik wat lomp met mijn code, maar ik heb gedacht dat het simpel omzetten van serial.print naar myfile.print (of println) er voor zou zorgen dat er keurig een filetje op mijn SDkaart zou komen met daar data in, welk format dan ook.

Echter, als ik de SD-kaart middels een tutorial benader, krijg ik keurig een bestandje met testing, 1, 2, 3. Met mijn code ben ik niet zo ver.

Ik heb gezocht in het forum en het e.e.a. geprobeerd maar krijg mijn waarden niet weggeschreven. Kan iemand me een duw geven in de goede richting?

#include <OneWire.h>
#include <DallasTemperature.h>
#include "Wire.h"
#include <SD.h>

File myFile;

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// Assign the addresses of the 1-Wire temp sensors.

DeviceAddress Probe1 = { 0x28, 0xE5, 0xC7, 0xD0, 0x04, 0x00, 0x00, 0x30 };
DeviceAddress Probe2 = { 0x28, 0x9D, 0xFF, 0xCF, 0x04, 0x00, 0x00, 0x11 };
DeviceAddress Probe3 = { 0x28, 0x4F, 0x07, 0xF1, 0x04, 0x00, 0x00, 0x7E };

#define DS1307_I2C_ADDRESS 0x68  // This is the I2C address
// Arduino version compatibility Pre-Compiler Directives
#if defined(ARDUINO) && ARDUINO >= 100   // Arduino v1.0 and newer
  #define I2C_WRITE Wire.write 
  #define I2C_READ Wire.read
#else                                   // Arduino Prior to v1.0 
  #define I2C_WRITE Wire.send 
  #define I2C_READ Wire.receive
#endif
// Global Variables
int command = 0;       // This is the command char, in ascii form, sent from the serial port     
int i;
long previousMillis = 0;        // will store last time Temp was updated
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte test;
byte zero;
char  *Day[] = {"","Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
char  *Mon[] = {"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
 
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
 
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}
 
 
void setup() {
  pinMode(10, OUTPUT);
  Wire.begin();
  //Serial.begin(57600); 
  zero=0x00;
  // Start up the library
  sensors.begin();
  // set the resolution to 12 bit
  sensors.setResolution(Probe1, 12);
  sensors.setResolution(Probe2, 12);
  sensors.setResolution(Probe3, 12);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    myFile.println("Error getting temperature");
  } else {
    //Serial.print("C: ");
    myFile.println(tempC);
    //Serial.print(" F: ");
    //Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}
void loop()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  I2C_WRITE(zero);
  Wire.endTransmission();
 
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
 
  // A few of these need masks because certain bits are control bits
  second     = bcdToDec(I2C_READ() & 0x7f);
  minute     = bcdToDec(I2C_READ());
  hour       = bcdToDec(I2C_READ() & 0x3f);  // Need to change this if 12 hour am/pm
  dayOfWeek  = bcdToDec(I2C_READ());
  dayOfMonth = bcdToDec(I2C_READ());
  month      = bcdToDec(I2C_READ());
  year       = bcdToDec(I2C_READ());
 
  myFile = SD.open("test1.txt", FILE_WRITE);
  sensors.requestTemperatures();
  printTemperature(Probe1);
  myFile.println(",");
  printTemperature(Probe2);
  myFile.println(",");
  printTemperature(Probe3);
  myFile.println(",");
  char buffer[24];
  sprintf(buffer,"%02d:%02d:%02d,-%02d-%02d-20%02d", hour, minute, second, dayOfMonth, month, year);
  myFile.println(buffer);
  myFile.close();
  //Serial.print("\n\r");
    delay(2000);
}

De RTC is een DS3231SN die via de I2C bus aan de arduino pro-mini hangt. Deze pro-mini draait op 3.3V op 8Mhz. De sketch zoals bovenstaand, maar dan met seriele commandos werkt wel.

myFile = SD.open("test1.txt", FILE_WRITE);

en

  myFile.close();

in de loop is volgens mij niet zo een goed idee.
verplaats

myFile = SD.open("test1.txt", FILE_WRITE);

eens naar de setup en verander

  myFile.close();

naar

  myFile.flush();

met vriendelijke groet
Jantje

Hallo Jantje,

Bedankt voor je advies, ga ik proberen.

Het verplaatsen van file.open naar de setup zou inhouden dat het bestand maar één keer geopend wordt, wanneer de Arduino aangezet wordt en daarna gesloten, is dat correct?

De bedoeling is dat de arduino, gedurende de tijd dat deze geen meting hoeft te doen, een uur in slaap gezet wordt en via een alarm trigger van de RTC ontwaakt en verder gaat met zijn programma. Ik ben me er niet zeker van of ie dan de setup weer doorloopt (en het bestand weer opent), dan zijn andere functies en loop.

Wellicht is het beter om het openen en flushen/sluiten van het bestand in een aparte functie (void) te doen en alleen in de loop te zetten dat ie ontwaakt, metingen laat uitvoeren door de andere functie en dan weer gaat slapen..

Als je elke keer het bestand wilt openen en sluiten moet je zorgen dat je bestands wijzer (file pointer) op het einde van de file staat.
Dat doe je nu niet dus overschijf je steeds je bestand.
Doe het rustig aan stap voor stap. Slapen is niet zo heel erg goed gedocumenteerd in de arduino community. Maar in princiepe kan je bestand gewoon open blijven. Def flush zorgt dat alles is weggeschreven dan is er minder kans op corruptie.
Maar enkel door het te doen kan je weten hoe het werkt. Ikzelf heb het nog niet gedaan.
Met vriendelijke groet
Jantje

Screenshot-About Mozilla Firefox.png

Hallo Leroy,

Is je vraag beantwoord naar tevredenheid?
Mag ik zo vrij zijn om je een tip te geven.
Gebruik .CSV files die kan je gemakkelijk terug lezen in access.
Heb je een RTC dan kan je ook per dag een file aanmaken.

        char filename[12];//char filebname[]="                ";
        sprintf(filename,"%02d-%02d-%02d.csv",dd,mm,yy);
        Serial.println(filename);
          dataFile=SD.open(filename,FILE_WRITE);
          if ( q==0)
        {
          delay(20);
        dataFile.println("DATE        ,TIME        ,Temp        ,Humid       ,Dauwp       ,temp,luchtdr. ");
        delay(50);
          Serial.println("DATE        ,TIME        ,Temp        ,Humid       ,Dauwp       ,temp,luchtdr. ");    
        delay(10);  
                           if (dataFile)       {// 00/00/00,00:00:00,23.52,53.67,11.31,12.56, Temp    ,
                                          q=1;
                                           dataFile.close();
                                           
                                               }  
 else        
                 {
                    Serial.println("error opening datalog.csv"); // if the file isn't open, pop up an error:
                    
                 } 
             }

 else     
                                        {
   
                                        dataFile.print(ReadTimeDate());
                                        dataFile.print(",");
                                        dataFile.print(tC,2);
                                        dataFile.print(",");
                                        dataFile.print(rhTrue,2);
                                        dataFile.print(",");
                                        dataFile.print(Dauwpunt,2);
                                        dataFile.print(",");
                                        dataFile.print(b.t,1);
                                        dataFile.print(" ,");
                                        dataFile.println(b.ppa);
                                        dataFile.close();   
                                        }

Dit is een deel van mij script. Werkt aardig.

Succes,'
ilioss