Using the 4D uDRIVE with Arduino

31 Jan 2010

Arduino and 4D uDrive

Below is an Arduino sketch that uses the 4D Systems' Microdrive (uDRIVE-uSD-G1) to write the values of three sensor readings to a text file stored on the microSD card within the Microdrive. This code is a work in progress but should work as described and can be modified to suit your needs.

Download the source code.

/*
 uDRIVE-uSD-G1 Embedded "DOS micro-Drive" Module
 by Rory Nugent
 last updated Feb. 28th, 2010

 This code demonstrates how to use the Arduino to write / append three analog sensor values
 to a text file located on the microSD card within the uDrive.

 Arduino 5V -> Microdrive VCC
 Arduino GND -> Microdrive GND
 Arduino RX -> Microdrive TX
 Arduino TX -> Microdrive RX

 */

#define ledPin 13

void setup()
{
  Serial.begin(9600);          // set the baud rate to 9600 bps
  pinMode(ledPin, OUTPUT);

  initialize();                // initialize the uDrive, i.e. automatic baud detection
  digitalWrite(ledPin, HIGH);
  delay(500);
}

void loop()
{
  int analogValues[3];
  int filesize = 6;

  for(int i = 0; i < 3; i++)
  {
    analogValues[i] = analogRead(i);  // read an analog value

    // determine the required amount of file space per read / write
    if(analogValues[i] >= 1000)
      filesize += 3;
    else if(analogValues[i] >= 100)
      filesize += 2;
    else if(analogValues[i] >= 10)
      filesize += 1;
  }

  openFile("log.txt", true, filesize);  // open "log.txt" and append X bytes of data

  // comma seperated values with each line ending in a new line feed, e.g. 123,456,789\n
  Serial.print(analogValues[0], DEC);
  Serial.print(",");
  Serial.print(analogValues[1], DEC);
  Serial.print(",");
  Serial.print(analogValues[2], DEC);
  Serial.println();

  wait_for_ack(50);  // wait for an ACK

  delay(250);        // pause between readings / storing
}

void initialize()
{
  boolean initialized = false;

  // continue to sending a 'U' for baud detection until we receive an ACK
  while(!initialized)
  {
    Serial.print('U');               // send a 'U'
    initialized = wait_for_ack(50);  // if we receive an ACK, finish initialization, otherwise continue
  }
}

byte wait_for_ack(int waitTime)
{
  byte response = 0;
  unsigned long beganWait = millis();  // save the time we began waiting for an ACK

  // wait until we either receive an ACK / NACK or we timeout
  do
  {
    response = Serial.read();
  } while(response != 0x06 && response != 0x15 && millis() - beganWait < waitTime);

  Serial.flush();
  if(response == 0x06)  // ACK
  {
    digitalWrite(ledPin, HIGH);
    return 1;
  }
  else  // NACK or no response
  {
    digitalWrite(ledPin, LOW);
    return 0;
  }
}

byte openFile(char* filename, boolean append, int filesize)
{
  Serial.print('@');            // ext. command header byte
  Serial.print('t');            // write command header byte

  if(append)
    Serial.print(0x80, BYTE);   // append
  else
    Serial.print(0x00, BYTE);   // don't append

  Serial.print(filename);       // file name, "log.txt"
  Serial.print(0, BYTE);        // file name terminator, null

  Serial.print(filesize >> 24, BYTE);  // file size, 4th byte, MSB
  Serial.print(filesize >> 16, BYTE);  // file size, 3rd byte
  Serial.print(filesize >> 8, BYTE);   // file size, 2nd byte
  Serial.print(filesize, BYTE);        // file size, 1st byte, LSB

  byte msg = wait_for_ack(50);   // wait for an ACK
  return(msg);                   // return ACK / NACK response
}