PDA

View Full Version : Round the clock



camerart
- 21st January 2016, 16:20
Hi,

I'm programming a PIC in Oshonsoft basic and having problems with > or < when it comes to, in my case a 360 degree compass bearing. I understand that this is not an Oshonsoft forum, but I am more interested in the logic.

If I explain it with a CLOCK face and a hour HAND. Hopefully it can be understood, by this explanation, but bear with my simple!!! explanation, and I have been known to make mistakes. There are 4x states, in the program.

If the HAND is pointing at 3 (HAND = 3) and I want it to go to 4 on the FACE (FACE = 4); [If HAND < FACE then move cwise] and visa versa.
If the HAND is pointing at 12 and I want it to go to 1; [If HAND < FACE then move cwise] doesn't apply.

It's this crossover point that I'm having trouble with. (HAND is counting and comparing as it moves)

1/2 way round the clock is 6, so [If HAND - FACE > 6 then move cwise] applies.

There is an added complication: I want HAND to be HAND + or - 1, so 3 includes 2 and 4.

If this is understandable, does anyone know how to solve it please?

Camerart.

Ioannis
- 21st January 2016, 19:38
Can you count on 24h basis? If your counter is counting that way, then you can display the modulus 12 value.

Ioannis

camerart
- 21st January 2016, 21:59
Hi I,

No because the HAND goes round and round.

C.

Ioannis
- 22nd January 2016, 09:19
The hand can do the round, but your variable can hold whatever value. Also with Mod 12 you still have the 12h basis value.

Ioannis

camerart
- 22nd January 2016, 09:29
The hand can do the round, but your variable can hold whatever value. Also with Mod 12 you still have the 12h basis value.

Ioannis

Hi I,

I don't understand your answer, can you explain what MOD 12 is please?

C.

Ioannis
- 22nd January 2016, 09:37
Modulus division. You divide by 12 and keep the as a result the integer remainder of the division.

So 23.00 h mod 12 gives remaider 11, exactly what 23 at 12h basis is.

Ioannis

camerart
- 22nd January 2016, 10:10
Modulus division. You divide by 12 and keep the as a result the integer remainder of the division.

So 23.00 h mod 12 gives remaider 11, exactly what 23 at 12h basis is.

Ioannis

Hi I,

I'm not so good at Maths, so please make allowances:)

I have to read instructions a number of times to 'get it'. In this line is there a word missing? [You divide by 12 and keep the=== as a result the integer remainder of the division.]

As mentioned, I'm programming a PIC and I just looked at the Oshonsoft manual, here is a paragraph:
Five arithmetic operations (+, -, *, /, MOD) are available for integer data types. MOD operation is not applicable for Single data type variables. The compiler is able to compile all possible complex arithmetic expressions, including those containing math functions and user defined functions. For example:
Dim i As Word
Dim j As Word
Dim x As Word
i = 123
j = i * 234
x = 2
x = (j * x - 12345) / (i + x)

From my reading, and as I'm using SINGLEs, this means I can't use MOD. If so is there another way? (SINGLEs allow 0.0000000)

C.

Ioannis
- 22nd January 2016, 11:01
I have not used the Oshonsoft compiler yet, although I have it.

But nothing bothers you to use a Word variable instead of the Single.

I wrote my post in succesive interruptions because of phone calls and other tasks, so yes, the word "the" should be deleted.

Ioannis

camerart
- 22nd January 2016, 11:12
I have not used the Oshonsoft compiler yet, although I have it.

But nothing bothers you to use a Word variable instead of the Single.

I wrote my post in succesive interruptions because of phone calls and other tasks, so yes, the word "the" should be deleted.

Ioannis

Hi I,

Oshonsoft is a good simulator for me, although it does have faults.

I need the SINGLE in the equation as it can cope with precision 0.0000000 calculations, WORD won't work.

C.

Amoque
- 22nd January 2016, 13:40
I do not follow the conversation well enough to speak in context, but in doing a similar thing I found the solution to calculate direction and distance separately; then, once I'd accurately calculated these, dump off those variables to a routine that "swung the needle". I did not need to worry about "round" however as I was programming to mimic analog gauges.

Last, to simulate MOD subtract the integer value from the single value - that decimal portion which remains...

camerart
- 22nd January 2016, 14:34
I do not follow the conversation well enough to speak in context, but in doing a similar thing I found the solution to calculate direction and distance separately; then, once I'd accurately calculated these, dump off those variables to a routine that "swung the needle". I did not need to worry about "round" however as I was programming to mimic analog gauges.

Last, to simulate MOD subtract the integer value from the single value - that decimal portion which remains...

Hi A,

Here's another explanation, again using the clock:

1/ The HAND is at 3. Input FACE 5. HAND<FACE = cwise. HAND moves and counts. HAND=4. HAND<FACE=cwise. HAND moves and counts. HAND=5. HAND=FACE =BRAKE.

2/ The HAND is at 12. Input FACE=1 HAND>FACE = ccwise NOT CORRECT.

I want FACE to cover FACE+1 and FACE-1.

3/ The HAND is at 12. Input FACE=1 Now FACE-1= -1.

This is difficult for me to understand.

I am also trying to understand the MOD suggestions. I will need to check the program to see if I can use MOD, as I get to understand it more.

Thanks. C.

C.

AvionicsMaster1
- 22nd January 2016, 21:14
Is it the MODulus operation you're having problems with or its implementation?

I had to get a pencil and paper out and do some modulus operations before my extremely thick skull was pierced enough to see how the modulus operator worked. Once understood it's pretty neat. Now if I could only get the */ thingy figured out.

camerart
- 22nd January 2016, 22:35
Is it the MODulus operation you're having problems with or its implementation?

I had to get a pencil and paper out and do some modulus operations before my extremely thick skull was pierced enough to see how the modulus operator worked. Once understood it's pretty neat. Now if I could only get the */ thingy figured out.

Hi A,
I've had quite a bit of MODulus explained to me since it cropped up a day or two ago, and I'm beggining to see the light. It does appear to be the right way to go.

What problems are you having with * and /?

C.

camerart
- 24th January 2016, 12:23
Hi,

The program itself is fine at the 12 to 0 changeover, but with a DEADBAND, it complicates things.

Ioannis suggested Modulus also using a 24Hr clock.

After trying to get to know Modulus, for a while, I can only guess, that it won't correct my problem. The problem is a DEADBAND, so 'say' 3 with a DEADBAND of 1 would be 2 to 4. At o it will be -1 to 1. I don't get the impression that Modulus works with minus numbers.

I experimented with the 24 hour clock, and as the clock goes round and round, eventually it will be 24 then 0 again, so a similar problem. I finally only use 24Hr for a small section around 12 or 0. then revert back to 12 hour, this works fine.

Thanks for all suggestions, C.

Ioannis
- 24th January 2016, 15:29
Normally you won't count to 24 but up to 23:59. But I have missed the point of -/+1 here.

Ioannis

camerart
- 25th January 2016, 12:47
Normally you won't count to 24 but up to 23:59. But I have missed the point of -/+1 here.

Ioannis

Hi I,

My actual system uses 0 to 3581 steps, but that's complicating things:) This is why I used the clock analogy. And yes, it is 0 to 23:59, but again this is complicating things, as there are 60 minutes/hour. So I'll use 0 to 11.

The mechanics of my system: A motor moves the pointer to the incoming data, so if it is pointing to 3 and data says 4 then it moves cwise till it matches. The motor moves quickly, so as it comes towards 4 it needs to switch off the motor, before it matches, so I added a deadband, which gives data -1 and +1, where no power to the motor within this band. Now say the pointer is at 3 and data says 5 the pointer is moves cwise and switches the power off at 4. In this example, this looks coarse, but in reality, it is much finer.

I hope this clarifies things.

C.

HenrikOlsson
- 25th January 2016, 18:55
Hi,
Try this:

Position VAR WORD
Target VAR WORD
Distance VAR WORD

Position = 1234

Main:
HSEROUT[13, "You're at position: ", DEC Position, 13]
HSEROUT["Enter new target: ",13]
HSERIN[DEC Target]

' Actual calculation starts here.
' When done the variable Distance contains the
' number of "ticks" to target in two's complement format.
Distance = Target - Position

IF Distance.15 = 0 THEN ' Distance is positive
If Distance > 1790 THEN
Distance = Distance - 3580
Endif
ENDIF

IF Distance.15 = 1 THEN ' Distance is negative
IF ABS Distance > 1790 THEN
Distance = Distance + 3580
ENDIF
ENDIF
' End of calculation, result now in Distance.

Done:
IF Distance.15 = 1 THEN ' Distance is negative
HSEROUT["CCW "]
ELSE
HSEROUT["CW "]
ENDIF

HSEROUT[DEC ABS Distance, " ticks.", 13]

Position = Target

Goto Main

/Henrik.

camerart
- 26th January 2016, 10:01
Hi H,

Thank you, I will try it and let you know what happens. I'm a bit slow understanding code though:)

Will you annotate where the DEADBAND is in your code please?

C.

HenrikOlsson
- 26th January 2016, 11:08
There's no deadband but it's easy enough to add that after the actual calculation, before you decide to move or not

IF ABS Distance > Deadband THEN
' Make the move
ELSE
' Sit tight
ENDIF


/Henrik.

camerart
- 26th January 2016, 19:42
Thanks H, C

camerart
- 27th January 2016, 06:09
There's no deadband but it's easy enough to add that after the actual calculation, before you decide to move or not

IF ABS Distance > Deadband THEN
' Make the move
ELSE
' Sit tight
ENDIF


/Henrik.

Hi Henrik
Does this also work for 'IF ABS Distance > Deadband THEN' and 'IF ABS Distance < Deadband THEN' at the change from 11 to 0 and 0 to 11?
C.

HenrikOlsson
- 27th January 2016, 10:46
Have you tried it?

Using your numbers with 3580 ticks around the circle:

If you're moving from 0 to 11 distance is +11.
If you're moving from 11 to 0 distance is -11.
In both cases the ABSolute value of distance is 11. If you have deadband set to 1 then you'll move because distance is larger than deadband.

If you're moving from 11 to 12 distance is +1.
If you're moving from 12 to 11 distance is -1.
In both cases the ABSolute value of distance is 1. If you have deadband set to 1 then you won't move because distance is not larger than deadband.

/Henrik.

camerart
- 27th January 2016, 12:16
Have you tried it?

Using your numbers with 3580 ticks around the circle:

If you're moving from 0 to 11 distance is +11.
If you're moving from 11 to 0 distance is -11.
In both cases the ABSolute value of distance is 11. If you have deadband set to 1 then you'll move because distance is larger than deadband.

If you're moving from 11 to 12 distance is +1.
If you're moving from 12 to 11 distance is -1.
In both cases the ABSolute value of distance is 1. If you have deadband set to 1 then you won't move because distance is not larger than deadband.

/Henrik.

Hi Henrik,

My system is actually 0 to 3581, so 3582 ticks/circle. I used the 0 to 11 clock face to simplify my question, so actually 11 to 0 is similar to 3283 to 0.

This is an interesting solution, if I can use it. At the moment I'm trying to unravel a pile if spaghetti:) with my existing program.

I have to convert it for use with the Oshonsoft system, while learning about ABS, and the ????????.15 variable. I'm not sure if Oshonsoft supports ABS, but I assume it can be got round in some way.

I'll let you know once I get it running, thanks.

C.

HenrikOlsson
- 27th January 2016, 12:47
PBP doesn't have signed 16-bit (WORD) variables so the distance.15 is simply a way to determine if the value is negative. The equivalent code, if you have signed variables, would be:


Distance = Target - Position

IF Distance > 1790 THEN
Distance = Distance - 3580
Endif

IF Distance < -1790 THEN
Distance = Distance + 3580
ENDIF

/Henrik.

camerart
- 27th January 2016, 15:28
Hi Henrik,

As mentioned my system has 3582 tick/rev, so is the 3580 in the last post correct?

I don't think Oshonsoft supports negative values, but I'll check.

Thanks, C.

HenrikOlsson
- 27th January 2016, 18:01
Oh come on, think or at least do some trial and error your self now! ;-)

The ABS and Distance.15 is some "trickery" to make it work with PBP but the "clean" formulas shuld work fine with pen and paper. Try it out, make it work with the 12 hour clock example you actually asked for first. Then try wth the larger numbers, I'm sure you'll be able to figure out what needs tweaking for any number of ticks around the circle.

You were interested in the logic. This, I think, is one way of doing it but I'm sure there are others. As for how to actually implement it on Oshonshoft you're on your own or at least in the hands of someone else.

/Henrik.

camerart
- 28th January 2016, 09:16
Oh come on, think or at least do some trial and error your self now! ;-)

The ABS and Distance.15 is some "trickery" to make it work with PBP but the "clean" formulas shuld work fine with pen and paper. Try it out, make it work with the 12 hour clock example you actually asked for first. Then try wth the larger numbers, I'm sure you'll be able to figure out what needs tweaking for any number of ticks around the circle.

You were interested in the logic. This, I think, is one way of doing it but I'm sure there are others. As for how to actually implement it on Oshonshoft you're on your own or at least in the hands of someone else.

/Henrik.

Hi Henrik,

I can assure you that I'm not simply asking questions and waiting for help, as I am working hard at this end;)

As I'm better at visual than pen and paper, I'm trying to get it to work in Oshonsoft, which causes extra problems.

In the larger program that this code is intended to go into, I have use another way, but it doesn't lend itself to adding DEADBAND easily around the 11 to 0 jump.

I asked someone to help me convert your code to Oshonsoft, and they 'jumped the gun' and are trying to add it into my larger program. This is good if I like your code, but a waste of time if I don't!!!

C.

camerart
- 28th January 2016, 09:44
Hi,

I just got a message from the other forum, helping me to get your code working in Oshonsoft: [Testing 'distance.15' in the program will not make any difference to the Dead band angle detection, its just another way of doing what we have already done.:)]

So it looks to me that I have to simply keep working on my program, till I come up with a solution for adding the DEADBAND.

Thanks to all that helped me.

Camerart.