Counting function on a "byte"
Elkin
Posts: 58
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
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
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)
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
I'd suggest a placeholder for the numbers you want to use.
Then to change the number just use:
Duane
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
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???
It would be a lot easier to read your code if you used CODE tags.
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
Yeah, that is MUCH better.
Those are quote tags. Code tags will preserve the indentation which is so important in Spin.
Duane
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.
I am going to do some work with this tomorrow and see what I can make it do.
I will post something up tomorrow...