Temperatuur logger met SD kaart

Toon hier Uw afgeronde projecten aan anderen.
Berichten: 6
Geregistreerd: 31 Aug 2012, 22:43

Temperatuur logger met SD kaart

Berichtdoor MarioV » 01 Apr 2013, 22:17

Hoi iedereen,

M'n laatste project is een temperatuur logger, bedoeld om een zonneboiler te loggen.
De sensor is een DS18B20, dit zijn niet de allergoedkoopste maar wel makkelijk en stabiel in gebruik terwijl de sensor toch erg klein blijft.
De metingen en datum/tijd worden als csv bestand op een SD kaart geschreven. Hier zat nog een addertje omdat de SD module 3.3V ipv 5V signalen verwacht, er was
dus een niveau aanpassing nodig wat door een 4050 wordt verzorgd. De tijd komt van een rtc DS1307.

Via de console kan de tijd worden ingesteld, de log file gelezen of gewist.

grtn


Code: Alles selecteren

// Temperature variables:
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
// ports 4 and 10 can't be used because of SD card
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device address
DeviceAddress insideThermometer;

// RTC variables:
#include <Wire.h>
//#include "RTClib.h"
#define DS1307_ADDRESS 0x68
#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
byte zero = 0x00; //workaround for issue #527
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
char  *Day[] = {
  "","Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
char  *Mon[] = {
  "","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

// SD variables:
#include <SD.h>
const int chipSelect = 10; // SD module met 4050 moet op pin 10!
boolean deleteRequest = LOW;

// Global variables
int command = 0;       // This is the command char, in ascii form, sent from the serial port     
int prevMin = 0;
int Counter = 0;
float tempC = 99;

void setup() {
  pinMode (2, INPUT); // DS18x20 temp sensor
  pinMode (3, INPUT);
  pinMode (4, OUTPUT); // Default SD pin (EthernetShield)
  pinMode (5, INPUT);
  pinMode (6, INPUT);
  pinMode (7, INPUT);
  pinMode (8, INPUT);
  pinMode (9, INPUT);
  pinMode (10, OUTPUT);// SD pin (SD adapte
  pinMode (11, INPUT);
  pinMode (12, INPUT);
  pinMode (13, INPUT);

  pinMode (A0, INPUT); 
  pinMode (A1, INPUT); 
  pinMode (A2, INPUT); 
  pinMode (A3, INPUT); 
  pinMode (A4, INPUT);
  pinMode (A5, INPUT);

  Serial.begin(9600);    //Setup serial to 9600 bps

  // Teperature setup:
  // linkse pin = GND, middenste pin = data, rechtse pin = Vcc.
  // Data verbonden via 1K .. 10K met VCC

  // locate devices on the bus
  Serial.print("Locating devices...");
  sensors.begin();
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");
  Serial.print("Parasite power is: ");
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(insideThermometer, 9);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC);
  Serial.println();

  // RTC setup: pin5 = A4, pin6 = A5, 1+2 = kristal, 3+4=GND, 7=nc, 8=+5V
  Wire.begin();

  // SD card setup:
  startSDCard();

  Serial.println("\nCommands:");
  Serial.println("T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)");
  Serial.println("ex= t2515192260313");
  Serial.println("\nD : delete LOG");
  Serial.println("R : read LOG (usb port)");
  Serial.println("\n[memCheck]");
  Serial.println(freeRAM(), DEC);
}

void loop() {
  // RTC
  //DateTime now = RTC.now();
  getDateTime();
  if (prevMin != minute){
    Counter += 1;
    Serial.print(".");
    prevMin = int(minute);
  }
  if (Counter >= 30){
    Counter = 0;
    Serial.println("*");
    Serial.print(year, DEC);
    Serial.print('/');
    Serial.print(month, DEC);
    Serial.print('/');
    Serial.print(dayOfMonth, DEC);
    Serial.print(' ');
    Serial.print(hour, DEC);
    Serial.print(':');
    Serial.print(minute, DEC);
    Serial.print(':');
    Serial.print(second, DEC);
    Serial.println();
    Serial.println();    //Print Blank Line 

    // DS18x20
    //Serial.print("Requesting temperatures...");
    sensors.requestTemperatures(); // Send the command to get temperatures
    //Serial.println("DONE");
    // It responds almost immediately. Let's print out the data
    tempC = printTemperature(insideThermometer); // Use a simple function to print out the data

    // open the file:
    File dataFile = SD.open("temp_log.csv", FILE_WRITE);
    digitalWrite(13,HIGH);
    // if the file is available, write to it:
    if (dataFile) {
      Serial.println("writing to file ... ");
      dataFile.print(tempC);
      dataFile.print(";");
      dataFile.print(year, DEC);
      dataFile.print('/');
      dataFile.print(month, DEC);
      dataFile.print('/');
      dataFile.print(dayOfMonth, DEC);
      dataFile.print(";");
      dataFile.print(hour, DEC);
      dataFile.print(':');
      dataFile.print(minute, DEC);
      dataFile.print(':');
      dataFile.println(second, DEC);
      dataFile.close();
      Serial.println("file closed");
      Serial.println();
      delay(100);
      digitalWrite(13,LOW);
    } 
    // if the file isn't open, pop up an error:
    else {
      Serial.println("error opening temp_log.csv");
    }
  }
  if (Serial.available()) {      // Look for char in serial que and process if found
    command = Serial.read();
    if (command == 84 || command == 116) {      //If command = "Tt" Set Date
      Serial.print("Command: ");
      Serial.println(command);
      setDateTime();
    }
    if (command == 68 || command == 100) {      //If command = "Dd" Delete log?
      Serial.println("Delete LOG? (y - n)");
      deleteRequest = HIGH;
      command = 0;
    } 
    if ((command == 89 || command == 121) && (deleteRequest)) {      //If command = "Yy" delete confirmes
      SD.remove("temp_log.csv");
      Serial.println("Log DELETED!");
      deleteRequest = LOW;
      command = 0;
    }
    if ((command == 78 || command == 110) && (deleteRequest)) {      //If command = "Nn" delete confirmed
      deleteRequest = LOW;
      Serial.println("Log delete CANCELED!");
      command = 0;
    }
    if (command == 82 || command == 114) {      //If command = "Rr" read log?
      File dataFile = SD.open("temp_log.csv", FILE_READ);
      if (dataFile) {
        while (dataFile.available()) {
          Serial.write(dataFile.read());
        }     
      } 
      command = 0; 
    }
  }

  command = 0;
  delay(250);
}

// RAM check
int freeRAM() {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

boolean startSDCard() {
  boolean result = false;
  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");
    result = false;
  }
  else {
    Serial.println("card initialized.");
    if (!SD.exists("temp_log.csv")){
      File dataFile = SD.open("temp_log.csv", FILE_WRITE);
      dataFile.print("DS18x20");
      dataFile.print(";");
      dataFile.print("Date");
      dataFile.print(";");
      dataFile.println("Time");
      Serial.println("Creating file ... ");
      dataFile.close();
      delay(100);
    }
    File dataFile = SD.open("temp_log.csv", FILE_READ);
    if (dataFile) {
      Serial.println("File opened ");
      dataFile.close();
      result = true;
    }
  } 
  return result;
}

// function to print the temperature for a device
float printTemperature(DeviceAddress deviceAddress)
{
  float temp = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.println(temp);
  return (temp);
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

void setDateTime(){

  second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. 
  minute = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hour  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  dayOfWeek = (byte) (Serial.read() - 48);
  dayOfMonth = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  month = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  year= (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(DS1307_ADDRESS);
  I2C_WRITE(zero);
  I2C_WRITE(decToBcd(second) & 0x7f);    // 0 to bit 7 starts the clock
  I2C_WRITE(decToBcd(minute));
  I2C_WRITE(decToBcd(hour));      // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  I2C_WRITE(decToBcd(dayOfWeek));
  I2C_WRITE(decToBcd(dayOfMonth));
  I2C_WRITE(decToBcd(month));
  I2C_WRITE(decToBcd(year));
  Wire.endTransmission();
}

byte decToBcd(byte val){
  // Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
  // Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

// Gets the date and time from the ds1307 and prints result
void getDateTime()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  I2C_WRITE(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_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());
}
Bijlagen
Temp_logger_bb2.jpg
fritzing schema
Temp_logger_bb2.jpg (28.55 KiB) 6163 keer bekeken

Advertisement

Gebruikers-avatar
Berichten: 270
Geregistreerd: 30 Dec 2012, 11:42

Re: Temperatuur logger met SD kaart

Berichtdoor Rudi » 03 Apr 2013, 20:25

MarioV schreef:De sensor is een DS18B20, dit zijn niet de allergoedkoopste .... tijd komt van een rtc DS1307.


Tip: probeer free samples vast te krijgen. Ik heb maandag zowel bij Texas Instruments als bij Maxim Integrated zo gratis onderdelen besteld.
Vandaag, rechtstreeks vanuit de VS al een doosje met componenten van TI ontvangen. Netjes, verzorgd én gratis.
Maxim zal enkele weken duren denk ik, maar als het gratis is ... :D .
Heb er, van elks twee stuks, de DS18B20, MAX7219, MAX7221 en DS3231 besteld.
Arduinows!
Why do computer programmers confuse Halloween with Christmas? Because Oct 31 = Dec 25
I got 01100011 problems but a bit ain't 00000001

Terug naar Afgeronde projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 7 gasten