mirror of
https://github.com/buzz-lightsnack-2007/MicroBit_Compass.git
synced 2024-08-14 22:46:45 +00:00
Update pxt.json, README.md, main.blocks, main.ts, main.py
This commit is contained in:
parent
83636085d2
commit
5bb5274b26
6 changed files with 442 additions and 27 deletions
BIN
.github/makecode/blocks.png
vendored
Normal file
BIN
.github/makecode/blocks.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
29
README.md
29
README.md
|
@ -1,27 +1,14 @@
|
||||||
|
# Micro:Bit Compass
|
||||||
|
**a simple compass made for the Micro:Bit**
|
||||||
|
|
||||||
> Open this page at [https://buzz-lightsnack-2007.github.io/microbit_compass/](https://buzz-lightsnack-2007.github.io/microbit_compass/)
|
## Edit this project
|
||||||
|
To edit this repository in MakeCode:
|
||||||
## Use as Extension
|
1. Open [Microsoft MakeCode](https://makecode.microbit.org/).
|
||||||
|
2. Click on **Import** then click on **Import URL**.
|
||||||
This repository can be added as an **extension** in MakeCode.
|
3. Paste **https://gitdab.com/buzz-lightsnack-2007/MicroBit_Compass** and click import.
|
||||||
|
|
||||||
* open [https://makecode.microbit.org/](https://makecode.microbit.org/)
|
|
||||||
* click on **New Project**
|
|
||||||
* click on **Extensions** under the gearwheel menu
|
|
||||||
* search for **https://github.com/buzz-lightsnack-2007/microbit_compass** and import
|
|
||||||
|
|
||||||
## Edit this project ![Build status badge](https://github.com/buzz-lightsnack-2007/microbit_compass/workflows/MakeCode/badge.svg)
|
|
||||||
|
|
||||||
To edit this repository in MakeCode.
|
|
||||||
|
|
||||||
* open [https://makecode.microbit.org/](https://makecode.microbit.org/)
|
|
||||||
* click on **Import** then click on **Import URL**
|
|
||||||
* paste **https://github.com/buzz-lightsnack-2007/microbit_compass** and click import
|
|
||||||
|
|
||||||
## Blocks preview
|
## Blocks preview
|
||||||
|
This image shows the blocks code from the last commit in master, although it may take a few minutes to refresh.
|
||||||
This image shows the blocks code from the last commit in master.
|
|
||||||
This image may take a few minutes to refresh.
|
|
||||||
|
|
||||||
![A rendered view of the blocks](https://github.com/buzz-lightsnack-2007/microbit_compass/raw/master/.github/makecode/blocks.png)
|
![A rendered view of the blocks](https://github.com/buzz-lightsnack-2007/microbit_compass/raw/master/.github/makecode/blocks.png)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1 @@
|
||||||
<xml xmlns="http://www.w3.org/1999/xhtml">
|
<xml xmlns="https://developers.google.com/blockly/xml"><block type="pxt-on-start" id="B!8QAXrEUoXxGR/S#U9:" x="20" y="20"></block><block type="device_forever" id="8d[A=}lg#%,Nc9+n!0+L" x="225" y="20"></block></xml>
|
||||||
<block type="pxt-on-start"></block>
|
|
||||||
<block type="device_forever"></block>
|
|
||||||
</xml>
|
|
217
main.py
Normal file
217
main.py
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
# compass system information
|
||||||
|
compass_info = {
|
||||||
|
'version': 2022.1211
|
||||||
|
}
|
||||||
|
|
||||||
|
# compass data and settings
|
||||||
|
compass_data = {
|
||||||
|
'configuration': {
|
||||||
|
'modes': {
|
||||||
|
'previous': '',
|
||||||
|
'current': 'measurement',
|
||||||
|
'measurement': 'number'
|
||||||
|
},
|
||||||
|
'loading': False,
|
||||||
|
'errored': False
|
||||||
|
},
|
||||||
|
'data': {
|
||||||
|
'measurement': 0,
|
||||||
|
'direction': ArrowNames.NORTH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def compass_calibrate():
|
||||||
|
"""
|
||||||
|
This triggers calibration.
|
||||||
|
|
||||||
|
Parameters: none
|
||||||
|
Returns: none
|
||||||
|
"""
|
||||||
|
# Enter calibration mode, saving the previous mode.
|
||||||
|
compass_data['configuration']['modes']['previous'] = compass_data['configuration']['modes']['current']
|
||||||
|
compass_data['configuration']['modes']['current'] = 'calibrate'
|
||||||
|
compass_data['configuration']['loading'] = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Calibrate the compass.
|
||||||
|
input.calibrate_compass()
|
||||||
|
|
||||||
|
except:
|
||||||
|
# Warn that an error has occured.
|
||||||
|
compass_data['configuration']['errored'] = True
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Exit calibration mode, restoring previous mode state.
|
||||||
|
compass_data['configuration']['loading'] = False
|
||||||
|
compass_data['configuration']['modes']['current'] = compass_data['configuration']['modes']['previous']
|
||||||
|
compass_data['configuration']['modes']['previous'] = 'calibrate'
|
||||||
|
|
||||||
|
def measurement_update():
|
||||||
|
"""
|
||||||
|
Record the new measurement.
|
||||||
|
|
||||||
|
Parameters: none
|
||||||
|
Returns: (float) heading in degrees
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get the new measurement.
|
||||||
|
compass_data['data']['measurement'] = input.compass_heading()
|
||||||
|
|
||||||
|
# Return the new measurement.
|
||||||
|
return(compass_data['data']['measurement'])
|
||||||
|
|
||||||
|
def measurement_arrow_update(angle = None):
|
||||||
|
"""
|
||||||
|
Display the correct directional arrow.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
angle: (float) the heading
|
||||||
|
Returns: (enum) directional arrow
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Automatically fill the angle value, if it isn't provided.
|
||||||
|
if angle == None:
|
||||||
|
angle = compass_data['data']['measurement']
|
||||||
|
|
||||||
|
# Check if the angle is negative. If it is, get the correct positive equivalent.
|
||||||
|
if angle < 0:
|
||||||
|
angle = 360 + angle
|
||||||
|
|
||||||
|
# Check which range it falls under. (Items are clockwise.)
|
||||||
|
direction_ranges = [
|
||||||
|
(angle < 22.5) or (angle > 337.5),
|
||||||
|
(angle >= 22.5) and (angle <= 67.5),
|
||||||
|
(angle > 67.5) and (angle < 112.5),
|
||||||
|
(angle >= 112.5) and (angle <= 157.5),
|
||||||
|
(angle > 157.5) and (angle < 202.5),
|
||||||
|
(angle >= 202.5) and (angle <= 247.5),
|
||||||
|
(angle > 247.5) and (angle < 292.5),
|
||||||
|
(angle >= 292.5) and (angle <= 337.5)
|
||||||
|
]
|
||||||
|
|
||||||
|
# This is the list of directions.
|
||||||
|
directions = [
|
||||||
|
ArrowNames.NORTH,
|
||||||
|
ArrowNames.NORTH_EAST,
|
||||||
|
ArrowNames.EAST,
|
||||||
|
ArrowNames.SOUTH_EAST,
|
||||||
|
ArrowNames.SOUTH,
|
||||||
|
ArrowNames.SOUTH_WEST,
|
||||||
|
ArrowNames.WEST,
|
||||||
|
ArrowNames.NORTH_WEST
|
||||||
|
]
|
||||||
|
|
||||||
|
# Set the correct direction.
|
||||||
|
compass_data['data']['direction'] = directions[direction_ranges.index(True)]
|
||||||
|
|
||||||
|
# Return the direction.
|
||||||
|
return(compass_data['data']['direction'])
|
||||||
|
|
||||||
|
def modes_measure_toggle(mode_measure_new = None):
|
||||||
|
"""
|
||||||
|
Toggle between the compass modes.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
mode_measure_new: (str) the new mode
|
||||||
|
Returns: (str) the new mode
|
||||||
|
"""
|
||||||
|
|
||||||
|
# valid modes of measurement
|
||||||
|
mode_measure = ['number', 'arrow']
|
||||||
|
mode_measure_current_index = mode_measure.index(compass_data['configuration']['modes']['measurement'])
|
||||||
|
|
||||||
|
if mode_measure_new:
|
||||||
|
if mode_measure_new in mode_measure:
|
||||||
|
compass_data['configuration']['modes']['measurement'] = mode_measure_new
|
||||||
|
else:
|
||||||
|
mode_measure_current_index =+ 1
|
||||||
|
|
||||||
|
# Check if it exceeds the maximum.
|
||||||
|
if mode_measure_current_index >= len(mode_measure):
|
||||||
|
# If so, revert it back to zero.
|
||||||
|
mode_measure_current_index = 0
|
||||||
|
|
||||||
|
# Apply the new mode.
|
||||||
|
compass_data['configuration']['modes']['measurement'] = mode_measure[mode_measure_current_index]
|
||||||
|
|
||||||
|
# Return the new mode.
|
||||||
|
return(compass_data['configuration']['modes']['measurement'])
|
||||||
|
|
||||||
|
|
||||||
|
def LEDs_update(status = None):
|
||||||
|
"""
|
||||||
|
Update the LEDs to display the corresponding pattern.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
status: (str) the pattern
|
||||||
|
Returns: none
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Check if there is a custom status input.
|
||||||
|
if status == None:
|
||||||
|
# Check if an error has occured.
|
||||||
|
if compass_data['configuration']['errored']:
|
||||||
|
status = 'error'
|
||||||
|
else:
|
||||||
|
# Otherwise, the current mode might be the basis.
|
||||||
|
status = compass_data['configuration']['modes']['current']
|
||||||
|
|
||||||
|
if (status == 'error'):
|
||||||
|
# Display that an error has occured simply through an exclamation mark.
|
||||||
|
basic.show_string("!")
|
||||||
|
|
||||||
|
elif (status == 'measurement'):
|
||||||
|
# measurement display
|
||||||
|
|
||||||
|
if compass_data['configuration']['modes']['measurement'] == 'number':
|
||||||
|
# Display the numerical data.
|
||||||
|
basic.show_number(compass_data['data']['measurement'])
|
||||||
|
if compass_data['configuration']['modes']['measurement'] == 'arrow':
|
||||||
|
# Display the arrow.
|
||||||
|
basic.show_arrow(compass_data['data']['direction'])
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Display the loading screen while the current screen is still present.
|
||||||
|
while compass_data['configuration']['loading']:
|
||||||
|
# plot
|
||||||
|
for x in range(0,5):
|
||||||
|
led.plot(x, 2)
|
||||||
|
basic.pause(100)
|
||||||
|
# unplot
|
||||||
|
for x in range (0,5):
|
||||||
|
led.unplot(x, 2)
|
||||||
|
basic.pause(100)
|
||||||
|
|
||||||
|
|
||||||
|
def startup():
|
||||||
|
"""
|
||||||
|
startup script
|
||||||
|
|
||||||
|
Parameters: none
|
||||||
|
Returns: none
|
||||||
|
"""
|
||||||
|
|
||||||
|
compass_calibrate()
|
||||||
|
|
||||||
|
def on_forever():
|
||||||
|
# Update the measurements.
|
||||||
|
measurement_update()
|
||||||
|
if compass_data['configuration']['modes']['measurement'] == 'arrow':
|
||||||
|
measurement_arrow_update()
|
||||||
|
|
||||||
|
LEDs_update()
|
||||||
|
|
||||||
|
|
||||||
|
def on_button_pressed_ab():
|
||||||
|
led.stop_animation()
|
||||||
|
compass_calibrate()
|
||||||
|
|
||||||
|
def on_button_pressed_a():
|
||||||
|
led.stop_animation()
|
||||||
|
modes_measure_toggle()
|
||||||
|
|
||||||
|
input.on_button_pressed(Button.AB, on_button_pressed_ab)
|
||||||
|
input.on_button_pressed(Button.A, on_button_pressed_a)
|
||||||
|
basic.forever(on_forever)
|
||||||
|
startup()
|
213
main.ts
213
main.ts
|
@ -1 +1,214 @@
|
||||||
|
// compass system information
|
||||||
|
let compass_info = {
|
||||||
|
"version" : 2022.1211,
|
||||||
|
}
|
||||||
|
|
||||||
|
// compass data and settings
|
||||||
|
let compass_data = {
|
||||||
|
"configuration" : {
|
||||||
|
"modes" : {
|
||||||
|
"previous" : "",
|
||||||
|
"current" : "measurement",
|
||||||
|
"measurement" : "number",
|
||||||
|
}
|
||||||
|
,
|
||||||
|
"loading" : false,
|
||||||
|
"errored" : false,
|
||||||
|
}
|
||||||
|
,
|
||||||
|
"data" : {
|
||||||
|
"measurement" : 0,
|
||||||
|
"direction" : ArrowNames.North,
|
||||||
|
}
|
||||||
|
,
|
||||||
|
}
|
||||||
|
|
||||||
|
function compass_calibrate() {
|
||||||
|
/**
|
||||||
|
This triggers calibration.
|
||||||
|
|
||||||
|
Parameters: none
|
||||||
|
Returns: none
|
||||||
|
|
||||||
|
*/
|
||||||
|
// Enter calibration mode, saving the previous mode.
|
||||||
|
compass_data["configuration"]["modes"]["previous"] = compass_data["configuration"]["modes"]["current"]
|
||||||
|
compass_data["configuration"]["modes"]["current"] = "calibrate"
|
||||||
|
compass_data["configuration"]["loading"] = true
|
||||||
|
try {
|
||||||
|
// Calibrate the compass.
|
||||||
|
input.calibrateCompass()
|
||||||
|
}
|
||||||
|
catch (_) {
|
||||||
|
// Warn that an error has occured.
|
||||||
|
compass_data["configuration"]["errored"] = true
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
// Exit calibration mode, restoring previous mode state.
|
||||||
|
compass_data["configuration"]["loading"] = false
|
||||||
|
compass_data["configuration"]["modes"]["current"] = compass_data["configuration"]["modes"]["previous"]
|
||||||
|
compass_data["configuration"]["modes"]["previous"] = "calibrate"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function measurement_update() {
|
||||||
|
/**
|
||||||
|
Record the new measurement.
|
||||||
|
|
||||||
|
Parameters: none
|
||||||
|
Returns: (float) heading in degrees
|
||||||
|
|
||||||
|
*/
|
||||||
|
// Get the new measurement.
|
||||||
|
compass_data["data"]["measurement"] = input.compassHeading()
|
||||||
|
// Return the new measurement.
|
||||||
|
return compass_data["data"]["measurement"]
|
||||||
|
}
|
||||||
|
|
||||||
|
function measurement_arrow_update(angle: any = null) {
|
||||||
|
/**
|
||||||
|
Display the correct directional arrow.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
angle: (float) the heading
|
||||||
|
Returns: (enum) directional arrow
|
||||||
|
|
||||||
|
*/
|
||||||
|
// Automatically fill the angle value, if it isn't provided.
|
||||||
|
if (angle == null) {
|
||||||
|
angle = compass_data["data"]["measurement"]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the angle is negative. If it is, get the correct positive equivalent.
|
||||||
|
if (angle < 0) {
|
||||||
|
angle = 360 + angle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check which range it falls under. (Items are clockwise.)
|
||||||
|
let direction_ranges = [angle < 22.5 || angle > 337.5, angle >= 22.5 && angle <= 67.5, angle > 67.5 && angle < 112.5, angle >= 112.5 && angle <= 157.5, angle > 157.5 && angle < 202.5, angle >= 202.5 && angle <= 247.5, angle > 247.5 && angle < 292.5, angle >= 292.5 && angle <= 337.5]
|
||||||
|
// This is the list of directions.
|
||||||
|
let directions = [ArrowNames.North, ArrowNames.NorthEast, ArrowNames.East, ArrowNames.SouthEast, ArrowNames.South, ArrowNames.SouthWest, ArrowNames.West, ArrowNames.NorthWest]
|
||||||
|
// Set the correct direction.
|
||||||
|
compass_data["data"]["direction"] = directions[_py.py_array_index(direction_ranges, true)]
|
||||||
|
// Return the direction.
|
||||||
|
return compass_data["data"]["direction"]
|
||||||
|
}
|
||||||
|
|
||||||
|
function modes_measure_toggle(mode_measure_new: any = null) {
|
||||||
|
/**
|
||||||
|
Toggle between the compass modes.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
mode_measure_new: (str) the new mode
|
||||||
|
Returns: (str) the new mode
|
||||||
|
|
||||||
|
*/
|
||||||
|
// valid modes of measurement
|
||||||
|
let mode_measure = ["number", "arrow"]
|
||||||
|
let mode_measure_current_index = _py.py_array_index(mode_measure, compass_data["configuration"]["modes"]["measurement"])
|
||||||
|
if (mode_measure_new) {
|
||||||
|
if (mode_measure.indexOf(mode_measure_new) >= 0) {
|
||||||
|
compass_data["configuration"]["modes"]["measurement"] = mode_measure_new
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mode_measure_current_index = +1
|
||||||
|
// Check if it exceeds the maximum.
|
||||||
|
if (mode_measure_current_index >= mode_measure.length) {
|
||||||
|
// If so, revert it back to zero.
|
||||||
|
mode_measure_current_index = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the new mode.
|
||||||
|
compass_data["configuration"]["modes"]["measurement"] = mode_measure[mode_measure_current_index]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the new mode.
|
||||||
|
return compass_data["configuration"]["modes"]["measurement"]
|
||||||
|
}
|
||||||
|
|
||||||
|
function LEDs_update(status: string = null) {
|
||||||
|
let x: number;
|
||||||
|
/**
|
||||||
|
Update the LEDs to display the corresponding pattern.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
status: (str) the pattern
|
||||||
|
Returns: none
|
||||||
|
|
||||||
|
*/
|
||||||
|
// Check if there is a custom status input.
|
||||||
|
if (status == null) {
|
||||||
|
// Check if an error has occured.
|
||||||
|
if (compass_data["configuration"]["errored"]) {
|
||||||
|
status = "error"
|
||||||
|
} else {
|
||||||
|
// Otherwise, the current mode might be the basis.
|
||||||
|
status = compass_data["configuration"]["modes"]["current"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == "error") {
|
||||||
|
// Display that an error has occured simply through an exclamation mark.
|
||||||
|
basic.showString("!")
|
||||||
|
} else if (status == "measurement") {
|
||||||
|
// measurement display
|
||||||
|
if (compass_data["configuration"]["modes"]["measurement"] == "number") {
|
||||||
|
// Display the numerical data.
|
||||||
|
basic.showNumber(compass_data["data"]["measurement"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compass_data["configuration"]["modes"]["measurement"] == "arrow") {
|
||||||
|
// Display the arrow.
|
||||||
|
basic.showArrow(compass_data["data"]["direction"])
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Display the loading screen while the current screen is still present.
|
||||||
|
while (compass_data["configuration"]["loading"]) {
|
||||||
|
// plot
|
||||||
|
for (x = 0; x < 5; x++) {
|
||||||
|
led.plot(x, 2)
|
||||||
|
basic.pause(100)
|
||||||
|
}
|
||||||
|
// unplot
|
||||||
|
for (x = 0; x < 5; x++) {
|
||||||
|
led.unplot(x, 2)
|
||||||
|
basic.pause(100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function startup() {
|
||||||
|
/**
|
||||||
|
startup script
|
||||||
|
|
||||||
|
Parameters: none
|
||||||
|
Returns: none
|
||||||
|
|
||||||
|
*/
|
||||||
|
compass_calibrate()
|
||||||
|
}
|
||||||
|
|
||||||
|
input.onButtonPressed(Button.AB, function on_button_pressed_ab() {
|
||||||
|
led.stopAnimation()
|
||||||
|
compass_calibrate()
|
||||||
|
})
|
||||||
|
input.onButtonPressed(Button.A, function on_button_pressed_a() {
|
||||||
|
led.stopAnimation()
|
||||||
|
modes_measure_toggle()
|
||||||
|
})
|
||||||
|
basic.forever(function on_forever() {
|
||||||
|
// Update the measurements.
|
||||||
|
measurement_update()
|
||||||
|
if (compass_data["configuration"]["modes"]["measurement"] == "arrow") {
|
||||||
|
measurement_arrow_update()
|
||||||
|
}
|
||||||
|
|
||||||
|
LEDs_update()
|
||||||
|
})
|
||||||
|
startup()
|
||||||
|
|
5
pxt.json
5
pxt.json
|
@ -10,7 +10,8 @@
|
||||||
"files": [
|
"files": [
|
||||||
"README.md",
|
"README.md",
|
||||||
"main.blocks",
|
"main.blocks",
|
||||||
"main.ts"
|
"main.ts",
|
||||||
|
"main.py"
|
||||||
],
|
],
|
||||||
"testFiles": [
|
"testFiles": [
|
||||||
"test.ts"
|
"test.ts"
|
||||||
|
@ -23,5 +24,5 @@
|
||||||
"supportedTargets": [
|
"supportedTargets": [
|
||||||
"microbit"
|
"microbit"
|
||||||
],
|
],
|
||||||
"preferredEditor": "blocksprj"
|
"preferredEditor": "tsprj"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue