Need some help understanding a counter
I have a variable named RevCount. I am able to call it and display it on my screen ok. When it counts the revolutions it increments by one just fine. The shaft revolution counter counts each turn of a shaft. Every shaft revolution moves a table by .007030371196429 inches.
1. My question is if I want it to increment my count display by that number with each revolution count how do I go about doing that?
2. I would like to have it as precise as possible and understand that the number above has quite a few decimal positions. How big a number can I use in the equations? I want the display resolution to be 4 decimal places.
I have kludged together some bits of code from the OBEX along with some of my own creation so please excuse my mess.
Here is some of the main code:
1. My question is if I want it to increment my count display by that number with each revolution count how do I go about doing that?
2. I would like to have it as precise as possible and understand that the number above has quite a few decimal positions. How big a number can I use in the equations? I want the display resolution to be 4 decimal places.
I have kludged together some bits of code from the OBEX along with some of my own creation so please excuse my mess.
Here is some of the main code:
con
_clkmode = xtal1 + pll16x ' enable external clock and pll times 16
_xinfreq = 5_000_000 ' set frequency to 5 MHZ
Encoder1pin = 16 ' shaft encoder - Propeller pin
F1 = 1.0 ' floating point 1
F60000 = 60_000.0 ' floating point 60,000
obj
kp : "Keypad_encoder" ' keypad driver object P0 - P7
'term : "FullDuplexSerial" ' for serial input & output monitoring
'vfd : "vfd_2x20_4bit_don"
'vfd : "LCD_16x2_4Bit_don"
pst : "Parallax Serial Terminal"
mm : "Motor_Minder"
'lcd : "serial_lcd"
num : "simple_numbers"
F : "FloatMath"
FS : "FloatString"
var
long period, revCount ' motor period and revCount updated by Motor_Minder.spin
long Fwidth, Frpm ' floating point variables for display
pub main | Pressed_Key
pst.start(115_200) ' start terminal (use PST)
pause(200)
'vfd.start
kp.start(4, 4, 0, 4, @table) ' start keypad driver
mm.start(Encoder1pin, @period, @revCount)
'vfd.clear ' clear vfd screen
'vfd.out($00)
pst.str(string("Table Controller", 13))
pst.str(string("Version 1.xx"))
'vfd.str(string("Position Controller"))
pause(2000)
'vfd.pos(0,2)
pst.clear
pst.position(0,0)
pst.str(string("Position: "))
pst.position(0,1)
pst.str(string("Press PROG for Menu"))
pause(1000)
'vfd.pos(0,0)
'vfd.str(string("Key pressed: "))
'repeat 7
' vfd.out($08)
repeat
Pressed_Key := kp.getkey
if Pressed_Key > 0
pst.char(Pressed_Key)
'vfd.tx(Pressed_Key)
'vfd.out(Pressed_Key)
'vfd.out($08)
'vfd.out($08)
pst.str(string(13))
if Pressed_Key == "R"
pst.str(string("PROG button was pressed", 13))
if Pressed_Key == "S"
pst.str(string("START button was pressed", 13))
if Pressed_Key == "E"
pst.str(string("SET button was pressed", 13))
if Pressed_Key == "X"
pst.str(string("STOP button was pressed", 13))
pst.position(10,0)
FS.setPrecision(8)
Fwidth := F.FFloat(period)
Fwidth := F.FDiv(F1, Fwidth)
'Frpm := F.FMul(Fwidth, F60000)
'lcd.str(FS.FloatToString(Frpm))
'lcd.str(string(" RPM "))
'revCount := revCount + 0070
'lcd.gotoxy(0,1)
pst.str(num.dec(revCount))
pri Pause(Duration)
waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
return
dat ' keypad translation table
table byte "1", "2", "3", "S"
byte "4", "5", "6", "R"
byte "7", "8", "9", "E"
byte "N", "0", "P", "X"
' Keypad layout
'
' 1 2 3 Start
' 4 5 6 Prog
' 7 8 9 Set
' - 0 + Stop

Comments
If you only need the result in inches for the display, you can either display it in 10,000ths (equivalent of 4 decimal places) of an inch with no decimal or add the decimal in when you are displaying it.
I have downloaded Jonny Macs 2 bit gray code demo. Here is a portion of his code for displaying the number:
pub main | newlevel, oldlevel term.start(31, 30, %0000, 115_200) ' start terminal for test pause(2000) term.tx(CLS) ' level.init(0, false, 0, 100, 50) ' non-detent encoder on p0/p1 ' level.init(0, true, 0, 100, 50) ' detented encoder on p0/p1 level.init(16, false, 0, 1000, 50) ' non-detent encoder on p16/p17 ' level.init(16, true, 0, 1000, 50) ' detented encoder on p16/p17 pause(1) newlevel := level.read ' read initial value repeat term.tx(HOME) ' display it term.str(string("Encoder: ")) term.dec(newlevel) term.tx(CLREOL) oldlevel := newlevel ' setup to detect change repeat newlevel := level.read ' poll encoder until (newlevel <> oldlevel) ' until it changesIt works very well and displays changes very smoothly and quickly. If I add a line of code to add a multiplication factor to the result before it is displayed it becomes very clunky in displaying the number. It comes in chucks (for lack of a better way to explain it).
Here is an example of what I added:
repeat term.tx(HOME) ' display it term.str(string("Encoder: ")) newlevel := newlevel * 35515 ' This is what I added as a multiplier term.dec(newlevel)Can someone explain why this is happening? Is there a better way to do this type of thing?
Thanks for your help.
Don
repeat term.tx(HOME) ' display it term.str(string("Encoder: ")) term.dec(newlevel [COLOR="red"]* 35515[/COLOR])Try this instead. In your example you modify newlevel which subsequently affects the old/new loop (chances are that it always ends up not equal immediately). If that doesn't solve your problem you'd have to elaborate on the clunky chunk bit.My only issue remaining here is how to apply the multiplier. The multiplier factor is .003515185598214 inches / pulse. I want the display to read in inches from 0 to 5.9999 which would be roughly 0 to 1707 pulses for the 6" max.
Attached please find my latest code.
con _clkmode = xtal1 + pll16x ' _xinfreq = 5_000_000 _clkfreq = 80_000_000 MS_001 = _clkfreq / 1_000 con #1, HOME, #8, BKSP, TAB, LF, CLREOL, CLRDN, CR, #16, CLS ' PST formmatting control ' 0.003515185598214 ' multiplier for inches / pulse obj term : "fullduplexserialdp" ' for terminal output level : "jm_grayenc2" ' 2-bit, graycode encoder kp : "Keypad_encoder" ' keypad driver object P0 - P7 vfd : "vfd_2x20_4bit_don" ' VFD driver var pub main | newlevel, oldlevel, Pressed_Key term.start(31, 30, %0000, 115_200) ' start terminal for test pause(2000) term.tx(CLS) level.init(16, false, 0, 60000, 0) ' non-detent encoder on p16/p17 vfd.start kp.start(4, 4, 0, 4, @table) ' start keypad driver pause(1) newlevel := level.read ' read initial value ' vfd.clear ' clear vfd screen vfd.out($00) term.str(string("Table Controller", 13)) term.str(string("Version 1.xx")) vfd.str(string("Table Controller")) pause(2000) vfd.pos(0,2) term.tx(CLS) 'term.position(0,0) 'term.str(string("Position: ")) 'pst.position(0,1) term.tx(LF) term.str(string("Press PROG for Menu", 13)) pause(1000) ' vfd.pos(0,0) ' vfd.str(string("Key pressed: ")) ' repeat 7 ' vfd.out($08) repeat 'Pressed_Key := kp.getkey 'if Pressed_Key > 0 'term.tx(Pressed_Key) 'vfd.tx(Pressed_Key) 'vfd.out(Pressed_Key) 'vfd.out($08) 'vfd.out($08) 'term.str(string(13)) 'if Pressed_Key == "R" 'term.str(string("PROG button was pressed", 13)) 'if Pressed_Key == "S" 'term.str(string("START button was pressed", 13)) 'if Pressed_Key == "E" 'term.str(string("SET button was pressed", 13)) 'if Pressed_Key == "X" 'term.str(string("STOP button was pressed", 13)) 'pst.position(10,0) oldlevel := newlevel ' setup to detect change term.tx(HOME) ' display it term.str(string("Position: ")) 'newlevel := newlevel * 3515 ' This is what I added as a multiplier 'newlevel := newlevel / 10000 term.decdp(newlevel, 4) term.tx(CLREOL) repeat newlevel := level.read ' poll encoder Pressed_Key := kp.getkey if Pressed_Key > 0 term.tx(Pressed_Key) term.str(string(13)) until (newlevel <> oldlevel) ' until it changes pub pause(ms) | t t := cnt repeat ms waitcnt(t += MS_001) dat ' keypad translation table table byte "1", "2", "3", "S" byte "4", "5", "6", "R" byte "7", "8", "9", "E" byte "N", "0", "P", "X" ' Keypad layout ' ' 1 2 3 Start ' 4 5 6 Prog ' 7 8 9 Set ' - 0 + StopWhat I am using is a separate prop board that "simulates" the gray code as from the machine. It has 2 buttons- one for count up and the other count down. What I'll do is slow the pulses way down to watch the count and verify the accuracy.
I hope that someday I can provide someone with such valuable help as you have for me. I'm marking this as solved.
Don
To do this using integers is relatively simple. First choose a power of 10 multiplier for 0.007030371196429. Since we are doing 32 bit math the largest signed number we can deal with is 2,147,483,647 (unless you want to go to double precision). If we multiply everything by 10^8 the table travel would be 600,000,000 units (deci-micro inches?) and the travel per revolution (0.007030371196429 x 10^8 rounded to nearest int) is 703037.
Add 703037 to a long for each turn of the shaft for distance travelled.
Convert the long to a decimal and insert a decimal point to the left of the 8th digit and you are ready to display it.
Accuracy:
853 x .7030371196 = 5.996906630188
853 x .7030371 = 5.996906463