Adding a new command to FemtoBasic
Duane C. Johnson
Posts: 955
Hi Mike;
I am attempting to add a special command, OPENX, to the DongleBasic variation of FemtoBasic with an SD Card.
What I want to do is open a file with the file name represented by a numeric expression, <expr>, instead of an alpha string.
I figured out the method to add the command and it worked correctly in the normal way before I started modifying it.
I added a new primary scanFilenameX(f) that doesn't look for quotes, (I hope).
OPENX doesn't work and I don't know why. Actually I don't know what I'm doing.
Would you look this over and divine or edit this to make it work.
I show examples of the Basic code I'm using.
Duane J
I am attempting to add a special command, OPENX, to the DongleBasic variation of FemtoBasic with an SD Card.
What I want to do is open a file with the file name represented by a numeric expression, <expr>, instead of an alpha string.
I figured out the method to add the command and it worked correctly in the normal way before I started modifying it.
I added a new primary scanFilenameX(f) that doesn't look for quotes, (I hope).
OPENX doesn't work and I don't know why. Actually I don't know what I'm doing.
Would you look this over and divine or edit this to make it work.
I show examples of the Basic code I'm using.
Duane J
pri scanFilename(f) | c, chars ' Original scanFilename(f) result := f chars := 0 tp++ ' skip past initial quote c := byte[tp] repeat while c <> quote and c <> 0 tp++ if chars++ < 31 byte[f++] := c ' keep up to 31 characters c := byte[tp] if c == quote ' move past closing quote tp++ byte[f] := 0 pri scanFilenameX(f) | c, chars ' ZZZZ New Added Primary Function without Quotes result := f chars := 0 tp++ ' skip past initial quote c := byte[tp] repeat while c <> 0 tp++ if chars++ < 31 byte[f++] := c ' keep up to 31 characters c := byte[tp] byte[f] := 0 140: ' OPEN " <file> ", R/W/A ' Original OPEN Command if spaces <> quote abort @syn scanFilename(@f0) if spaces <> "," abort @syn case skipspaces "A", "a": d := "a" "W", "w": d := "w" "R", "r": d := "r" other: abort string("Invalid open file mode") tp++ if \mass.mountSDVol(def#spiDO,def#spiClk,def#spiDI,def#spiCS) < 0 abort string("Can't mount SD card") if \mass.openFile(@f0,d) abort string("Can't open file") fileOpened := true 187: ' OPENX <expr>, R/W/A ' ZZZZ New Open a file based on the value of <expr> if spaces <> 0 ' At least one parameter b := c := expr scanFilenameX(@f0) if spaces <> "," abort @syn case skipspaces "A", "a": d := "a" "W", "w": d := "w" "R", "r": d := "r" other: abort string("Invalid open file mode") tp++ if \mass.mountSDVol(def#spiDO,def#spiClk,def#spiDI,def#spiCS) < 0 abort string("Can't mount SD card") if \mass.openFile(@f0,d) abort string("Can't open file") fileOpened := true This writes data to a file with a Numeric Name NEW 10 OPEN "201212", W 20 WRITE 2012, 12, 1 30 CLOSE RUN OK This reads the file with an Alphabetic Name NEW 20 OPEN "201212", R 30 READ B, C, D 40 CLOSE 50 PRINT B, C, D RUN 2012 12 1 OK This reads the file with a Numeric Name NEW 10 A = 201212 20 OPENX A , R 30 READ B, C, D 40 CLOSE 50 PRINT B, C, D RUN IN LINE 20 Syntax Error OK
Comments
Your scanFilenameX routine doesn't have an appropriate stop condition. I think you're stopping the scan on a zero byte. That'll gobble up the rest of the OPENX statement. You'd want to stop on a comma, then backup the text pointer so the main OPENX code will see the comma again.
You could also modify the existing OPEN statement. Currently it checks that the first non-blank after the OPEN is a quote. If it's not a quote, you could call "expr" to look for a numeric value, then convert the number to a zero-terminated string in "f0" instead of calling "scanFilename". The rest of the OPEN code should work fine for either case. Something like: The convertToString routine would convert the value of its first parameter into a zero-terminated string pointed to by the second parameter. You could use a modified version the decimal output routine in the PRINT statement code.
Yes, I did these things. My new OPENX works the same as OPEN when it has the same code. So I assume I have at least got this right.
I 'm trying to use this.
I made a PRIvate method named "convertToString" with "(expr,@f0)" as the passed parameters.
However, expr is a PRIvate method. My "Propeller Manual" says parameters are escentially lomg variables.
The spin tool doesn't like this.
What am I doing wrong?
I know I will have more questions later as I'm a spin newbie.
Duane J
Adding commands has been easy, however, getting them to work has been much tougher.
Mainly because I'm not a good programmer. Far from it.
What I want to do is be able to open files on the SD-Card based on a changeable number as the name.
Currently OPEN in DongleBasic works this way:
OPEN "<file>", {R | W | A }
"<file>" is a string surrounded by QUOTES that is coded within the command, essentially it is unchangeable.
If other files are to be used a separate command is needed for each of them.
This is very cumbersome as I need about 500 data files on the card.
What I need is:
OPENX <expr>, {R | W | A }
<expr> is a numeric expression WITHOUT QUOTES, such as:
1234 a number
A a number in a variable
12 + 34 an equation with numbers that evaluates to a number
A + B an equation with variables that evaluates to a number.
I assume there are restrictions to this as the resultant number must contain 8 or less characters without an extension.
This would be an important advance to the usefulness of DongleBasic. I doesn't seem to me this will take much code to do this.
I got OPENX to accept strings both with or without quotes to work.
I can't get it to use an expression though.
I keep getting spin compiler errors.
Help, I'm over my head.
Would anyone be willing to edit my version of DongleBasicX so the OPENX command accepts an <expr> instead of a "string" for use as the SD-Card file name?
My project is for a computational based solar tracker. I use a program in my PC that pre calculates stepper motor movements years in advanced. Each file contains stepper movements for a week or so. The data has a granularity of about 15 minutes of time. My program moves the motors between these data points linearly over the time period. The SD-Card easily has enough space to have at least 500 files, probably a lot more.
I can zip my version and send it to you?
Duane C. Johnson
redrok@redrok.com
(651)426-4766
Thanks for the reply.
I may not have made it clear. I was looking for a way to mathematically evaluate the contents of the string of characters.
The string may contain numbers, variable, or mathematical operators. The resultant number then is used as the file name to be opened.
As an example, the print command does this:
A = 4
PRINT 1 + 2 * 3 + A ' results in:
11
Duane J
A simpler method might be that I do the mathematics and put the number in a variable.
This variable is a single alpha character, A .. Z.
As an example, the OPEN command does this:
A = 4
B = 1 + 2 * 3 + A
OPEN B , W
Note! If there are quotes the OPEN works in the normal way.
In absence of the quotes OPEN uses the contents of the variable as the name.
Thanks.
Duane J
I got it to work. Yey!!!
Well not the way I originally wanted with numeric equations within the OPEN command.
But this method seams acceptable and much easier to do.
The OPEN statement accepts either a "<String>" with Quotes
or a single character <var>, without Quotes, that points
to a variable which contains a 32 bit number. This is converted
to an 8 character name.
The beauty of this is one can easily access any of many files
that contain stepper motor data.
Mu intention is to have files that contain a weeks worth of
stepper movements. The numeric name can be calculate from
the clock/calendar.
BTW, there can be 511 files in the root directory. I can
have over 9 years of movement data on one SD card.
Cool huh!!
Things to do:
1. The var name must use upper case letters. Lower case doesn't
work. I have to convert lower case to upper case.
2. I have to add syntax aborts.
3. The DELETE statement should have this same also.
4. I added a bunch of test code that needs to be removed.
5. Learn to program better.
This is some clips of my working copy of DongleBasic.
I can send you a zip of the full thing if you want.
Duane J
redrok@redrok.com
I got it to work. Yey!!!
Here's the DELETE statement.
The DELETE statement accepts either a "<String>" with Quotes
or a single character <var>, without Quotes, that points
to a variable which contains a 32 bit number. This is converted
to an 8 character name.
Thanks.
Duane J
If you added a "Are you sure?" to this, it would make a nifty addition to the standard Femto package.
OBC
Hmmmm?
That would get in the way of software controlled OPEN and DELETE functions.
Maybe the "Are you sure?" should work only when in "edit" mode and not in "running" mode.
Next, I need to add a Clock/Calendar statement.
I'm using the DS1307
I have several variations of FemtoBasic I regularly use:
[HTML]<pre>
DongleBasic with SD card, can autostart a Basic program on the card after reset
DongleBasicX with SD card, with the new OPEN statements, can autostart a Basic program on the card after reset
StickBasic no SD card, no autostart
StickBasicProm no SD card but will autostart a preveiosly saved Basic program after reset.
</pre>[/HTML]
Here are a couple of test FemtoBasic programs to demonstrate the added commands. Duane J
<redrok@redrok.com>
I didn't want to just convert a number in the OPEN statement into a name.
I wanted to convert a number contained in a variable into a name.
I can use math to store the result of a mathematical equation in a variable that results in a file name.
Does this make sense?
Duane J.
Thank You, Thank You, Thank You!!!!!!
That worked perfectly. And much better than my crude solution.
To answer question:
I just couldn't get it to work. Mostly due to my incompetence.
Having seen your "Working" version I can see my mistakes.
The main one was the requirement for proper "Indentation" in spin. I just didn't get it.
BTW, it was easy to do the same thing to the DELETE statement.
For me, this has been a valuable, if not harrowing, learning experience.
Do you recommend a book that would teach me the "Best Practices and Recommendations" of writing spin code? I really don't need the hardware (robotic) side of things as I am pretty good at this stuff already. The Propeller Manual just doesn't do this for me.
On to implementing the DS1307 clock commands in FemtoBasic.
You might ask why I keep focusing on FemtoBasic.
For me, this is the perfect platform. I make many utility micros that I can put together in less than an hour. Then make them work very quickly by writing in the Femto tokenized interpreter. Sure the code runs slowly, but I rarely need the code to run very fast.
I have made Tiny Basic interpreters for many years using 8080, Z80, 1802, 8052-basic, and others. The Prop is by far the nicest of all of them for ease of implementation and use.
When introducing newcomers to micro controllers, seeing a bag of parts magically transform into a working unit and then programming in a simple language really hooks them in.
Duane J