Page 1 of 1

Variable types Versus PIC type

Posted: Mon Nov 20, 2023 9:03 am
by simon-sandtcontrols
Hi All,

This might be a daft question, but I can't find any information on it. Will any variable type work in any PIC?

I am using a PIC16F1937 and with a number of 40,000 in a long variable generated a negative value, then tried an unsigned integer and got a negative value again.

Many Thanks.

Simon

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 9:24 am
by Steve-Matrix
If I understand you question correctly, then you are asking about implicit integer conversion/promotion.

Flowcode generates C code that is compiled by different compiler toolchains depending on the target device. For example, XC8 is used for 8-bit PICs. Once the C code is generated, the compiler takes charge and creates the code for the device and follows certain rules around implicit conversions. However, some of these are not defined by the C standard and the resulting code will be "implementation specific" (i.e. it is up to that specific compiler to decide).

This page has more information on the specifics, but it can get quite complicated. The specific compiler documentation may also have information.

To avoid this issue you should use data types that can accommodate any value you anticipate that variable will need to hold. But this is sometimes impractical (especially on a smaller 8-bit device). Similarly, floating point values could be used, but these might be overkill and can cause their own issues (e.g. rounding errors).

If you are likely to encounter these issues, then you should test your code in many situations - especially the "corner cases" where the values of variables can cause problems.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 9:47 am
by simon-sandtcontrols
Thanks Steve,

I must confess I didn't realise it was as complex as this behind the scenes, so to speak, I have simply done a calculation that generates a number larger than a signed integer can cope with, so changed the variable type to a long, when this didn't make any difference I started to try and work out why, or what I had done wrong. The code worked fine in the simulation, but not in the chip. Hence the question.

From this, I am guessing that the 8 bit PIC's (or compiler) can't cope with anything more than a signed integer, so generating numbers bigger than 32767 should be avoided.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 10:04 am
by Steve-Matrix
Yes - it can be complicated!

8bit PICs can copy with larger numbers fine, so you don't need to avoid them. You just need to be aware and ensure you are using the appropriate data type.

Regarding the discrepancy between simulation and chip execution, there are sometimes differences like these that we cannot completely account for. But it could be a bug in the simulation. If you can reduce the issue to a very simple flowchart and post that, that may help us determine if it requires a fix.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 11:04 am
by simon-sandtcontrols
OK, Thanks Steve,

The problem has occurred in one apparently simple calculation. I have attached the entire flowchart as it isn't exactly the most complicated. It is to dispense oil, so reads a flow meter that gives 596 pulses per litre and matches it to the value entered on the keypad. The problem occurs in the last part of the chart, scroll to the bottom and there is a calculation box, and as it's working in ml and to get the accuracy, I multiplied the input value by 596, then divided it by 1000. The divide by 1000 is rem'ed out and the value is printed to the LCD just before it enters the last loop, these are for bug picking. Obviously 9999ml x 596, gives a 7 digit value, but should be well within a Long variables capability.

I may have done something daft, it won't be the first time. But changing the "Pulses" variable to different types, Long, Unsigned integer, etc, makes no difference, I can still generate a negative number.

I think I may have encountered this problem before and just found work arounds, which is what I can do with this, but it would be nice to know for future, where I am going wrong, or if it's simply the 16F1937 can't cope with Longs or Unsigned Integers.

Thanks again.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 11:48 am
by Steve-Matrix
One thing to note is this:

Code: Select all

Pulses = Qty_Tot * (Pulses_Per_l / 100)

i.e. Pulses = Qty_Tot * (596 / 100)
This will evaluate the "596 / 100" first, which produces "5" (it is rounded down to the nearest integer). You should have:

Code: Select all

Pulses = (Qty_Tot * Pulses_Per_l) / 100
to maintain precision.

It may be best to separate your calculation lines into separate ones to see where the calculation is going wrong for you.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 11:56 am
by simon-sandtcontrols
Hi Steve,

Bugger, I have missed deleting the /100 and brackets when I sent it to you. I added them to try and get round the problem. I was going to try dividing by 100 and then divide by 10 later to try and keep the numbers smaller!!

That line should read "Pulses = Qty_Tot * Pulses_Per_l" then the "Pulses = Pulses / 1000" comes in afterwards.

Sorry, that just confused things.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 11:59 am
by simon-sandtcontrols
I have just corrected it. This is what I had originally when I encountered the problem.

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 1:24 pm
by LeighM
On this target device, the "Qty_Tot * Pulses_Per_l" will give an INT result (even if it overflows)
this will then get saved as a LONG in Pulses

Try changing Qty_Tot to a LONG (this will force the maths on the right hand side)

Re: Variable types Versus PIC type

Posted: Mon Nov 20, 2023 3:00 pm
by simon-sandtcontrols
That's sorted it, oh so simple when you know how.

Thank you very much, very much appreciated, it's the silly things you can spend so much time chasing.