Shop OBEX P1 Docs P2 Docs Learn Events
Memsic 2125 angle sensor math — Parallax Forums

Memsic 2125 angle sensor math

ArchiverArchiver Posts: 46,084
edited 2003-06-15 20:02 in General Discussion
All-
I'm using a 2125 angle sensor and would like to display the angle of a surface
to the
nearest tenth of a degree. There are two issues as I understand the problem:

(1) the capacitors and resistor that spec the bandwidth need to be installed in
the
circuit (This is a no-brainer.);
(2) the algorithm that transforms the duty-cycle reading from the 2125 needs to
be
tweaked to allow the additional accuracy. My first thought, and I may have to go
this
route if all else fails, was to use a look-up table, but the amount of memory
that
would be wasted on this is staggering (and boy, I'm really short of memory). The

CORDIC algorithm, at least, that's what I understand the thing to be, is
something I
am totally unfamiliar with, my numeric analysis course took place BC (before
computers), and after looking at the thing for a while, I realized I was
clueless as to
what's going on.

Is anybody out there at all familiar enough with the algorithm (the source code
is
below) to understand how to tweak the accuracy to the tenth of a degree? I think
it's
more than just going out to another integer-equivalent of a decimal point. It's
the
arccosine routine that is the problem, I think, but I really don't know WHAT is
going
on in this code.
Read_Tilt:
GOSUB Read_G_Force

' restrict displacement to unit circle (0.0 - 1.0)

disp = ABS xmG / 10 MAX 100 ' x displacement
GOSUB Arcsine
xTilt = angle * (-2 * xmG.bit15 + 1) ' fix sign
disp = ABS ymG / 10 MAX 100 ' y displacement
GOSUB Arcsine
yTilt = angle * (-2 * ymG.bit15 + 1) ' fix sign
RETURN


Read_G_Force:
PULSIN Xin, HiPulse, xRaw ' read pulse output
xmG = ((xRaw / 5) - 500) * 8 ' convert to 1/1000 g
PULSIN Yin, HiPulse, yRaw
ymG = ((yRaw / 5) - 500) * 8
RETURN


' Trig routines courtesy Tracy Allen, PhD. (www.emesystems.com)

Arccosine:
disp = disp */ 983 / 3 ' normalize input to 127
angle = 63 - (disp / 2) ' approximate angle
DO ' find angle
IF (COS angle <= disp) THEN EXIT
angle = angle + 1
LOOP
angle = angle */ 360 ' convert brads to degrees
RETURN


Arcsine:
GOSUB Arccosine
angle = 90 - angle
RETURN

Comments

  • ArchiverArchiver Posts: 46,084
    edited 2003-06-15 01:42
    The algorithm is really very simple. The Stamp has built in sine and
    cosine functions, but not the inverses. (At the time I did not know
    that the Stamp _does_ have an undocumented arctangent function.) The
    algorithm simply iterates on COS or SIN until it finds the angle
    corresponding angle. The algorithm is not very intelligent (not not
    even binary search), but it does make a first linear approximation
    before it starts on the search. The first line "disp = disp */ 983 /
    3", in the program listing you have, is a normalization step, to
    scale the values the Memsic puts out down to the range of +/- 127.

    Note that the Stamp trig functions are only good to 8 bits around the
    whole circle. The circle is divided into 256 angular segments,
    called "brads" (binary radians). And the sine and cosine is mapped
    into the interval -127 to +127, to represent the scale from -1 to +1.
    (See the Stamp manual, or <http://www.emesystems.com/BS2math3.htm>)

    Having the Stamp's ATN funciton, you could use ATN
    (X/SQR(16129-(X*X))), where X is the value from the Memsic, without
    any iteration. {for trig, if the sine of an angle is X, then the
    tangent of that angle is X/SQR(1-X^2)}. That is just a thought. I
    haven't used the formula for anything. Since 1 is represented as
    127, 1^2 has to be 127^2 =16129.

    I've not used the memsic 2125 myself, but I would guess that the
    range of angles that it measures is relatively narrow. Is that
    right? Let's say that it is 90 degrees. In Stampese, that is only
    64 units of angle, or not even one degree of resolution. But you are
    asking for 0.1 degree. If the range of angles is small, there might
    be a better power series approximation. Or lookup with
    *interpolation* in a relatively small (not staggering!) table might
    do the trick. As you noted, CORDIC is also a possibility.

    -- best regards
    Tracy Allen
    electronically monitored ecosystems
    http://www.emesystems.com
    mailto:tracy@e...






    >All-
    > I'm using a 2125 angle sensor and would like to display the angle
    >of a surface to the
    >nearest tenth of a degree. There are two issues as I understand the problem:
    >
    >(1) the capacitors and resistor that spec the bandwidth need to be
    >installed in the
    >circuit (This is a no-brainer.);
    >(2) the algorithm that transforms the duty-cycle reading from the
    >2125 needs to be
    >tweaked to allow the additional accuracy. My first thought, and I
    >may have to go this
    >route if all else fails, was to use a look-up table, but the amount
    >of memory that
    >would be wasted on this is staggering (and boy, I'm really short of
    >memory). The
    >CORDIC algorithm, at least, that's what I understand the thing to
    >be, is something I
    >am totally unfamiliar with, my numeric analysis course took place BC (before
    >computers), and after looking at the thing for a while, I realized I
    >was clueless as to
    >what's going on.
    >
    >Is anybody out there at all familiar enough with the algorithm (the
    >source code is
    >below) to understand how to tweak the accuracy to the tenth of a
    >degree? I think it's
    >more than just going out to another integer-equivalent of a decimal
    >point. It's the
    >arccosine routine that is the problem, I think, but I really don't
    >know WHAT is going
    >on in this code.
    >
    >Read_Tilt:
    > GOSUB Read_G_Force
    >
    > ' restrict displacement to unit circle (0.0 - 1.0)
    >
    > disp = ABS xmG / 10 MAX 100 ' x displacement
    > GOSUB Arcsine
    > xTilt = angle * (-2 * xmG.bit15 + 1) ' fix sign
    > disp = ABS ymG / 10 MAX 100 ' y displacement
    > GOSUB Arcsine
    > yTilt = angle * (-2 * ymG.bit15 + 1) ' fix sign
    > RETURN
    >
    >
    >Read_G_Force:
    > PULSIN Xin, HiPulse, xRaw ' read pulse output
    > xmG = ((xRaw / 5) - 500) * 8 ' convert to 1/1000 g
    > PULSIN Yin, HiPulse, yRaw
    > ymG = ((yRaw / 5) - 500) * 8
    > RETURN
    >
    >
    >' Trig routines courtesy Tracy Allen, PhD. (www.emesystems.com)
    >
    >Arccosine:
    > disp = disp */ 983 / 3 ' normalize input to 127
    > angle = 63 - (disp / 2) ' approximate angle
    > DO ' find angle
    > IF (COS angle <= disp) THEN EXIT
    > angle = angle + 1
    > LOOP
    > angle = angle */ 360 ' convert brads to degrees
    > RETURN
    >
    >
    >Arcsine:
    > GOSUB Arccosine
    > angle = 90 - angle
    > RETURN
    >
    >
    >To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    >from the same email address that you subscribed. Text in the
    >Subject and Body of the message will be ignored.
    >
    >
    >Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
  • ArchiverArchiver Posts: 46,084
    edited 2003-06-15 20:02
    Tracy-
    Thanks very much. I think I'm gonna scratch my head on this one. If I
    figure out anything better, I'll post it to the group.
    -Mark
    On Saturday, June 14, 2003, at 08:42 PM, Tracy Allen wrote:

    > The algorithm is really very simple. The Stamp has built in sine and
    > cosine functions, but not the inverses. (At the time I did not know
    > that the Stamp _does_ have an undocumented arctangent function.) The
    > algorithm simply iterates on COS or SIN until it finds the angle
    > corresponding angle. The algorithm is not very intelligent (not not
    > even binary search), but it does make a first linear approximation
    > before it starts on the search. The first line "disp = disp */ 983 /
    > 3", in the program listing you have, is a normalization step, to
    > scale the values the Memsic puts out down to the range of +/- 127.
    >
    > Note that the Stamp trig functions are only good to 8 bits around the
    > whole circle. The circle is divided into 256 angular segments,
    > called "brads" (binary radians). And the sine and cosine is mapped
    > into the interval -127 to +127, to represent the scale from -1 to +1.
    > (See the Stamp manual, or <http://www.emesystems.com/BS2math3.htm>)
    >
    > Having the Stamp's ATN funciton, you could use ATN
    > (X/SQR(16129-(X*X))), where X is the value from the Memsic, without
    > any iteration. {for trig, if the sine of an angle is X, then the
    > tangent of that angle is X/SQR(1-X^2)}. That is just a thought. I
    > haven't used the formula for anything. Since 1 is represented as
    > 127, 1^2 has to be 127^2 =16129.
    >
    > I've not used the memsic 2125 myself, but I would guess that the
    > range of angles that it measures is relatively narrow. Is that
    > right? Let's say that it is 90 degrees. In Stampese, that is only
    > 64 units of angle, or not even one degree of resolution. But you are
    > asking for 0.1 degree. If the range of angles is small, there might
    > be a better power series approximation. Or lookup with
    > *interpolation* in a relatively small (not staggering!) table might
    > do the trick. As you noted, CORDIC is also a possibility.
    >
    > -- best regards
    > Tracy Allen
    > electronically monitored ecosystems
    > http://www.emesystems.com
    > mailto:tracy@e...
    >
    >
    >
    >
    >
    >
    >> All-
    >> I'm using a 2125 angle sensor and would like to display the angle
    >> of a surface to the
    >> nearest tenth of a degree. There are two issues as I understand the
    >> problem:
    >>
    >> (1) the capacitors and resistor that spec the bandwidth need to be
    >> installed in the
    >> circuit (This is a no-brainer.);
    >> (2) the algorithm that transforms the duty-cycle reading from the
    >> 2125 needs to be
    >> tweaked to allow the additional accuracy. My first thought, and I
    >> may have to go this
    >> route if all else fails, was to use a look-up table, but the amount
    >> of memory that
    >> would be wasted on this is staggering (and boy, I'm really short of
    >> memory). The
    >> CORDIC algorithm, at least, that's what I understand the thing to
    >> be, is something I
    >> am totally unfamiliar with, my numeric analysis course took place BC
    >> (before
    >> computers), and after looking at the thing for a while, I realized I
    >> was clueless as to
    >> what's going on.
    >>
    >> Is anybody out there at all familiar enough with the algorithm (the
    >> source code is
    >> below) to understand how to tweak the accuracy to the tenth of a
    >> degree? I think it's
    >> more than just going out to another integer-equivalent of a decimal
    >> point. It's the
    >> arccosine routine that is the problem, I think, but I really don't
    >> know WHAT is going
    >> on in this code.
    >>
    >> Read_Tilt:
    >> GOSUB Read_G_Force
    >>
    >> ' restrict displacement to unit circle (0.0 - 1.0)
    >>
    >> disp = ABS xmG / 10 MAX 100 ' x displacement
    >> GOSUB Arcsine
    >> xTilt = angle * (-2 * xmG.bit15 + 1) ' fix sign
    >> disp = ABS ymG / 10 MAX 100 ' y displacement
    >> GOSUB Arcsine
    >> yTilt = angle * (-2 * ymG.bit15 + 1) ' fix sign
    >> RETURN
    >>
    >>
    >> Read_G_Force:
    >> PULSIN Xin, HiPulse, xRaw ' read pulse output
    >> xmG = ((xRaw / 5) - 500) * 8 ' convert to 1/1000 g
    >> PULSIN Yin, HiPulse, yRaw
    >> ymG = ((yRaw / 5) - 500) * 8
    >> RETURN
    >>
    >>
    >> ' Trig routines courtesy Tracy Allen, PhD. (www.emesystems.com)
    >>
    >> Arccosine:
    >> disp = disp */ 983 / 3 ' normalize input to
    >> 127
    >> angle = 63 - (disp / 2) ' approximate angle
    >> DO ' find angle
    >> IF (COS angle <= disp) THEN EXIT
    >> angle = angle + 1
    >> LOOP
    >> angle = angle */ 360 ' convert brads to
    >> degrees
    >> RETURN
    >>
    >>
    >> Arcsine:
    >> GOSUB Arccosine
    >> angle = 90 - angle
    >> RETURN
    >>
    >>
    >> To UNSUBSCRIBE, just send mail to:
    >> basicstamps-unsubscribe@yahoogroups.com
    >> from the same email address that you subscribed. Text in the
    >> Subject and Body of the message will be ignored.
    >>
    >>
    >> Your use of Yahoo! Groups is subject to
    >> http://docs.yahoo.com/info/terms/
    >
    >
    > To UNSUBSCRIBE, just send mail to:
    > basicstamps-unsubscribe@yahoogroups.com
    > from the same email address that you subscribed. Text in the Subject
    > and Body of the message will be ignored.
    >
    >
    > Your use of Yahoo! Groups is subject to
    > http://docs.yahoo.com/info/terms/
    >
    >
    >
Sign In or Register to comment.