Shop OBEX P1 Docs P2 Docs Learn Events
Create file name from incoming serial string — Parallax Forums

Create file name from incoming serial string

at_jayat_jay Posts: 16
edited 2012-05-08 18:40 in Propeller 1
I want to creat a new file using fopen function but instead of declaring the file name as
fopen () argument e.g. fopen("abc.txt") I want to use serial received string of 9 characters
E.g name.txt including 0 as end of string. Please guide me how to do this in spin.
Thanks
Jay

Comments

  • Mike GMike G Posts: 2,702
    edited 2012-04-30 05:57
    Read the file name into a buffer array one byte at a time from the serial object. Pass the pointer of the buffer array to the file object.
  • at_jayat_jay Posts: 16
    edited 2012-05-02 04:14
    Thanks Mike, it works.
    Now my next question,which is quite basic, is how I can I write a file with stream of serial in coming data?
    Do I need to define a local buffer (of type BYTE) that receives the in coming stream first and then write on SD card ? if yes then whats the maximum size of buffer I need to set? or?
    Also the in coming stream is variable then how to effectively exit from the write operation after certain interval of time when no data is coming?

    Cheers
    Jay
  • Mike GMike G Posts: 2,702
    edited 2012-05-02 06:02
    I'd have to know a little more about your project to provide specific advice. Conceptually it works that same as the file name. Buffer the incoming serial data, process the serial data, write the serial data. Buffer sizes and timeout values are dependent on your project and the type of data you are receiving.

    Get a piece of paper and sketch a basic flow design.
  • at_jayat_jay Posts: 16
    edited 2012-05-02 06:55
    Thanks Mike.

    I started using Byte buffer of size 512 for storing in coming serial stream that needs to be written into SD card.
    Is it worth to use multiple buffers for handling stream of size greater than 512 bytes?
    Also your opinion of using dedicated cog for write operations?

    Thanks
    Jay
  • Mike GMike G Posts: 2,702
    edited 2012-05-02 07:18
    Is it worth to use multiple buffers for handling stream of size greater than 512 bytes?
    Also your opinion of using dedicated cog for write operations?
    There's not enough information to provide an accurate answer.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-05-02 10:25
    Use rxtime with a timeout value to break out of your receive loop. As an example, if your timeout period is 1 second you would do something like "repeat while (val := ser.rxtime(1000)) <> -1".

    If you can buffer all the data in memory then just read all the bytes into a big buffer and then write it to a file with a single write call. If you can't buffer all the data I would suggest that you use a seperate cog to read the data into two ping-ping buffers. Each buffer should be able to hold about 1 second's worth of data. Your main cog would then write each buffer to the file when it fills up. You would need a flag or two to indicate when a buffer is ready to be written, and when it has been emptied.
  • pik33pik33 Posts: 2,398
    edited 2012-05-02 11:29
    http://forums.parallax.com/showthread.php?139819-How-to-dump-Eskimonika-%29-partially-solved...

    Here I struggled with serial receive-and-sd-write-problem.

    My implementation loses bytes from time to time. SD driver can't write as fast as serial receiver gets bytes from PC.
  • at_jayat_jay Posts: 16
    edited 2012-05-08 00:13
    Thank you all, I did got success in getting the file name and storing it in a ping-ping buffer by using adviced flags and conditional statements.
    Now I got a problem and is that :
    at first time I use "w" to creat and write a new file (abcdefgh.txt", but later on I used the same file with "a" append option. But what I want is that when I go for second fresh download to SD card with the same file name (abcdefgh.txt) it appends in stead of creating the same file once more. What I saw in the file the same text is repeated twice like as the new file was not created and written to same file.
    How do I creat a new file each time I go for fresh download?
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    DO = 0 'Set these pins to match your SD connections.
    CLK = 1
    DI = 2
    CS = 3
    LEDR = 4
    LEDG = 5

    OBJ
    sdfat : "fsrw"
    pst : "Serial Terminal SD" '"Parallax Serial Terminal"
    num : "Numbers"
    VAR
    BYTE _Flag1, _Flag2, _Fill, w_ap, control, i, _trigger, _fclose
    BYTE _temp1, _temp2 'to be removed just to see the write operation
    BYTE cntrldata[2], filename[13], buffer[40]
    BYTE bigbuf1[512], bigbuf2[512]
    long mount
    long Stack[500]

    PUB _writebufproc | j, _timevar
    pst.Start(9600,31,30)
    waitcnt(clkfreq*1 + cnt)
    _Flag1 := 0
    _Flag2 := 0
    mount := 0
    w_ap := 0
    _trigger := 0
    _temp1 := 0
    _temp2 := 0
    _timevar := 0
    _fclose := 0

    cognew(_demo(@bigbuf1, @bigbuf2, @_Flag1, @_Flag2, @mount, @filename, @w_ap, @_trigger, @_temp1, @_temp2, @_fclose), @Stack)

    repeat
    if mount < 0
    pst.str( string( 13, "Failed to mount", 13 ) )
    else
    pst.str(string(13,"SD was card found and mounted fine.",13,13))
    i := 0
    repeat 2
    control := pst.rxtime(1000)
    cntrldata := control
    i := i + 1
    if cntrldata[0] == "F" AND cntrldata[1] == "F"
    bytefill(@bigbuf1, 0, 512)
    bytefill(@bigbuf2, 0, 512)
    _fclose := 0
    pst.str(string(13,"Got the Command ID",13,13))
    _Pause(100)
    pst.str(string(13,"ok to pass file name --->>>>",13,13))

    i := 0
    repeat 12
    filename := pst.rxtime(2000)
    i := i + 1
    filename[12] := 0
    _trigger := 1
    pst.str(string(13,"Ready to Write Stream", 13))
    repeat
    if _Flag1 == 0 AND _temp1 == 0
    pst.str(string(13,"WRITING FIRST", 13))
    bytefill(@bigbuf1, 54, 512) ''USE RX.TIME() TO FILL BUFFER
    _Flag1 := 1
    w_ap := 0
    _temp1 := 0
    elseif _Flag2 == 0 AND _temp2 == 0
    w_ap := 1
    bytefill(@bigbuf2, 55, 512) ''USE RX.TIME() TO FILL BUFFER
    pst.str(string(13,"WRITING SECOND", 13))
    _Flag2 := 1
    _temp2 := 0
    _timevar := _timevar + 1
    if _timevar == 250_000 ''USE RX.TIME(1000) <> -1
    pst.str(string(13,"Safe to Remove", 13))
    '_Pause(5_000)
    w_ap := 0
    _timevar := 0
    _trigger := 0
    _temp1 := 0
    _temp2 := 0
    if _fclose == 1
    pst.str(string(13,"File closed successfully", 13))
    quit



    PUB _demo(bbigbuf1, bbigbuf2, _FFlag1, _FFlag2, mmount, ffilename, ww_ap, _ttrigger, _ttemp1, _ttemp2, _ffclose) | k
    dira[LEDR] := 1
    dira[LEDG] := 1
    outa[LEDR] := 1
    outa[LEDG] := 0
    _Pause(400)
    'Start the required code to communicate with Parallax Serial Terminal.
    'Wait four seconds for the user to launch PST and press the Enable button.
    ' pst.Start(9600,31,30)
    ' waitcnt(clkfreq*1 + cnt) 'Increase the 4 if more time is required.

    'Attempt to mount the SD card.
    'Report a failure to mount if the card is not found.
    'Halt if the card fails to mount.
    repeat
    long [mmount] := \sdfat.mount_explicit(DO, CLK, DI, CS)
    repeat 1
    if long [mmount] < 0
    'pst.str( string( 13, "Failed to mount", 13 ) )
    !outa[LEDR]
    !outa[LEDG]
    _Pause(50)
    quit'abort
    else
    outa[LEDR] := 0
    outa[LEDG] := 1
    'Report a message that the card was found and mounted.
    'pst.str(string(13,"SD was card found and mounted fine.",13,13))
    if byte [ww_ap] == 0 AND byte [_ttrigger] == 1
    sdfat.popen(ffilename,"w")
    elseif byte [ww_ap] == 1 AND byte [_ttrigger] == 1
    sdfat.popen(ffilename,"a")
    if byte [_ttrigger] == 0
    byte [_ffclose] := 1 'debug purposes delete if req
    sdfat.pclose

    if byte [_FFlag1] == 1 AND byte [_ttemp1] == 0
    k := sdfat.pwrite(bbigbuf1, 512)
    byte [_FFlag1] := 0
    byte [_ttemp1] := 1
    if k < 0
    sdfat.pputs(string(13, "Write Error", 13, 10))
    else
    sdfat.pputs(string(13, "Write Successful", 13, 10))

    elseif byte [_FFlag2] == 1 AND byte [_ttemp2] == 0
    k := sdfat.pwrite(bbigbuf2, 512)
    byte [_FFlag2] := 0
    byte [_ttemp2] := 1
    if k < 0
    sdfat.pputs(string(13, "Write Error", 13, 10))
    else
    sdfat.pputs(string(13, "Write Successful", 13, 10))
    sdfat.unmount

    PUB _writeSD(fname,buf) | j, k
    'j := 0
    'repeat 4
    ' filename[j] := byte [fname][j]
    sdfat.popen(fname,"w")
    _Pause(2000)
    j := 0
    repeat 40
    byte [buf][j] := pst.rxtime(2000)
    j := j + 1

    k := sdfat.pwrite(buf, 40)
    if k < 0
    sdfat.pputs(string(13, "Write Error", 13, 10))
    else
    sdfat.pputs(string(13, "Write Successful", 13, 10))
    sdfat.pclose

    PUB _Pause(msec)| _t
    _t := cnt
    repeat until (cnt - _t) / (clkfreq / 1000) > msec
  • msrobotsmsrobots Posts: 3,709
    edited 2012-05-08 00:25
    Hi Pik33,

    I think a

    sdfat.seek(0) will do that for you.hm. FileSeek? sorry I use kye's sd-driver, but fsrw has something like this for sure.

    or delete the file if it is there and then recreate a new one ...

    enjoy!

    Mike
  • Mike GMike G Posts: 2,702
    edited 2012-05-08 08:51
    at_jay, if you want a new file name then create a new file; file1.txt, file2.txt... filex.txt.

    If you want to keep the file name and not the new data, then use the 'w' parameter not the 'a'.
  • at_jayat_jay Posts: 16
    edited 2012-05-08 18:20
    Thanks all!
    I want to creat the file name (as received serially in 8.3 format), which is same each time. I want to append the created file only during ping-ping buffer writing loop. Once after the file is closed and before the new download to SD card I want to delete the previous file first and then start to open and write the new file.
    sdfat.seek(0) does't work, what should I do to delete the exisiting files? or to overwrite the file with same name?
  • Mike GMike G Posts: 2,702
    edited 2012-05-08 18:40
    Comments from fsrw.spin
    pub popen(s, mode) : r | i, sentinel, dirptr, freeentry
    {{
    '   Close any currently open file, and open a new one with the given
    '   file name and mode.  Mode can be "r" "w" "a" or "d" (delete).
    '   If the file is opened successfully, 0 will be returned.  If the
    '   file did not exist, and the mode was not "w" or "a", -1 will be
    '   returned.  Otherwise abort will be called with a negative error
    '   code.
    }}
    

    Comments from readme.spin
    We only support the root directory at the moment, and only one
    file open at a time.  The file can be open for read, write, or
    append.  We also support delete (open a file in mode "d"), as well
    as a traversal of the root directory.
    
Sign In or Register to comment.