0

Problem

I have an Arduino on an Adafruit feather mo. I am attempting to store data on an adalogger. The idea is simple. I have a potentiometer and I wish to write data from that potentiometer to an SD card. I can create, open, and close a CSV file, but I cannot write data from the potentiometer to the CSV file on the SD card.

Very rarely, I can get data from the sensor to write into the CSV file. However, I am not convinced this is a hardware issue, because I can see all the data in COM using Serial.println() just like I want from the potentiometer. It just won't write to the SD card. Can someone point out what I could be going wrong?

Code

This code works:

**Initalize Stuff** 
//Project Dependencies 
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <string.h>
#include "RTClib.h"

// the setup function runs once when you press reset or power the board
//Global variables, usually associated with physical assets on the board
Sd2Card card;
SdVolume volume;
SdFile root;
char filename[13] = "";
File logfile;
int potPin = 2; //select the input pin for the potentiometer 
const int chipSelect = 10;//chip select for SPID 
File dataFile;
File sensorData;
bool fileOpen = false;

void setup() {
  //Step 1: Initialize Serial
  //================================================================
  Serial.begin(57600);
  //Step 1: Initialize the SD Card
  //================================================================
  //Step 1: Initialize the SD Card
  //================================================================
  Serial.println("Initializing SD card...");
  while (!SD.begin(chipSelect)) {
    // see if the card is present and can be initialized:
    Serial.println("...Card failed, or not present");
    delay(2000);
  }
  Serial.println("...Success.");
  if (card.init(SPI_HALF_SPEED, chipSelect))
    Serial.println("...Card initialized.");
  //// print the type of card
    Serial.print("\n...Card type: ");
    switch (card.type()) {
      case SD_CARD_TYPE_SD1:
        Serial.println("SD1");
        break;
      case SD_CARD_TYPE_SD2:
        Serial.println("SD2");
        break;
      case SD_CARD_TYPE_SDHC:
        Serial.println("SDHC");
        break;
      default:
        Serial.println("Unknown");
    }
    sprintf(filename, "%02d%02d%02d%02d.csv", now.month(), now.day(), now.hour(), now.minute());
    Serial.print("Initializing date file: ");
    Serial.println(filename);
    //Step 2: Create and open new logfile
    if (SD.exists(filename)) {
      Serial.print("...file ");
      Serial.print(filename);
      Serial.println(" already created before...Success.");
    } else {
      //File not found, so create it.
      dataFile = SD.open(filename, FILE_WRITE);
      if (!dataFile) {
        Serial.print("...Couldn't create ");
        Serial.println(filename);
      } else {
        Serial.print("...Success opening ");
        Serial.println(filename);
        Serial.print("...Starting size: ");
        Serial.print(dataFile.size());
        Serial.print(" bytes");
      }
      dataFile.close();
    }
  }

Loop

This code doesn't work:

// the loop function runs over and over again until power down or reset
void loop() {
  int WriteEnabled = digitalRead(5); //This is when I turn a switch on to record, this works
  if (WriteEnabled) {
    sensorData = SD.open(filename, FILE_WRITE);
    if (sensorData) {
      uint32_t value = analogRead(potPin);
      //char line[27] = ""; //Define my input line
      //sprintf(line, "%04d/%02d/%02d, %02d:%02d:%02d, %04d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second(), value); //Doesn't work either, why?
      String dataString = String(value);
      sensorData.println(dataString);//This doesn't work
      Serial.println(dataString);
    }
  }
  if (!WriteEnabled && sensorData) {
    sensorData.close();
  }
}

References

I have attempted to fix the problem by consulting several resources. Similar questions on Stack Overflow do not answer my problem.

I have changed writing to the SD card by using String() and also sprint to help define the data. Nothing is working. I don't think it is a hardware problem because I can open and close a file, but just not write any data. Can someone please help me out? If someone suspects hardware, please let me know why. I really doubt it because why can I create a file on SD card and see potentiometer values in COM but not store them?

Community
  • 1
  • 1
hlyates
  • 1,279
  • 3
  • 22
  • 44

1 Answers1

3

Try changing the code so that the open call only happens when the WriteEnable flag changes from false to true. Do the opposite for the close call.

To more directly match the Arduino Reference move the close call to be just after the write.

Derek
  • 58
  • 3
  • Pardon me sir, can you please elaborate? I believe your suggestion has confused me because as I understand your suggestion, I'm already doing this? My open call already happens inside the conditional when WriteEnable (switch is on) is true. When WriteEnable is false (turned off) and my file is open, it closes. – hlyates Mar 30 '17 at 02:03
  • 1
    The open call happens every time through the loop call when write enable is true. But the close call is only happening when the file is open and the writeEnable is false. – Derek Mar 30 '17 at 02:04
  • I understand. I should set it up to only open the file once when I first enable (turn on the switch). I'll go ahead and remove the logic for WriteEnable for now and simple open, write, close. However, should I be concerned about looping too fast and getting into a weird state if I am in the middle of closing the file and trying to open it again sir? – hlyates Mar 30 '17 at 02:07
  • 1
    It should be fine for the Arduino platform, all of these calls block until finished. It is always a good idea to establish a defined read rate for sensor data. I usually default things with human interaction to at least 8 Hz. Things that are just monitoring a fairly static environment (ie. thermostats) can run much slower. While something like a motor controller can run in the thousands of Hz. To implement a simple rate control use the delayMicroseconds call. delayMicroseconds(125000) will yield a loop rate of 1/(125000 + code execution). – Derek Mar 30 '17 at 02:15
  • Can I do delay(250) and record data every 1/8th of a second then sir? What's the advantage of delayMicroseconds sir? I may use what you suggested, but would like to understand the advantage. BTW, the open/close works. I am going to modify the code to only execute if write is enabled (with open/close inside + delay). – hlyates Mar 30 '17 at 02:26
  • It is working much better now. Thank you. The only remaining issue I have is the clock on the RTC (the adalogger chip) doesn't seem to be synced well with the PC System.Date.Now time. I'm going to get it off a breadboard and start piecing it together. I hope that helps solve some of that weirdness. However, you helped me resolve the issue above. If you have experience with RTC, please let me know. :) – hlyates Mar 30 '17 at 03:18