Skip to content

Commit 43cd771

Browse files
committed
Merge git://github.com/dfluff/icm20948-python into dfluff-master
2 parents ff02016 + 1896ac1 commit 43cd771

File tree

1 file changed

+76
-30
lines changed

1 file changed

+76
-30
lines changed

examples/magnetometer.py

100644100755
Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,65 @@
33
from icm20948 import ICM20948
44
import time
55
import math
6+
import argparse
7+
import os
8+
import signal
9+
import sys
10+
11+
BAR_CHAR = u'\u2588' # Unicode FULL BLOCK
12+
13+
running = True
14+
mingraphval = 0
15+
maxgraphval = 360
16+
17+
# Terminal bar-graph adapted from examples/graph.py file from
18+
# https://github.com/pimoroni/vl53l1x-python
19+
def graphValue(value):
20+
global cols, mingraphval, maxgraphval
21+
if( value > maxgraphval ):
22+
value = maxgraphval
23+
elif( value < mingraphval):
24+
value = mingraphval
25+
26+
graphvalue = value - mingraphval
27+
28+
bar_size = int((graphvalue / float(maxgraphval-mingraphval)) * (cols-10)) # Scale bar_size to our terminal width
29+
bar = BAR_CHAR * bar_size # Create a bar out of `bar_size` unicode FULL BLOCK characters
30+
bar = bar.ljust(cols - 7, u' ') # Pad the bar to the full with of the terminal, minus the value prefix
31+
sys.stdout.write("\r") # Return the cursor to the beginning of the current line
32+
sys.stdout.write(u"{:05.1f} {}".format(value, bar)) # Output our measurement and bar
33+
sys.stdout.flush() # Flush the output buffer, since we're overdrawing the last line
34+
35+
36+
37+
def exit_handler(signal, frame):
38+
global running,args
39+
running = False
40+
if( args.graph == True ):
41+
# Clean up terminal after using --graph output
42+
sys.stdout.write("\n")
43+
sys.exit(0)
44+
45+
signal.signal(signal.SIGINT, exit_handler)
46+
47+
48+
parser = argparse.ArgumentParser()
49+
parser.add_argument( '--axis', choices=['xy','yz','xz'], default='yz', help="Axis to measure (default: yz)")
50+
parser.add_argument( '--graph', '-g', action="store_true", default=False, help="Display heading as terminal-graph")
51+
args = parser.parse_args()
52+
53+
54+
if( args.graph == True):
55+
try:
56+
rows, cols = [int(c) for c in os.popen("stty size", "r").read().split()]
57+
except ValueError:
58+
print("Cannot get size of tty! Try running in Terminal.")
59+
sys.exit(1)
60+
661

762
print("""magnetometer.py - Convert raw values to heading
863
9-
Rotate the sensor (X-axis upwards) through 360 degrees to calibrate.
64+
Rotate the sensor through 360 degrees to calibrate.
1065
1166
Press Ctrl+C to exit!
1267
@@ -16,61 +71,52 @@
1671
Y = 1
1772
Z = 2
1873

19-
# The two axes which relate to heading, depends on orientation of the sensor
20-
# Think Left & Right, Forwards and Back, ignoring Up and Down
21-
AXES = Y, Z
74+
if( args.axis == 'xy' ):
75+
AXES = X, Y
76+
elif( args.axis == 'yz' ):
77+
AXES = Y, Z
78+
elif( args.axis == 'xz' ):
79+
AXES = X, Z
80+
81+
82+
if( args.graph == True ):
83+
sys.stdout.write("\n")
84+
2285

23-
# Initialise the imu
2486
imu = ICM20948()
2587

26-
# Store an initial two readings from the Magnetometer
2788
amin = list(imu.read_magnetometer_data())
2889
amax = list(imu.read_magnetometer_data())
2990

30-
while True:
31-
# Read the current, uncalibrated, X, Y & Z magnetic values from the magnetometer and save as a list
91+
while running:
3292
mag = list(imu.read_magnetometer_data())
33-
34-
# Step through each uncalibrated X, Y & Z magnetic value and calibrate them the best we can
35-
for i in range(3):
93+
for i in AXES:
3694
v = mag[i]
37-
# If our current reading (mag) is less than our stored minimum reading (amin), then save a new minimum reading
38-
# ie save a new lowest possible value for our calibration of this axis
3995
if v < amin[i]:
4096
amin[i] = v
41-
# If our current reading (mag) is greater than our stored maximum reading (amax), then save a new maximum reading
42-
# ie save a new highest possible value for our calibration of this axis
4397
if v > amax[i]:
4498
amax[i] = v
45-
46-
# Calibrate value by removing any offset when compared to the lowest reading seen for this axes
4799
mag[i] -= amin[i]
48-
49-
# Scale value based on the higest range of values seen for this axes
50-
# Creates a calibrated value between 0 and 1 representing magnetic value
51100
try:
52101
mag[i] /= amax[i] - amin[i]
53102
except ZeroDivisionError:
54103
pass
55-
# Shift magnetic values to between -0.5 and 0.5 to enable the trig to work
56104
mag[i] -= 0.5
57105

58-
# Convert from Gauss values in the appropriate 2 axis to a heading in Radians using trig
59-
# Note this does not compensate for tilt
60106
heading = math.atan2(
61107
mag[AXES[0]],
62108
mag[AXES[1]])
63109

64-
# If heading is negative, convert to positive, 2 x pi is a full circle in Radians
65110
if heading < 0:
66111
heading += 2 * math.pi
67-
68-
# Convert heading from Radians to Degrees
69112
heading = math.degrees(heading)
70-
# Round heading to nearest full degree
71-
heading = round(heading)
72113

73-
# Note: Headings will not be correct until a full 360 deg calibration turn has been completed to generate amin and amax data
74-
print("Heading: {}".format(heading))
114+
if( args.graph == True ):
115+
# Display the heading as a bar-graph in the terminal
116+
graphValue(heading)
117+
else:
118+
# Round the heading value and print out directly
119+
heading = round(heading)
120+
print("Heading: {}".format(heading))
75121

76122
time.sleep(0.1)

0 commit comments

Comments
 (0)