Teensy 3.2 SdFat always losing last data set, not saving to SD

Status
Not open for further replies.

Matadormac

Well-known member
Good day. I have been working on this for days and have tried many work arounds but I am still having no success saving the last data set. The instrument readings and the button push which initiates it are all working. I can't seem to cause a successful sync or flush or close file function to cause the latest data set to be saved to the SD. For example, the button push/data set reading works fine for all button pushes except for whichever is the last one. So button push 1,2,3,4,5 are captured and saved to the SD but the last button push "6" will not be. It is maddening.

It is likely something very basic but I just cannot see it. I would be grateful for any help on the matter. I am leaving out the code for the sensors but if that becomes necessary I will post it. It is just a lot of code.

Here is the main code including all the SD functions.

Thank you in advance.

Code:
#include <Adafruit_AM2315.h>
#include <Wire.h>
#include <TimeLib.h>
#include <Timer.h>
#include <DS1307RTC.h>
#include <SdFat.h>
#include "Adafruit_TSL2591.h"
//#include "Adafruit_HTU21DF.h"

#include <Arduino.h>
#include <U8g2lib.h>
SdFat SD;
//=================================================

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SSD1325_NHD_128X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 8, /* reset=*/ 9);

//================================================================
//Hardware pin definitions for ML8511
int UVOUT = A0; //Output from the sensor
int REF_3V3 = A1;
//=================================================
float h = 0;
float tC = 0;
float tF = 0;
int theYear;
int theMonth;
int theDay;
int theHour;
int theMinute;
int theSecond;
int digits;
String monthText;
float ftcandle;
float uvAmount;
float luxReal;
float infraredReal;
float irReal;
float luxVal;
String nameOfFile;
String stringOne;
long sampleRate;
float sampleRateSeconds;
float sampleRateMinutes;
float sampleRateHours;
int i = 0;
int j;
//float d = 0;
int logPoint;
//float logPoint;
float outputVoltage;
float uvIntensity;
Timer t;
//char fileName;


//===============================================================
//int data;
//================================================================
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)/**************************************************************************/
//  I2C device 0x29
//================================================================
tmElements_t tm;
//==============================================

// Connect RED of the AM2315 sensor to 5.0V
// Connect BLACK to Ground
// Connect WHITE to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect YELLOW to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4

Adafruit_AM2315 am2315;
//================================================================
// SD chip select pin.  Be sure to disable any other SPI devices such as Enet.
const uint8_t chipSelect = 6; // pin 10 is taken by display, use pin 6 for SD card
#define FILE_BASE_NAME "Data"
////==============================================================
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
char fileName[13] = FILE_BASE_NAME "00.csv";
//delay(1000);
////=====================================================
// File system object.
SdFat sd;

//// Log file.
//SdFile file;
File dataFile;   // the logging file
#define error(msg) sd.errorHalt(F(msg))
//================================================================
#define DEBOUNCE 5  // how many ms to debounce, 5+ ms is usually plenty

//define the buttons that we'll use.
byte buttons[] = {1, 2, 3, 4};

//determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)

//track if a button is just pressed, just released, or 'currently pressed'
byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
byte previous_keystate[NUMBUTTONS], current_keystate[NUMBUTTONS];

//================================================================
//const uint32_t SAMPLE_INTERVAL_MS = 5000; // 5 seconds
//const uint32_t SAMPLE_INTERVAL_MS = 10000; // 10 seconds
//const uint32_t SAMPLE_INTERVAL_MS = 15000; // interval of 15 seconds
//const uint32_t SAMPLE_INTERVAL_MS = 30000; // interval of 30 seconds
//const uint32_t SAMPLE_INTERVAL_MS = 1800000;  // interval of 30 minutes
//const uint32_t SAMPLE_INTERVAL_MS = (5*60*1000);  // interval of 5 minutes
//const uint32_t SAMPLE_INTERVAL_MS = (30*60*1000);  // interval of 30 minutes
//const uint32_t SAMPLE_INTERVAL_MS = 1800000;  // interval of 30 minutes
//const uint32_t SAMPLE_INTERVAL_MS = (60 * 60 * 1000); // interval of 30 minutes
float SAMPLE_INTERVAL_MS = 0;
//==============================================
//const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
//char fileName[13] = FILE_BASE_NAME "00.csv";

void setup(void) {
  byte j;
  Serial.begin(9600); //set up serial port
  while (!Serial && (millis() <= 1000));
  Serial.print("Button checker with ");
  Serial.print(NUMBUTTONS, DEC);
  Serial.println(" buttons");
  // Make input & enable pull-up resistors on switch pins
  for (j = 0; j < NUMBUTTONS; j++) {
    pinMode(buttons[j], INPUT);
    digitalWrite(buttons[j], HIGH);
  }

  if (RTC.read(tm)) {
    Serial.print("Ok, Time = ");
    digitalClockDisplay();
    Serial.println();
  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS3231 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS3231 read error!  Please check the circuitry.");
      Serial.println();
    }
  }
  delay(250);
  //================================================
  Serial.println("DS1307RTC Read Test");
  Serial.println("-------------------");
  //================================================
  pinMode(UVOUT, INPUT);
  pinMode(REF_3V3, INPUT);
  //  analogReference(INTERNAL);
  analogReference(DEFAULT);
  Serial.println("ML8511 example");
  //============================================
  Serial.println("Starting Adafruit TSL2591 Test!");
  if (tsl.begin()) {
    Serial.println("Found a TSL2591 sensor");
  }
  else
  {
    Serial.println("No sensor found ... check your wiring?");
    while (1);
  }
  /* Display some basic information on this sensor */
  // displaySensorDetails();
  /* Configure the sensor */
  //  configureSensor();
  //============================================
  Serial.println("AM2315 Test!");
  if (! am2315.begin()) {
    Serial.println("Sensor not found, check wiring & pullups!");
    while (1);
  }
  delay(100);
  //  SaveButton();
  //}
  // == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == =
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";
  delay(1000);
  // == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == =
  // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  if (!sd.begin(chipSelect, SPI_FULL_SPEED)) {
    sd.initErrorHalt();
  }
  //===============================================
  // Find an unused file name.
  if (BASE_NAME_SIZE > 6) {
    error("FILE_BASE_NAME too long");
  }
  while (sd.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      error("Can't create file name");
    }
  }
  //  dataFile = sd.open(fileName, FILE_WRITE);
  do {
    delay(100);
  } while (Serial.read() >= 0);
  Serial.print(F("Logging to: "));
  Serial.println(fileName);
  nameOfFile = (fileName);
  dataFile.print(F("Name of Data File:,"));
  dataFile.print(',');
  dataFile.print(nameOfFile);
  dataFile.println();
  dataFile.print(F("#,Date Time, Rh%,temp C,temp F, Visible Lux, IR mW/cm^2, UV mW/cm^2,"));
  dataFile.println();
  dataFile.close();
  //================================================
  //  takeReadings();
  //  delay(100);
  //  betweenReadings = (exFloat * 1000 * 60) * 60;
  //  t.every(betweenReadings, takeReadings);
  //================================================
  u8g2.begin();
  u8g2.enableUTF8Print();    // enable UTF8 support for the Arduino print() function
  takeReadings();
  refreshDisplay();
}

void loop(void) {

  byte thisSwitch = thisSwitch_justPressed();
  switch (thisSwitch)
  {
    case 0:
      Serial.println("switch 1 just pressed");
      takeReadings();
      delay(100);
      Serial.println("SAVE button hit");
      //      ++i;
      // i++;
      i = i + 1;
      logPoint = i;
      Serial.print("Just incremented i "); Serial.println(i);
      dataFile = sd.open(nameOfFile, FILE_WRITE);
      // dataFile.open(fileName, O_CREAT | O_APPEND | O_WRITE);
      dataFile.print(i); dataFile.print(",");
      dataFile.print('"'); dataFile.print(theYear); dataFile.print('/'); dataFile.print(theMonth);
      dataFile.print('/'); dataFile.print(theDay); dataFile.print(' '); dataFile.print(theHour);
      dataFile.print(':'); dataFile.print(theMinute); dataFile.print(':'); dataFile.print(theSecond);
      dataFile.print('"'); dataFile.print(',');
      dataFile.print(h); dataFile.print(',');
      dataFile.print(tC); dataFile.print(',');
      dataFile.print(tF);  dataFile.print(',');
      dataFile.print(luxReal); dataFile.print(',');
      dataFile.print(irReal); dataFile.print(',');
      dataFile.print(uvAmount); dataFile.print(',');
      dataFile.println();
      //      dataFile.sync();
      dataFile.close();            //Close the file.
      //    dataFile.sync();
      Serial.println("Updated and done for now");
      Serial.print("Done");
      Serial.println(logPoint);
      delay(100);
      refreshDisplay();
      break;
    case 1:
      Serial.println("switch 2 just pressed"); break;
    case 2:
      Serial.println("switch 3 just pressed"); break;
    case 3:
      Serial.println("switch 4 just pressed"); break;

  }

}
 
Resolved

Along with changes I made to the SD coding there was a conflict between the SPI of the SD card breakout and that of the 2.7 inch OLED display. When calling the display to show the resfreshed data after saving to the SD card I needed to add a " u8g2.begin();" to my "refreshdisplay(); code block. Previously, I had the u8g2.begin(); only once in the setup function.

Now it works capturing the last button push refreshed sensor data.
 
Status
Not open for further replies.
Back
Top