Searching \ for '[PIC]: another challenge' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'another challenge'.

Exact match. Not showing close matches.
'[PIC]: another challenge'
2000\11\08@154619 by

Good day to all.

I've got another little challenge to throw out:  I have 2 - 9 bit numbers
that I need to find the ratio of, where the ratio is expressed as a number
from 00 to FF.

Its the usual thing: x = (remainder of) (a+b) / b  and I'm doing it with
the standard 16 bit divide routines.  But I figure there has to be an
easier / shorter / quicker method.

Any takers?

dwayne

Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax

Celebrating 16 years of Engineering Innovation (1984 - 2000)

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.

--

I'm somewhat confused...  You want the ratio of A to B (ratio = A/B) and
you are instead using the equation ratio = (A+B)/B ?

Dwayne Reid wrote:
{Quote hidden}

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

At 08:51 AM 11/9/00 -0500, M. Adam Davis wrote:
>I'm somewhat confused...  You want the ratio of A to B (ratio = A/B) and
>you are instead using the equation ratio = (A+B)/B ?
>
>
>Dwayne Reid wrote:
> >
> > Good day to all.
> >
> > I've got another little challenge to throw out:  I have 2 - 9 bit numbers
> > that I need to find the ratio of, where the ratio is expressed as a number
> > from 00 to FF.
> >
> > Its the usual thing: x = (remainder of) (a+b) / b  and I'm doing it with
> > the standard 16 bit divide routines.  But I figure there has to be an
> > easier / shorter / quicker method.

You are right - I wrote in a confusing manner.  I have 2 quantities, where
a goes increases when b decreases, similar to the wiper on a pot.  In
effect, I want to find the position of the wiper expressed as a number from
00 to FF.

One other thing: since a + b is a constant, the sum of the two will also
fit in 9 bits.

Like I said, I am using a relatively clunky 16 bit divide routine that I'd
really like to optimise for 9 bits.  I've already modified it to use only 9
shifts / iterations instead of 16 but I can't help think that there is a
better way.

dwayne

Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax

Celebrating 16 years of Engineering Innovation (1984 - 2000)

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

On Thu, 9 Nov 2000, Dwayne Reid wrote:

{Quote hidden}

Without cranking out the code, I don't how much more efficient this will be.

But, suppose you write b as a sum of two integers:

b = x*16 + y

i.e. x is the high order 5 bits, y the low 4.

If x is 0, then just branch to a 4-bit divide routine. If x is not zero then
apply this formula:

1 / (16*x + y) = 1/x/16 * (1 - (y/x/16) + (y/x/16)^2 - ...)

Since x is a 5 bit number, you only need a 5-bit division routine. Furthermore,
you only need two terms (okay maybe three) since y/(x*16)^3 is less than an
8-bit result.

You might be able to optimize.

~= 1/(16*x) * ( 1 - y/(16*x) + ( y/(16*x))^2 )

= 1/(16*x) * ( (1 - y/(16*x))^2 + y/(16*x) )

The division y/(16*x) only needs to be performed once. Now the approximation
isn't fantastic. For example, suppose b = 24

1/24 = 1/(1*16 + 8) = 0.0416666

where as for x=1, y=8 you get:

1/24 ~= 1/16 *( (1 - 1/2)^2 + 1/2) = 0.046875

It's kind of close. If you care this example out to three terms:

1/24 ~= 1/16 * (1 - 1/2 + (1/2)^2 - (1/2)^3)
= 0.0390625

closer, but now on the low side. Now, 1/24 is an extreme example. Ideally you
want a large x and a small y. Lets take b = 500 = 31*16 + 4. Well,

1/500 = 0.002

1/500 ~= 1/(31*16) * ( (1 - 4/(31*16))^2 + 4/(31*16) )
= 0.00201607

A little better.

Scott

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

What you've told us so far:
Two 9 bit numbers, A and B
A + B is constant, so B is inversely proportional to A.
There is a constant (A + B)
This means their relationship is linear,
Given A, B could be determined (and vice versa)
(ie, A+B=512, 512-A=B, 512-B=A, etc if 512 is the constant)

X = (remainder of) ( (A+B)/B )
is actually
X = B MOD Constant  (MOD being the remainder of the division Constant/B)
If the constant is a power of two (1,2,4,8,16,32,64,128,256,512,etc) then
you can get the answer to this equation by masking out the top few bits of
B.

I still don't understand how this equation fits with your description,
though.

So far, as I understand it, you are modeling a three terminal pot
(terminals 1,2,3, with 2 being the wiper).  A represents the resistance
between 1 & 2, B the resistance between 2 & 3, so A + B is the total
resistance of the POT, which is constant.

Your first message indicates that you want the ratio of A to B (for
whatever reason), while your second message says you want the position of
the wiper from 0x00-0xff.

If you want the position of the wiper, you need to tell us two more bits
of information:  What do you want the position relative to (ie, do you
want the pot's position relative to terminal 3 or 1), and we need to know
the value A + B (the constant).

If you want the ratio of A to B, then you want:
A/B
Since B = 512 - A then you want
A/(512-A)
Which simplifies to
512/(512-a) - 1

There are ways of simplifying that further, and it should not be too
difficult to render in assembly language since you now are only dividing a
variable by a constant rather than one variable by another.  You should
also be able to take a look at your numbers more closely, perhaps you can
throw out the least significant bit and only use an 8x8 division routine.

Dwayne Reid wrote:
{Quote hidden}

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

Dwayne Reid wrote:

You are right - I wrote in a confusing manner.  I have 2 quantities, where
>a goes increases when b decreases, similar to the wiper on a pot.  In
>effect, I want to find the position of the wiper expressed as a number from
>00 to FF.
>
>One other thing: since a + b is a constant, the sum of the two will also
>fit in 9 bits.

Why not simply multiply a with a constant that make the result = 0xFF00 when a is max, then use only the high byte of the answer?

Multiplying with a constant gives fast short code.

Regards
/Morgan

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

At 01:56 PM 11/9/00 -0500, M. Adam Davis wrote:
>What you've told us so far:
>Two 9 bit numbers, A and B
>A + B is constant, so B is inversely proportional to A.
>  There is a constant (A + B)
>  This means their relationship is linear,
>  Given A, B could be determined (and vice versa)
>  (ie, A+B=512, 512-A=B, 512-B=A, etc if 512 is the constant)

I'm getting in trouble here because I'm not speaking precisely enough.

A + B = C

X is not a constant per se - its just that for a given set of components
and ambient temperature, A increases by the same amount that B
decreases.  I find C when I've measured both A and B.

>X = (remainder of) ( (A+B)/B )
>is actually X = B MOD Constant  (MOD being the remainder of the division
>Constant/B)

This is where I'm not speaking precisely enough - I don't have a constant
that I can work with at compile time.  I find (a+b) only after I've
measured both a & b during operation.

>So far, as I understand it, you are modeling a three terminal pot
>(terminals 1,2,3, with 2 being the wiper).  A represents the resistance
>between 1 & 2, B the resistance between 2 & 3, so A + B is the total
>resistance of the POT, which is constant.

Its the best analogy I could come up with.  The application is for
differential sensors, both resistive and capacitive.

As I mentioned in my first message, what I'm looking for is x = (remainder
of) (a+b) / b or, as you more correctly state: x = b MOD (a+b).

My first message said "I have 2 - 9 bit numbers that I need to find the
ratio of, where the ratio is expressed as a number from 00 to FF."  I guess
what I failed to express clearly enough was that the ratio was "b" (top
part) and a+b (bottom part).  Sorry for being imprecise.

dwayne

Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax

Celebrating 16 years of Engineering Innovation (1984 - 2000)

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

> You are right - I wrote in a confusing manner.  I have 2 quantities, where
> a goes increases when b decreases, similar to the wiper on a pot.  In
> effect, I want to find the position of the wiper expressed as a number
from
{Quote hidden}

I'm still confused.  It sounds like your answer is simply A scaled
appropriately to the
0 - FF range.  Why are you trying to divide A/B?

*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, olincognivis.com, http://www.cognivis.com

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

At 03:51 PM 11/9/00 -0500, Olin Lathrop wrote:

>I'm still confused.  It sounds like your answer is simply A scaled
>appropriately to the
>0 - FF range.  Why are you trying to divide A/B?

I'm not trying to divide A/B, I'm trying to divide A / (A+B).  A and B are
quantities that I measure during program execution.  Both are typically 9
bit numbers (range is actually 10 on the low end to somewhere between 200 -
400 on the high end (decimal numbers)).  Its a ratiometric
measurement.  The sum of (A+B) is relatively constant as A and B vary for a
given sensor and temperature.

dwayne

Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax

Celebrating 16 years of Engineering Innovation (1984 - 2000)

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

Dwayne, it's still a bit confusing what you exactly need,
but looks like it's actually

A = 256 * A / (A + B)

where A and B are integers, and A < (A+B)

So, when A is lowest and B is highest the ratio is lowest,
and when A is highest and B is lowest the ratio is highest.

Note that you won't get 0 to 255 range for the ratio if A
and B vary from 10 to 400 or so. The minimum value acts like
bias here. It probably can be subtracted from both A and B,
in case you know it.

Below is my version of that formula. It requires 8
iterations (since result is 8 bit long). It's just a
variation of a division routine, starting from the point
when the integer part is already found. In our case we
assume that A/(A+B) is less than one and skip the part of
division that founds integer part.

cblock
Temp0, Temp1
A0, A1, B0, B1
endc

mov     macro x, y
movlw x
movwf y
endm

;A=0x000A, B=0x0180, ratio=0x06
mov 0x0A, A0
mov 0x00, A1
mov 0x80, B0
mov 0x01, B1
call ratio
nop
;A=0x0180, B=0x000A, ratio=0xF9
mov 0x80, A0
mov 0x01, A1
mov 0x0A, B0
mov 0x00, B1
call ratio
nop
;A=0x00FF, B=0x00FF, ratio=0x80
mov 0xff, A0
mov 0x00, A1
mov 0xff, B0
mov 0x00, B1
call ratio
nop
;A=0x017d, B=0x0155, ratio=0x87
mov 0x7d, A0
mov 0x01, A1
mov 0x55, B0
mov 0x01, B1
call ratio
nop

; Ratio calculation     A = 256 * A / (A + B)
;
; Input:
;   A1:A0 - 9 bit unsigned integer
;   B1:B0 - 9 bit unsigned integer
;   Note: A < (A + B)
; Output:
;   A0 - 8 bit unsigned integer
; Temporary regs:
;   Temp0 - current result and counter
;   Temp1 - higher byte of remainder
;
; Size: 38 instructions
; Max timing: 2+3+6+8*20-1+2+2 = 174 cycles

ratio   clrf Temp1      ;initialize remainder
movlw 1         ;and counter
movwf Temp0     ;

movf A0, w      ;replace B with A+B
movf A1, w
skpnc
incfsz A1, w

ratio_loop
rlf A0, f       ;shift remainder left (carry was cleared)
rlf A1, f
rlf Temp1, f

movf B0, w      ;load LSB of (a+b) to w
btfss Temp0, 0

;subtraction branch,
;we get here on first iteration and each time
;remainder is positive or zero
subwf A0, f
movf B1, w
skpc
incfsz B1, w
subwf A1, f
movlw 1
skpc
subwf Temp1, f
goto ratio_next

;we get here if remainder is negative
movf B1, w
skpnc
incfsz B1, w
movlw 1
skpnc
ratio_next
rlf Temp0, f    ;shift in next result bit
skpc            ;repeat until carry is set (8
;iterations)
goto ratio_loop

movf Temp0, w   ;copy result from Temp0 to A0
movwf A0
return

Nikolai

---- Original Message ----
From: Dwayne Reid <dwaynerPLANET.EON.NET>
Sent: Friday, November 10, 2000 1:45:28
To: PICLISTMITVMA.MIT.EDU
Subj: [PIC]: another challenge

{Quote hidden}

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use listservmitvma.mit.edu?body=SET%20PICList%20DIGEST

At 04:36 PM 11/11/00 +0200, Nikolai Golovchenko wrote:
>Dwayne, it's still a bit confusing what you exactly need,
>but looks like it's actually
>
>A = 256 * A / (A + B)
>
>where A and B are integers, and A < (A+B)
>
>So, when A is lowest and B is highest the ratio is lowest,
>and when A is highest and B is lowest the ratio is highest.

That's it exactly!

I apologized earlier for writing imprecisely and now do so again.  It seems
easy to explain it in person but I still sometimes find it difficult to
express myself properly in writing.

I'll take a closer look at your post shortly and let you know how I make out.

Many thanks!

dwayne

Dwayne Reid   <dwaynerplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax

Celebrating 16 years of Engineering Innovation (1984 - 2000)

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use listservmitvma.mit.edu?body=SET%20PICList%20DIGEST

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...