News:

Let's find out together what makes a PIC Tick!

Main Menu

Struggling with simple maths syntax.

Started by david, Oct 14, 2024, 11:21 AM

Previous topic - Next topic

david

Hi All,
I've spent many hours trying to figure out what I'm doing wrong with two simple lines of code.

Using constants of 130 and 100, this works as expected.  As count decreases the buzzer comes on at 130 and the program goes to quit at 100.  Count is a signed word value but in this part of the code is always >0.  stopset is byte variable.
If mode=1 And count<130 Then buzzer=1       
If mode=1 And count<100 And stopflag=0 Then GoTo quit

If I then use a variable (stopset) of value 50 this effectively produces the same values and works as expected
If mode=1 And count<2*stopset+30 Then buzzer=1
If mode=1 And count<2*stopset And stopflag=0 Then GoTo quit

The problem arises when I add a 1 in the second line with stopset still=50.
If mode=1 And count<2*stopset+30 Then buzzer=1
If mode=1 And count<2*stopset+1 And stopflag=0 Then GoTo quit
There's no sign of the buzzer being activated by the first line and the second line is true when the count goes less than 130.
Is there anything obvious I'm missing here?  I have a work around but would like to learn where I'm going wrong.

Cheers,
David


Frizie

David, I'm not sure if this is the cause but use brackets () to make the code more readable for the compiler and yourself.
Ohm sweet Ohm | www.picbasic.nl

trastikata

Hello david,

can you give a bit more detailed code.

david

Hello Frizie, trastikata - thank you for your interest.
I did try all combinations of brackets but to no avail.   The program is somewhat involved and it may be quicker if I write a new one that is just doing the maths here so I can post the entire process.

Just to recheck, I tried these.  Count is signed Word, stopset is Byte with value of 50.

If mode=1 And count<2*50+30 Then buzzer=1       
If mode=1 And count<2*50+1 And stopflag=0 Then GoTo quit
First line buzzes below 130, second line quits below 101.   Total program bytes is 1216


If mode=1 And count<stopset+stopset+30 Then buzzer=1
If mode=1 And count<stopset+stopset+1 And stopflag=0 Then GoTo quit
First line seems to be ignored, second line quits below 130.   Total program bytes now 1357.  Seems a lot.

Logic would tell me that the value of stopset must be changing but I'm printing it out to the OLED display.
I will try to make up a short diagnostic program that easy to follow and of course it may even highlight to me where I've goofed up.

Cheers,
David


david

I just tried this-

stopset=50
If mode=1 And count<(stopset+stopset+30) Then buzzer=1
If mode=1 And count<(stopset+stopset+1) And stopflag=0 Then GoTo quit
So I assert stopset as 50 immediately before the two problem lines but results are the same. 
The first conditional statement appears to be ignored while the second quits below 130.
I think I can say that stopset is not dynamically changing in the program and it confirms what the display is presenting.

David

trastikata

I think the problem arises in the comparison of signed variable "count" and the expression of unsigned variable with literal "2*stopset+1", which comparison is being interpreted wrongly and the wrong routines are called.

If you adjust the code to:

QuoteDim swTemp As SWord

swTemp = 2*stopset
If mode=1 And count<swTemp+30 Then buzzer=1
If mode=1 And count<swTemp+1 And stopflag=0 Then GoTo quit

It should work, because now for the comparison the correct routines will be used.


david

Hi trastikata,
Many thanks for your kind support.  I think you're on to something.
I tried declaring stopset as a SWord

If mode=1 And count<(stopset+stopset+30) Then buzzer=1
If mode=1 And count<(stopset+stopset+1) And stopflag=0 Then GoTo quit
Neither line responded to a decrementing count value.

However - changing stopset to a SByte, both lines worked correctly.

This format also worked correctly with stopset as a SByte.
If mode=1 And count<2*stopset+30 Then buzzer=1
If mode=1 And count<2*stopset+1 And stopflag=0 Then GoTo quit

Aren't I lucky that stopset only needs to go as high as 90 and as low as zero.
Many thanks for your great assistance.

Cheers,
David



joesaliba

David,

If you are using the syntax in your code as you listed: -

If mode = 1 And count < 130 Then buzzer = 1       
If mode = 1 And count < 100 And stopflag = 0 Then GoTo quit

you might have the buzzer on but at a reduced / different tone. Why?

Because you are checking for Count if is smaller than 100 to Quit, but it is also true that in line 1, if Count is say 90, Count is also smaller than 130, so the buzzer will turn ON, and then immediately OFF with line 2.

If that is the case, you must swap the lines: -

If mode=1 And count < 100 And stopflag = 0 Then GoTo quit
If mode = 1 And count < 130 Then buzzer = 1

So, if Count is 90, it will Goto quit, hence executing line 1, but if Count is greater than 100 and smaller 130, 1st line is skipped, as it does not match the criteria, and then executes line 2 as it meets the criteria.

Apologies if I wrongly interpreted your question.

Kind regards

Joe

david

Hello Joe and many thanks for your input.
It's a fair thought you raise but in this case I should be ok as I exit the loop that these statements are in when the count descends below 100.  So mode=1 effectively means counting down and below 130 the buzzer is on but below 100 all processes stop including the counting.    I still might change them over as you suggest as it does seem more logical and in a different application it could catch me out.

Cheers,
David

SeanG_65


david

I can't say I have but I believe the problem lies in the mix of a signed Word and an unsigned Byte.
This was working correctly by declaring stopset as SByte....

If mode=1 And count<2*stopset+30 Then buzzer=1
If mode=1 And count<2*stopset+1 And stopflag=0 Then GoTo quit

BUT - it was taking around 300uS (at 16MHz clock) !!!!!  At high -ve counts (-4096) I didn't have enough time left on the fastest stepper pulses.  Now I don't need the logic to function on -ve counts but I also don't want it to mess up the stepper rate.

After much playing around, I ended up with this

temp=count
If count<0 Then temp=0
temp1=2*stopset+1
temp2=2*stopset+31
If temp<temp2 And mode=1 Then buzzer=1
If temp<temp1 And mode=1 And stopflag=0 Then GoTo quit

It's more verbose but works correctly and executes in under 17uS so no problems with high -ve counts.

I will try ElseIf - I've tried everything else but there is definitely something about this simple maths that I'm not understanding.
The attached picture shows the stepper pulses (800uS lower trace) and the (cryptic) serial data sent to the display (top trace).  The small gap at the end of the serial data represents the worst case timing - shortest stepper period and maximum data sent to the display board.

Cheers,
David