Need to convert user input to multiple word value
Hi,
Along with a separate PIC chip, I am using a BS2pe to accumulate total flow from a flow meter. The BS2pe's role is to calculate an ongoing accumulation of the total pulse count into 2 words, giving a maximum value of 2^32 using Tracy Allen's double precision math routines (http://emesystems.com/BS2math6.htm).
Here's the issue that my feeble brain just can't seem to figure out:
I want a user in the field to be able to set an initial value for the count, as the flow meters we're working with often already have some initial total flow when we install our equipment. I can't figure out how to translate a large number that might be entered by a user (up to 8 digits) into a binary value that spans two 16-bit words.
For instance, if a user enters a value of "12345678", I need that to be stored in two words as $BC $614E. (Note that the user could also enter a small value (even 0) as well)
I have gone down several paths trying to solve this, but haven't gotten there. All I have so far is the user input stored in sequential bytes which I can then convert to decimal values for processing (of course, I could just as easily store the user input as a sequence of bytes in the scratchpad):
char0 VAR Byte
char1 VAR Byte
.
.
.
char7 VAR Byte
SERIN 16,$54,[STR char0\8\CR] <--- if user enter <8 digits, char0(ix) will be set to 0. Can be used to determine number of chars entered by user.
{Convert char0-char7 from ASCII to decimal before processing}
{Move decimal values into 2 words: the part where I can't figure out what to do...}
Any ideas how to get these digits into two words? Thank you.
-Gian
Along with a separate PIC chip, I am using a BS2pe to accumulate total flow from a flow meter. The BS2pe's role is to calculate an ongoing accumulation of the total pulse count into 2 words, giving a maximum value of 2^32 using Tracy Allen's double precision math routines (http://emesystems.com/BS2math6.htm).
Here's the issue that my feeble brain just can't seem to figure out:
I want a user in the field to be able to set an initial value for the count, as the flow meters we're working with often already have some initial total flow when we install our equipment. I can't figure out how to translate a large number that might be entered by a user (up to 8 digits) into a binary value that spans two 16-bit words.
For instance, if a user enters a value of "12345678", I need that to be stored in two words as $BC $614E. (Note that the user could also enter a small value (even 0) as well)
I have gone down several paths trying to solve this, but haven't gotten there. All I have so far is the user input stored in sequential bytes which I can then convert to decimal values for processing (of course, I could just as easily store the user input as a sequence of bytes in the scratchpad):
char0 VAR Byte
char1 VAR Byte
.
.
.
char7 VAR Byte
SERIN 16,$54,[STR char0\8\CR] <--- if user enter <8 digits, char0(ix) will be set to 0. Can be used to determine number of chars entered by user.
{Convert char0-char7 from ASCII to decimal before processing}
{Move decimal values into 2 words: the part where I can't figure out what to do...}
Any ideas how to get these digits into two words? Thank you.
-Gian

Comments
ix VAR Word x0 VAR Word x1 VAR Word y0 VAR Word y1 VAR Word z0 VAR Word z1 VAR Word Ww VAR Word Wx VAR Word char0 VAR x0.BYTE0 temp VAR Byte rm VAR Byte UserInputTo2Words: DO 'loop for this demo DEBUG CR,"Enter up TO 8 digits",CR,">" SERIN 16,$54,[STR char0\8\CR] 'Accept user input up to 8 chars. use STR command so we can take advantage of the \terminating char feature FOR ix = 0 TO 7 'move digits entered by user into scratchpad so variable space can be reused PUT ix, char0(ix) 'DEBUG 13,DEC ix,32,DEC char0(ix) NEXT DEBUG CR x0=0 x1=0 z0=0 z1=0 y0=0 y1=0 FOR ix = 0 TO 7 GET ix, x0 IF x0 = 0 THEN EXIT 'SERIN..[STR...] command fills unused bytes with decimal 0. Use this as an indicator that all user-entered digits have been addded to total. y0= z0 * 10 'multiply result variable, Z, by 10. Begin with low word, z0, using double precision multiplication y1= z0 ** 10 z0 = y0 z1 = z1 * 10 + y1 'now multiply the high result word, z1, by ten, and add in the result of the high word of the z0 x 10 calculation x0 = x0 - 48 'convert current digit to be added to total from ASCII to decimal z0 = z0 + x0 'add low word of result to the current digit being added to the total 'z1 = z1 + x1 'don't need this step of the double precision addition as x1 is always 0 in this case IF z0<x0 THEN 'if addition of z0 + x0 causes z0 to roll over the max value of a word then increment the value of the high result word z1=z1+1 ENDIF DEBUG "ix: ",DEC ix, TAB, "z1 z0: ",HEX z1,32,HEX z0,TAB,"x0: ",DEC x0,13 NEXT DEBUG CR,"Final Results: ",13, "Hex (z1 z0): ",HEX z1,32,HEX z0,13, "Decimal: " GOSUB showdubdec100 'display decimal version of 2 words LOOP showdubdec100: FOR ix=4 TO 0 ' 5 bytes can hold 10 digits temp=z1//100 ' high remainder z1=z1/100 ' high word of quotient rm=((temp*36//100)+(z0//100)) ' remainder calc z0=(temp*655)+(temp*36/100)+(z0/100)+(rm/100) 'low word of quotient rm=rm//100 ' final remainder PUT ix,rm ' store remainder NEXT ' ix next digits ' -- printout routine, digits stored in spRAM FOR ix=0 TO 4 ' print digits, most significant first GET ix,char0 ' from spRAM 'GOSUB wratbuff1 DEBUG DEC2 char0,32 ' includes leading zeros NEXT DEBUG CR RETURNData entry and accumulation can be done in line with fewer variables and without first PUTting the data in scratchpad RAM.
[SIZE=1][FONT=courier new]' {$STAMP BS2pe} ' {$PBASIC 2.5} x0 VAR WORD ' x1:x0 is double word accumulator x1 VAR WORD char VAR BYTE idx VAR NIB DO DEBUG 13,"Enter a number up to 8 digits: " GOSUB enterDigits DEBUG 13,"Your number in binary hex is: ", IHEX4 x1, HEX4 x0 LOOP enterDigits: x0 = 0 x1 = 0 FOR idx=0 TO 7 SERIN 16,$54,[char] IF char = CR THEN EXIT IF char>="0" AND char <="9" THEN char = char - "0" x1 = (x1 * 10) + (x0 ** 10) ' accumulator*10 x0 = x0 * 10 x0 = x0 + char ' add user char IF x0 < char THEN x1 = x1 + 1 ' carry?! ENDIF NEXT RETURN ' x1:x0 contains the binary value of digits entered. [/FONT][/SIZE]Much more elegant than my clumsy solution, as usual. After we tried this in the field today, it was immediately apparent 8 characters were not going to be enough to cover the existing flow totals on some previously installed flow meters. For instance, a flow meter that's been in the field for some time has already accumulated 570 acre-feet of flow. Given the meter they're using, that translates to 399,323,920 counts! I've expanded the algorithm to accept up to 10 characters, with a warning that the maximum value that can be entered is 4,294,967,295. I tried the algorithm up to that 32 bit max value and it appears to work. In this case it doesn't make sense to allow for values greater than 32-bits since the rest of the BS2pe accumulation program is using a 32-bit value, as is the server we send it to.