PDA

View Full Version : Need advice on 32bit signed values in SPIN

T Chap
03-30-2012, 08:11 PM
PUB iTRipSet(tr) 'must REPEAT to work**** iTRipSet(audiofrq)** older
Dira[CurrentTripSetPin]~~
outa[CurrentTripSetPin]~
ctrb := %00110* << 26 +* CurrentTripSetPin
repeat
'''' This line below has values that can range from -2B to 2B required for the range of voltage output on the
''''' pin of 0 - 3v3.
'frqb := ((TripLevel * TripLevelBias) - (tempnew * TempBias)) #> 500_000_000

'''''' test values, produces voltages as shown
'frqb := -1 '3.265V***** 4.294B
'frqb := -2_147483646 '1.655V***** 2.147B
'frqb := 2_147483647 '1.655V***** 2.147B
'frqb := 0 '0.000V

The formula in the code above derives user input values from TRIPLEVEL, and a motor current value derived from a formula in a PID loop, relative to a PWM value.

The problem is when the values rolls over beyond 2147483647. If I output the value 2147483647 to and LCD, it shows the same number. If I output 2147483647 + 1 to an LCD, the LCD shows a 0. 2147483647 + 2 shows -2147483647. 2147483647 + 3 shows -2147483646.

The current checking software is getting thrown off when it sees the 0 just beyond 2147483647, as it expects -2147483646 which is the logical next value up, picking up at 1.655V onwards up to 3v3.

Why is this 0 there? How to work about this without more code to filter it?

The second part of the problem is the Limin Min of 500_000_000. I need the values from -2147483646 to -1 to get the output from 1.65v to 3v3. The Limit Min seems to prevent any negative values, which it should be doing but you get what I am trying to accomplish here.

T Chap
03-30-2012, 08:48 PM
repeat
'frqb := ((TripLevel * TripLevelBias) - (tempnew * TempBias)) #> 500_000_000

f := (TripLevel * TripLevelBias) - (tempnew * TempBias)
if f > 0 ' filter if negative, if positive then limit min
f #>= 500_000_000
if f <> 0 ' filter if 0 which is not allowed
frqb := f

This seems to solve the problems.

kuroneko
03-30-2012, 11:37 PM
Why is this 0 there? How to work about this without more code to filter it?
What object are you using to send the number to the LCD? Some of them choke on NEGX (\$80000000).

T Chap
03-31-2012, 12:31 AM
No LCD object, just 4port serial object ser.dec(3, 2147483647 + 1)

Lawson
03-31-2012, 12:39 AM
The simple way I deal with this problem is to only work with numbers between 0 and POSX when driving the counters and use phsa := number << 1 to set the counter. Whenever I read phsa I use (phsa >> 1) instead. This neatly solves the signed/unsigned issues.

Lawson

kuroneko
03-31-2012, 12:44 AM
No LCD object, just 4port serial object ser.dec(3, 2147483647 + 1)
Yes, that's what I meant. Any 4port object in particular? The one I just inspected (pcFullDuplexSerial4FC) prints NEGX as -0. As it's based on FDS you might want to try to re-apply the fix introduced there.

T Chap
03-31-2012, 01:35 AM
Thanks for the info guys. I use Tim Moore's 4port. As long as the frqb is not actually getting the -0 but it is just an LCD artifact, then no problem, the LCD is only for debug. Lawson, I need the negative values for frqb to achieve the full DAC output range of 0 - 3v3.

Lawson
03-31-2012, 06:26 PM
Thanks for the info guys. I use Tim Moore's 4port. As long as the frqb is not actually getting the -0 but it is just an LCD artifact, then no problem, the LCD is only for debug. Lawson, I need the negative values for frqb to achieve the full DAC output range of 0 - 3v3.

right, that's why you always left shift one when setting the counter. This sacrifices 1 lsb of precision, but you're only likely to get 12 or the 32 bits of counter precision anyway so this isn't much of a loss.

Lawson