3. If we took the cell phone in Figure 3 and oriented it so
the +Y axis was pointed skyward, the top of the cell
phone would be facing left —
just as the orientation bits tell
us. Neat!
If you tap the badge with
your finger, you'll see the tap
indication. Don't be alarmed if
you see shake at the same
time, albeit briefly. Remember
that the MMA7660FC sets the
shake bit when the g-force on
any axis exceeds 1.3g.
Actually shaking the device
sets the shake indication
without setting tap — tap is a
quick action and is filtered out
when shaking occurs.
in Figure 5. The main()
method gets things started and
waits for us to open a terminal
and press a key. After the key
press, the terminal is cleared
and the report output set up.
With the report printed, we
drop into a loop that reads
and displays data from the
accelerometer every 100 ms:
MMA7660FC
Demo.
pub main | t
setup
term.rxflush
term.rx
term.tx(term#CLS)
term.str(@Display)
t : cnt
repeat
update display
waitcnt(t +
(MS 001 100))
October 2015 13
■ FIGURE 5.
Time to Review
Propeller Timing
The update_display() method uses the acc.read_all()
method to read and convert all of the accelerometer
register to g-force values. The rest is simple cursor moving
and data display:
The last couple episodes
have had me talking about a fun little timing object I
wrote that just seems to get more useful every day. Part of
this has to do with the way the Propeller does timing
versus what we may have been used to with a BASIC
Stamp or other processor.
pub update display
acc.read all(@xg)
show gforce(15, 4, xg)
show gforce(15, 5, yg)
show gforce(15, 6, zg)
show side(15, 8, acc.side(tilt))
show orientation(15, 9, acc.
orientation(tilt))
For delays, the Propeller uses a command called
waitcnt (pronounced wait count), and I think it's the name
that confuses people; a more descriptive name would
have been wait4cnt (wait for count). What confuses the
newcomer is that waitcnt doesn't wait a specific number
of cycles. It waits for a specific value to show up in the cnt
register. While tricky to understand at first, this behavior is
advantageous, allowing us to create loops that run at a
fixed time and — if we want — generate a fixed delay like
we used to do with PAUSE in the Stamp.
goto xy(15, 11)
tf str(acc.tap(tilt), @Yes, @No)
If we want to do an old-school fixed delay — which
starts now — we code it like this:
goto xy(15, 12)
tf str(acc.shake(tilt), @Yes, @No)
long xg
long yg
long zg
long tilt
waitcnt(cnt + delaytix)
Note that read_all() expects a pointer to an array of
longs. With Spin, we have the option of declaring an array
or — as I prefer here — simply declaring four longs (in the
correct order) and pointing to the first, like this:
In this case, the code takes a snapshot of the cnt
register and adds the delay tix to that value (there are
minimums for delaytix in Spin and PASM). Now, the code
will wait until the value in cnt reaches what was just
calculated. The equivalent code in PASM looks like this:
var
mov t1, cnt
add t1, delaytix
waitcnt t1, #0
If you look at the g-force readings in the display, you'll
see that the Y axis is near +1g. Now, refer back to Figure
An important point to remember is that reading the
cnt register takes a bit of time and does pad the timing
just a bit. In many cases, this won't cause a problem, but a
recent discussion in the Parallax forums points out that
accessing the count register in a loop can extend timing in