Gabriella Levine

ongoing and past work

logging solar data

Genevieve and I now decided to log data from the sun over the course of the month – most likely, voltage, and light level. We will use both a photocell and two large solar panels (during the day one gave about 20 V). (And of course, we will power the arduino sustainably!)

We are using a RTC (real time clock from adafruit), a micro sd card data shield, and the following code (derived from Tom Igoe’s github)
Here is the circuit:

With a 9 V battery plugged in for a few minutes, this is the result (reading voltage once per minute):

#include <EEPROM.h>

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"
#include <SD.h>

const int chipSelect = 8;
const int LOCATION_FILE_NUMBER_LSB = 0x00;
const int LOCATION_FILE_NUMBER_MSB = 0x01;

RTC_DS1307 RTC;
File dataFile;

void setup () {
 // initialize serial communications:
 Serial.begin(9600);

 // set up pins A2 and A3 as the power and ground for the real time clock:
 pinMode(A2, OUTPUT);
 pinMode(A3, OUTPUT);
 // A2 is the ground, A3 is the power:
 digitalWrite(A2, LOW);
 digitalWrite(A3, HIGH);

 Serial.print("Initializing SD card...");
 // make sure that the default chip select pin is set to
 // output, even if you don't use it:
 pinMode(10, OUTPUT);

 // see if the card is present and can be initialized:
 if (!SD.begin(chipSelect)) {
   Serial.println("Card failed, or not present");
   // don't do anything more:
   return;
 }
 Serial.println("card initialized.");



 // start the wire and RTC libraries:
 Wire.begin();
 RTC.begin();

 if (! RTC.isrunning()) {
   Serial.println("RTC is NOT running!");
   // following line sets the RTC to the date & time this sketch was compiled
   RTC.adjust(DateTime(__DATE__, __TIME__));
 }

 Serial.println("RTC is set");

 newlog();

}

void loop () {


 // if the file is available, write to it:
 if (dataFile) {
   DateTime now = RTC.now();

   dataFile.print(now.month(), DEC);
   dataFile.print('/');
   dataFile.print(now.day(), DEC);
   dataFile.print('/');
   dataFile.print(now.year(), DEC);
   dataFile.print(',');
   dataFile.print(now.hour(), DEC);
   dataFile.print(':');
   dataFile.print(now.minute(), DEC);
   dataFile.print(':');
   dataFile.print(now.second(), DEC);
   dataFile.print(",");
   // calculate the voltage on A1:
   float voltage = 5 * analogRead(A0) / 1024.0;
   dataFile.print(voltage);
   dataFile.println();

   dataFile.flush();
 }
 // delay for a minute:
 delay(60000);
 // delay for three seconds:
 //delay(3000);
}

void newlog(void)
{
 uint8_t msb, lsb;
 uint16_t new_file_number;

 //Combine two 8-bit EEPROM spots into one 16-bit number
 lsb = EEPROM.read(LOCATION_FILE_NUMBER_LSB);
 msb = EEPROM.read(LOCATION_FILE_NUMBER_MSB);
 new_file_number = msb;
 new_file_number = new_file_number << 8;
 new_file_number |= lsb;

 //If both EEPROM spots are 255 (0xFF), that means they are un-initialized (first time OpenLog has been turned on)
 //Let's init them both to 0
 if((lsb == 255) && (msb == 255))
 {
   new_file_number = 0; //By default, unit will start at file number zero
   EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0x00);
   EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0x00);
 }

 //The above code looks like it will forever loop if we ever create 65535 logs
 //Let's quit if we ever get to 65534
 //65534 logs is quite possible if you have a system with lots of power on/off cycles
 if(new_file_number == 65534)
 {
   //Gracefully drop out to command prompt with some error
   PgmPrint("!Too many logs:1!");
   return; //Bail!
 }

 //If we made it this far, everything looks good - let's start testing to see if our file number is the next available

 //Search for next available log spot
 char fileName[] = "LOG00000.TXT";
 while(1)
 {
   new_file_number++;
   if(new_file_number > 65533) //There is a max of 65534 logs
   {
     PgmPrint("!Too many logs:2!");
     return;
   }

   sprintf(fileName, "LOG%05d.TXT", new_file_number); //Splice the new file number into this file name

   //Try to open file, if fail (file doesn't exist), then break
   if (!SD.exists(fileName)) break;
 }
Serial.print(fileName);

 //Record new_file number to EEPROM
 lsb = (uint8_t)(new_file_number & 0x00FF);
 msb = (uint8_t)((new_file_number & 0xFF00) >> 8);

 EEPROM.write(LOCATION_FILE_NUMBER_LSB, lsb); // LSB

 if (EEPROM.read(LOCATION_FILE_NUMBER_MSB) != msb)
   EEPROM.write(LOCATION_FILE_NUMBER_MSB, msb); // MSB


  // open the file. note that only one file can be open at a time,
 // so you have to close this one before opening another.
 dataFile = SD.open(fileName, FILE_WRITE);
}

Leave a Reply