Doing something at predefined amount of steps?

# Thread: Doing something at predefined amount of steps?

1. ## Doing something at predefined amount of steps?

Hello and sorry for bogus title, I just can't explain it simpler in short terms The idea is as follows, there is a variable, incremented from 1 to say 1000.

There is something to be done in each 5, 19, 23, 49 or whatever step of that variable.

On ZX Spectrum, I was using thing like: IF I/21=INT(I/21) THEN xxxx

Here we don't have floating math, so trick with INT won't work. So I came up with the following solution - inside the main variable loop, there's another helper variable, which is incremented by 1, along with main variable. When it reaches predefined value - say 84, we do the thing we have to do, and also reset that variable, so count starts again.

Are there other ways of doing that more simple?  Reply With Quote

2. ## Re: Doing something at predefined amount of steps?

I think what you're looking for is the modulo operator (//).
It will return the remainder of a division so whenever it returns 0 it means it was an "even division".

Code:
```MainCount = MainCount + 1

IF MainCount // 5 = 0 THEN  ' Do something every 5th count
GOSUB Task1
ENDIF

IF MainCount// 19 = 0 THEN   ' Do something every 19th count
GOSUB Task2
ENDIF```
Something like that perhaps.  Reply With Quote

3. ## Re: Doing something at predefined amount of steps?

Thanks! this is way better and simpler. Speaking speed-wise, will this be faster in execution than my code with additional variable?  Reply With Quote

4. ## Re: Doing something at predefined amount of steps?

I don't know for sure but since it involves division my guess is that this is slower. Speed isn't always everything though.

Tell you what, why don't you try both ways and measure the difference, that way we might learn something and/or figure out an even better way.

/Henrik.

EDIT: Just tried it, the modulo aproach is about an order of magnitude slower.

EDIT2: And that's with a WORD sized variable. If using a BYTE sized variable the modulo aproach is pretty much the same while "the other method" is yet again reduced to about 1/4 or roughly 40-50 times faster than the math intensice modulo aproach.
Last edited by HenrikOlsson; - 21st July 2019 at 15:14.  Reply With Quote

5. ## Re: Doing something at predefined amount of steps?

Wasnt it just something like this?
not even timing of course because every fifth iteration takes slightly longer to execute, but could be balanced up if it mattered.

Code:
```variable var word
something var word

for variable = 0 to 1000
'do the first thing
something = something + 1
if something > 4 then
something = 0
'do the second thing as well
endif
next variable```  Reply With Quote

6. ## Re: Doing something at predefined amount of steps?

Yes, I meant exactly that one.

In my case, there will be 16F886 running at 8mhz and maximum frequency will be around 2khz, so I guess, modulo variant will also work. Will assemble test circuit tomorrow and measure speeds.  Reply With Quote

7. ## Re: Doing something at predefined amount of steps?

Oh and by the way, currently I don't have access to machine with PBP, what will happen if C=A-B and B is > A ? all variables are word length. I need to determine difference between A and B, but sometimes B can be greater then A, so have to invent something   Reply With Quote

8. ## Re: Doing something at predefined amount of steps?

It will wrap around, 0-1=65535 provided the variable where the result is stored is a WORD.  Reply With Quote

9. ## Re: Doing something at predefined amount of steps?

How about For..Next...Step  Reply With Quote

10. ## Re: Doing something at predefined amount of steps?

Thanks Henrik, so Say A=200 B=300, C in this case will be 65535-100=65435, right? So if I take 65535 and minus it result, I should receive correct difference between A and B, right?

How about For..Next...Step - this won't work, since there are several actions which had to be done at various steps of main variable.  Reply With Quote

11. ## Re: Doing something at predefined amount of steps?

No, 200-300=65436.
65435 is -101 in two's complement because 65435+101 = 65536 which, when being truncated to 16 bits is 0.

If what you want is the difference between the two numbers while not caring which one is bigger or smaller just use the ABS operator.

A = 200
B = 300
C = ABS(A-B) ' C will now be 100  Reply With Quote

12. ## Re: Doing something at predefined amount of steps?

for the sign, so long as a & b are the same variable type:
Code:
```if (a - b) > a then
sign = 1 ' result will be negative
else
sign = 0 ' result will be positive or zero
endif```
or something similar to what ABS would have to do behind the scenes:

Code:
```a var byte
b var byte
c var byte
sign var bit

a = 10
b = 20

if (a - b) > a then
sign = 1 ' result will be negative
else
sign = 0 ' result will be positive or zero
endif

c = a - b

if sign = 1 then
c = \$ff - c ' fix the abs value
endif

'result is sign,c ... or negative 10.```  Reply With Quote

13. ## Re: Doing something at predefined amount of steps?

I'm slowly advancing in this task Here you can see video filmed from slider itself, and video how slider operates (on this video it is running 20x faster than during filming).

(Some jerking is due to youtube issues, original video is all fine)

So now I come to "programming" part - where I move slider into start position and set head as needed, record that position and then move it to end position and record settings again. This part of software is done and I'm writing directly to eeprom, so data can be re-called on next boot. Now I have to "play" recorded data back. I see it in the following way:

Logic:

1. Measure position readings for both axes at beginning and end, and based on this, calculate number of steps needed on each axis

2. determine amount of steps on which axis is larger

3. Divide larger number of steps by smaller, to determine skip value

4. Make loop with length of longer axis, which gives single pulse on each loop turn for that axis, and skips calculated number of steps to deliver required number of pulses on shorter axis.

Here is "code" for it, have not tried it yet, since no PBP on this machine, but I'm having feeling, that something is wrong here....

Code:
```GOSUB CALCULATOR' This is routine which reads ADC values and returns number of steps in X and Y variables. (already done)

IF X>Y
THEN   'DETERMINE WHICH STEPS ARE MORE and make Z equal it and make W equal to less
Z=X 'Z=more steps
W=Y 'W=less steps
ELSE
Z=Y 'make loop walk more steps which is
W=X
endif

E=Z/W 'determine how much is difference

FOR A=0 TO Z 'LOOP FOR MAKING STEPS

If X>Y 'need to make step on the correct lane
Then Gosub PULSEX 'this subroutine makes single step on X axis
ELSE
Gosub PULSEY 'this one - on Y axis
Endif

'now make pulse with skipping on 2nd axis, based on modulo operation

IF A//E=0 and X>Y then GOSUB PULSEY
IF A//E=0 and Y>X then GOSUB PULSEX
next```  Reply With Quote

14. ## Re: Doing something at predefined amount of steps?

Logic look good to me.

But you have very inefficient part of code...
Code:
```IF A//E=0 and X>Y then GOSUB PULSEY
IF A//E=0 and Y>X then GOSUB PULSEX```
This 2 line generate more than 400bytes of code, and it is really slow to execute.
If you define one more word or long variable, you can get more than double speed of execution with exactly same output. Here is example.

Code:
```tmp=A//E 'Calculate mod only once
if Tmp=0 then check only once if it is zero
if X>Y then 'if it zero, check is X>Y
GOSUB PULSEY
else 'or if Y<=X, your code doesn't do anything if it is =
GOSUB PULSEX
endif
endif```
Compile do 257bytes.  Reply With Quote

15. ## Re: Doing something at predefined amount of steps?

It works, but not exactly, the problem is that ADC readings are not linear, so using predefined number of steps does not work, need to read adc constantly and adjust steps based on it.  Reply With Quote

16. ## Re: Doing something at predefined amount of steps?

Can't Select case help?

Ioannis  Reply With Quote

17. ## Re: Doing something at predefined amount of steps?

So currently I have the following conditions.

Slider movement from edge to edge (30cm) is 100 readings from ADC - value changes from 300 to 400.
Head rotation (it can do 720 degrees) is 800 readings from ADC - value changes from 100 to 900.
So for one step on slider, I have to do 8 steps on head.
Now I'm adjusting code based on that.  Reply With Quote

18. ## Re: Doing something at predefined amount of steps?

Does this come close to what you want?

Code:
```SELECT CASE slider_adc
CASE 300
SELECT CASE head_rotation
CASE 100
do_this1
CASE 200
do_this2
END SELECT
CASE 310
SELECT CASE head_rotation
CASE 300
do_this3
CASE 400
do_this4
END SELECT
.....

CASE ELSE
anything_else_here_(optional)
END SELECT```
Ioannis  Reply With Quote

19. ## Re: Doing something at predefined amount of steps?

I run into different problem now - division by 0 returns 65535. Is this normal?

Code:
```SPOS1=550
SPOS2=600
RPOS1=550
RPOS2=550

SLEN1=ABS(SPOS1-SPOS2)
RLEN1=ABS(RPOS1-RPOS2)

IF RLEN1/8>SLEN1 then 'if rotator movement is more than slider
MOVE1=RLEN1/8/SLEN1 'then coefficient equals to   rotator divided by slider
else
MOVE1=SLEN1/(RLEN1/8) 'else coefficient equals to slider divided by rotator
endif

LCDOUT \$FE,\$01,"sl ",#SLEN1, " rl ", #RLEN1
lcdout \$FE,\$C0,"coeff ",#MOVE1```
With above values, MOVE1 becomes 65535, why?  Reply With Quote

20. ## Re: Doing something at predefined amount of steps?

division by 0 returns 65535
Division by zero is a meaningless operation. Its result is undefined.

What does your calculator do when you try to divide by 0? What should it return?  Reply With Quote

21. ## Re: Doing something at predefined amount of steps?

Division by 0 returned 0 in good old times, and I was hoping for same here, but no problem, adding another IF-THEN fixes that.

Another question, going on business trip with my laptop, so I will be doing nothing for about 16 hours, which I hope to use for working on this firmware. Are there any freeware, easy to use simulators which can simulate 16F886 with 1602 LCD attached and couple of buttons, leds and ADC input? I  Reply With Quote

22. ## Re: Doing something at predefined amount of steps?

Free, I do not think so. Cheap yes...

http://www.oshonsoft.com/pic.html

Ioannis  Reply With Quote

23. ## Re: Doing something at predefined amount of steps?

Write it your self's....  Reply With Quote

24. ## Re: Doing something at predefined amount of steps?

Downloaded trial of that PIC simulator - it appears to not be working, I mean I can load hex, run it, I see instructions cycling, but no led blinking, no LCD is outputting anything....

Also downloaded trial of Proteus - this is mega huge, still haven't figured out how to simulate   Reply With Quote

25. ## Re: Doing something at predefined amount of steps?

Just did a quick test on the demo version of PICSimulator.exe with the attached hex file. This program was built for 16F84 and the whole basic code is this:

Code:
```led var portb.0

start:
high led
low led
goto start```
test.HEX.txt

It is simulated just fine, toggling portb.0.

I guess you did not waited long enough for the initialization of the LCD. It takes time. Long time. You can speed it up a bit by Ctrl+F6, but this leads to not showing "real time" port changes.

Best result if you write the program in the PIC simulator editor with the Oshon's basic version. This way you will see the basic commands executing.

Ioannis  Reply With Quote

26. ## Re: Doing something at predefined amount of steps?

Thanks a lot! it was really time issue, I did not expected it to take so long to show something I waited about 20 seconds and LCD shows text now and led also blinks.  Reply With Quote

#### Members who have read this thread : 21

You do not have permission to view the list of names.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts