adafruit-circuitpython-qmc5883p 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adafruit_circuitpython_qmc5883p-1.0.0.dist-info/METADATA +147 -0
- adafruit_circuitpython_qmc5883p-1.0.0.dist-info/RECORD +6 -0
- adafruit_circuitpython_qmc5883p-1.0.0.dist-info/WHEEL +5 -0
- adafruit_circuitpython_qmc5883p-1.0.0.dist-info/licenses/LICENSE +21 -0
- adafruit_circuitpython_qmc5883p-1.0.0.dist-info/top_level.txt +1 -0
- adafruit_qmc5883p.py +316 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adafruit-circuitpython-qmc5883p
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: CircuitPython driver for the Adafruit QMC5883P - Triple Axis Magnetometer - STEMMA QT
|
|
5
|
+
Author-email: Adafruit Industries <circuitpython@adafruit.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/adafruit/Adafruit_CircuitPython_QMC5883P
|
|
8
|
+
Keywords: adafruit,blinka,circuitpython,micropython,qmc5883p,magnetometer,,sensor
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
11
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
12
|
+
Classifier: Topic :: System :: Hardware
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Description-Content-Type: text/x-rst
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: Adafruit-Blinka
|
|
18
|
+
Requires-Dist: adafruit-circuitpython-busdevice
|
|
19
|
+
Requires-Dist: adafruit-circuitpython-register
|
|
20
|
+
Provides-Extra: optional
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
Introduction
|
|
24
|
+
============
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
.. image:: https://readthedocs.org/projects/adafruit-circuitpython-qmc5883p/badge/?version=latest
|
|
28
|
+
:target: https://docs.circuitpython.org/projects/qmc5883p/en/latest/
|
|
29
|
+
:alt: Documentation Status
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
.. image:: https://raw.githubusercontent.com/adafruit/Adafruit_CircuitPython_Bundle/main/badges/adafruit_discord.svg
|
|
33
|
+
:target: https://adafru.it/discord
|
|
34
|
+
:alt: Discord
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
.. image:: https://github.com/adafruit/Adafruit_CircuitPython_QMC5883P/workflows/Build%20CI/badge.svg
|
|
38
|
+
:target: https://github.com/adafruit/Adafruit_CircuitPython_QMC5883P/actions
|
|
39
|
+
:alt: Build Status
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
|
|
43
|
+
:target: https://github.com/astral-sh/ruff
|
|
44
|
+
:alt: Code Style: Ruff
|
|
45
|
+
|
|
46
|
+
CircuitPython driver for the Adafruit QMC5883P - Triple Axis Magnetometer - STEMMA QT
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Dependencies
|
|
50
|
+
=============
|
|
51
|
+
This driver depends on:
|
|
52
|
+
|
|
53
|
+
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
|
54
|
+
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
|
|
55
|
+
* `Register <https://github.com/adafruit/Adafruit_CircuitPython_Register>`_
|
|
56
|
+
|
|
57
|
+
Please ensure all dependencies are available on the CircuitPython filesystem.
|
|
58
|
+
This is easily achieved by downloading
|
|
59
|
+
`the Adafruit library and driver bundle <https://circuitpython.org/libraries>`_
|
|
60
|
+
or individual libraries can be installed using
|
|
61
|
+
`circup <https://github.com/adafruit/circup>`_.
|
|
62
|
+
|
|
63
|
+
`Purchase one from the Adafruit shop <http://www.adafruit.com/products/6388>`_
|
|
64
|
+
|
|
65
|
+
Installing from PyPI
|
|
66
|
+
=====================
|
|
67
|
+
|
|
68
|
+
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
|
|
69
|
+
PyPI <https://pypi.org/project/adafruit-circuitpython-qmc5883p/>`_.
|
|
70
|
+
To install for current user:
|
|
71
|
+
|
|
72
|
+
.. code-block:: shell
|
|
73
|
+
|
|
74
|
+
pip3 install adafruit-circuitpython-qmc5883p
|
|
75
|
+
|
|
76
|
+
To install system-wide (this may be required in some cases):
|
|
77
|
+
|
|
78
|
+
.. code-block:: shell
|
|
79
|
+
|
|
80
|
+
sudo pip3 install adafruit-circuitpython-qmc5883p
|
|
81
|
+
|
|
82
|
+
To install in a virtual environment in your current project:
|
|
83
|
+
|
|
84
|
+
.. code-block:: shell
|
|
85
|
+
|
|
86
|
+
mkdir project-name && cd project-name
|
|
87
|
+
python3 -m venv .venv
|
|
88
|
+
source .env/bin/activate
|
|
89
|
+
pip3 install adafruit-circuitpython-qmc5883p
|
|
90
|
+
|
|
91
|
+
Installing to a Connected CircuitPython Device with Circup
|
|
92
|
+
==========================================================
|
|
93
|
+
|
|
94
|
+
Make sure that you have ``circup`` installed in your Python environment.
|
|
95
|
+
Install it with the following command if necessary:
|
|
96
|
+
|
|
97
|
+
.. code-block:: shell
|
|
98
|
+
|
|
99
|
+
pip3 install circup
|
|
100
|
+
|
|
101
|
+
With ``circup`` installed and your CircuitPython device connected use the
|
|
102
|
+
following command to install:
|
|
103
|
+
|
|
104
|
+
.. code-block:: shell
|
|
105
|
+
|
|
106
|
+
circup install adafruit_qmc5883p
|
|
107
|
+
|
|
108
|
+
Or the following command to update an existing version:
|
|
109
|
+
|
|
110
|
+
.. code-block:: shell
|
|
111
|
+
|
|
112
|
+
circup update
|
|
113
|
+
|
|
114
|
+
Usage Example
|
|
115
|
+
=============
|
|
116
|
+
|
|
117
|
+
.. code-block:: python
|
|
118
|
+
|
|
119
|
+
import time
|
|
120
|
+
import board
|
|
121
|
+
import adafruit_qmc5883p
|
|
122
|
+
|
|
123
|
+
i2c = board.I2C()
|
|
124
|
+
|
|
125
|
+
sensor = adafruit_qmc5883p.QMC5883P(i2c)
|
|
126
|
+
|
|
127
|
+
while True:
|
|
128
|
+
mag_x, mag_y, mag_z = sensor.magnetic
|
|
129
|
+
|
|
130
|
+
print(f"X:{mag_x:2.3f}, Y:{mag_y:2.3f}, Z:{mag_z:2.3f} G")
|
|
131
|
+
print("")
|
|
132
|
+
|
|
133
|
+
time.sleep(1)
|
|
134
|
+
|
|
135
|
+
Documentation
|
|
136
|
+
=============
|
|
137
|
+
API documentation for this library can be found on `Read the Docs <https://docs.circuitpython.org/projects/qmc5883p/en/latest/>`_.
|
|
138
|
+
|
|
139
|
+
For information on building library documentation, please check out
|
|
140
|
+
`this guide <https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/sharing-our-docs-on-readthedocs#sphinx-5-1>`_.
|
|
141
|
+
|
|
142
|
+
Contributing
|
|
143
|
+
============
|
|
144
|
+
|
|
145
|
+
Contributions are welcome! Please read our `Code of Conduct
|
|
146
|
+
<https://github.com/adafruit/Adafruit_CircuitPython_QMC5883P/blob/HEAD/CODE_OF_CONDUCT.md>`_
|
|
147
|
+
before contributing to help this project stay welcoming.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
adafruit_qmc5883p.py,sha256=ZdenYn0bvGe0vFlGU2hnrqcT-0JkbW0xxnxCXCWTD_Y,8960
|
|
2
|
+
adafruit_circuitpython_qmc5883p-1.0.0.dist-info/licenses/LICENSE,sha256=wVvRttvrBkNBywZ9UleFPOXyBN2G0jmzBWx2sMlPn84,1100
|
|
3
|
+
adafruit_circuitpython_qmc5883p-1.0.0.dist-info/METADATA,sha256=nHm6IPBBN-0CDBltLq_IO0TEDm7L7T5gaR3j8xam6-s,4693
|
|
4
|
+
adafruit_circuitpython_qmc5883p-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
adafruit_circuitpython_qmc5883p-1.0.0.dist-info/top_level.txt,sha256=pRG0X7-QH4J554Rk-AIdHQ6E4jAZymZEuGF5fyJaprA,18
|
|
6
|
+
adafruit_circuitpython_qmc5883p-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Liz Clark for Adafruit Industries
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
adafruit_qmc5883p
|
adafruit_qmc5883p.py
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 Liz Clark for Adafruit Industries
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
"""
|
|
5
|
+
`adafruit_qmc5883p`
|
|
6
|
+
================================================================================
|
|
7
|
+
|
|
8
|
+
CircuitPython driver for the Adafruit QMC5883P - Triple Axis Magnetometer - STEMMA QT
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
* Author(s): Liz Clark
|
|
12
|
+
|
|
13
|
+
Implementation Notes
|
|
14
|
+
--------------------
|
|
15
|
+
|
|
16
|
+
**Hardware:**
|
|
17
|
+
|
|
18
|
+
* `Adafruit QMC5883P - Triple Axis Magnetometer <https://www.adafruit.com/product/6388>`_"
|
|
19
|
+
|
|
20
|
+
**Software and Dependencies:**
|
|
21
|
+
|
|
22
|
+
* Adafruit CircuitPython firmware for the supported boards:
|
|
23
|
+
https://circuitpython.org/downloads
|
|
24
|
+
|
|
25
|
+
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
|
|
26
|
+
* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
import struct
|
|
30
|
+
import time
|
|
31
|
+
|
|
32
|
+
from adafruit_bus_device.i2c_device import I2CDevice
|
|
33
|
+
from adafruit_register.i2c_bit import ROBit, RWBit
|
|
34
|
+
from adafruit_register.i2c_bits import RWBits
|
|
35
|
+
from adafruit_register.i2c_struct import ROUnaryStruct
|
|
36
|
+
from micropython import const
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
from typing import Tuple
|
|
40
|
+
|
|
41
|
+
import busio
|
|
42
|
+
except ImportError:
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
__version__ = "1.0.0"
|
|
46
|
+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_QMC5883P.git"
|
|
47
|
+
|
|
48
|
+
# I2C Address
|
|
49
|
+
_DEFAULT_ADDR = const(0x2C)
|
|
50
|
+
|
|
51
|
+
# Registers
|
|
52
|
+
_CHIPID = const(0x00)
|
|
53
|
+
_XOUT_LSB = const(0x01)
|
|
54
|
+
_XOUT_MSB = const(0x02)
|
|
55
|
+
_YOUT_LSB = const(0x03)
|
|
56
|
+
_YOUT_MSB = const(0x04)
|
|
57
|
+
_ZOUT_LSB = const(0x05)
|
|
58
|
+
_ZOUT_MSB = const(0x06)
|
|
59
|
+
_STATUS = const(0x09)
|
|
60
|
+
_CONTROL1 = const(0x0A)
|
|
61
|
+
_CONTROL2 = const(0x0B)
|
|
62
|
+
|
|
63
|
+
# Operating modes
|
|
64
|
+
MODE_SUSPEND = const(0x00)
|
|
65
|
+
MODE_NORMAL = const(0x01)
|
|
66
|
+
MODE_SINGLE = const(0x02)
|
|
67
|
+
MODE_CONTINUOUS = const(0x03)
|
|
68
|
+
|
|
69
|
+
# Output data rates
|
|
70
|
+
ODR_10HZ = const(0x00)
|
|
71
|
+
ODR_50HZ = const(0x01)
|
|
72
|
+
ODR_100HZ = const(0x02)
|
|
73
|
+
ODR_200HZ = const(0x03)
|
|
74
|
+
|
|
75
|
+
# Over sample ratios
|
|
76
|
+
OSR_8 = const(0x00)
|
|
77
|
+
OSR_4 = const(0x01)
|
|
78
|
+
OSR_2 = const(0x02)
|
|
79
|
+
OSR_1 = const(0x03)
|
|
80
|
+
|
|
81
|
+
# Downsample ratios
|
|
82
|
+
DSR_1 = const(0x00)
|
|
83
|
+
DSR_2 = const(0x01)
|
|
84
|
+
DSR_4 = const(0x02)
|
|
85
|
+
DSR_8 = const(0x03)
|
|
86
|
+
|
|
87
|
+
# Field ranges
|
|
88
|
+
RANGE_30G = const(0x00)
|
|
89
|
+
RANGE_12G = const(0x01)
|
|
90
|
+
RANGE_8G = const(0x02)
|
|
91
|
+
RANGE_2G = const(0x03)
|
|
92
|
+
|
|
93
|
+
# Set/Reset modes
|
|
94
|
+
SETRESET_ON = const(0x00)
|
|
95
|
+
SETRESET_SETONLY = const(0x01)
|
|
96
|
+
SETRESET_OFF = const(0x02)
|
|
97
|
+
|
|
98
|
+
# LSB per Gauss for each range
|
|
99
|
+
_LSB_PER_GAUSS = {RANGE_30G: 1000.0, RANGE_12G: 2500.0, RANGE_8G: 3750.0, RANGE_2G: 15000.0}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class QMC5883P:
|
|
103
|
+
"""Driver for the QMC5883P 3-axis magnetometer.
|
|
104
|
+
|
|
105
|
+
:param ~busio.I2C i2c_bus: The I2C bus the QMC5883P is connected to.
|
|
106
|
+
:param int address: The I2C address of the device. Defaults to :const:`0x3C`
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
# Register definitions using adafruit_register
|
|
110
|
+
_chip_id = ROUnaryStruct(_CHIPID, "<B")
|
|
111
|
+
|
|
112
|
+
# Status register bits
|
|
113
|
+
data_ready = ROBit(_STATUS, 0)
|
|
114
|
+
"""Check if new magnetic data is ready."""
|
|
115
|
+
overflow = ROBit(_STATUS, 1)
|
|
116
|
+
"""Check if data overflow has occurred."""
|
|
117
|
+
|
|
118
|
+
# Control register 1 bits
|
|
119
|
+
_mode = RWBits(2, _CONTROL1, 0)
|
|
120
|
+
_odr = RWBits(2, _CONTROL1, 2)
|
|
121
|
+
_osr = RWBits(2, _CONTROL1, 4)
|
|
122
|
+
_dsr = RWBits(2, _CONTROL1, 6)
|
|
123
|
+
|
|
124
|
+
# Control register 2 bits
|
|
125
|
+
_setreset = RWBits(2, _CONTROL2, 0)
|
|
126
|
+
_range = RWBits(2, _CONTROL2, 2)
|
|
127
|
+
_selftest = RWBit(_CONTROL2, 6)
|
|
128
|
+
_reset = RWBit(_CONTROL2, 7)
|
|
129
|
+
|
|
130
|
+
def __init__(self, i2c_bus: busio.I2C, address: int = _DEFAULT_ADDR) -> None:
|
|
131
|
+
self.i2c_device = I2CDevice(i2c_bus, address)
|
|
132
|
+
|
|
133
|
+
# Check chip ID
|
|
134
|
+
if self._chip_id != 0x80:
|
|
135
|
+
raise RuntimeError("Failed to find QMC5883P chip")
|
|
136
|
+
|
|
137
|
+
# Initialize with default settings
|
|
138
|
+
self.mode = MODE_NORMAL
|
|
139
|
+
self.data_rate = ODR_50HZ
|
|
140
|
+
self.oversample_ratio = OSR_4
|
|
141
|
+
self.downsample_ratio = DSR_2
|
|
142
|
+
self.range = RANGE_8G
|
|
143
|
+
self.setreset_mode = SETRESET_ON
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def magnetic(self) -> Tuple[float, float, float]:
|
|
147
|
+
"""The magnetic field measured in microteslas (uT).
|
|
148
|
+
|
|
149
|
+
:return: A 3-tuple of X, Y, Z axis values in microteslas
|
|
150
|
+
"""
|
|
151
|
+
# Wait for data ready
|
|
152
|
+
while not self.data_ready:
|
|
153
|
+
time.sleep(0.001)
|
|
154
|
+
|
|
155
|
+
# Read all 6 bytes at once
|
|
156
|
+
buf = bytearray(6)
|
|
157
|
+
with self.i2c_device as i2c:
|
|
158
|
+
i2c.write_then_readinto(bytes([_XOUT_LSB]), buf)
|
|
159
|
+
|
|
160
|
+
# Unpack as signed 16-bit integers
|
|
161
|
+
raw_x, raw_y, raw_z = struct.unpack("<hhh", buf)
|
|
162
|
+
|
|
163
|
+
# Get conversion factor based on current range
|
|
164
|
+
lsb_per_gauss = _LSB_PER_GAUSS[self._range]
|
|
165
|
+
|
|
166
|
+
# Convert to Gauss then to microteslas (1 Gauss = 100 uT)
|
|
167
|
+
x = raw_x / lsb_per_gauss
|
|
168
|
+
y = raw_y / lsb_per_gauss
|
|
169
|
+
z = raw_z / lsb_per_gauss
|
|
170
|
+
|
|
171
|
+
return (x, y, z)
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def magnetic_raw(self) -> Tuple[int, int, int]:
|
|
175
|
+
"""The raw magnetic field sensor values as signed 16-bit integers.
|
|
176
|
+
|
|
177
|
+
:return: A 3-tuple of X, Y, Z axis raw values
|
|
178
|
+
"""
|
|
179
|
+
# Wait for data ready
|
|
180
|
+
while not self._data_ready:
|
|
181
|
+
time.sleep(0.001)
|
|
182
|
+
|
|
183
|
+
# Read all 6 bytes at once
|
|
184
|
+
buf = bytearray(6)
|
|
185
|
+
with self.i2c_device as i2c:
|
|
186
|
+
i2c.write_then_readinto(bytes([_XOUT_LSB]), buf)
|
|
187
|
+
|
|
188
|
+
# Unpack as signed 16-bit integers
|
|
189
|
+
return struct.unpack("<hhh", buf)
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def mode(self) -> int:
|
|
193
|
+
"""The operating mode of the sensor.
|
|
194
|
+
|
|
195
|
+
Options are:
|
|
196
|
+
- MODE_SUSPEND (0x00): Suspend mode
|
|
197
|
+
- MODE_NORMAL (0x01): Normal mode
|
|
198
|
+
- MODE_SINGLE (0x02): Single measurement mode
|
|
199
|
+
- MODE_CONTINUOUS (0x03): Continuous mode
|
|
200
|
+
"""
|
|
201
|
+
return self._mode
|
|
202
|
+
|
|
203
|
+
@mode.setter
|
|
204
|
+
def mode(self, value: int) -> None:
|
|
205
|
+
if value not in {MODE_SUSPEND, MODE_NORMAL, MODE_SINGLE, MODE_CONTINUOUS}:
|
|
206
|
+
raise ValueError("Invalid mode")
|
|
207
|
+
self._mode = value
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def data_rate(self) -> int:
|
|
211
|
+
"""The output data rate in Hz.
|
|
212
|
+
|
|
213
|
+
Options are:
|
|
214
|
+
- ODR_10HZ (0x00): 10 Hz
|
|
215
|
+
- ODR_50HZ (0x01): 50 Hz
|
|
216
|
+
- ODR_100HZ (0x02): 100 Hz
|
|
217
|
+
- ODR_200HZ (0x03): 200 Hz
|
|
218
|
+
"""
|
|
219
|
+
return self._odr
|
|
220
|
+
|
|
221
|
+
@data_rate.setter
|
|
222
|
+
def data_rate(self, value: int) -> None:
|
|
223
|
+
if value not in {ODR_10HZ, ODR_50HZ, ODR_100HZ, ODR_200HZ}:
|
|
224
|
+
raise ValueError("Invalid output data rate")
|
|
225
|
+
self._odr = value
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def oversample_ratio(self) -> int:
|
|
229
|
+
"""The over sample ratio.
|
|
230
|
+
|
|
231
|
+
Options are:
|
|
232
|
+
- OSR_8 (0x00): Over sample ratio = 8
|
|
233
|
+
- OSR_4 (0x01): Over sample ratio = 4
|
|
234
|
+
- OSR_2 (0x02): Over sample ratio = 2
|
|
235
|
+
- OSR_1 (0x03): Over sample ratio = 1
|
|
236
|
+
"""
|
|
237
|
+
return self._osr
|
|
238
|
+
|
|
239
|
+
@oversample_ratio.setter
|
|
240
|
+
def oversample_ratio(self, value: int) -> None:
|
|
241
|
+
if value not in {OSR_8, OSR_4, OSR_2, OSR_1}:
|
|
242
|
+
raise ValueError("Invalid oversample ratio")
|
|
243
|
+
self._osr = value
|
|
244
|
+
|
|
245
|
+
@property
|
|
246
|
+
def downsample_ratio(self) -> int:
|
|
247
|
+
"""The downsample ratio.
|
|
248
|
+
|
|
249
|
+
Options are:
|
|
250
|
+
- DSR_1 (0x00): Downsample ratio = 1
|
|
251
|
+
- DSR_2 (0x01): Downsample ratio = 2
|
|
252
|
+
- DSR_4 (0x02): Downsample ratio = 4
|
|
253
|
+
- DSR_8 (0x03): Downsample ratio = 8
|
|
254
|
+
"""
|
|
255
|
+
return self._dsr
|
|
256
|
+
|
|
257
|
+
@downsample_ratio.setter
|
|
258
|
+
def downsample_ratio(self, value: int) -> None:
|
|
259
|
+
if value not in {DSR_1, DSR_2, DSR_4, DSR_8}:
|
|
260
|
+
raise ValueError("Invalid downsample ratio")
|
|
261
|
+
self._dsr = value
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
def range(self) -> int:
|
|
265
|
+
"""The magnetic field range.
|
|
266
|
+
|
|
267
|
+
Options are:
|
|
268
|
+
- RANGE_30G (0x00): ±30 Gauss range
|
|
269
|
+
- RANGE_12G (0x01): ±12 Gauss range
|
|
270
|
+
- RANGE_8G (0x02): ±8 Gauss range
|
|
271
|
+
- RANGE_2G (0x03): ±2 Gauss range
|
|
272
|
+
"""
|
|
273
|
+
return self._range
|
|
274
|
+
|
|
275
|
+
@range.setter
|
|
276
|
+
def range(self, value: int) -> None:
|
|
277
|
+
if value not in {RANGE_30G, RANGE_12G, RANGE_8G, RANGE_2G}:
|
|
278
|
+
raise ValueError("Invalid range")
|
|
279
|
+
self._range = value
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def setreset_mode(self) -> int:
|
|
283
|
+
"""The set/reset mode.
|
|
284
|
+
|
|
285
|
+
Options are:
|
|
286
|
+
- SETRESET_ON (0x00): Set and reset on
|
|
287
|
+
- SETRESET_SETONLY (0x01): Set only on
|
|
288
|
+
- SETRESET_OFF (0x02): Set and reset off
|
|
289
|
+
"""
|
|
290
|
+
return self._setreset
|
|
291
|
+
|
|
292
|
+
@setreset_mode.setter
|
|
293
|
+
def setreset_mode(self, value: int) -> None:
|
|
294
|
+
if value not in {SETRESET_ON, SETRESET_SETONLY, SETRESET_OFF}:
|
|
295
|
+
raise ValueError("Invalid set/reset mode")
|
|
296
|
+
self._setreset = value
|
|
297
|
+
|
|
298
|
+
def soft_reset(self) -> None:
|
|
299
|
+
"""Perform a soft reset of the chip."""
|
|
300
|
+
self._reset = True
|
|
301
|
+
time.sleep(0.05) # Wait 50ms for reset to complete
|
|
302
|
+
|
|
303
|
+
# Verify chip ID after reset
|
|
304
|
+
if self._chip_id != 0x80:
|
|
305
|
+
raise RuntimeError("Chip ID invalid after reset")
|
|
306
|
+
|
|
307
|
+
def self_test(self) -> bool:
|
|
308
|
+
"""Perform self-test of the chip.
|
|
309
|
+
|
|
310
|
+
:return: True if self-test passed, False otherwise
|
|
311
|
+
"""
|
|
312
|
+
self._selftest = True
|
|
313
|
+
time.sleep(0.005) # Wait 5ms for self-test to complete
|
|
314
|
+
|
|
315
|
+
# Check if self-test bit auto-cleared (indicates completion)
|
|
316
|
+
return not self._selftest
|