Data Logging Help Please

Hi everyone,

I am working on a project that utilizes a TTL camera, SD breakout board, DHT sensor, RTC and a laser/photoresistor. I would like to relate when a picture was taken to the corresponding temperature and humidity. Below is what the the output file currently looks like.

In the "Image" column, when the laser is triggered, I would like to write imagexxx.JPG (where xxx defines the specific image) in the corresponding row only and leave the rest of the column blank until another image is taken.

Any help or advice would be greatly appreciated.

Thanks,

Eric

Date Time rH (%) temp. (*F) Image
2013/10/11 16:54:16 33.00 71.60
2013/10/11 16:54:16 33.00 71.60
2013/10/11 16:54:17 33.00 71.60
2013/10/11 16:54:18 33.00 71.60
2013/10/11 16:54:21 34.00 71.60
2013/10/11 16:54:22 34.00 71.60
2013/10/11 16:54:22 34.00 71.60
2013/10/11 16:54:23 34.00 71.60
2013/10/11 16:54:23 33.00 71.60
2013/10/11 16:54:24 33.00 71.60
2013/10/11 16:54:25 33.00 71.60
2013/10/11 16:54:25 33.00 71.60
2013/10/11 16:54:26 33.00 71.60
2013/10/11 16:54:27 33.00 71.60
2013/10/11 16:54:27 33.00 71.60
2013/10/11 16:54:30 34.00 71.60[/table]

sky,
when you open the file on the SD card, it will be a SEQUENTIAL file. You build the record, write it, wait and then build the next record and write it,,, and so on. There are no rows and collumns (sorry for the spelling), You will have to convert that in post processing the data file in something that understands rows and coll.s (maybe Excel?).

Rough guess, but as I see it, you will have to pre-determine the image number (I do not know how you would get the exact value from the camera subsystem). Maybe a saved counter... when the laser/photo resistor (I'm guessing that is your trigger to take the picture?) indicates a trigger condition, you poll the RTC to get your Time/Date data, stow that, poll the temp/humidity sensor, massage that data and stow the results, then build your output record, and put it to the output file on SD, increment the picture counter, then go do something else (sleep, ponder the meaning of the universe), and wait for the next trigger interrupt.
you will need some type of terminator input (grounding a switch on an input pin maybe) to drive a routine to close the output file when you are ready to post process the data.

Does this help at all? Good luck with your project.

LiquidSky:
In the "Image" column, when the laser is triggered, I would like to write imagexxx.JPG (where xxx defines the specific image) in the corresponding row only and leave the rest of the column blank until another image is taken.

Normally with a sequential text file you would write to the file row by row rather than writing to a specific row and column. If that's what you have in mind then it would be very easy to append a new row to the file containing a new set of values, with one of the values being a filename. If you haven't chosen a file format yet then I would suggest comma separated value (CSV) as a format that is very easy to read and write. It has the advantage of already being recognised by many applications, for example most spreadsheet applications would be able to handle the data you described above if it was written in CSV format.

Thank you very much Splat and Peter for your quick responses.

Yes, the sequential text file is exactly what I would like. I want it to write to the text file row by row and insert the image name in the very last row written when the laser is tripped then continue on leaving the image column blank until the laser is tripped again.

What I tried doing was having my code for writing the above table shown in the void loop section then add the same code within the IF statement within the void loop section hoping that it would add an entire new row including the image name if the laser was tripped. Right now I only have it trying to input "picture" into the image column because I'm not sure how to call/insert the image name there. This did not work or I was making a mistake somewhere.

Below is the void loop section of the code. I'm very new to this so I apologize if the code is sloppy. Most of the code is pieced together from code others have written.

Thanks,

Eric

void loop() {



  delay(50);
  LDRValue = analogRead(LDR); //reads the ldr’s value through LDR which we have set to Analog input 0 “A0?
  Serial.println(LDRValue);   //prints the LDR values to serial monitor
  delay(50); //This is the speed by which LDR sends value to arduino

  // Get the current time in ms:
  long currentTime = millis();

  if (currentTime > lastReadTime + interval) {
    float humidity = readSensor (HUMIDITY);
    float temperature = readSensor(TEMPERATURE);

    // open the file:
    File dataFile = SD.open("datalog.csv", FILE_WRITE);

    // if the file is available, write to it:
    if (dataFile) {
      DateTime now = rtc.now();  
      dataFile.print(now.year(), DEC);
      dataFile.print('/');
      dataFile.print(now.month(), DEC);
      dataFile.print('/');
      dataFile.print(now.day(), DEC);
      dataFile.print(' ');
      dataFile.print("\t");
      dataFile.print(now.hour(), DEC);
      dataFile.print(':');
      dataFile.print(now.minute(), DEC);
      dataFile.print(':');
      dataFile.print(now.second(), DEC);
      dataFile.print(' ');
      dataFile.print("\t");
      dataFile.print(humidity);
      dataFile.print(' ');
      dataFile.print("\t");
      dataFile.println(temperature);
      dataFile.close();
      // print to the serial port too:
      Serial.print(humidity);
      Serial.print("\t");
      Serial.println(temperature);
      lastReadTime = millis();
    }  
    // if the file isn't open, pop up an error:
    else {
      Serial.println("error opening datalog.csv");
    } 
  }

  {  


    if (LDRValue < light_sensitivity) 
    {

      digitalWrite(13, HIGH);
      // When using hardware SPI, the SS pin MUST be set to an
      // output (even if not connected or used).  If left as a
      // floating input w/SPI on, this can cause lockuppage.
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      if(chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
#else
      if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
#endif
#endif

      Serial.begin(9600);
      Serial.println("VC0706 Camera snapshot test");


      // Try to locate the camera
      if (cam.begin()) {
        Serial.println("Camera Found:");
      } 
      else {
        Serial.println("No camera found?");
        return;
      }
      // Print out the camera version information (optional)
      char *reply = cam.getVersion();
      if (reply == 0) {
        Serial.print("Failed to get version");
      } 
      else {
        Serial.println("-----------------");
        Serial.print(reply);
        Serial.println("-----------------");
      }

      // Set the picture size - you can choose one of 640x480, 320x240 or 160x120 
      // Remember that bigger pictures take longer to transmit!

      //cam.setImageSize(VC0706_640x480);        // biggest
      //cam.setImageSize(VC0706_320x240);        // medium
      cam.setImageSize(VC0706_160x120);          // small

      // You can read the size back from the camera (optional, but maybe useful?)
      uint8_t imgsize = cam.getImageSize();
      Serial.print("Image size: ");
      if (imgsize == VC0706_640x480) Serial.println("640x480");
      if (imgsize == VC0706_320x240) Serial.println("320x240");
      if (imgsize == VC0706_160x120) Serial.println("160x120");

      Serial.println("Snap in 3 secs...");
      delay(1);

      if (! cam.takePicture()) 
        Serial.println("Failed to snap!");
      else 
        Serial.println("Picture taken!");

      // Create an image with the name IMAGExx.JPG
      char filename[13];
      strcpy(filename, "IMAGE000.JPG");
      for (int i = 0; i < 1000; i++) {
        filename[5] = '0' + i/100;
        filename[6] = '0' + i/10;
        filename[7] = '0' + i%10;
        //create if does not exist, do not open existing, write, sync after write
        if (! SD.exists(filename)) {
          break;
        }
      } 

      // Open the file for writing
      File imgFile = SD.open(filename, FILE_WRITE);

      // Get the size of the image (frame) taken  
      uint16_t jpglen = cam.frameLength();
      Serial.print("Storing ");
      Serial.print(jpglen, DEC);
      Serial.print(" byte image.");

      int32_t time = millis();
      pinMode(53, OUTPUT);
      // Read all the data up to # bytes!
      byte wCount = 0; // For counting # of writes
      while (jpglen > 0) {
        // read 32 bytes at a time;
        uint8_t *buffer;
        uint8_t bytesToRead = min(32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
        buffer = cam.readPicture(bytesToRead);
        imgFile.write(buffer, bytesToRead);
        if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
          Serial.print('.');
          wCount = 0;
        }
        //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
        jpglen -= bytesToRead;
      }
      imgFile.close();

      time = millis() - time;
      Serial.println("done!");
      Serial.print(time); 
      Serial.println(" ms elapsed");

      if (currentTime > lastReadTime + interval) {
        float humidity = readSensor (HUMIDITY);
        float temperature = readSensor(TEMPERATURE);

        File dataFile = SD.open("datalog.csv", FILE_WRITE);

        DateTime now = rtc.now(); 
        dataFile.print(now.year(), DEC);
        dataFile.print('/');
        dataFile.print(now.month(), DEC);
        dataFile.print('/');
        dataFile.print(now.day(), DEC);
        dataFile.print(' ');
        dataFile.print("\t");
        dataFile.print(now.hour(), DEC);
        dataFile.print(':');
        dataFile.print(now.minute(), DEC);
        dataFile.print(':');
        dataFile.print(now.second(), DEC);
        dataFile.print(' ');
        dataFile.print("\t");
        dataFile.print(humidity);
        dataFile.print(' ');
        dataFile.print("\t");
        dataFile.println(temperature);
        dataFile.close();
        dataFile.print(' ');
        dataFile.print("\t");
        dataFile.println("picture");
        dataFile.close();

      }

    }

    if (LDRValue >= light_sensitivity)
    {
      digitalWrite(13, LOW);
    }

  }

}