Is there something erasing my setup header (ID, Voltage, Current) in the CSV file? No biggy with a couple data points, but helpful when you have more. Serial monitor confirms it wrote it, but when I view the file its not there...
//Jeremey Blum - Tutorial 11
//http://www.jeremyblum.com/2011/04/05/tutorial-11-for-arduino-sd-cards-and-datalogging/
//iteadstudio SDCard Shield v1.0
#include <SD.h>
//SPI Settings
//MOSI, MISO, SCLK Set by default
int CS_pin = 10;
//int pow_pin = 8;
//sensor analog inputs
int voltage_pin = 0;
int current_pin = 1;
int sensorCal = 531; //531 manual input raw input at zero amps for Hall Sensor
int sensorSpec = 40; //Hall Sensor, 40 mV per Amp
float refresh_rate = 0.0; //Datalogger Refresh Rate
long id = 1; //Store the id# of our reading
void setup()
{
Serial.begin(9600);
Serial.println("Initializing Card");
//CS Pin is an output
pinMode(CS_pin, OUTPUT);
//Card will Draw Power from Pin 8, so set it high
//pinMode(pow_pin, OUTPUT);
//digitalWrite(pow_pin, HIGH);
//Check if card ready
if(!SD.begin(CS_pin))
{
Serial.println("Card Failed");
return;
}
Serial.println("Card Ready");
//Read the configuration information (COMMANDS.txt)
File commandFile = SD.open("COMMANDS.txt");
if (commandFile)
{
Serial.println("Reading Command File");
float decade = pow(10, (commandFile.available() - 1));
while(commandFile.available())
{
float temp = (commandFile.read() - '0');
refresh_rate = temp*decade+refresh_rate;
decade = decade/10;
}
Serial.print("Refresh Rate = ");
Serial.print(refresh_rate);
Serial.println("ms");
}
else
{
Serial.println("Could not read commande file.");
return;
}
//Write Log.csv File Header
File logFile = SD.open("LOG.csv", FILE_WRITE);
if (logFile)
{
logFile.println(", ,"); //Just a leading blank line, incase there was previous data
String header = "ID, Voltage, Current";
logFile.println(header);
logFile.close();
Serial.println(header);
}
else
{
Serial.println("Couldn't open log file");
return;
}
}
void loop()
{
//read voltage divider circuit output r1=10k(really 9.88k) r2=1k
int voltage_grab = analogRead(voltage_pin);
float voltRatio = voltage_grab / 1023.00; //find ratio of reading to convert to v where 1023=5v
float voltFloat = voltRatio * 5.00 * 11.00 * 100.00; //5v * voltage divider measured ratio 11 * mV conversion 100
int voltage_reading = voltFloat; //convert float reading to integer for the dataString
//convert hall amp sensor reading to actual current
int ampRead = analogRead(current_pin); //Read hall sensor output
ampRead = constrain(ampRead, sensorCal, 1023); //constrain to manual sensor calibration
int current_reading = ampRead - sensorCal; //Declare new int for conversion
current_reading = (current_reading * 4.9) / sensorSpec; //4.9 * Analog signal =~ mV, divide by example: "ACS756 spec: 40mV/1A"
//int hallMv = analogRead(hallIn) * 4.9; //debugging to view mV
String dataString = String(id) + ", " + String(voltage_reading) + ", " + String(current_reading);
//Open a file to write to
//Only one file can be open at a time
File logFile = SD.open("LOG.csv", FILE_WRITE);
if(logFile)
{
logFile.println(dataString);
logFile.close();
Serial.println(dataString);
}
else
{
Serial.println("Couldn't access file");
}
//increment ID #
id++;
delay(refresh_rate);
}
I downloaded the Blum tutorial code and compared it to your posted code here is one difference I found, look for the <<<<<<<<<<<<<<<<<.
//Read the Configuration information (COMMANDS.txt)
File commandFile = SD.open("COMMANDS.txt");
if (commandFile)
{
Serial.println("Reading Command File");
float decade = pow(10, (commandFile.available() - 1));
while(commandFile.available())
{
float temp = (commandFile.read() - '0');
refresh_rate = temp*decade+refresh_rate;
decade = decade/10;
}
Serial.print("Refresh Rate = ");
Serial.print(refresh_rate);
Serial.println("ms");
commandFile.close(); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< You are missing this line in your code at this same spot.
Now I need to figure out how to increase resolution, I have no delay and can only get about 3 data points per second (float math?). This gets me started so I am happy.
//Based on Jeremey Blum's - Tutorial 11
//http://www.jeremyblum.com/2011/04/05/tutorial-11-for-arduino-sd-cards-and-datalogging/
//Voltage and Amp conversion code created by Steelmesh
//Hardware: duel with a iteadstudio SDCard Shield v1.0
#include <SD.h>
//SPI Settings
//MOSI, MISO, SCLK Set by default
int CS_pin = 10;
//int pow_pin = 8;
//sensor analog inputs
int voltage_pin = 0;
int current_pin = 1;
int sensorCal = 531; //531 manual input raw input at zero amps for Hall Sensor
int sensorSpec = 40; //Hall Sensor, 40 mV per Amp
long id = 1; //Store the id# of our reading
unsigned long timestamp;
void setup()
{
Serial.begin(9600);
Serial.println("Initializing Card");
//CS Pin is an output
pinMode(CS_pin, OUTPUT);
//Card will Draw Power from Pin 8, so set it high
//pinMode(pow_pin, OUTPUT);
//digitalWrite(pow_pin, HIGH);
//Check if card ready
if(!SD.begin(CS_pin))
{
Serial.println("Card Failed");
return;
}
Serial.println("Card Ready");
//Write Log.csv File Header
File logFile = SD.open("LOG.csv", FILE_WRITE);
if (logFile)
{
logFile.println(", , ,"); //Just a leading blank line, incase there was previous data
logFile.println("ID, Time (ms), Voltage (mV), Current");
logFile.close();
}
else
{
Serial.println("Couldn't open log file");
return;
}
}
void loop()
{
//Grab sensor readings and "immediately" timestamp it
int voltage_grab = analogRead(voltage_pin); //read voltage divider circuit output r1=10k(really 9.88k) r2=1k
int ampRead = analogRead(current_pin); //Read hall sensor output
timestamp = millis();
//convert voltage divider reading to mV
float voltRatio = voltage_grab / 1023.00; //find ratio of reading to convert to v where 1023=5v
float voltFloat = voltRatio * 5.00 * 11.00 * 100.00; //5v * voltage divider actual ratio 11 * mV conversion 100
int voltage_reading = voltFloat; //convert float reading to integer for the dataString
//convert hall amp sensor reading to amps
ampRead = constrain(ampRead, sensorCal, 1023); //constrain to manual sensor calibration
int current_reading = ampRead - sensorCal; //Declare new int for conversion
current_reading = (current_reading * 4.9) / sensorSpec; //4.9 * Analog signal =~ mV, divide by example: "ACS756 spec: 40mV/1A"
//int hallMv = analogRead(hallIn) * 4.9; //debugging to view mV
String dataString = String(id) + ", " + String(timestamp) + ", " + String(voltage_reading) + ", " + String(current_reading);
//Open a file to write to
//Only one file can be open at a time
File logFile = SD.open("LOG.csv", FILE_WRITE);
if(logFile)
{
logFile.println(dataString);
logFile.close();
Serial.println(dataString);
}
else
{
Serial.println("Couldn't access file");
}
//increment ID #
id++;
//delay(refresh_rate);
}
int voltage_grab = analogRead(voltage_pin); //read voltage divider circuit output r1=10k(really 9.88k) r2=1k
int ampRead = analogRead(current_pin); //Read hall sensor output
voltage_grab and ampRead as outputs from the same function (on different pins, of course). I don't get it. Consistency in naming variables makes your life easier.
A colossal waste of resources. The File::println() function could be replaced with several calls to File::print() and one call to File::println() to print the individual variables, with no need to have the String class make the same unformatted conversion to a string. Concatenating is most certainly not required. After this line of code, several calls to the String class' destructor are going to be made, any one of which, when calling the defective free() function, can corrupt your memory.
Avoid that potential problem by ditching the String class.
I have no delay and can only get about 3 data points per second (float math?).
No. It is more likely that opening and closing the file for each record added is what is slowing you down. That, and all the constructor and destructor calls and copying memory locations that the String class has to do.