Shop OBEX P1 Docs P2 Docs Learn Events
writing to sd card — Parallax Forums

writing to sd card

claym53claym53 Posts: 36
edited 2007-03-07 15:29 in General Discussion
I have a program that I'm working on the javelin with that uses gps. What I want to be able to do is record the gps coordinates to an sd card, so I can put it in my computer and then make use of that data.

So I need to know what hardware I would need to write to a memory card and then hopefully a few java examples if someone could.

Thanks...
«1

Comments

  • yvesByvesB Posts: 22
    edited 2007-01-17 00:16
    This should do what you want

    http://www.sparkfun.com/commerce/product_info.php?products_id=7955

    use the UART VP and away you go.
  • Brian CarpenterBrian Carpenter Posts: 728
    edited 2007-01-18 03:42
    Or you could use this stellar piece of equipment.
    www.SDdatalogger.com

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    It's Only A Stupid Question If You Have Not Googled It First!!
  • yvesByvesB Posts: 22
    edited 2007-01-18 14:21
    Depending on what claym53's GPS data log application requires, max 19200 baud rate may not cut it along with the 32MB space limitation. $70 is not cheap either but hey, the more options the better I guess.
  • claym53claym53 Posts: 36
    edited 2007-01-19 18:24
    I ordered the piece that yvesB·recommended along with a 512MD SD card and I plan on using the UART VP like he said.

    I'm not sure about the code though. So if someone could write an example of reading and writing data to the card, it would be greatly appreciated.
  • yvesByvesB Posts: 22
    edited 2007-01-20 17:33
    Follow command table:

    http://chipdos.com/library/CD17B10_User_Guide_0v1.pdf


    Code may look something like this:

    //Program Listing - Logging bytes using SD DosOnChip

    import stamp.core.*;

    public class SDlog_demo {
    final static int SERIAL_TX_PIN = CPU.pin0; // 2
    final static int SERIAL_RTS_PIN = CPU.pin1; // 7
    final static int SERIAL_CTS_PIN = CPU.pin2; // 8
    final static int SERIAL_RX_PIN = CPU.pin3; // 3


    static Uart txUart = new Uart( Uart.dirTransmit, SERIAL_TX_PIN, Uart.dontInvert,
    SERIAL_RTS_PIN, Uart.dontInvert, Uart.speed19200,
    Uart.stop1 );

    static Uart rxUart = new Uart( Uart.dirReceive, SERIAL_RX_PIN, Uart.dontInvert,
    SERIAL_CTS_PIN, Uart.dontInvert, Uart.speed19200,
    Uart.stop1 );

    static StringBuffer buffer = new StringBuffer(128);
    static StringBuffer bufferLog = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

    static void bufferCmdMakeDir(){
    buffer.clear();
    buffer.append("md A:\\Logs\\\r");
    }

    static void bufferCmdOpenLog(){
    buffer.clear();
    buffer.append("ow #1 A:\\Logs\\log1.txt\r");
    }

    static void bufferCmdLogByte(char logChar){
    buffer.clear();
    buffer.append("w #1 ");
    buffer.append(logChar);
    buffer.append("\r");
    }
    public static void main(){
    //set autobaud
    txUart.sendString("\r\r");
    //set Echo Off
    txUart.sendString("e0\r");

    bufferCmdMakeDir();
    txUart.sendString(buffer.toString());
    bufferCmdOpenLog();
    txUart.sendString(buffer.toString());
    int i = 0;
    do{
    bufferCmdLogByte(bufferLog.charAt(i));
    txUart.sendString(buffer.toString());
    i++ ;
    } while(i < bufferLog.length());

    //close file
    txUart.sendString("q #1\r");
    } // end main
    } // end class declaration

    Post Edited (yvesB) : 1/20/2007 5:37:26 PM GMT
  • claym53claym53 Posts: 36
    edited 2007-01-22 18:56
    Looks good, I'll try it out when the card writer comes in the mail.
  • claym53claym53 Posts: 36
    edited 2007-01-29 19:49
    I hooked up the sd card writer to my board with the javelin chip on it.
    I wasn't sure about what parts to hook up to pins.

    I hooked it up as follows:
    UART_RTS/BUSY to pin2
    UART_CTS to pin1
    UART_TX to pin0
    UART_RX to pin3
    VCC to 5v
    GND to ground

    I also changed the setting in the java program to match my setup:
    final static int SERIAL_TX_PIN = CPU.pin0;
    final static int SERIAL_RTS_PIN = CPU.pin2;
    final static int SERIAL_CTS_PIN = CPU.pin1;
    final static int SERIAL_RX_PIN = CPU.pin3;

    I ran the program and then put the sd card in my laptop and couldn't find that any files had been written to the card.

    Please help...
    Thanks
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-01-29 19:59
    On page 1 and 2 of the userguide
    http://chipdos.com/library/CD17B10_User_Guide_0v1.pdf
    you find the connections and the baudrates
    The allowable baud rates are:
    • 1200
    • 2400
    • 9600
    • 28800
    • 38400
    • 57600
    • 115200
    • 230400

    so baudrate 19200 appears not to be an option. Use 9600 or 28800 instead.

    regards peter
  • claym53claym53 Posts: 36
    edited 2007-02-01 18:56
    I changed the baud to 9600 and I also tried 28800.
    It seems that data is still not being written to the card.

    Anybody have any ideas for an echo program that prints what comes back to the debugger?
  • claym53claym53 Posts: 36
    edited 2007-02-01 19:06
    I wrote this program which I think should make it echo back NULL to me.

    import stamp.core.*;

    public class SDlog_demo {
    final static int SERIAL_TX_PIN = CPU.pin0; // 2
    final static int SERIAL_RTS_PIN = CPU.pin2; // 7
    final static int SERIAL_CTS_PIN = CPU.pin1; // 8
    final static int SERIAL_RX_PIN = CPU.pin3; // 3


    static Uart txUart = new Uart( Uart.dirTransmit, SERIAL_TX_PIN, Uart.dontInvert,
    SERIAL_RTS_PIN, Uart.dontInvert, Uart.speed9600,
    Uart.stop1 );

    static Uart rxUart = new Uart( Uart.dirReceive, SERIAL_RX_PIN, Uart.dontInvert,
    SERIAL_CTS_PIN, Uart.dontInvert, Uart.speed9600,
    Uart.stop1 );


    public static void main() {
    txUart.sendString("\r\r");
    txUart.sendString("NULL");
    // response
    while (true) {
    System.out.print((char)rxUart.receiveByte());
    }
    }
    }

    Nothing is returned... any ideas?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-02 09:28
    Upon reset the dosonchip device enables the echo.
    Try this echo without javelin handshake, that is, connect the device RTS pin to its CTS pin (local handshake).
    Redefine your uarts without handshake pins.
    Then try your echo test program again.
    I could not locate the startup baudrate in the manual.
    This could be different from 9600.

    Edit: I just noted the autobaud feature, hence your double '\r' at the start of your
    test program. The manual also states it sends out a prompt after baudrate has been set.
    Have you set the mode0 and mode1 pins to select uart interface?

    regards peter

    Post Edited (Peter Verkaik) : 2/2/2007 9:36:24 AM GMT
  • claym53claym53 Posts: 36
    edited 2007-02-07 16:08
    No, how do you set the mode0 or mode1 pin to work with uart?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-07 17:17
    Here is the datasheet for the DosOnChip for your module
    http://chipdos.com/library/CD17Bxx-0v8.pdf

    At the start of chapter 6 the mode pins are described
    Both mode pins must be left open to select Uart interface.

    Here is the schematic of the module
    http://chipdos.com/library/DOSonCHIP-SD_Schematic_1v2.pdf
    mode0 is at pin6 and mode1 is at pin7 of connector P1
    VCC is at pin9 and is specified as 2.7-3.3V

    regards peter
    ·
  • yvesByvesB Posts: 22
    edited 2007-02-08 18:28
    I believe he purchased from Sparkfun so you should refer him to http://www.sparkfun.com/datasheets/BreakoutBoards/DOSonCHIP-SD-Schematic.pdf
    which has solder points SJ1 and SJ2 for Mode0 and Mode1.· These are left "open" so the device should already be in "UART" mode.
  • yvesByvesB Posts: 22
    edited 2007-02-08 18:30
    Also, try posting your question on the Sparkfun forum or email their support people. They usually respond fairly quickly and understand their product more than anyone.
  • claym53claym53 Posts: 36
    edited 2007-02-09 16:11
    Ok, the board that I have my javelin on and the sd card hooked up to puts out 5v, so I think I have fried the sd card module.

    I believe that the sd module runs on something around 3v. If someone could tell me how I would get the right voltage from my board which puts out 5v that would be great.

    Would I use resistors or what?
  • claym53claym53 Posts: 36
    edited 2007-02-09 16:15
    or could I use a potentiometer?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-09 16:28
    I would recommend a LM3940 or compatible regulator
    http://www.national.com/pf/LM/LM3940.html

    regards peter
  • claym53claym53 Posts: 36
    edited 2007-02-09 19:26
    Couldn't I get the voltage I need by using the javelins PWM VP?

    any ideas?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-09 20:27
    Possibly, I would use DAC then.
    It depends how much current the device draws.
    A javelin pin can only source 25mA.

    regards peter
  • claym53claym53 Posts: 36
    edited 2007-02-12 19:48
    Ok I definatly fried the module, So I did what Brian Carpenter·said and ordered the sd data logger from www.sddatalogger.com.

    There are a few pieces of example code that are written for the basic stamp on thier website, but no javelin code.

    So could someone help me with some examples to make this thing work with my javelin chip?
  • claym53claym53 Posts: 36
    edited 2007-02-16 18:56
    ok here is the code that I wrote for the sddatalogger module:

    import stamp.core.*;
    public class SDControl {
    final static int SERIAL_PIN = CPU.pin4;
    static Uart rxUart = new Uart( Uart.dirReceive, SERIAL_PIN, Uart.invert,
    ························ SERIAL_PIN,Uart.speed19200,
    ························ Uart.stop1 );
    static Uart txUart = new Uart( Uart.dirTransmit, SERIAL_PIN, Uart.invert,
    ························ SERIAL_PIN, Uart.speed19200,
    ························ Uart.stop1 );
    public static void main() {
    · txUart.sendByte('!');· // wake up
    · txUart.sendByte('W');
    · txUart.sendByte('U');
    · txUart.sendByte('!');· // set pacing value
    · txUart.sendByte('P');
    · txUart.sendByte('V');
    · txUart.sendByte(3);
    · txUart.sendByte(0);
    · //txUart.sendString("");
    · // display response (if any)
    · while (true) {
    · System.out.print((char)rxUart.receiveByte());
    · }
    ·}
    }

    I think it should return 30, but I doesn't.
    There is some code written for this piece of hardware at www.sddatalogger.com
    Any ideas on getting data written and read to an sd card with this?
  • BeanBean Posts: 8,129
    edited 2007-02-16 20:00
    Change

    txUart.sendByte(3);
    txUart.sendByte(0);

    To

    txUart.sendByte(30);

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-16 21:10
    The datalogger uses a single wire for bidirectional communication.

    import stamp.core.*;
    public class SDControl {
    final static int SERIAL_PIN = CPU.pin4;
    static Uart rxUart = new Uart( Uart.dirReceive, SERIAL_PIN, Uart.invert,Uart.speed19200,Uart.stop1 );
    public static void main() {
    · int c;
    · rxUart.setDirection(Uart.dirTransmit);
    · rxUart.sendByte('!');· // wake up
    · rxUart.sendByte('W');
    · rxUart.sendByte('U');
    · rxUart.sendByte('!');· // set pacing value
    · rxUart.sendByte('P');
    · rxUart.sendByte('V');
    · rxUart.sendByte(30);
    · while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    · // display response (if any)
    · rxUart.setDirection(Uart.dirReceive);
    · while (true) {
    · c = rxUart.receiveByte();
    · System.out.println(c); //display data as integer values
    · }
    ·}
    }

    regards peter
  • claym53claym53 Posts: 36
    edited 2007-02-19 15:14
    Ok. What Peter said works, but now after I wake it up, set the pacing value, and then open a file, I'm not sure how to write to and read from a file.

    What I would like to do is be able to go through a loop and for each instance of the loop write a variable to DATA.TXT followed by a new line.

    Then at a later time open that same file and for each line, put it into an array.

    If you look at my other post: http://forums.parallax.com/forums/default.aspx?f=8&m=166896
    You can see what I am trying to do.
    I am trying to save the array that holds the pulses generated to a file on the card and then read and use them later to create those pulses again.

    I hope that since peter has made this work out for me on both of my posts that he can see what I am trying to acomplish.
  • BeanBean Posts: 8,129
    edited 2007-02-19 17:59
    You can read and write your data in two different formats: STRING or RAW.

    If you want to read your data from a PC, then use the STRING format "!AS" to append and "!RS" to read. For STRING format all values must be converted to ASCII before writing, and value read back must be converted from ASCII. But your data will be readable from most any PC application. STRING data is always terminated with the string termination character (usually a linefeed because PC strings end with carriage-return and linefeed). STRING data can be variable length, but cannot be read randomly. In other words if you want the 20th string, you must read past the first 19 to get to it.

    STRING commands:
    !ST - Sets the string terminator character
    !AS - Appends a string to the end of a file
    !RS - Reads a string from a file


    If you want to read and write from the microcontroller, then use the RAW format. Here data is stored in the normal binary format that the microcontroller uses. No conversion is require. BUT a PC application will most likely NOT be able to read the data. RAW data is fixed in size, but CAN be read randomly. If you want the 20th record you can just seek it and read it.

    RAW commands:
    !AR - Append record
    !RR - Read record
    !GP - Goto file position

    I hope this helps,
    Bean

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-19 18:27
    It is possible to use strings and have random access if you keep the string length constant.
    The Format class can easily convert binary data to ascii and vice versa.

    char[noparse]/noparse buf = new char[noparse][[/noparse]9]; //holds sign + 5 decimals + CR + LF + closing null
    int value = 1756;
    Format.sprintf(buf,"%6d\r\n",value); //convert binary to ascii (8 bytes + null)
    tx.sendByte('!');
    tx.sendByte('A');
    tx.sendByte('S');
    int i = 0;
    while (buf[noparse][[/noparse]i]!=0) tx.sendByte(buf[noparse][[/noparse]i++]); //send string
    The above example sends "· 1756",CR,LF

    To read a string
    tx.sendByte('!');
    tx.sendByte('R');
    tx.sendByte('S');
    int len = rx.receiveByte(); //get length (includes termination character)
    for (i=0; i<len; i++) buf[noparse][[/noparse]i] = (char)rx.receiveByte(); //read string charracters
    buf[noparse][[/noparse]i]=0; //make asciiz
    len = rx.receiveByte(); get errorcode

    int[noparse]/noparse newvalue = new int[noparse][[/noparse]1]; //placeholder for binary value
    Format.sscanf(buf,"%d",newvalue); //convert ascii to binary
    If the string was "· 1756",CR,LF then now newvalue = 1756

    regards peter
  • claym53claym53 Posts: 36
    edited 2007-02-19 19:14
    Where can I find the format class at? because it seems that I don't have it.
  • claym53claym53 Posts: 36
    edited 2007-02-19 19:35
    Nevermind, I found the format library.
    Here is what I have now, but when I put the card in my laptop, I'm still not seeing any files on it.
    I believe I should see a DATA.TXT with 1756 in it, but I dont.

    import stamp.core.*;
    import stamp.util.text.*;

    public class SDControl {

    final static int SERIAL_PIN = CPU.pin15;
    static Uart rxUart = new Uart( Uart.dirReceive, SERIAL_PIN, Uart.invert,Uart.speed19200,Uart.stop1 );

    public static void main() {
    int c;
    rxUart.setDirection(Uart.dirTransmit);
    rxUart.sendByte('!'); // wake up
    rxUart.sendByte('W');
    rxUart.sendByte('U');
    rxUart.sendByte('!'); // set pacing value
    rxUart.sendByte('P');
    rxUart.sendByte('V');
    rxUart.sendByte(30);
    CPU.delay(2000);

    rxUart.sendByte('!'); // attempt to close file
    rxUart.sendByte('C');
    rxUart.sendByte('F');
    CPU.delay(2000);

    rxUart.sendByte('!'); // attempt to open DATA.TXT
    rxUart.sendByte('O');
    rxUart.sendByte('F');
    CPU.delay(30);
    rxUart.sendByte('D');
    rxUart.sendByte('A');
    rxUart.sendByte('T');
    rxUart.sendByte('A');
    rxUart.sendByte('.');
    rxUart.sendByte('T');
    rxUart.sendByte('X');
    rxUart.sendByte('T');
    CPU.delay(2000);

    char[noparse]/noparse buf = new char[noparse][[/noparse]9]; //holds sign + 5 decimals + CR + LF + closing null
    int value = 1756;
    Format.sprintf(buf,"%6d\r\n",value); //convert binary to ascii (8 bytes + null)
    rxUart.sendByte('!');
    rxUart.sendByte('A');
    rxUart.sendByte('S');
    int i = 0;
    while (buf!=0) rxUart.sendByte(buf[noparse][[/noparse]i++]); //send string


    while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    // display response (if any)
    rxUart.setDirection(Uart.dirReceive);
    while (true) {
    c = rxUart.receiveByte();
    System.out.println(c); //display data as integer values
    }
    }

    }
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-19 21:13
    You must follow the communication prrotocol, that includes receiving responses.

    import stamp.core.*;
    import stamp.util.text.*;

    public class SDControl {

    final static int SERIAL_PIN = CPU.pin15;
    static Uart rxUart = new Uart( Uart.dirReceive, SERIAL_PIN, Uart.invert,Uart.speed19200,Uart.stop1 );

    public static void main() {
    int c;
    rxUart.setDirection(Uart.dirTransmit);
    rxUart.sendByte('!'); // wake up
    rxUart.sendByte('W');
    rxUart.sendByte('U');
    rxUart.sendByte('!'); // set pacing value
    rxUart.sendByte('P');
    rxUart.sendByte('V');
    rxUart.sendByte(30);
    while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    rxUart.setDirection(Uart.dirReceive);
    c = rxUart.receiveByte(); //get returned pacing
    if (c != 30) { //returned value invalid
    · System.out.println("pacing set unsuccesful");
    · while (true) ; //halt program
    }

    CPU.delay(2000);
    rxUart.setDirection(Uart.dirTransmit);
    rxUart.sendByte('!'); // attempt to close file
    rxUart.sendByte('C');
    rxUart.sendByte('F');
    while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    rxUart.setDirection(Uart.dirReceive);
    c = rxUart.receiveByte(); //get error code

    CPU.delay(2000);
    rxUart.setDirection(Uart.dirTransmit);
    rxUart.sendString("!OFDATA.TXT"); // attempt to open DATA.TXT
    while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    rxUart.setDirection(Uart.dirReceive);
    c = rxUart.receiveByte(); //get error code
    if (c!=0) {
    · System.out.println("file not opened");
    · while (true) ; //halt program
    }

    CPU.delay(2000);
    char[noparse]/noparse buf = new char[noparse][[/noparse]9]; //holds sign + 5 decimals + CR + LF + closing null
    int value = 1756;
    Format.sprintf(buf,"%6d\r\n",value); //convert binary to ascii (8 bytes + null)
    rxUart.setDirection(Uart.dirTransmit);
    rxUart.sendByte('!');
    rxUart.sendByte('A');
    rxUart.sendByte('S');
    int i = 0;
    while (buf[noparse][[/noparse]i]!=0) rxUart.sendByte(buf[noparse][[/noparse]i++]); //send string
    while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    // display response (if any)
    rxUart.setDirection(Uart.dirReceive);
    c = rxUart.receiveByte(); //get error code
    if (c!=0) {
    · Format.printf("appending string failed, errorcode %d\n",c);
    · while (true) ; //halt program
    }

    CPU.delay(2000);
    rxUart.setDirection(Uart.dirTransmit);
    rxUart.sendByte('!'); // attempt to close file
    rxUart.sendByte('C');
    rxUart.sendByte('F');
    while (!rxUart.sendBufferEmpty()) ; //wait until transmit buffer empty
    rxUart.setDirection(Uart.dirReceive);
    c = rxUart.receiveByte(); //get error code
    Format.printf("closed file, errorcode %d\n",c);
    while (true) ; //halt program
    }

    }
Sign In or Register to comment.