0

Logfile.flush(); results in incorrect data!
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Logfile.flush(); results in incorrect data!

by kevarlon on Tue Mar 28, 2017 8:33 pm

I am trying to datalog sound levels to an SD card. I have implemented the sound level tutorial code with the lighttemp logger code from the datalogging tutorial. When I use logfile.flush(); the output readings are much larger and abnormal (compared to the correct values achieved with the simple sound level code). When I comment out logfile.flush(); the data matches the readings achieved with the basic sound level code in serial print, however, the data doesn't print to the SD card. How do I print to the SD card without affecting the data with the logfile.flush();?

The first attached image is a serial print screenshot with logfile.flush(); Notice the range of values is smaller and kind of hovers around 2.30.
The second attached image is a serial print screenshot with logfile.flush(); commented out. Notice the range is greater (value range from 0.30 up to 5.0 (0-5v as expected)).

Please advise,
Thank you in advance

Heres my code; It's the lighttemp datalogger code with the LED commands removed and the sound level meter implemented.
Code: Select all | TOGGLE FULL SIZE
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

#include <avr/power.h>

// A simple data logger for the Arduino analog pins

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  500 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 500 // mills between calls to flush() - to write data to the card

uint32_t syncTime = 500; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port

#define aref_voltage 4.2        // we tie 3.3V to ARef and measure it with a multimeter!

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

const int sampleWindow = 500; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  while(1);
}

void setup()
{
  Serial.begin(9600);
  Serial.println();

  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
 
  // initialize the SD card
  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)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
 
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, (O_READ | O_WRITE | O_CREAT));
      break;  // leave the loop!
    }
  }
 
  if (! logfile) {
    error("couldnt create file");
  }
 
  Serial.print("Logging to: ");
  Serial.println(filename);

  // connect to RTC
  Wire.begin(); 
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
 

  logfile.println("millis,stamp,datetime,volt");   
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,volt");
#endif //ECHO_TO_SERIAL
 
  // If you want to set the aref to something other than 5v
analogReference(EXTERNAL);
}

void loop (void)
{
  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
 
  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");   
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", "); 
#endif

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(now.unixtime()); // seconds since 1/1/1970
  logfile.print(", ");
  logfile.print('"');
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"');
#if ECHO_TO_SERIAL
  Serial.print(now.unixtime()); // seconds since 1/1/1970
  Serial.print(", ");
  Serial.print('"');
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print('"');
#endif //ECHO_TO_SERIAL

   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level

   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   double volts = (peakToPeak * aref_voltage) / 1024;  // convert to volts

  logfile.print(", ");   
  logfile.print(volts);
#if ECHO_TO_SERIAL

  Serial.print(", ");   
  Serial.print(volts);
#endif //ECHO_TO_SERIAL

 logfile.println();
#if ECHO_TO_SERIAL
 Serial.println();
#endif // ECHO_TO_SERIAL

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  //logfile.flush();
}
Attachments
Screen Shot 2017-03-28 at 5.10.59 PM.png
Screen Shot 2017-03-28 at 5.10.59 PM.png (135.8 KiB) Viewed 520 times
Screen Shot 2017-03-28 at 5.11.35 PM.png
Screen Shot 2017-03-28 at 5.11.35 PM.png (141.66 KiB) Viewed 520 times

kevarlon
 
Posts: 8
Joined: Tue Mar 07, 2017 5:02 am

Re: Logfile.flush(); results in incorrect data!

by adafruit_support_mike on Thu Mar 30, 2017 3:44 am

Nothing in the code should create any link between the ADC readings and .flush().

Post a photo showing your hardware and connections and we'll take a look. 800x600 images usually work best.

adafruit_support_mike
 
Posts: 63074
Joined: Thu Feb 11, 2010 2:51 pm

Re: Logfile.flush(); results in incorrect data!

by kevarlon on Thu Apr 06, 2017 2:27 am

Sorry, did not see you responded. Attached is a picture of my setup. No matter what setup I use (I've also tried with a trinket pro 5v and tried different wires and arrangements) I get the same results: with logfile.flush() the values are increased by about 2 (doesn't drop below ~2.2), with no logfile.flush() the serial print readings are correct (full correct range as expected from sound level tutorial https://learn.adafruit.com/adafruit-microphone-amplifier-breakout/assembly-and-wiring) coming directly from the device and IDE serial print port but, of course, nothing is printing to the SD card.

Please advise! Been toying with it and have had zero luck!
Thank you
Attachments
IMG_8314_lo.jpg
IMG_8314_lo.jpg (285.63 KiB) Viewed 479 times

kevarlon
 
Posts: 8
Joined: Tue Mar 07, 2017 5:02 am

Re: Logfile.flush(); results in incorrect data!

by adafruit_support_mike on Fri Apr 07, 2017 1:39 am

Which microphone breakout are you using? That jumper to the Arduino's Aref pin looks like it might be related to the issue.

adafruit_support_mike
 
Posts: 63074
Joined: Thu Feb 11, 2010 2:51 pm

Re: Logfile.flush(); results in incorrect data!

by kevarlon on Fri Apr 07, 2017 2:00 am

This difference in readings actually occurs exactly the same without the aref. If I just use the 5v power supply and don't call external analog reference I get the exact same values.

Im using the adafruit Electret microphone with the MAX4466. PID 1063.

kevarlon
 
Posts: 8
Joined: Tue Mar 07, 2017 5:02 am

Re: Logfile.flush(); results in incorrect data!

by adafruit_support_mike on Sun Apr 09, 2017 12:44 am

Okay, the next most likely candidate would be series resistance through the breadboard's power rails.

Try moving the SD card breakout off to another breadboard and see if you still get the same results.

adafruit_support_mike
 
Posts: 63074
Joined: Thu Feb 11, 2010 2:51 pm

Re: Logfile.flush(); results in incorrect data!

by kevarlon on Sun May 21, 2017 9:16 pm

Hi, Sorry I didn't see your response sooner.

I used a different breadboard for the SD breakout and I still get the strange higher value numbers in the serial feed while using logfile.flush(). The difference is very consistent; an addition of a value of ~2 when the logfile.flush() is being used (as noted in the screenshots from an earlier post). I feel this is a code issue (although I know very little).

I hope you see this and have more thoughts! Thank you for your help
Attachments
48188374-AD5B-44D4-AF3E-7F97A76720C3.JPG
48188374-AD5B-44D4-AF3E-7F97A76720C3.JPG (378.4 KiB) Viewed 397 times

kevarlon
 
Posts: 8
Joined: Tue Mar 07, 2017 5:02 am

Please be positive and constructive with your questions and comments.