Why not just use a LOWPASS filter like this?

' ************************************************** ******************
LOWPASS0: 'LOW PASS FILTER (256 = NO FILTER)
' ************************************************** ******************
PASTVAR = (PASTVAR - (PASTVAR */ FILTER)) + INVAR
OUTVAR = PASTVAR */ FILTER 'FINAL DRIVE OUTPUT COMPUTED
RETURN

LOL what I actually need is ROUND statement which will round, for example, 799 to 800.

Hysteresis idea is great and I've done in fact PID algorithm on pic by myself, but I don't see how it is related. All I want is to have rough, 80 position input from ADC, without data flickering, that's all.

What are you doing with that data? Are you just displaying it and you are annoyed by the flicker?

Ioannis

LOL what I actually need is ROUND statement which will round, for example, 799 to 800.
what would you "round" 798 to ?

This data is feedback from position of camera slider. For the rounding, I'm dividing it by 10, and PBP does it wrong - instead of rounding to nearest big, it rounds to nearest small value.

I mean, 796/10 should be 80, but PBP returns 79.

I mean, 796/10 should be 80, but PBP returns 79.
so (796+5)/10 = ?

For the rounding, I'm dividing it by 10, and PBP does it wrong -
It doesn't do it wrong. Integer division doesn't round... it truncates. If you want to round the number you need to do something before the division.

so (796+5)/10 = ?
Thank you.

796 will keep changing, so there always will be then case than final result will be less again.

Regarding how it does, in school I was taught that if something is above 5, it is rounded to nearest big, and if less than 5, then to nearest small. I mean, 79.6 should be rounded to 80 and 79.4 to 79.

That's how rounding works when you have fractional numbers.

Most (all?) uC's only represent numbers using integers so there's no fractional part for it to "round". Division always throws away what would be the fractional part.

Do your division first looking at the integer result (796 / 10 = Result) then do it again looking at the remainder/modulus (796 % 10 = Modulus). If modulus >= 5 Then Result += 1.

That will give you the control of your rounding issues.

I have been following this thread for some time and you say this in post #46 "This data is feedback from position of camera slider." What are you doing with the feedback data? Using it to close loop on the position? WOW I can see it now, the camera jittering back and forth because of rounding of the position data. When I mention a lowpass filter in post #41 you "LOL". What kind of position timing are you looking for? In an earlier post you talked about controlling the position from some position data entered into eeprom or ram and recalling it. Once again I have to ask, What kind of response timing are you looking for as far as positioning the slide to the commanded data? Personally I would use a lowpass filter for the feedback data to do a closed loop and not have the camera moving back and forth due to rounding of the position data. It also looks like you have significant noise problems with the target system as Richard mentioned in post #38.

Originally Posted by mpgmike
Do your division first looking at the integer result (796 / 10 = Result) then do it again looking at the remainder/modulus (796 % 10 = Modulus). If modulus >= 5 Then Result += 1.

That will give you the control of your rounding issues.
in Post #35 , I tried to explain the same thing in a different way; but I think he could not get it work.

I tried that thing with modulus and +5, but in real code it causes more noise. Say digit is jumping between 699-700, with that code, I occasionally see it jumping to 707. For the noise, in ADC reading in 0-1023 range, I only have last digit having noise issues, and that is also only sometimes.

But meanwhile I run into an speed issue.

Code:
```dremo:
if SPS>350 and SPS<480 then
high SST
@nop
@nop
@nop
low SST
endif
if SPS<360 then high SEN
if SPS>470 then low SEN
goto dremo

pause 1
St3=abs(st1-st2)
if St3=0 then
SPS=St1
else
SPS=SOL
endif
SOL=SPS
return```
Driving SST pin high and low generates pulses to stepper motor. On PIC16F886, this code runs fine with speed of around 200Hz. Considering this is for only one axis and similar code should be added for another axis, speed will be even lower, which is not enough for my uses (need at least 200Hz on both axes). So I have either to switch to at least 32mhz chip, or optimize code above?

Replaced Pause 1 in ADC subroutine with 5 NOPs and speed is now 780Hz. I guess if I interleave both ADC reading operations, can get total speed of 400Hz, which should be enough...

An approach I use to reduce UART transmissions of redundant data is to use a simple filter:

Code:
```AdcVal VAR BYTE

;Do Something
ENDIF```
Expanding this you might try something like this:
Code:
```VarCnt VAR BYTE

VarCnt = VarCnt + 1
IF VarCnt = 10 THEN
;Change Camera Angle
VarCnt = 0
ENDIF
ENDIF```
This would reduce the jitter, and with fast ADC reads, latency might not be an issue.