Hello all,
I am looking to do a couple of things with the Arduino and was wondering if my ideas were at all possible? Any help would be greatly appreciated.
First off, I am using the Arduino Uno with the Wireless + SD shield and an XBee Pro hooked onto that shield. I am also using a 4GB microSD card that has been formatted in Windows with the FAT file system. The project that I am creating is a Solar Radiation Monitor that will have a shorted solar cell as an input on Analog Pin A0 which has an input voltage range of 0mV-256.7mV. I have also changed the reference voltage to INTERNAL for a reference of 1.1V to try and get a higher resolution result. End goal would be to have the Arduino take a measurement reading from the attached Solar Cell every minute, convert the reading to a Solar Radiation value (in W/m^2), then save the data to the SD card in the file format of a .csv file and after 3/6/12 months, I could pull the .csv file off of the SD card.
There are a couple of stumbling blocks that I have run into so far that I don't quite know how to solve just yet and was wondering if anyone could supply some guidance.
My first issue is that I wanted to try to take 10 readings inside of that one minute time frame (roughly every 8 secs-ish) and average out the result to get a more precise reading each minute. Below is the code that I have worked out to do this, but for some reason I am getting an error of 'int' is not a template upon compilation at the second for loop. Is it impossible to nest loops (or specifically for loops) in the Arduino architecture?
for (int counter = 0; counter < 100; counter++)
{
//Obtain Solar Sensor Value
for (int i = 0; int < 10; int++)
{
delay (50);
radiationReading += analogRead(cellPin);
delay (50);
}
radiationReading = radiationReading / 10;
float trueRadiation = radiationReading * 5.31218;
wholeNumRad = int (trueRadiation);
trueRadiation -= wholeNumRad;
trueRadiation *= 100;
decimalNumRad = int (trueRadiation);
String dataString = String(readingNumber) + ", " + String(wholeNumRad) + "." + String(decimalNumRad);
File dataFile = SD.open("datalog.txt", FILE_WRITE);
//If the file is available, write to it
if (dataFile)
{
dataFile.println(dataString);
dataFile.close();
//Output to the serial port as well
Serial.println(dataString);
}
//Error for unsuccessful file opening
else
{
Serial.println("Error Opening datalog.txt");
}
readingNumber++;
delay (5);
}
I know the delays are different than my specified times, but I was just testing to see if it worked and I wanted it to go faster.
In the above example, the user would be connected to the Arduino through an XBee on their computer and send a command through Serial to start data acquisition for a pre-described time frame (in this case 100 loops). What I would like to accomplish would be to send the command to start recording data and then being able to leave it infinitely recording for the user's desired time frame and then have the user stop the loop with a Serial command or keyboard keypress (ESC or similar "kill" command or something). Is something like this possible at all?
My last problem is that I would like to retrieve the .csv file from the SD card at anytime through the XBee connection. Is there a way to retrieve a file from the Arduino SD card without pulling out the SD card itself and transferring the data yourself?
Essentially I want the work flow to go like this:
1.) Power up Arduino + XBee outside (on roof or similar).
2.) Have user with computer connect to Arduino + XBee with FTDI connected XBee on their computer.
3.) User sends a "1" to start data acquisition indefinitely.
4.) Wait 3/6/12 months.
5.) User connects to Arduino again and sends an "ESC" keypress to kill data acquisition.
6.) User does X (presses "2" or runs a script or something) and the .csv with all of the data is transferred to the user's computer.
7.) Repeat from 3 or Done.
Below is the total code that I have so far. Thank you so much for your help and effort.
-Billy-
#include <SD.h> //SD card Library
#include <Wire.h> //I2C Library
//Solar Sensor Pin Variables
int cellPin = 0;
int radiationReading;
int wholeNumRad = 0;
int decimalNumRad = 0;
long readingNumber = 1;
//SD card Chip Select Constant
const int chipSelect = 4;
//User Input Value
int userInput = 0;
/*************************************************************************/
void dataLogging()
{
Wire.begin();
Serial.begin(9600);
Serial.print("Initializing SD card...");
//Pin 10 must be set to OUTPUT even if it goes unused
pinMode(10, OUTPUT);
//Check to see if SD card can be seen
if (SD.begin(chipSelect))
{
Serial.println("FAILED!");
Serial.println("Card failed or not present!");
return;
}
Serial.println("done!");
Serial.println("SD card has been initialized.");
//Write Log File Header
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile)
{
//Lead with a blank line since there could be previous data
dataFile.println(", , , ,");
String header = "ID, Radiation";
dataFile.println(header);
dataFile.close();
Serial.println(header);
}
else
{
Serial.println("Couldn't open log file.");
}
//Record the Solar Radiation for 10 minutes
for (int counter = 0; counter < 100; counter++)
{
//Obtain Solar Sensor Value
for (int i = 0; int < 10; int++)
{
delay (50);
radiationReading += analogRead(cellPin);
delay (50);
}
radiationReading = radiationReading / 10;
float trueRadiation = radiationReading * 5.31218;
wholeNumRad = int (trueRadiation);
trueRadiation -= wholeNumRad;
trueRadiation *= 100;
decimalNumRad = int (trueRadiation);
String dataString = String(readingNumber) + ", " + String(wholeNumRad) + "." + String(decimalNumRad);
File dataFile = SD.open("datalog.txt", FILE_WRITE);
//If the file is available, write to it
if (dataFile)
{
dataFile.println(dataString);
dataFile.close();
//Output to the serial port as well
Serial.println(dataString);
}
//Error for unsuccessful file opening
else
{
Serial.println("Error Opening datalog.txt");
}
readingNumber++;
delay (5);
}
}
/*************************************************************************/
void dumpFile()
{
Serial.print("Initializing SD card...");
//Pin 10 must be set to OUTPUT even if it goes unused
pinMode(10, OUTPUT);
//Check to see if SD card can be seen
if (SD.begin(chipSelect))
{
Serial.println("FAILED!");
Serial.println("Card failed or not present!");
return;
}
Serial.println("done!");
Serial.println("SD card has been initialized.");
//Open the file
File dataFile = SD.open("datalog.txt");
//Check for the file and, if available, print to serial
if (dataFile)
{
while (dataFile.available())
{
Serial.write(dataFile.read());
}
dataFile.close();
}
//Error for unsuccessful file opening
else
{
Serial.println("Error opening datalog.txt");
}
}
/*************************************************************************/
void closeFile()
{
pinMode(10, OUTPUT);
File dataFile = SD.open("datalog.txt");
dataFile.close();
}
/*************************************************************************/
void deleteFile()
{
Serial.print("Removing datalog.txt...");
SD.remove("datalog.txt");
if (SD.exists("datalog.txt"))
{
Serial.println("FAILED!");
Serial.println("datalog.txt was not deleted.");
}
else
{
Serial.println("done!");
Serial.println("datalog.txt has been deleted.");
readingNumber = 1;
}
}
/*************************************************************************/
int getSerialNumber() // user input
{
int result = 0;
int q = 0;
while (Serial.available()==0)
{
//Wait until something comes into the serial buffer
}
while (Serial.available()>0)
{
while (Serial.available()>0)
{
//Move the previous digit to the next column on the left, e.g. 1 becomes 10 while there is data in the buffer
result *= 10;
//Read the next number in the buffer, subtract 48 to convert to the actual number
q = Serial.read() - 48;
result += q;
}
delay(5); // the processor needs a moment to process
}
return result;
}
/*************************************************************************/
void setup(void)
{
Serial.begin(9600);
analogReference(INTERNAL);
SD.begin(chipSelect);
}
void loop(void)
{
userInput = getSerialNumber();
if (userInput == 1)
{
dataLogging();
}
if (userInput == 2)
{
dumpFile();
}
if (userInput == 3)
{
deleteFile();
}
}