Add CircuitPython code
This commit is contained in:
parent
e5e9b99006
commit
ff949df3f8
1 changed files with 145 additions and 0 deletions
145
CPX_Compass/code.py
Normal file
145
CPX_Compass/code.py
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
"""
|
||||
Circuit Playground Express Compass
|
||||
|
||||
Adafruit invests time and resources providing this open source code.
|
||||
Please support Adafruit and open source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Dave Astels for Adafruit Industries
|
||||
Copyright (c) 2018 Adafruit Industries
|
||||
Licensed under the MIT license.
|
||||
|
||||
All text above must be included in any redistribution.
|
||||
"""
|
||||
|
||||
import time
|
||||
import math
|
||||
import board
|
||||
import busio
|
||||
import adafruit_lsm303
|
||||
import neopixel
|
||||
import digitalio
|
||||
|
||||
BLACK = 0x000000
|
||||
RED = 0xFF0000
|
||||
GREEN = 0x00FF00
|
||||
BLUE = 0x0000FF
|
||||
|
||||
i2c = busio.I2C(board.SCL, board.SDA)
|
||||
compass = adafruit_lsm303.LSM303(i2c)
|
||||
compass.mag_rate = adafruit_lsm303.MAGRATE_30
|
||||
#compass.mag_gain = adafruit_lsm303.MAGGAIN_8_1
|
||||
|
||||
calibrate_button = digitalio.DigitalInOut(board.BUTTON_A)
|
||||
calibrate_button.direction = digitalio.Direction.INPUT
|
||||
calibrate_button.pull = digitalio.Pull.UP
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Replace these two lines with the results of calibration
|
||||
#-------------------------------------------------------------------------------
|
||||
raw_mins = [1000.0, 1000.0]
|
||||
raw_maxes = [-1000.0, -1000.0]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
mins = [0.0, 0.0]
|
||||
maxes = [0.0, 0.0]
|
||||
corrections = [0.0, 0.0]
|
||||
|
||||
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.2, auto_write=False)
|
||||
|
||||
led_patterns = [[4, 5], [5], [6], [7], [8], [9], [9, 0], [0], [1], [2], [3], [4]]
|
||||
|
||||
|
||||
def fill(colour):
|
||||
pixels.fill(colour)
|
||||
pixels.show()
|
||||
|
||||
|
||||
def warm_up():
|
||||
fill(BLUE)
|
||||
for _ in range(100):
|
||||
_, _, _ = compass.magnetic
|
||||
time.sleep(0.010)
|
||||
|
||||
|
||||
def calibrate(do_the_readings):
|
||||
values = [0.0, 0.0]
|
||||
start_time = time.monotonic()
|
||||
|
||||
fill(GREEN)
|
||||
|
||||
# Update the high and low extremes
|
||||
if do_the_readings:
|
||||
while time.monotonic() - start_time < 10.0:
|
||||
values[0], values[1], _ = compass.magnetic
|
||||
values[1] *= -1 # since the accel is mounted upside down, y is reversed
|
||||
if values[0] != 0.0 and values[1] != 0.0: # ignore the random 0 values
|
||||
for i in range(2):
|
||||
if values[i] < raw_mins[i]:
|
||||
raw_mins[i] = values[i]
|
||||
if values[i] > raw_maxes[i]:
|
||||
raw_maxes[i] = values[i]
|
||||
# time.sleep(0.005)
|
||||
|
||||
# Recompute the correction and the correct mins/maxes
|
||||
for i in range(2):
|
||||
corrections[i] = (raw_maxes[i] + raw_mins[i]) / 2
|
||||
mins[i] = raw_mins[i] - corrections[i]
|
||||
maxes[i] = raw_maxes[i] - corrections[i]
|
||||
|
||||
fill(BLACK)
|
||||
|
||||
|
||||
def normalize(value, in_min, in_max):
|
||||
mapped = (value - in_min) * 200 / (in_max - in_min) + -100
|
||||
return max(min(mapped, 100), -100)
|
||||
|
||||
|
||||
|
||||
# Setup
|
||||
|
||||
warm_up()
|
||||
|
||||
if not calibrate_button.value or (raw_mins[0] == 1000.0 and raw_mins[1] == 1000.0):
|
||||
print("Compass calibration")
|
||||
raw_mins[0] = 1000.0
|
||||
raw_mins[1] = 1000.0
|
||||
raw_maxes[0] = -1000.0
|
||||
raw_maxes[1] = -1000.0
|
||||
calibrate(True)
|
||||
|
||||
|
||||
print("Calibration results")
|
||||
print("Update the corresponding lines near the top of the code\n")
|
||||
print("raw_mins = [{0}, {1}]".format(raw_mins[0], raw_mins[1]))
|
||||
print("raw_maxes = [{0}, {1}]".format(raw_maxes[0], raw_maxes[1]))
|
||||
while True:
|
||||
pass
|
||||
else:
|
||||
calibrate(False)
|
||||
|
||||
|
||||
while True:
|
||||
if not calibrate_button.value:
|
||||
calibrate(True)
|
||||
|
||||
x, y, _ = compass.magnetic
|
||||
y = y * -1 # negation of y & z becasue the board is mounted upside-down
|
||||
|
||||
normalized_x = normalize(x - corrections[0], mins[0], maxes[0])
|
||||
normalized_y = normalize(y - corrections[1], mins[1], maxes[1])
|
||||
|
||||
compass_heading = int(math.atan2(normalized_y, normalized_x) * 180.0 / math.pi)
|
||||
# compass_heading is between -180 and +180 since atan2 returns -pi to +pi
|
||||
# this translates it to be between 0 and 360
|
||||
compass_heading += 180
|
||||
|
||||
direction_index = ((compass_heading + 15) % 360) // 30
|
||||
|
||||
pixels.fill(BLACK)
|
||||
for l in led_patterns[direction_index]:
|
||||
pixels[l] = RED
|
||||
pixels.show()
|
||||
time.sleep(0.050)
|
||||
Loading…
Reference in a new issue