On Sat, Sep 24, 2016 at 5:56 PM, Russell Senior <[email protected]>
wrote:

> >>>>> "Denis" == Denis Heidtmann <[email protected]> writes:
>
> Denis> I am developing a logging program.  The Arduino is a Uno R2.  It
> Denis> has an ATAfruit SD shield w/ RTC.  For testing purposes I record
> Denis> data once per second.  When I am finished testing I will be
> Denis> taking data much less frequently, although there might be random
> Denis> times when a few data points are only one second apart.
>
> Denis> I convert the data ( a long; two strings, 3 ints) to a string in
> Denis> CSV format.  But often not all the data gets assembled into the
> Denis> string.  It seems that the += operation does not append the
> Denis> string to be added.
>
> Denis> I removed the references to the SD card and the failures went
> Denis> away, or so it seems.  I need to run it for a longer time, but
> Denis> before I removed the SD stuff the problem showed up in two to
> Denis> four seconds.  So let's assume that the issue was the SD writing.
>
> Denis> How might I go about exploring this issue?
>
> Can you post the relevant code?


Since I do not know what code is relevant, I must post the entire thing,
warts and all.  The function which has been my focus is the csv_data, so it
is filled with spurious Serial.print commands.  I have since found that +=
will append ints to Strings.  Changing csv_data to use that feature does
not change the behavior:  things do not get added to the string being
assembled.  Note that initially the code worked fine.  Then I noticed that
some items did not appear in the returned string.  Finally most recently no
complete strings get returned.  Then I found that if I removed the code
relating to the SD, the  problem went away.

What I believe the cause of the gradual change from good to bad is that I
regularly remove the SD from the Arduino, put it in the laptop, view the
data, then delete the files before unmounting it and returning it to the
Arduino.  I notice that although I empty the trash the laptop reports that
there is still some space used, an amount that has been slowly increasing
over the days I have been exploring this issue.  (It would not surprise me
if formatting the SD would make the problem go away for a while.)

As to keeping data in ram; other threads in use, etc.:  I thought that the
Arduino was single-threaded, and I have no clue which data is stored where.

Looks like version 1.6.9 of the Arduino IDE. I am running Ubuntu 16.04 The
SD library is SD Built-in by Arduino, SparkFun Version 1.0.8

Please excuse the long post.  Feel free to discard any irrelevant code
below.

-Denis

/*
  hot water heater logger
 9/13/2016 added limit to # records in file
 9/21/2016 changing to using difference between successive reading
        as a way to detect change in state. Of questionable
        accuracy in detecting water in use.
 The circuit:
 * Flue TC pin 0 amp gain 325 type J TC
 * Cold H2O pin 1 amp gain 1000 type J TC
 *   temp. of cold water pipe at input to tank rises
 *   when no water is being used.  It drops to the
 *   temp. of water supply when the water is used.
 * Hot H2O pin 2 type 36 sensor
 *
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 10

 */

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

const int chipSelect = 10;
const int flue_pin = 0;//amp gain approx. 360
const int cold_pin = 1;//amp gain approx. 1000
const int hot_pin = 2;//type 36, no gain
const int d_flueToff = -10; //burner going off diff
const int d_flueTon = +10; //burner going on diff
const int d_coldTon = -1; //water going on diff
const int d_coldToff = +2; //water going off diff
long t1; //unix time
const int report_interval = 600; //seconds
const int maxcount = 1008; // limits # records in file.
int rem1; //remainder of time/interval
boolean burn_on; //burner is on
boolean H2O_on; //water is in use

volatile boolean close_file = false;

const int greenLEDpin=4;
const int redLEDpin=3;

String dataString;
String filename;
File dataFile;
int Tflue1,Tflue2,Tcold1,Tcold2,Thot;

void setup() {
   pinMode(redLEDpin, OUTPUT);
   pinMode(greenLEDpin, OUTPUT);

  // Open serial communications:
  Serial.begin(9600);

  attachInterrupt(digitalPinToInterrupt(2),button_press,RISING);

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    fail_flash(2);
  }
  Serial.println("card initialized.");

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    fail_flash(3);
  }
  //short wait on reset or power on w/ rapid green flashing
  for(int i = 1; i<16; i++){
    digitalWrite(greenLEDpin,HIGH);
    delay(150);
    digitalWrite(greenLEDpin,LOW);
    delay(150);
  }
}
void loop() {

  int count = 0;
  //Generate file name:
  filename = "D";
  time_temp(t1,Tflue1,Tcold1,Thot);//initial data
  String foo = String(t1);
  int n = foo.length();
  foo = foo.substring(n-7); //7 digits of seconds to make name
  filename += foo;
  filename += ".csv";

  //now set initial states
  burn_on = false; //arbitrary
  H2O_on = false;  //arbitrary
  rem1 = t1%report_interval;
  Serial.println("");
  Serial.println("");
  Serial.println(filename);

  dataFile = SD.open(filename,FILE_WRITE);
  if(!dataFile){
    Serial.print(filename);
    Serial.println(" failed to open");
    fail_flash(4);
  }

  String title =
"unix-time,burner-status,water-status,hot-water-T(dn),flue-T(dn),cold-water-T(dn)";
  //  expect:     seconds,  burn_on or off, H2O_on or off, C = dn/2-52.2,
C=.285*dn+rT, C=.0926*dn +rT
  //  the above calculations need to be updated.
  Serial.println(title);
  foo = csv_data(t1,burn_on,H2O_on,Thot,Tflue1,Tcold1);
  Serial.println(foo);
  dataFile.println(title);
  dataFile.println(foo);

  while(count < maxcount){ // Limits # records in file:
    boolean report = true;//make this true to record all data
    long t2;
    digitalWrite(greenLEDpin,HIGH);
    delay(100);
    digitalWrite(greenLEDpin,LOW);
    delay(900);

    time_temp(t2, Tflue2, Tcold2, Thot); // new data
    int rem2=t2%report_interval;
    if (rem2<rem1){
      report = true;
      //Serial.print("new time:");
    }
    rem1=rem2;

    if (burn_on){
      if (Tflue2 - Tflue1 < d_flueToff){
        burn_on = false;
        report = true;
        Serial.print("burner going off:");
      }
    }
    else {
        if (Tflue2 - Tflue1 > d_flueTon){
          burn_on = true;
          report = true;
          Serial.print("burner turning on:");
        }
     }
     Tflue1 = Tflue2;

     if (H2O_on){
       if (Tcold2 - Tcold1 > d_coldToff){
         H2O_on = false;
         report = true;
         Serial.print("water going off:");
        }
      }
      else {
          if (Tcold2 -Tcold1 < d_coldTon){
            H2O_on = true;
            report = true;
            Serial.print("water turning on");
          }
       }
       Tcold1 = Tcold2;

    if (report || close_file){ // record final data point on close
      dataString = csv_data(t2,burn_on,H2O_on,Thot,Tflue2,Tcold2);
      Serial.println(dataString);
      dataFile.println(dataString);
      count++;
    }

    if(close_file){
      Serial.println("closing file");
      dataFile.close();
      delay(1000);//ignore switch bounce
      digitalWrite(redLEDpin, LOW);
      while(1){  //wait forever for RESET
        digitalWrite(greenLEDpin, HIGH);
        delay(1500);
        digitalWrite(greenLEDpin, LOW);
        delay(500);
      }

    }
  } //end while
  Serial.println("closing file");
  dataFile.close();
} // end loop

//Get time and data:
void time_temp(long &t_sec, int &flue_T, int &cold_T, int &hot_T){
  DateTime now = rtc.now();
  t_sec = now.unixtime();
  flue_T = analogRead(flue_pin);
  cold_T = analogRead(cold_pin);
  hot_T = analogRead(hot_pin);
}

//ISR:
void button_press(){
  close_file = true;
  digitalWrite(redLEDpin, HIGH);
}

//assemble data into a csv string:
String csv_data(long t, boolean burn_state, boolean H2O_state, int hot_T,
int flue_T, int cold_T){
  String dum;
  String foo = String(t);
  foo += ",";
  if(burn_state){
    foo += "burn_on,";
  }  else {
    foo += "burn_off,";
  }
  if(H2O_state){
    foo += "H2O_on,";
  }  else {
    foo += "H2O_off,";
  }
  dum = String(hot_T);
  Serial.print(hot_T);
  Serial.print(" hot len =");
  Serial.println(dum.length());
  foo += dum;
  foo += ",";
  dum = String(flue_T);
  Serial.print(flue_T);
  Serial.print(" flue len =");
  Serial.println(dum.length());
  foo += dum;
  foo += ",";
  dum = String(cold_T);
  Serial.print(cold_T);
  Serial.print(" cold len =");
  Serial.println(dum.length());
  foo += dum;
  return foo;
}

//rapid LED error flashing
void fail_flash(int n){
  while(1){
    for(int i=1;i<=n;i++){
    digitalWrite(redLEDpin, HIGH);
    delay(150);
    digitalWrite(redLEDpin, LOW);
    delay(150);
  }
  delay(1000);
}
}
_______________________________________________
PLUG mailing list
[email protected]
http://lists.pdxlinux.org/mailman/listinfo/plug

Reply via email to