Skip to content

Commit 809755b

Browse files
committed
Lint, move to bargraph.py
1 parent 43cd771 commit 809755b

File tree

2 files changed

+150
-76
lines changed

2 files changed

+150
-76
lines changed

examples/bargraph.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/env python
2+
3+
from icm20948 import ICM20948
4+
import time
5+
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+
18+
# Terminal bar-graph adapted from examples/graph.py file from
19+
# https://github.com/pimoroni/vl53l1x-python
20+
def graphValue(value):
21+
global cols, mingraphval, maxgraphval
22+
if value > maxgraphval:
23+
value = maxgraphval
24+
elif value < mingraphval:
25+
value = mingraphval
26+
27+
graphvalue = value - mingraphval
28+
29+
bar_size = int((graphvalue / float(maxgraphval - mingraphval)) * (cols - 10)) # Scale bar_size to our terminal width
30+
bar = BAR_CHAR * bar_size # Create a bar out of `bar_size` unicode FULL BLOCK characters
31+
bar = bar.ljust(cols - 7, u' ') # Pad the bar to the full with of the terminal, minus the value prefix
32+
sys.stdout.write("\r") # Return the cursor to the beginning of the current line
33+
sys.stdout.write(u"{:05.1f} {}".format(value, bar)) # Output our measurement and bar
34+
sys.stdout.flush() # Flush the output buffer, since we're overdrawing the last line
35+
36+
37+
def exit_handler(signal, frame):
38+
global running, args
39+
running = False
40+
if args.graph:
41+
# Clean up terminal after using --graph output
42+
sys.stdout.write("\n")
43+
sys.exit(0)
44+
45+
46+
signal.signal(signal.SIGINT, exit_handler)
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:
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+
61+
62+
print("""bargraph.py - Convert raw values to heading
63+
64+
Rotate the sensor through 360 degrees to calibrate.
65+
66+
Press Ctrl+C to exit!
67+
68+
""")
69+
70+
X = 0
71+
Y = 1
72+
Z = 2
73+
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:
83+
sys.stdout.write("\n")
84+
85+
86+
imu = ICM20948()
87+
88+
amin = list(imu.read_magnetometer_data())
89+
amax = list(imu.read_magnetometer_data())
90+
91+
while running:
92+
mag = list(imu.read_magnetometer_data())
93+
for i in AXES:
94+
v = mag[i]
95+
if v < amin[i]:
96+
amin[i] = v
97+
if v > amax[i]:
98+
amax[i] = v
99+
mag[i] -= amin[i]
100+
try:
101+
mag[i] /= amax[i] - amin[i]
102+
except ZeroDivisionError:
103+
pass
104+
mag[i] -= 0.5
105+
106+
heading = math.atan2(mag[AXES[0]], mag[AXES[1]])
107+
108+
if heading < 0:
109+
heading += 2 * math.pi
110+
heading = math.degrees(heading)
111+
112+
if args.graph:
113+
# Display the heading as a bar-graph in the terminal
114+
graphValue(heading)
115+
else:
116+
# Round the heading value and print out directly
117+
heading = round(heading)
118+
print("Heading: {}".format(heading))
119+
120+
time.sleep(0.1)

examples/magnetometer.py

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,10 @@
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-
616

627
print("""magnetometer.py - Convert raw values to heading
638
64-
Rotate the sensor through 360 degrees to calibrate.
9+
Rotate the sensor (X-axis upwards) through 360 degrees to calibrate.
6510
6611
Press Ctrl+C to exit!
6712
@@ -71,52 +16,61 @@ def exit_handler(signal, frame):
7116
Y = 1
7217
Z = 2
7318

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-
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
8522

23+
# Initialise the imu
8624
imu = ICM20948()
8725

26+
# Store an initial two readings from the Magnetometer
8827
amin = list(imu.read_magnetometer_data())
8928
amax = list(imu.read_magnetometer_data())
9029

91-
while running:
30+
while True:
31+
# Read the current, uncalibrated, X, Y & Z magnetic values from the magnetometer and save as a list
9232
mag = list(imu.read_magnetometer_data())
93-
for i in AXES:
33+
34+
# Step through each uncalibrated X, Y & Z magnetic value and calibrate them the best we can
35+
for i in range(3):
9436
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
9539
if v < amin[i]:
9640
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
9743
if v > amax[i]:
9844
amax[i] = v
45+
46+
# Calibrate value by removing any offset when compared to the lowest reading seen for this axes
9947
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
10051
try:
10152
mag[i] /= amax[i] - amin[i]
10253
except ZeroDivisionError:
10354
pass
55+
# Shift magnetic values to between -0.5 and 0.5 to enable the trig to work
10456
mag[i] -= 0.5
10557

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
10660
heading = math.atan2(
10761
mag[AXES[0]],
10862
mag[AXES[1]])
10963

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

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))
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))
12175

12276
time.sleep(0.1)

0 commit comments

Comments
 (0)