Problem with string manipulation
kolyur
Posts: 43
I'm trying to write a function that will take a signed integer (maximum 5 digits) and convert it to a string of the form XX.XXX with optional sign display. This string will then be displayed on a VFD. I know my VFD implementation is correct because if I use the Numbers or Simple_Numbers object to create the string, it displays correctly. However, the following code seems like it should work but it just shows garbled characters on the VFD.
stringvar is a global array with 8 elements. Can anyone see any glaring errors? I compared it to the string object in Simple_Numbers and the procedure seems very similar. One thing that's still tripping me up with Spin is knowing when I need to use the pointer @ symbol in front of a variable. I'm using @stringvar[0] as the argument in my VFD send string function, as I want to specify the address of the first character (I think). I'd appreciate any suggestions!
PUB PosToString(value,signdisp) | idx, divisor bytefill(stringvar, " ", 8) 'Clear array stringvar[7] := 0 'Add zero terminator if signdisp == 2 AND value => 0 'Determine sign character stringvar[0] := "+" elseif signdisp > 0 AND value < 0 stringvar[0] := "-" else stringvar[0] := " " value := ||(-99_999 #> value <#= 99_999) 'Constrain value to 5 digits, remove sign divisor := 10_000 repeat idx from 1 to 5 stringvar[idx] := value / divisor + "0" value //= divisor divisor /= 10 repeat idx from 5 to 3 'Shift digits and add decimal point stringvar[idx+1] := stringvar[idx] stringvar[3] := "." if stringvar[1] == "0" 'Remove leading zero stringvar[1] := " "
stringvar is a global array with 8 elements. Can anyone see any glaring errors? I compared it to the string object in Simple_Numbers and the procedure seems very similar. One thing that's still tripping me up with Spin is knowing when I need to use the pointer @ symbol in front of a variable. I'm using @stringvar[0] as the argument in my VFD send string function, as I want to specify the address of the first character (I think). I'd appreciate any suggestions!
Comments
Strsend is called with argument @stringvar[0] as I mentioned. I can display strings on the VFD all day long using this method (including those generated by Numbers.spin), but my PosToString method just shows garbage characters. Unfortunately I don't remember exactly what characters are shown and I don't have access to the controller at the moment. I'll fire it up tonight and see if I can figure out what it's showing. Thanks for your help.
If memory serves me correct, the output I am getting on the VFD with this code is a single ASCII character $9D (at least, that's what it looks like in my ASCII chart) and the rest spaces, regardless of the input value. So I admit that "garbage characters" plural was a bit of an exaggeration--there's only one.
I will get more information tonight and post back.
It does the same thing you're doing, just in a single loop. Another way to skin the cat as it were....
You can move a value to the buffer like this:
... where buffer is a byte array big enough to hold the string (plus one for the trailing zero). After that, you should be able to use the .str() method in FDS:
Thanks for the code, I can't wait to try it out.
By modifying your method to accept a string pointer, you have a bit more flexibility: you could, for example, prepare two strings (requires two buffers) and via your HMI switch between them without having to re-run the conversion method.
2. It uses a FIFO buffer to retain multiple string results at once.
I haven't submitted it to the OBEX, though, because there is still one thing I want to modify. The "fixed-width" decimal-to-string routines are not really fixed-width, since they add a character position for negative numbers to accommodate the sign. This causes column misalignment in mixed-sign displays. I'd like to change that behavior, but haven't gotten around to it yet.
-Phil