Finally, we convert to 1/100ths gs by multiplying the
raw value by 4. 69. Of course, the Propeller uses integer
math, so we do that with a multiply and
divide. The tilt register contains orientation
information and status bits for tap and shake.
Figure 4 shows the configuration of the tilt
register. Using the default initialization, we can
call the side(), orientation(), tap(), and
shake() methods to extract information from
the tilt register:
■ FIGURE 4. Tilt Register Bits.
Reading g-force registers is as easy as reading from
any other I2C device. If desired, we can do a multi-byte
read to capture all axes and the tilt register with one call.
return (raw << 26 ~> 26) 469 / 100
pub side(tbits)
Here's that code:
if (tbits < 0)
tbits : read tilt
pub read all raw(p axes)
repeat
i2c.start
i2c.write(MMA7660 WR)
i2c.write(XOUT)
i2c.start
i2c.write(MMA7660 RD)
byte[p axes][XOUT] : i2c.read(i2c#ACK)
byte[p axes][YOUT] : i2c.read(i2c#ACK)
byte[p axes][ZOUT] : i2c.read(i2c#ACK)
byte[p axes][TILT] : i2c.read(i2c#NAK)
case (tbits & %11)
%01 : return FRONT
%10 : return BACK
return -1
ifnot (long[p axes] & ALERT XYZT)
quit
case ((tbits >> 2) & %111)
%001 : return LEFT
%010 : return RIGHT
%101 : return DOWN
%110 : return UP
return -1
If you've worked with I2C, you'll recognize this as a
very standard multi-byte read transaction. The key to this
method is that it requires a pointer to a long, and this long
will be used to hold the four byte registers read from the
pub tap(tbits)
if (tbits < 0)
tbits : read tilt
MMA7660FC. The reason for doing this is at the end of
the loop. Each of the registers uses bit 6 as an alert flag;
when this bit is set, the MMA7660FC may have been
updating the register while the I2C read was in process,
and the register value should be considered corrupt. By
storing each of the axis bytes in a long, we can test for any
alert flags with one statement using ALERT_XYZT
return (tbits & TAP BIT) >> 5
pub shake(tbits)
if (tbits < 0)
tbits : read tilt
return (tbits & SHAKE BIT) >> 7
($40404040).
If there are no error bits, we return to the caller. The
axes registers hold a signed six-bit value that we need to
fix up and convert to g-force before putting it to use.
That's easy using a couple Spin operators in this method:
Note that these methods allow you to pass a previous
tilt register reading for conversion. We don't have to,
though; by passing a negative value to either of these
methods, the tilt register will be read and the desired
information returned.
pub raw to gforce(raw)
The first part of the code (in parenthesis) converts a
six-bit signed byte to a 32-bit signed long by left-shifting to
move the raw sign bit to bit 31, then doing a shift
arithmetic right (~>) to realign it. With a standard right
shift, we pad the MSB with zero; with the SAR, we pad
the MSB with what's in bit 31 (sign bit for longs). This
process correctly preserves the sign of the original value.
The side() method tells us the direction that the front
of the badge (or our cell phone) is facing. When laying flat
on a table with the face pointed skyward, side() will return
FRONT. If we flip it upside-down so the front is pointed
toward the Earth's core, side() will return BACK.
The orientation() method gives up portrait or
landscape mode information when the device is standing
up. If the top of the badge is pointed skyward, we will get
UP. If we rotate it so the top of the badge (as we're
looking at it) is pointed to the left, orientation will return
LEFT. Using the orientation bits is how your cell phone
knows how to update the screen when you rotate it.
Okay, let's put this together for a little demo as shown
12 October 2015