Go Down

Topic: SdFat logger will not work when detached from computer.  (Read 371 times) previous topic - next topic

WanderingKing

I'm working on making a logger that will record a few temperature sensors onto an SD Card. It also has an LCD display to show current readings. Everything works perfectly fine when I have the Arduino plugged into the computer, but when I try to use an external power source (a wall plug converter that says it puts out 2A at 5V) it does not work. I'm pretty sure it is failing somewhere inside the setup loop. Probably at the initialization of the SD Card.
"
if (!sd.begin(chipSelect, SD_SCK_MHZ(4)))
  {
    sd.initErrorHalt();
  }
"

Any help would be appreciated.
Code is as follows:
Code: [Select]


/*YourDuino SD Card Temperature Logger
  V1.2 02/07/2018

  This sketch will log multiupl Temperature sensors and record the data as a .CSV file onto an SD card.
  This allows easy transfer of data to a computer where it can be opened in Excel or similar programs
  and worked on.

  Uses SD Card Module availabe here:http://www.yourduino.com/sunshop/index.php?l=product_detail&p=246
  Uses DS18B20 Temperature sensor here:http://www.yourduino.com/sunshop/index.php?l=product_detail&p=134
  Waterproof Version here: http://www.yourduino.com/sunshop/index.php?l=product_detail&p=151

  Wiring: SD Card Module
  (Arduino Pin) - Module Pin
  10 (SS) to CS
  11 (MOSI) to DI
  12 (MISO) to DO
  13 (SCK) to CLK
  and G to GND and + to 5V
  Switch the switch to 5V

  Wiring: Temperature Sensor
  CONNECTIONS: (Holding chip with pins down, label towards you)
  - Left  pin:  Ground
  - Right pin:  +5V
  - Center pin: Arduino Pin 9 and ALSO "Pullup Resistor":
  - Center pin: to 4700 (4.7K) or 5K resistor * (other end goes to +5V)
    NOTE: Two 10K resistors connected in parallel can be used.

  Wiring: Status LED
  Connect and LED to pin 8 (don't forget 220 reisitor between pin and LED)

  Based on YourDuino Temperature Sensor Example and SDFat dataLogger example.
*/

/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include "SdFat.h"
//#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>  // Comes with Arduino IDE

/*-----( Declare Constants )-----*/
#define ONE_WIRE_BUS 9
#define STATUS_LED 8
// Log file base name.  Must be six characters or less.
#define FILE_BASE_NAME "Data"


/*-----( Declare objects )-----*/
/* Set up a oneWire instance to communicate with any OneWire device*/
OneWire ourWire(ONE_WIRE_BUS);

/* Tell Dallas Temperature Library to use oneWire Library */
DallasTemperature sensors(&ourWire);

// set the LCD address to 0x3F for a 20 chars 4 line display
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

/*-----( Declare Variables )-----*/
// SD chip select pin.  Be sure to disable any other SPI devices such as Enet.
const uint8_t chipSelect = SS;

// Time in Seconds for next data record.
uint32_t logTime;

// Interval between data records in seconds.
// The interval must be greater than the maximum SD write latency plus the
// time to acquire and write data to the SD to avoid overrun errors.
// Run the bench example to check the quality of your SD card.
const uint32_t SAMPLE_INTERVAL = 2;

//Number of attached temperature sensors
const uint8_t SENSOR_COUNT = 1;

bool DEBUG = 0; //set to 1 for serial monitor debug

/*-----( SD Stuff )-----*/
// File system object.
SdFat sd;

// Log file.
SdFile file;

// Error messages stored in flash.
#define error(msg) sd.errorHalt(F(msg))

void setup() /*----( SETUP: RUNS ONCE )----*/
{
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
  char fileName[13] = FILE_BASE_NAME "00.csv";

  pinMode(STATUS_LED, OUTPUT); //Set the Status LED pin to output
  digitalWrite(STATUS_LED, HIGH); //Turn On the status LED
if(DEBUG==1)
{
  Serial.begin(9600);//Start Serial communication
}
  lcd.begin(20, 4);        // initialize the lcd for 20 chars 4 lines, turn on backlight

  // ------- Quick 3 blinks of backlight  -------------
  for (int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on

  //-------- Write characters on the display ------------------
  // NOTE: Cursor Position: Lines and Characters start at 0
  lcd.setCursor(0, 0); //Start at character 4 on line 0
  lcd.print("YourDuino SD Logger");
  if (DEBUG == 1)
  {
    // Wait for USB Serial
    while (!Serial)
    {
      SysCall::yield();
    }
  }
  delay(1000);
  //Start Dalas Temperature Library
  sensors.begin();

  // Initialize at the highest speed supported by the board that is
  // not over 50 MHz. Try a lower speed if SPI errors occur.
  if (!sd.begin(chipSelect, SD_SCK_MHZ(4)))
  {
    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");
    }
  }
  if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL))
  {
    error("file.open");
  }
  if (DEBUG == 1)
  {
    // Read any Serial data.
    do
    {
      delay(10);
    }
    while (Serial.available() && Serial.read() >= 0);

    Serial.print(F("Logging to: "));
    Serial.println(fileName);
    Serial.println(F("Type any character to stop"));
  }
  lcd.setCursor(3, 1); //Start at character 4 on line 1
  lcd.print("Loggin to:");
  lcd.setCursor(0, 2);
  lcd.print(fileName);

  // Write data header.
  writeHeader();

  logTime = 0;
  delay(2000);
  digitalWrite(STATUS_LED, LOW); //turn off Status LED
}/*--(end setup )---*/

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
{
  logData(); //Call the Log Data Function
  delay(SAMPLE_INTERVAL * 1000); //wait for log time (in mils)
  logTime = logTime + SAMPLE_INTERVAL; //Set the new logtime

  // Force data to SD and update the directory entry to avoid data loss.
  if (!file.sync() || file.getWriteError())
  {
    error("write error");
  }
  if (DEBUG == 1)
  {
    if (Serial.available()) //Stop Recording data if Serial Monitor detects a character.
    {
      // Close file and stop.
      file.close();
      Serial.println(F("Done"));
      SysCall::halt();
    }
  }
} /* --(end main loop )-- */


/*-----( Functions)-----*/
// Write data header creates the first line of the CSV with the titles of each column
void writeHeader()
{
  file.print(F("Seconds"));
  for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
    file.write(',');
    file.print(F("Temp Sensor:"));
    file.print(i, DEC);
    file.print(F("( F)"));
  }
  file.println();
}


// Log a data record.
void logData()
{
  if (DEBUG == 1)
  {
    Serial.println("New Log");
  }
  digitalWrite(STATUS_LED, HIGH); //Turn on Staus LED

  lcd.clear();// clear the LCD screen
  lcd.print("Time Elapsed:");
  lcd.print(logTime);
  lcd.print("  ");
  lcd.setCursor(0, 1);
  //create a one demensional matrix to hold the data from all the sensors
  uint16_t data[SENSOR_COUNT];

  // Read all sensors to avoid SD write latency between readings.
  sensors.requestTemperatures(); // Send the command to get temperatures
  for (uint8_t i = 0; i < SENSOR_COUNT; i++) //For each sensor put the data into the matrix
  {
    data[i] = sensors.getTempFByIndex(i); //log temperature
    if (DEBUG == 1)
    {
      Serial.print("Temperature Sensor"); //write the data to the Serial Monitor
      Serial.print(i);
      Serial.print(" F:");
      Serial.println(data[i]);
    }
    lcd.print("S"); //print the data on the LCD screen
    lcd.print(i);
    lcd.print(":");
    lcd.print(data[i]);
    lcd.print("  ");
  }
  // Write data to file.  Start with log time in seconds.
  file.print(logTime);

  // Write data to CSV record.
  for (uint8_t i = 0; i < SENSOR_COUNT; i++)
  {
    file.write(',');
    file.print(data[i]);
  }
  file.println();
  digitalWrite(STATUS_LED, LOW);
}
//==============================================================================


/* ( THE END ) */


Assuming this is an Arduino UNO make sure the CS pin is connected to pin 10.

Also, I would rather check if the SD card is ready by using this function:
Code: [Select]
#define pinCS 10
void SD_setup() {
  pinMode(pinCS, OUTPUT);
    // SD Card Initialization
  if (!SD.begin(pinCS)) {
    Serial.println("initialization failed!");
    while(1);
  }
  else{
    Serial.println("Success");
  }
  // Create file if it doesn't exist
  myFile = SD.open("fileName.txt", FILE_WRITE);
  myFile.close();
}

WanderingKing

Solved! I was using an external wall wart that supplied 5 volts, which was just not enough for the SD card and LCD screen. I changed to a 9V wall wart and it works perfectly. 

Go Up