Ga naar inhoud

magnetometer

MagnetometerPeriod module-attribute #

MagnetometerPeriod = Union[
    Literal[1],
    Literal[2],
    Literal[5],
    Literal[10],
    Literal[20],
    Literal[80],
    Literal[160],
    Literal[640],
]

Het interval waarmee de magnetometer wordt uitgelezen, dit is een geheel getal en drukt het aantal milliseconden uit. Er is een beperkt aantal geldige periodes: 1, 2, 5, 10, 20, 80, 160, 640

Warning

Dit zijn de geldige waarden volgens de specificatie, maar het lijkt erop dat dit niet klopt/werkt zoals ik verwacht TODO te onderzoeken

Calibration #

Een klasse die je toelaat een calibratie op te volgen

Source code in src/kaspersmicrobit/services/magnetometer.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Calibration:
    """
    A class that allows you to follow up on a calibration
    """
    def __init__(self, future: Future[ByteData]):
        self._future = future
        self._result = None

    def done(self) -> bool:
        """
        Check whether the calibration is still in progress

        Returns:
            True if the calibration is done, False if it is still in progress
        """
        return self._future.done()

    def wait_for_result(self, timeout=None) -> bool:
        """
        Wait for the end of the calibration process
        Args:
            timeout: the maximum number of seconds you want to wait for a result

        Returns:
            True if the calibration was successful, False if it was unsuccessful
        """
        if not self._result:
            self._result = int.from_bytes(self._future.result(timeout=timeout)[0:2], "little")

        return self._result

done #

done() -> bool

Kijk na of de calibratie nog bezig is

Returns:

  • bool

    True indien de calibratie gedaan is, False indien het nog bezig is

Source code in src/kaspersmicrobit/services/magnetometer.py
32
33
34
35
36
37
38
39
def done(self) -> bool:
    """
    Check whether the calibration is still in progress

    Returns:
        True if the calibration is done, False if it is still in progress
    """
    return self._future.done()

wait_for_result #

wait_for_result(timeout=None) -> bool

Wacht op het einde van het calibreren Args: timeout: het aantal seconden dat je maximaal wil wachten op een resultaat

Returns:

  • bool

    True indien de calibratie gelukt is, False indien het mislukt is

Source code in src/kaspersmicrobit/services/magnetometer.py
41
42
43
44
45
46
47
48
49
50
51
52
53
def wait_for_result(self, timeout=None) -> bool:
    """
    Wait for the end of the calibration process
    Args:
        timeout: the maximum number of seconds you want to wait for a result

    Returns:
        True if the calibration was successful, False if it was unsuccessful
    """
    if not self._result:
        self._result = int.from_bytes(self._future.result(timeout=timeout)[0:2], "little")

    return self._result

MagnetometerData dataclass #

De waarden op de 3 assen van een meting van de magnetometer

Attributes:

  • x (int) –

    horizontaal (van links naar rechts)

  • y (int) –

    horizontaal (van achter naar voor)

  • z (int) –

    verticaal (van onder naar boven)

Source code in src/kaspersmicrobit/services/magnetometer.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
@dataclass
class MagnetometerData:
    """
    The values on the 3 axes of a magnetometer measurement

    Attributes:
        x (int): horizontal (left to right)
        y (int): horizontal (from back to front)
        z (int): vertical (from bottom to top)
    """
    x: int
    y: int
    z: int

    @staticmethod
    def from_bytes(values: ByteData):
        return MagnetometerData(
            int.from_bytes(values[0:2], "little", signed=True),
            int.from_bytes(values[2:4], "little", signed=True),
            int.from_bytes(values[4:6], "little", signed=True)
        )

MagnetometerService #

Deze klasse bevat de functies die je kan aanspreken in verband met de magnetometor van de micro:bit. Er zijn functies om

  • het magnetisch veld langs 3 assen te meten
  • de hoek in graden ten opzichte van het noorden te meten
  • de magnetometer te calibreren. Het is het best om de magnetometer te calibreren voor je gegevens uitleest, zoniet kunnen de gegevens of de hoek in graden verkeerd zijn.
Warning

Ik heb gemerkt dat ondanks calibratie, de microbits die ik testte slechte resultaten gaven (verder te onderzoeken)

Dit zijn alle mogelijkheden aangeboden door de bluetooth magnetometer service

Zie ook: https://lancaster-university.github.io/microbit-docs/ble/magnetometer-service/

Zie ook: https://lancaster-university.github.io/microbit-docs/ubit/compass/

Source code in src/kaspersmicrobit/services/magnetometer.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
class MagnetometerService:
    """
    This class contains the functions that you can use related to the magnetometor of the micro:bit.
    There are functions to

    - measure the magnetic field along 3 axes
    - measure the angle in degrees relative to north
    - calibrate the magnetometer. It is best to calibrate the magnetometer before reading data,
      otherwise the data or angle in degrees may be wrong.

    Warning:
        I noticed that despite calibration, the microbits I tested gave poor results
        (to be further investigated)

    These are all options offered by the Bluetooth magnetometer service

    See Also: https://lancaster-university.github.io/microbit-docs/ble/magnetometer-service/

    See Also: https://lancaster-university.github.io/microbit-docs/ubit/compass/
    """
    def __init__(self, device: BluetoothDevice):
        self._device = device
        self._calibration = None

    def is_available(self) -> bool:
        """
        Checks whether the magnetometer Bluetooth service is found on the connected micro:bit.

        Returns:
            true if the magnetometer was found, false if not.
        """
        return self._device.is_service_available(Service.MAGNETOMETER)

    def notify_data(self, callback: Callable[[MagnetometerData], None]):
        """
        You can call this method when you want to be notified of new magnetometer data. How often you
        receive new data depends on the magnetometer period

        Warning:
            The micro:bit will not provide any measurements if there has been no calibration

        Args:
            callback (Callable[[MagnetometerData], None]): a function that is called when there is new data
                are of the magnetometer. The new MagnetometerData is passed as an argument to this function

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to activate magnetometer data notifications (normally does not occur)
        """
        self._device.notify(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_DATA,
                            lambda sender, data: callback(MagnetometerData.from_bytes(data)))

    def read_data(self) -> MagnetometerData:
        """
        Returns the magnetometer data.

        Returns:
            The magnetometer data (x, y and z)

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to read the magnetometer data (normally does not occur)
        """
        return MagnetometerData.from_bytes(self._device.read(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_DATA))

    def set_period(self, period: MagnetometerPeriod):
        """
        Sets the interval at which the magnetometer takes measurements (in milliseconds).

        Args:
            period (MagnetometerPeriod): the interval at which the magnetometer takes measurements,
                valid values are: 1, 2, 5, 10, 20, 80, 160, 640

        Warning:
            These are the valid values according to the specification, but it seems that this does not work as I expect
            TODO to investigate

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to write the magnetometer period (normally does not occur)
        """
        self._device.write(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_PERIOD, period.to_bytes(2, "little"))

    def read_period(self) -> int:
        """
        Returns the interval at which the magnetometer takes measurements

        Returns:
            The interval in milliseconds

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to read the magnetometer period (normally does not occur)
        """
        return int.from_bytes(
            self._device.read(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_PERIOD)[0:2], "little")

    def notify_bearing(self, callback: Callable[[int], None]):
        """
        You can call this method if you want to be informed of the angle in degrees at which the micro:bit is oriented
        is compared to the north.

        Warning:
            The micro:bit will not provide any measurements if there has been no calibration

        Args:
            callback (Callable[[int], None]): a function that is called periodically with the angle in degrees
                compared to the north

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to activate magnetometer bearing notifications (normally does not occur)
        """
        self._device.notify(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_BEARING,
                            lambda sender, data: callback(int.from_bytes(data[0:2], "little")))

    def read_bearing(self) -> int:
        """
        Read the angle in degrees at which the micro:bit is pointed relative to north.

        Returns:
            the angle in degrees with respect to north

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to read the magnetometer bearing (normally does not occur)
        """
        return int.from_bytes(
            self._device.read(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_BEARING)[0:2], 'little')

    def calibrate(self) -> Calibration:
        """
        Calibrate the magnetometer. This method starts the calibration process on the micro:bit, you will be asked
        to tilt the micro:bit until all LEDs on the LED display are on. The magnetometer is calibrated by tilting
        If a calibration is already in progress, a new calibration will not be started

        Warning:
            The micro:bit will not provide any measurements if there has been no calibration

        See Also: https://support.microbit.org/support/solutions/articles/19000008874-calibrating-the-micro-bit-compass

        Returns:
            It is the calibration in progress. You can use this to check whether the calibration is still in progress, or wait until
            The calibration is done.

        Raises:
            errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
            errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
                to activate or monitor the magnetometer calibration (normally does not occur)
        """
        if self._calibration and not self._calibration.done():
            return self._calibration

        future = self._device.wait_for(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_CALIBRATION)
        self._device.write(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_CALIBRATION, int.to_bytes(1, 1, 'little'))
        calibration = Calibration(future)
        self._calibration = calibration
        return calibration

is_available #

is_available() -> bool

Kijkt na of de magnetometer bluetooth service gevonden wordt op de geconnecteerde micro:bit.

Returns:

  • bool

    true als de magnetometer gevonden werd, false indien niet.

Source code in src/kaspersmicrobit/services/magnetometer.py
103
104
105
106
107
108
109
110
def is_available(self) -> bool:
    """
    Checks whether the magnetometer Bluetooth service is found on the connected micro:bit.

    Returns:
        true if the magnetometer was found, false if not.
    """
    return self._device.is_service_available(Service.MAGNETOMETER)

notify_data #

notify_data(callback: Callable[[MagnetometerData], None])

Deze methode kan je oproepen wanneer je verwittigd wil worden van nieuwe magnetometer gegevens. Hoe vaak je nieuwe gegevens ontvangt hangt af van de magnetometer periode

Warning

De micro:bit geeft geen metingen indien er geen calibratie is geweest

Parameters:

  • callback (Callable[[MagnetometerData], None]) –

    een functie die wordt opgeroepen wanneer er nieuwe gegevens zijn van de magnetometer. De nieuwe MagnetometerData worden meegegeven als argument aan deze functie

Raises:

  • BluetoothServiceNotFound

    Wanneer de magnetometer service niet actief is op de micro:bit

  • BluetoothCharacteristicNotFound

    Wanneer de magnetometer service actief is, maar er geen manier was om de notificaties van magnetometer data te activeren (komt normaal gezien niet voor)

Source code in src/kaspersmicrobit/services/magnetometer.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def notify_data(self, callback: Callable[[MagnetometerData], None]):
    """
    You can call this method when you want to be notified of new magnetometer data. How often you
    receive new data depends on the magnetometer period

    Warning:
        The micro:bit will not provide any measurements if there has been no calibration

    Args:
        callback (Callable[[MagnetometerData], None]): a function that is called when there is new data
            are of the magnetometer. The new MagnetometerData is passed as an argument to this function

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to activate magnetometer data notifications (normally does not occur)
    """
    self._device.notify(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_DATA,
                        lambda sender, data: callback(MagnetometerData.from_bytes(data)))

read_data #

read_data() -> MagnetometerData

Geeft de gegevens van de magnetometer.

Returns:

Raises:

Source code in src/kaspersmicrobit/services/magnetometer.py
132
133
134
135
136
137
138
139
140
141
142
143
144
def read_data(self) -> MagnetometerData:
    """
    Returns the magnetometer data.

    Returns:
        The magnetometer data (x, y and z)

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to read the magnetometer data (normally does not occur)
    """
    return MagnetometerData.from_bytes(self._device.read(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_DATA))

set_period #

set_period(period: MagnetometerPeriod)

Stelt het interval in waarmee de magnetometer metingen doet (in milliseconden).

Parameters:

  • period (MagnetometerPeriod) –

    het interval waarop de magnetometer metingen doet, geldige waarden zijn: 1, 2, 5, 10, 20, 80, 160, 640

Warning

Dit zijn de geldige waarden volgens de specificatie, maar het lijkt erop dat dit niet klopt/werkt zoals ik verwacht TODO te onderzoeken

Raises:

Source code in src/kaspersmicrobit/services/magnetometer.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
def set_period(self, period: MagnetometerPeriod):
    """
    Sets the interval at which the magnetometer takes measurements (in milliseconds).

    Args:
        period (MagnetometerPeriod): the interval at which the magnetometer takes measurements,
            valid values are: 1, 2, 5, 10, 20, 80, 160, 640

    Warning:
        These are the valid values according to the specification, but it seems that this does not work as I expect
        TODO to investigate

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to write the magnetometer period (normally does not occur)
    """
    self._device.write(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_PERIOD, period.to_bytes(2, "little"))

read_period #

read_period() -> int

Geeft het interval terug waarmee de magnetometer metingen doet

Returns:

  • int

    Het interval in milliseconden

Raises:

Source code in src/kaspersmicrobit/services/magnetometer.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
def read_period(self) -> int:
    """
    Returns the interval at which the magnetometer takes measurements

    Returns:
        The interval in milliseconds

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to read the magnetometer period (normally does not occur)
    """
    return int.from_bytes(
        self._device.read(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_PERIOD)[0:2], "little")

notify_bearing #

notify_bearing(callback: Callable[[int], None])

Deze methode kan je oproepen wanneer je verwittigd wil worden van de hoek in graden waarin de micro:bit gericht wordt ten opzichte van het noorden.

Warning

De micro:bit geeft geen metingen indien er geen calibratie is geweest

Parameters:

  • callback (Callable[[int], None]) –

    een functie die periodiek wordt opgeroepen met de hoek in graden ten opzichte van het noorden

Raises:

  • BluetoothServiceNotFound

    Wanneer de magnetometer service niet actief is op de micro:bit

  • BluetoothCharacteristicNotFound

    Wanneer de magnetometer service actief is, maar er geen manier was om de notificaties van magnetometer bearing te activeren (komt normaal gezien niet voor)

Source code in src/kaspersmicrobit/services/magnetometer.py
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def notify_bearing(self, callback: Callable[[int], None]):
    """
    You can call this method if you want to be informed of the angle in degrees at which the micro:bit is oriented
    is compared to the north.

    Warning:
        The micro:bit will not provide any measurements if there has been no calibration

    Args:
        callback (Callable[[int], None]): a function that is called periodically with the angle in degrees
            compared to the north

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to activate magnetometer bearing notifications (normally does not occur)
    """
    self._device.notify(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_BEARING,
                        lambda sender, data: callback(int.from_bytes(data[0:2], "little")))

read_bearing #

read_bearing() -> int

Lees de hoek in graden waarin de micro:bit gericht wordt ten opzichte van het noorden.

Returns:

  • int

    de hoek in graden tov het noorden

Raises:

Source code in src/kaspersmicrobit/services/magnetometer.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
def read_bearing(self) -> int:
    """
    Read the angle in degrees at which the micro:bit is pointed relative to north.

    Returns:
        the angle in degrees with respect to north

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to read the magnetometer bearing (normally does not occur)
    """
    return int.from_bytes(
        self._device.read(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_BEARING)[0:2], 'little')

calibrate #

calibrate() -> Calibration

Calibreer de magnetometer. Deze methode start het calibratieproces op de micro:bit, waarbij je de micro:bit moet kantelen om het LED scherm te vullen. Door het kantelen wordt de magnetometer gecalibreerd Indien er al een calibratie bezig is wordt geen nieuwe calibratie gestart

Warning

De micro:bit geeft geen metingen indien er geen calibratie is geweest

Zie ook: https://support.microbit.org/support/solutions/articles/19000008874-calibrating-the-micro-bit-compass

Returns:

  • Calibration

    Het de calibratie die bezig is. Je kan hiermee nakijken of het calibreren nog bezig is, of wachten tot

  • Calibration

    De calibratie gedaan is.

Raises:

  • BluetoothServiceNotFound

    Wanneer de magnetometer service niet actief is op de micro:bit

  • BluetoothCharacteristicNotFound

    Wanneer de magnetometer service actief is, maar er geen manier was om de magnetometer calibratie te activeren of op te volgen (komt normaal gezien niet voor)

Source code in src/kaspersmicrobit/services/magnetometer.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
def calibrate(self) -> Calibration:
    """
    Calibrate the magnetometer. This method starts the calibration process on the micro:bit, you will be asked
    to tilt the micro:bit until all LEDs on the LED display are on. The magnetometer is calibrated by tilting
    If a calibration is already in progress, a new calibration will not be started

    Warning:
        The micro:bit will not provide any measurements if there has been no calibration

    See Also: https://support.microbit.org/support/solutions/articles/19000008874-calibrating-the-micro-bit-compass

    Returns:
        It is the calibration in progress. You can use this to check whether the calibration is still in progress, or wait until
        The calibration is done.

    Raises:
        errors.BluetoothServiceNotFound: When the magnetometer service is not active on the micro:bit
        errors.BluetoothCharacteristicNotFound: When the magnetometer service is active but there was no way
            to activate or monitor the magnetometer calibration (normally does not occur)
    """
    if self._calibration and not self._calibration.done():
        return self._calibration

    future = self._device.wait_for(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_CALIBRATION)
    self._device.write(Service.MAGNETOMETER, Characteristic.MAGNETOMETER_CALIBRATION, int.to_bytes(1, 1, 'little'))
    calibration = Calibration(future)
    self._calibration = calibration
    return calibration