Custom function for data logging does not work

Hi everyone,
I am still trying to get my own functions to work. I would like to implement them to get cleaner main code and also to learn how to write functions. The functions in my which (seem) not to work are dataToSD() and dataToSerial().
I end up with error logfile all the time. The serial monitor will also end after the setup. So the problem seems to be in the loop, and especially in the custom functions. But I dont understand wheres the error.

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

// climatic parameters //////////////////////////////////////////
const byte maxTemp = 29;
const byte normTemp = 26;
const byte minHum = 85;
const byte minHumFan = 80;

// state declaration and control timings ////////////////////////

const unsigned long rainDuration = 5000;
unsigned long previousRain = 0;

const unsigned long rainFanDuration = 3000;
unsigned long previousRainFan = 0;

const unsigned long logFrequency = 30000;
unsigned long previousLog = 0;

unsigned long previousSerialLog = 0;
const unsigned long serialFrequency = 1000;

byte fanState = 0;
byte rainState = 0;

byte i = 0;
byte k = 0;

float t_1;
float t_2;
float h_1;
float h_2;

// pin assignments //////////////////////////////////////////////
const byte switchPin = 4;
const byte DHTPIN_1 = 5;
const byte DHTPIN_2 = 6;
const byte fanRelay = 7;
const byte rainRelay = 8;
const byte chipSelect = 10;

LiquidCrystal_I2C lcd(0x27, 16, 2);

#define DHTTYPE DHT22
DHT dht_1(DHTPIN_1, DHTTYPE);
DHT dht_2(DHTPIN_2, DHTTYPE);
RTC_DS1307 rtc;

File myFile;
char dateBuffer[12];
char sensBuffer[10];

void setup() {
  Serial.begin(57600);
  while (!Serial) {
    ;
  }

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);

  if (! rtc.begin()) {
    error("No RTC");
    Serial.flush();
    abort();
  }
  if (! rtc.isrunning()) {
    error("RTC was off. Setting new time.");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  Serial.print(F("Initializing SD card..."));
  if (!SD.begin(chipSelect)) {
    error("SD initialization failed");
    while (1);
  }

  Serial.println(F("initialization done."));
  if (SD.exists("terralog.txt")) {
    Serial.println(F("terralog.txt exists."));
  } else {
    Serial.println(F("terralog.txt doesn't exist."));
    Serial.println(F("Creating terraaaaa.txt"));
    if (SD.exists("terralog.txt")) {
      Serial.println(F("terralog.txt was successfully created."));
    } else {
      Serial.println(F("File creation failed."));
    }
  }

  myFile = SD.open("terralog.txt", FILE_WRITE);
  myFile.println("date,time,temp_1,temp_2,hum_1,hum_2,fanState, rainState,i,k,rainTime,rainTimeFan,minHum,minHumFan");
  myFile.close(); //this might be uncommented later

  pinMode(switchPin, INPUT);
  pinMode(fanRelay, OUTPUT);
  pinMode(rainRelay, OUTPUT);
  dht_1.begin();
  dht_2.begin();
  Serial.println(F("date,time,temp_1,temp_2,hum_1,hum_2,fanState, rainState,i,k,rainTime,rainTimeFan,minHum,minHumFan"));
}

void loop() {

  while (switchPin == HIGH) {
    break;
  }

  unsigned long currentTime = millis();

  h_1 = dht_1.readHumidity();
  t_1 = dht_1.readTemperature();
  while (isnan(h_1) || isnan(t_1)) {
    error("DHT 1");
  }

  h_2 = dht_2.readHumidity();
  t_2 = dht_2.readTemperature();
  while (isnan(h_2) || isnan(t_2)) {
    error("DHT 2");
  }

  DateTime time = rtc.now();
  lcd.setCursor(0, 0);
  lcd.print(t_1);
  lcd.print(", ");
  lcd.print(h_1);
  lcd.setCursor(0, 1);
  lcd.print(t_2);
  lcd.print(", ");
  lcd.print(h_2);

  //
  // Temperature Control
  //

  if (t_2 >= maxTemp) {
    fanState = 1;
    digitalWrite(fanRelay, HIGH);
  } else if (t_2 < maxTemp && t_2 >= normTemp) {
  } else if (t_2 < normTemp) {
    fanState = 0;
    digitalWrite(fanRelay, LOW);
  }

  //
  // Rain Control
  //

  if (h_1 < minHum & fanState == 0) {
    if (previousRain - currentTime <= rainDuration) {
      digitalWrite(rainRelay, HIGH);
      rainState = 1;
      previousRain = currentTime;
    }
  }
  else if (h_1 < minHumFan & fanState) {
    if (previousRainFan - currentTime <= rainFanDuration) {
      digitalWrite(rainRelay, HIGH);
      rainState = 1;
      previousRainFan = currentTime;
    }
  }
  else {
    rainState = 0;
    digitalWrite(rainRelay, LOW);
  }

  /*if (previousLog - currentTime <= logFrequency) {
    dataToSD(t_1,  t_2,  h_1,  h_2, fanState, rainState, i, k, rainDuration, rainFanDuration, minHum, minHumFan);
    previousLog = currentTime;
  }*/
  if (previousSerialLog - currentTime <= serialFrequency) {
    dataToSerial(t_1, t_2, h_1, h_2, fanState, rainState, i, k, rainDuration, rainFanDuration, minHum, minHumFan);
    previousSerialLog = currentTime;
  }
  Serial.println(currentTime);
}


void dataToSerial(float t_1, float t_2, float h_1, float h_2, byte fanState, byte rainState, byte i, byte k, const byte rainDuration, const byte rainFanDuration, const byte minHum, const byte minHumFan)  {
  DateTime time = rtc.now();
  sprintf(dateBuffer, "%02u-%02u-%04u", time.day(), time.month(), time.year());
  Serial.print(dateBuffer);
  Serial.print(",");
  sprintf(dateBuffer, "%02u:%02u:%02u", time.hour(), time.minute(), time.second());
  Serial.print(dateBuffer);
  Serial.print(F(","));
  Serial.print(t_1);
  Serial.print(F(","));
  Serial.print(t_2);
  Serial.print(F(","));
  Serial.print(h_1);
  Serial.print(F(","));
  Serial.print(h_2);
  Serial.print(F(","));
  Serial.print(fanState);
  Serial.print(F(","));
  Serial.print(rainState);
  Serial.print(F(","));
  Serial.print(i);
  Serial.print(",");
  Serial.print(k);
  Serial.print(",");
  Serial.print(rainDuration);
  Serial.print(",");
  Serial.print(rainFanDuration);
  Serial.print(",");
  Serial.print(minHum);
  Serial.print(",");
  Serial.print(minHumFan);
  Serial.println();
}

void dataToSD (float t_1, float t_2, float h_1, float h_2, byte fanState, byte rainState, byte i, byte k, const byte rainDuration, const byte rainFanDuration, const byte minHum, const byte minHumFan) {
  File myFile = SD.open("terralog.txt", FILE_WRITE);
  if (!myFile) {
    error("logfile");
  }

  DateTime time = rtc.now();
  sprintf(dateBuffer, "%02u-%02u-%04u", time.day(), time.month(), time.year());
  myFile.print(dateBuffer);
  myFile.print(",");
  sprintf(dateBuffer, "%02u:%02u:%02u", time.hour(), time.minute(), time.second());
  myFile.print(dateBuffer);
  myFile.print(",");
  myFile.print(t_1);
  myFile.print(",");
  myFile.print(t_2);
  myFile.print(",");
  myFile.print(h_1);
  myFile.print(",");
  myFile.print(h_2);
  myFile.print(",");
  myFile.print(fanState);
  myFile.print(",");
  myFile.print(rainState);
  myFile.print(",");
  myFile.print(i);
  myFile.print(",");
  myFile.print(k);
  myFile.print(",");
  myFile.print(rainDuration);
  myFile.print(",");
  myFile.print(rainFanDuration);
  myFile.print(",");
  myFile.print(minHum);
  myFile.print(",");
  myFile.println(minHumFan);
  myFile.flush();
}

void error(char *str) {
  Serial.print(F("Fehler: "));
  Serial.println(str);
  lcd.clear();
  lcd.print("Error: ");
  lcd.print(str);
  delay(5000);
  lcd.clear();
  //while(1);
}

Couple of questions:

  1. what do you think the below does?
  • if switchPin is high then the while will run and reach break, then exit.
  • If switchPin is low the while will be bypassed
  1. at what rate are you trying to log to the SD?

const unsigned long logFrequency = 30000;

  1. Have you run the SD example providing the SD card is fully functional?

The only way I know to accomplish your goal is to divide and conquer. Take each functional piece separate and show you can make that piece function.
Do this for each piece (i.e. the SD card, simply create constants to save tot he SD card and make sure you can save what you want successfully.

1 Like

Thank you for the reply.

This part is just in progress, thats why theres the break. I will use this as simple halt in the future as working on my terrarium with doors opened triggers the misting system.

The code is an evolutionary process and thus I know from previous versions that the logging to sd should work. The only new thing are the voids for serial print and sd logging. I simply lack the knowledge to find the mistake over here.

My understanding of "break" is that it will cause the program flow to exit the while statement. It will no stop or stall the program.

If you change to:

 while(switchPin == HIGH) {}

This will cause the program to stay in the while loop as long as the switchPin is HIGH.

At what frequency are you trying to log data?

/*if (previousLog - currentTime <= logFrequency) {
    dataToSD(t_1,  t_2,  h_1,  h_2, fanState, rainState, i, k, rainDuration, rainFanDuration, minHum, minHumFan);
    previousLog = currentTime;
  }*/
  if (previousSerialLog - currentTime <= serialFrequency) {
    dataToSerial(t_1, t_2, h_1, h_2, fanState, rainState, i, k, rainDuration, rainFanDuration, minHum, minHumFan);
    previousSerialLog = currentTime;
  }

Just to make sure that I understand the issue, you are indicating that the function dadaToSerial() when called does not run and the below code ran from setup()

if (SD.exists("terralog.txt")) {
    Serial.println(F("terralog.txt exists."));
  } else {
    Serial.println(F("terralog.txt doesn't exist."));
    Serial.println(F("Creating terraaaaa.txt"));
    if (SD.exists("terralog.txt")) {
      Serial.println(F("terralog.txt was successfully created."));
    } else {
      Serial.println(F("File creation failed."));
    }
  }

does not print an error message and the function dadaToSD() when uncommented produces the error "logfile", correct?

Note that

unsigned long previousSerialLog = 0;`

is initialized to 0 and when the following is done previousSerialLog - currentTime <= serialFrequency 0 minus the currentTime will be a what kind of number? Also when does previousSerialLog ever get updated?

you are right

this might be the key to make it work. I will have a look at it and update you. Thanks so far.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.