Parallax Data Logger interfacing via UART at 2Mbaud

I needed to log data for a project I am working on and the FAT overhead for SD card writes was not going to work. I needed something that I could log without 40ms+ delays. So I decided to go with this:

http://www.parallax.com/StoreSearchResults/tabid/768/List/0/SortField/4/ProductID/434/Default.aspx?txtSearch=data+logger

I was going to interface with it over SPI, but it uses some crazy non compliant to the standard SPI protocol. It specifies CS to go high and a 13 bit data frame. So it was UART time. The datasheet for the device said that it can run at 3Mbaud. I was able to interface with the device at 3Mbaud via an FTDI cable. To solve the CTS / RTS problem I connected the RTS pin on the logger (#2) to +5V and the CTS pin (#6) to ground. I used this code to run the interface at 2Mbaud. The only strange thing is after changing the baud rate the first time I send the check if online command (0x0D ie carriage return) it responds with BC. I send it the command again and it responds with the prompt. But since I couldn't find any code floating around the internet to interface with this thing here is my code:

//Serial.write chokes on a zero for some reason
const uint8_t hexZero = 0x00;

byte inByte;

void setup(){
  delay(5000);//wait for the logger to boot
  //the logger can run at 3Mbaud but I was only able to interface at 2Mbaud
  Serial2.begin(2000000);
  //switch to short commands
  Serial1.begin(9600);
  Serial1.write(0x10);
  Serial1.write(0x0D);
  Serial1.flush();
  //change baud rate to 2Mbaud
  Serial1.write(0x14);
  Serial1.write(0x20);
  Serial1.write(0x01);
  Serial1.write(hexZero);
  //Serial1.write(0x00);
  //sketch_jun13b:13: error: call of overloaded 'write(int)' is ambiguous ???
  //makes no sense to me whatsoever 
  Serial1.write(hexZero);
  Serial1.write(0x0D);
  Serial1.flush();
  Serial1.end();
  //wait then restart the serial port
  delay(500);
  Serial1.begin(2000000);
}

void loop(){
  while (Serial2.available() > 0){
    inByte = Serial2.read();
    Serial1.write(inByte);
  }
  while (Serial1.available() > 0){
    inByte = Serial1.read();
    Serial2.write(inByte);
  }
}

Hope this helps someone. This guy never got an answer:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247707277

Here is some code for basic data logging. It isn't very robust, but it works. Hopes this helps anyone who wants to use this little device. Using this thing brings data storage times down into the 5ms and below range. This code could use a lot of improvements, but this is a nice start.

#include <PString.h>


#define POTPIN 2
#define SWITCHPIN 3

//Serial.write chokes on a zero for some reason
const uint8_t hexZero = 0x00;

char inByte;

char parseBuffer[30];
char outBuffer[100];

PString parseString(parseBuffer,30);
PString outString(outBuffer,100);

int i;


union{
  unsigned long outBytes;
  byte outBytesHex[4];
}
outBytesUnion;

int potValue = 5;

unsigned long timeStampStart = 0;
unsigned long timeStampEnd = 0;

boolean switchPinPrevious = 0;

long writeTimer = 0;
void setup(){

  pinMode(SWITCHPIN,INPUT);
  parseString.begin();
  delay(5000);//wait for the logger to boot
  //the logger can run at 3Mbaud but I was only able to interface at 2Mbaud
  Serial2.begin(2000000);
  //switch to short commands
  Serial1.begin(9600);
  Serial1.write(0x10);
  Serial1.write(0x0D);
  Serial1.flush();
  //change baud rate to 2Mbaud
  Serial1.write(0x14);
  Serial1.write(0x20);
  Serial1.write(0x01);
  Serial1.write(hexZero);

  Serial1.write(hexZero);
  Serial1.write(0x0D);
  Serial1.flush();
  Serial1.end();
  //wait then restart the serial port
  delay(500);
  Serial1.begin(2000000);
  delay(1000);



  writeTimer = millis();
}

void loop(){

  if(millis() - writeTimer >=10){
    timeStampStart = millis();
    potValue = analogRead(POTPIN);
    if(digitalRead(SWITCHPIN) == HIGH){
      if (switchPinPrevious == 0){
        OpenFile();
      }
      LogData();
      switchPinPrevious = 1;
    }
    else{
      if (switchPinPrevious == 1){
        CloseFile();
        switchPinPrevious = 0;
      }
    }
    timeStampEnd = millis();
    writeTimer = millis();
  }
}
void LogData(){

  Serial1.write(0x0D);

  parseString.begin();
  while(Serial1.available() < 1 ){
  }
  while(Serial1.available() > 0){
    inByte = Serial1.read();
    parseString += inByte;
  }

  if(strncmp(parseBuffer,">\r",2) != 0){

    Serial2.println("failed prompt check log");
    Serial2.println(parseString);
    delay(1000);
    Serial1.flush();
    LogData();
  }

  outString.begin();
  outString+=timeStampStart;
  outString+=",";
  outString+=timeStampEnd;
  outString+=",";
  outString+=potValue;
  outString+="\r\n";
  outBytesUnion.outBytes = outString.length();


  Serial1.write(0x08);
  Serial1.write(0x20);
  Serial1.write(outBytesUnion.outBytesHex[3]);
  Serial1.write(outBytesUnion.outBytesHex[2]);
  Serial1.write(outBytesUnion.outBytesHex[1]);
  Serial1.write(outBytesUnion.outBytesHex[0]);
  Serial1.write(0x0D);
  Serial1.write(outString);
  Serial1.write(0x0D);

  parseString.begin();
  while(Serial1.available() < 1 ){
  }
  while(Serial1.available() > 0 ){
    inByte = Serial1.read();
    parseString += inByte;
  }
  if(strncmp(parseBuffer,"BC",2) == 0){  

    Serial2.println("bad command log");
    Serial2.println(parseString);
    delay(1000);
    Serial1.flush();
    LogData();
  }

}

void OpenFile(){

  Serial1.write(0x0D);

  parseString.begin();
  while(Serial1.available() < 1 ){
  }
  while(Serial1.available() > 0){
    inByte = Serial1.read();
    parseString += inByte;
  }

  if(strncmp(parseBuffer,">\r",2) != 0){
    Serial2.println("no prompt open");
    Serial2.println(parseString);
    delay(1000);
    Serial1.flush();
    OpenFile();
  }


  Serial1.write(0x09);
  Serial1.write(0x20);
  Serial1.write("log.csv");
  Serial1.write(0x0D);
  parseString.begin();
  while(Serial1.available() < 1 ){

  }
  while(Serial1.available() > 0 ){
    inByte = Serial1.read();
    parseString += inByte; 
  }

  if(strncmp(parseBuffer,"BC",2) == 0){  
    Serial2.println("bad command open");
    Serial2.println(parseString);
    delay(1000);
    Serial1.flush();
    OpenFile();
  }

  Serial1.write(0x01);
  Serial1.write(0x0D);

  parseString.begin();
  while(Serial1.available() < 6 ){
  }
  while(Serial1.available() > 0){
    inByte = Serial1.read();
    parseString += inByte;
  }

  if(strncmp(parseBuffer,"\rLOG.CSV\r>\r",11) != 0){

    Serial2.println("did not return file name");
    Serial2.println(parseString);
    delay(1000);
    Serial1.flush();
    OpenFile();
  }
} 
void CloseFile(){

  Serial1.write(0x0D);

  parseString.begin();
  while(Serial1.available() < 1 ){
  }
  while(Serial1.available() > 0){
    inByte = Serial1.read();
    parseString += inByte;
  }

  if(strncmp(parseBuffer,">\r",2) != 0){

    Serial2.println(parseString);
    Serial2.println("no prompt  close");
    delay(1000);
    Serial1.flush();
    CloseFile();
  }


  Serial1.write(0x0A);
  Serial1.write(0x20);
  Serial1.write("log.csv");
  Serial1.write(0x0D);
  parseString.begin();
  while(Serial1.available() < 1 ){
  }
  while(Serial1.available() > 0 ){
    inByte = Serial1.read();
    parseString += inByte;
  }


  if(strncmp(parseBuffer,"BC",2) == 0){  
    Serial2.println("bad command");
    Serial2.println(parseString);
    delay(1000);
    Serial1.flush();
    CloseFile();
  }
}