1#!/usr/bin/env python
2#-----------------------------------------------------------------------------
3# ex7_qwiic_adxl313_fifo.py
4#
5# Simple Example for the Qwiic ADXL313 DeviceSet that shows how to setup the FIFO on the ADXL313.
6# One key advantage of using the FIFO is that it allows us to
7# let the ADXL313 store up to 32 samples in it's FIFO "buffer".
8# While it is doing this, we can use our microcontroller to do other things,
9# Then, when the FIFO is full (or close to), we can quickly read in the 32 samples.
10
11# In order to use the FIFO in this way, we need to set it up to fire an interrupt
12# when it gets "almost full". This threshold of samples is called the "watermark".
13# When the watermark level is reached, it will fire the interrupt INT1.
14# Our raspi will be monitoring the watermark int source bit, and then quickly
15# read whatevers in the FIFO and save it to a log file.
16# Note, we can't print the data in real time to the terminal
17# because python terminal is too slow.
18
19# Some timestamps of each stage of this cycle will also be printed.
20# This will allow us to fine tune bandwidth and watermark settings.
21# The "Entries" of the FIFO_STATUS register will also be printed before each read.
22# This will tell us how many samples are currently held in the FIFO.
23# This will allow us to read the entire contents and keep an eye on how full it is
24# getting before each read. This will help us fine tune how much time we have
25# between each read to do other things. (in this example, we are simplly going to do
26# a delay and print dots, but you could choose to do more useful things).
27
28# **SPI app note***
29# Note, this example uses I2C to communicate the the sensor.
30# If you are going to use SPI, then you will need to add in a sufficient
31# delay in between reads (at least 5uSec), to allow the FIFO to "pop" the next
32# reading in the data registers. See datasheet page 16 for more info.
33
34# ///// FIFO setup //////
35# Stream mode
36# Trigger INT1, Note, this example does not utilize monitoring this hardware interrupt.
37# We will be monitoring via software by reading the int source and watching the
38# watermark bit.
39# Watermark Threshold (aka (samples in FIFO_CTL register)): 30
40
41# ///// Interrupt setup //////
42# Enable watermark interrupt.
43# Map watermark interrupt to "int pin 1".
44# This harware interrupt pin setup could be monitored by a GPIO on the raspi,
45# or external system, however, for this example, we will simply
46# poll the interrupt register via software to monitor its status.
47
48#------------------------------------------------------------------------
49#
50# Written by SparkFun Electronics, October 2020
51#
52# This python library supports the SparkFun Electroncis qwiic
53# qwiic sensor/board ecosystem on a Raspberry Pi (and compatable) single
54# board computers.
55#
56# More information on qwiic is at https://www.sparkfun.com/qwiic
57#
58# Do you like this library? Help support SparkFun. Buy a board!
59#
60#==================================================================================
61# Copyright (c) 2019 SparkFun Electronics
62#
63# Permission is hereby granted, free of charge, to any person obtaining a copy
64# of this software and associated documentation files (the "Software"), to deal
65# in the Software without restriction, including without limitation the rights
66# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67# copies of the Software, and to permit persons to whom the Software is
68# furnished to do so, subject to the following conditions:
69#
70# The above copyright notice and this permission notice shall be included in all
71# copies or substantial portions of the Software.
72#
73# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
75# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
76# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
77# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
78# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
79# SOFTWARE.
80#==================================================================================
81# Example 7
82#
83
84from __future__ import print_function
85import qwiic_adxl313
86import time
87import sys
88
89lastWatermarkTime = 0 # used for printing timestamps in debug
90fifoEntriesAmount = 0 # used to know how much is currently in the fifo and make sure to read it all out.
91
92def micros():
93 return round(time.time_ns()/1000)
94
95# Open a log file in "append mode", We must log data here because printing to terminal is too slow
96logfile = open("log.txt","a")
97
98def runExample():
99
100 print("\nSparkFun Adxl313 Example 7 - FIFO reading with debug info about timing.\n")
101 myAdxl = qwiic_adxl313.QwiicAdxl313()
102
103 if myAdxl.connected == False:
104 print("The Qwiic ADXL313 device isn't connected to the system. Please check your connection", \
105 file=sys.stderr)
106 return
107 else:
108 print("Device connected successfully.")
109
110 myAdxl.standby() # Must be in standby before changing settings.
111 # This is here just in case we already had sensor powered and/or
112 # configured from a previous setup.
113
114 myAdxl.setRange(myAdxl.ADXL313_RANGE_4_G)
115
116 # set bandwidth
117 # note, 12.5Hz was chosen for this example to highlight the FIFO wait/read cycle
118 # you can tweak BW and the fifo sample threshhold to suit your application.
119 myAdxl.setBandwidth(myAdxl.ADXL313_BW_12_5)
120 # also try:
121 # myAdxl.bandwidth = myAdxl.ADXL313_BW_12_5
122
123 # setup activity sensing options
124 myAdxl.setActivityX(False) # disable x-axis participation in detecting activity
125 myAdxl.setActivityY(False) # disable y-axis participation in detecting activity
126 myAdxl.setActivityZ(False) # disable z-axis participation in detecting activity
127
128 # setup inactivity sensing options
129 myAdxl.setInactivityX(False) # disable x-axis participation in detecting inactivity
130 myAdxl.setInactivityY(False) # disable y-axis participation in detecting inactivity
131 myAdxl.setInactivityZ(False) # disable z-axis participation in detecting inactivity
132
133 # FIFO SETUP
134 myAdxl.setFifoMode(myAdxl.ADXL313_FIFO_MODE_STREAM)
135 myAdxl.setFifoSamplesThreshhold(30) # can be 1-32
136
137 # Interrupt Mapping
138 # when fifo fills up to watermark level, it will effect the int1 pin on the sensor
139 myAdxl.setInterruptMapping(myAdxl.ADXL313_INT_WATERMARK_BIT, myAdxl.ADXL313_INT1_PIN)
140
141 # enable/disable interrupts
142 # note, we set them all here, just in case there were previous settings,
143 # that need to be changed for this example to work properly.
144 myAdxl.ActivityINT(0) # disable activity
145 myAdxl.InactivityINT(0) # disable inactivity
146 myAdxl.DataReadyINT(0) # disable dataready
147 myAdxl.WatermarkINT(1) # enable watermark
148
149 myAdxl.autosleepOff() # just in case it was set from a previous setup
150
151 myAdxl.measureModeOn() # wakes up sensor from stanby and puts into measurement mode
152
153 # print int enable statuses, to verify we're setup correctly
154 print("activity int enable: ", myAdxl.isInterruptEnabled(myAdxl.ADXL313_INT_ACTIVITY_BIT))
155 print("inactivity int enable: ", myAdxl.isInterruptEnabled(myAdxl.ADXL313_INT_INACTIVITY_BIT))
156 print("dataReady int enable: ", myAdxl.isInterruptEnabled(myAdxl.ADXL313_INT_DATA_READY_BIT))
157 print("FIFO watermark int enable: ", myAdxl.isInterruptEnabled(myAdxl.ADXL313_INT_WATERMARK_BIT))
158 print("FIFO watermark Samples Threshhold: ", myAdxl.getFifoSamplesThreshhold())
159 print("FIFO mode: ", myAdxl.getFifoMode())
160
161 lastWatermarkTime = micros()
162
163 myAdxl.clearFifo() # clear FIFO for a fresh start on this example.
164 # The FIFO may have been full from previous use
165 # and then would fail to cause an interrupt when starting this example.
166
167 uSecTimer = 0 # used to print some "dots" during down time in cycle
168 while True:
169 myAdxl.updateIntSourceStatuses() # this will update all INTSOURCE statuses.
170 if myAdxl.ADXL313_INTSOURCE_WATERMARK:
171 entries = myAdxl.getFifoEntriesAmount()
172 timegap_us = (micros() - lastWatermarkTime)
173 timegap_ms = round(timegap_us / 1000)
174
175 print("\nWatermark Interrupt! Time since last read: ", timegap_us, "us ", timegap_ms, "ms Entries:", entries)
176 lastWatermarkTime = micros()
177 while entries > 0:
178 myAdxl.updateIntSourceStatuses() # this will update all INTSOURCE statuses.
179 if myAdxl.ADXL313_INTSOURCE_DATAREADY:
180 myAdxl.readAccel() # read all axis from sensor, note this also updates all instance variables
181
182 # Gotta log data to a text file, because printing to terminal is too slow
183 logfile.write(str(myAdxl.x))
184 logfile.write("\t")
185 logfile.write(str(myAdxl.y))
186 logfile.write("\t")
187 logfile.write(str(myAdxl.z))
188 logfile.write("\n")
189 entries -= 1 # we've read one more entry, so let's keep track and keep going until we're done
190 else:
191 print("Waiting for Data.")
192
193 time.sleep(0.000001) # sleep 1 microsecond
194 uSecTimer += 1
195 if uSecTimer > 100:
196 print(".", end = '')
197 uSecTimer = 0
198
199
200if __name__ == '__main__':
201 try:
202 runExample()
203 except (KeyboardInterrupt, SystemExit) as exErr:
204 print("\nEnding Example 1")
205 logfile.close()
206 sys.exit(0)
207
208