Shop OBEX P1 Docs P2 Docs Learn Events
Counting function on a "byte" — Parallax Forums

Counting function on a "byte"

ElkinElkin Posts: 58
edited 2011-08-11 10:53 in Propeller 1
I have a the following in my DAT block:

logfile byte "adc.csv"


I want "adc.csv" to change during my program such as: "adc2.csv", "adc3.csv", "adc4.csv", etc.

I know that this can be done inside a PUB block using the increment function (+=) where you can start with count =1 and then at the end of that section of code you can write count +=1 and count will increase. Can this be combined with dec2str to have it written in the DAT block or does the byte need to be moved?

Is there a way that I can do this?

below is my source code that I want to have change each run:



check := \sdcard.popen(@logfile, "w") ' attempt to create
if (check == 0)
term.str(string("-- log file created; logging started", CR))
\sdcard.pputs(@header) ' column header in CSV
else
term.str(string("-- ERROR: could not create log file", CR))
repeat
waitcnt(0)

term.rxflush

sync := cnt
count := 1


repeat
read_adc(@ch0) ' get data

' write to log file

\sdcard.pputs(dec2str(count, @sbuf)) ' write count
\sdcard.pputc(",") ' separate
\sdcard.pputs(dec2str(ch0, @sbuf)) ' write ch0 value
\sdcard.pputs(@crlf) ' terminate line

if outa[3] := 1 ' if pin 3 goes high
quit ' abort

waitcnt(sync += clkfreq/10) ' update every 100 milliseconds
count += 1 ' update readings count

"count up at this point? (from adc.csv to adc2.csv)"

\sdcard.pclose

Comments

  • Mike GMike G Posts: 2,702
    edited 2011-08-10 06:24
    Write the string "adcx.csv" to memory using bytemove().

    DAT
    filename byte $0[12]

    1) Write "adc" to memory (bytemove(@filename, string("adc"), 3)
    2) Convert the number "count" to ASCII and write the character to memory
    3) Write ".csv" to memory (bytemove(@filename+4, string(".csv"), 4)
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-08-10 13:41
    Is this code running continuously and you want to change the file from time to time or do you want to use another file with each start of the propeller?

    First of all I'd use number 1 for the first file and not use no number at all.
    2nd I'd use hex-numbers with leading zeros for the number. Using a 4 digit hex-number allows you to create 65535 files and as far as I remember the directory of a FAT file system has a limit, so this should be enough. The leading zeros will give you a nice sorting order and will make handling easier as you will always exchange the same 4 digits.

    So, no extra buffer is needed like described by Mike.

    DAT
    filename byte "adc_0000.csv"

    would be the initial value.

    A function for creating a hexadecimal output is available in several drivers and other obex code, like in the serial driver, video drivers, the string library ... You simply need make sure or change it in a way that the result is written to @filename + 4

    If you want it to work this way after restarts, then at least the number-part of the filename needs to be rewritten to EEPROM. Count can then be
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-08-10 14:40
    I think this might be a simpler method.

    I'd suggest a placeholder for the numbers you want to use.
    filename byte "acd0.csv", 0 ' terminate with a zero so you can use string functions
    

    Then to change the number just use:
    PUB ChangeFileNumber(value)
     
      filename[3] := value + "0"
      ' the + "0" moves the number to an ASCII digit
    

    Duane
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-08-10 14:46
    Elkin,

    I don't know if you'll be importing the file into Excel or not. I had problems (and I know another forum member had the same problem) opening csv files in Excel. If I saved the file as txt file instead of csv then chose "import" in Excel and selected "coma delimited", then it would read the data correctly.

    Duane
  • ElkinElkin Posts: 58
    edited 2011-08-11 07:02
    Thanks for the help. I have the system operating nicely in hex form but when I tried to use the decimal driver I was getting unreadable files... I would prefer to have the files just count rather than have them stop at 9, switch to letters and then back to 0-9 again.

    To answer your questions, I am running continuously and changing files from time to time. I want to separate ADC files at 15 minute intervals so there is about 10000 measurements in each file (every 0.1 seconds). I dont have to worry about this being saved after restarts or reprogramming.

    I am using the drivers from the string library but the decimal one doesnt seem to function for me.

    If I change all of the decimalString below to filename that should work, right? That is what I did for integerToHexadecimal.

    DAT filename byte "adc_0000.txt"

    PUB integerToDecimal(number, length) '' 5 Stack Longs

    '' // Converts an integer number to the decimal string of that number padded with zeros.
    '' //
    '' // Returns a pointer to the converted string.
    '' //
    '' // Number - A 32 bit signed integer number to be converted to a string.
    '' // Length - The length of the converted string, "+" or "-" will be concatenated onto the head of converted string.

    length := (10 - ((length <# 10) #> 0))

    decimalString := "+"
    if(number < 0)
    decimalString := "-"

    if(number == negx)
    bytemove(@decimalString, string("-2147483648KA"), 11)

    else
    repeat result from 10 to 1
    decimalString[result] := ((||(number // 10)) + "0")
    number /= 10

    decimalString[length] := decimalString
    return @decimalString[length] ****does this go to @filename + 4 like in the intergerToHexadecimal???
  • ElkinElkin Posts: 58
    edited 2011-08-11 07:04
    Thanks for the tip, Duane, I was having an issue importing into excel, but using .txt resolved it.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-08-11 07:27
    Elkin,

    It would be a lot easier to read your code if you used CODE tags.

    attachment.php?attachmentid=78421&d=1297987572



    I don't know why Excel expects csv files to be tab delimited and not coma delimited. I'm glad the .txt extension helped.

    Duane
  • ElkinElkin Posts: 58
    edited 2011-08-11 07:34
    Let me give that a shot...
    DAT filename byte "adc_0000.txt"

    PUB integerToDecimal(number, length) '' 5 Stack Longs

    '' // Converts an integer number to the decimal string of that number padded with zeros.
    '' //
    '' // Returns a pointer to the converted string.
    '' //
    '' // Number - A 32 bit signed integer number to be converted to a string.
    '' // Length - The length of the converted string, "+" or "-" will be concatenated onto the head of converted string.

    length := (10 - ((length <# 10) #> 0))

    decimalString := "+"
    if(number < 0)
    decimalString := "-"

    if(number == negx)
    bytemove(@decimalString, string("-2147483648KA"), 11)

    else
    repeat result from 10 to 1
    decimalString[result] := ((||(number // 10)) + "0")
    number /= 10

    decimalString[length] := decimalString
    return @decimalString[length] ****does this go to @filename + 4 like in the intergerToHexadecimal???


    Yeah, that is MUCH better.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-08-11 09:19
    Elkin,

    Those are quote tags. Code tags will preserve the indentation which is so important in Spin.

    Duane
  • ElkinElkin Posts: 58
    edited 2011-08-11 09:24
    If I change all of the decimalString below to filename that should work, right? That is what I did for integerToHexadecimal.
    DAT filename byte "adc_0000.txt" 
    
    PUB integerToDecimal(number, length) '' 5 Stack Longs
    
    '' /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts an integer number to the decimal string of that number padded with zeros.
    '' //
    '' // Returns a pointer to the converted string.
    '' //
    '' // Number - A 32 bit signed integer number to be converted to a string.
    '' // Length - The length of the converted string, "+" or "-" will be concatenated onto the head of converted string.
    '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      length := (10 - ((length <# 10) #> 0))
    
      decimalString := "+"
      if(number < 0)
        decimalString := "-"
    
      if(number == negx)
        bytemove(@decimalString, string("-2147483648KA"), 11)
    
      else
        repeat result from 10 to 1
          decimalString[result] := ((||(number // 10)) + "0")
          number /= 10
    
      decimalString[length] := decimalString
      return @decimalString[length]                       'does this go to @filename + 4 like in the intergerToHexadecimal???
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-08-11 10:04
    Elkin,

    Merry Christmas.

    I happen to working on almost the same type of problem right now.

    My code doesn't take the cool shortcuts in the code you posted. Here's what I'm using. I think it should do the trick for you.
    CON
      _clkmode = xtal1 + pll16x                           
      _xinfreq = 5_000_000
     
      _DebugBaud = 57600
     
    OBJ   
      Debug : "FullDuplexSerial"   
     
    PUB Main | localIndex
      Debug.start(31, 30, 0, _DebugBaud)
      waitcnt(clkfreq * 3 + cnt) 'time to open PST
     
      repeat localIndex from 0 to 9999
        ZeroPad(localIndex, 4, @filename + 4)
        Debug.str(@filename)
        Debug.tx(13)
     
    PUB ZeroPad(value, digits, localPtr) | temp
    '' This method truncates the most_significant_digits in value
    '' if value doesn't fit the number giving in "digits."
      result := 1
      repeat digits  
        result *= 10
      value //= result
      result /= 10  
      repeat digits
        temp := value / result
        byte[localPtr++] := temp + "0"
        value //= result
        result /= 10
     
    DAT
    filename   byte "ADC_0000.txt", 0
    
  • ElkinElkin Posts: 58
    edited 2011-08-11 10:53
    That looks great! Thanks, Duane.

    I am going to do some work with this tomorrow and see what I can make it do.

    I will post something up tomorrow...
Sign In or Register to comment.