By Jeff Gray, March 2008

Three analog sensors, formatted and sending out of the Arduino. Processing takes them and does a simple display on screen.

Arduino Code

This code will take an analog value, and place it in the xD card, one byte per loop.

/*
 * 4dSystems uDrive xD Datalogger
 * Author: Jeff Gray - 2008
 *
 */

int currentByteLoc = 0;

void setup(){

  Serial.begin(19200);

  // have device warm up
  delay(200);

  // Send U to AutoSet Baudrate
  Serial.print("U");

  // Send @i to initialize the xD card (which should already be in the device)
  Serial.print("@");
  Serial.print("i");
}

void loop(){
  // read in analog
  byte an0 = analogRead(0) / 4;

  // sending @A to tell disk where to write your data
  Serial.print("@");
  Serial.print("A");

  // 4 byte address for the current byte
  Serial.print(currentByteLoc >> 24,BYTE);
  Serial.print(currentByteLoc >> 16,BYTE);
  Serial.print(currentByteLoc >> 8,BYTE);
  Serial.print(currentByteLoc % 256,BYTE);

  // sending @w to tell disk to get ready for a byte
  Serial.print("@");
  Serial.print("w");

  // send out the byte
  Serial.println(an0,BYTE);
  // increment the currentByteLoc so the next go around, new data will be in next sector
  currentByteLoc++;

  // delay a bit, so data slowly gets saved
  delay(250);
}

Processing Code

The processing code looks through the xD card byte by byte and saved to a file, until a full empty sector is found (containing all 255 or 0 bytes)

import processing.serial.*;

int currentByte = 0;
boolean readyToRun = false;
int emptyByteCounter = 0;

Serial port;
PrintWriter output;

void setup() {
  size(200, 200);
  noStroke();
  fill(0);

  // Open the port that the board is connected to and use the same speed (9600 bps)
  port = new Serial(this, Serial.list()[0], 19200);  

  // file to store your incoming data
  output = createWriter("datalogged.txt"); 
}

void keyPressed(){

  // press r to auto set the baud rate and initialize
  if(key == 'r'){
    port.write("U");
    port.write("@i");
  }

  // press s to begin downloading the data until you find
  // an empty sector
  if(key == 's'){
    readyToRun = true;
    getNextByte();
  }
}

void draw() {
  background(255);
  if (0 < port.available()) {
    // read it and store it in val
    int val = port.read();         

    // if its a 6, then its a status message from the disk (ACK)
    if(val == 6 && readyToRun){
      // increment the next byte address to get
      currentByte++;

      // grab it
      getNextByte();
    } else {

      // if data coming in isn't a 6, its our data
      // save it to file and/or println
      output.println(val);
      println(val);

      // check to see if a full sector is empty
      // if so, close the saving app
      if(val == 255 || val == 0){
        emptyByteCounter++;
        if(emptyByteCounter >= 512){
          stop();
        }
      } else {
        emptyByteCounter = 0;
      }
    }
  }
}

void getNextByte(){
  // tells disk what byte to view
  port.write("@A");
  port.write(currentByte >> 24);
  port.write(currentByte >> 16);
  port.write(currentByte >> 8);
  port.write(currentByte % 256);

  // tells disk to grab that byte
  port.write("@r");
}

void stop(){
  // Writes the remaining data to the file
  // and closes it before closing sketch
  output.flush(); 
  output.close();
  println("Data Saved");
  super.stop();
}