micrOSDevToolKit 2.10.6__py3-none-any.whl → 2.11.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.
Potentially problematic release.
This version of micrOSDevToolKit might be problematic. Click here for more details.
- env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
- env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +17 -1
- micrOS/micropython/esp32c6-GENERIC-20250415-v1.25.0.bin +0 -0
- micrOS/micropython/esp32s3-4MBflash-20241129-v1.24.1.bin +0 -0
- micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +45 -49
- micrOS/source/Common.py +262 -87
- micrOS/source/Debug.py +44 -88
- micrOS/source/Espnow.py +1 -1
- micrOS/source/Files.py +21 -2
- micrOS/source/Hooks.py +60 -17
- micrOS/source/IO_esp32c6.py +16 -0
- micrOS/source/IO_esp32s3.py +37 -1
- micrOS/source/IO_m5stamp.py +35 -1
- micrOS/source/IO_qtpy.py +22 -17
- micrOS/source/IO_s3matrix.py +21 -0
- micrOS/source/IO_tinypico.py +38 -0
- micrOS/source/LM_VL53L0X.py +1 -1
- micrOS/source/LM_buzzer.py +6 -7
- micrOS/source/LM_cct.py +6 -5
- micrOS/source/LM_dimmer.py +6 -5
- micrOS/source/LM_espnow.py +15 -10
- micrOS/source/LM_i2c.py +3 -2
- micrOS/source/LM_neoeffects.py +173 -230
- micrOS/source/LM_neomatrix.py +305 -0
- micrOS/source/LM_neopixel.py +10 -10
- micrOS/source/LM_pacman.py +25 -21
- micrOS/source/LM_qmi8658.py +204 -0
- micrOS/source/LM_rgb.py +6 -6
- micrOS/source/LM_roboarm.py +5 -4
- micrOS/source/LM_switch.py +6 -4
- micrOS/source/LM_tcs3472.py +75 -0
- micrOS/source/LM_telegram.py +5 -4
- micrOS/source/Logger.py +46 -32
- micrOS/source/Shell.py +1 -1
- micrOS/source/Tasks.py +7 -4
- micrOS/source/Time.py +5 -3
- micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
- micrOS/source/micrOS.py +5 -2
- micrOS/source/microIO.py +8 -6
- {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.11.0.dist-info}/METADATA +2 -1
- {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.11.0.dist-info}/RECORD +92 -87
- toolkit/DevEnvUSB.py +5 -0
- toolkit/LM_to_compile.dat +1 -0
- toolkit/dashboard_apps/NeoEffectsDemo.py +8 -15
- toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
- toolkit/dashboard_apps/_app_base.py +2 -2
- toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
- toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
- toolkit/simulator_lib/machine.py +0 -1
- toolkit/simulator_lib/neopixel.py +3 -2
- toolkit/socketClient.py +3 -2
- toolkit/workspace/precompiled/Common.mpy +0 -0
- toolkit/workspace/precompiled/Debug.mpy +0 -0
- toolkit/workspace/precompiled/Espnow.mpy +0 -0
- toolkit/workspace/precompiled/Files.mpy +0 -0
- toolkit/workspace/precompiled/Hooks.mpy +0 -0
- toolkit/workspace/precompiled/IO_esp32c6.mpy +0 -0
- toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
- toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
- toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
- toolkit/workspace/precompiled/IO_s3matrix.mpy +0 -0
- toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
- toolkit/workspace/precompiled/LM_VL53L0X.py +1 -1
- toolkit/workspace/precompiled/LM_buzzer.mpy +0 -0
- toolkit/workspace/precompiled/LM_cct.mpy +0 -0
- toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
- toolkit/workspace/precompiled/LM_espnow.py +15 -10
- toolkit/workspace/precompiled/LM_i2c.py +3 -2
- toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
- toolkit/workspace/precompiled/LM_neomatrix.mpy +0 -0
- toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
- toolkit/workspace/precompiled/LM_pacman.mpy +0 -0
- toolkit/workspace/precompiled/LM_qmi8658.py +204 -0
- toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
- toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
- toolkit/workspace/precompiled/LM_switch.mpy +0 -0
- toolkit/workspace/precompiled/LM_tcs3472.py +75 -0
- toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
- toolkit/workspace/precompiled/Logger.mpy +0 -0
- toolkit/workspace/precompiled/Shell.mpy +0 -0
- toolkit/workspace/precompiled/Tasks.mpy +0 -0
- toolkit/workspace/precompiled/Time.mpy +0 -0
- toolkit/workspace/precompiled/micrOS.mpy +0 -0
- toolkit/workspace/precompiled/microIO.mpy +0 -0
- micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
- micrOS/source/LM_catgame.py +0 -75
- micrOS/source/LM_demo.py +0 -97
- micrOS/source/LM_intercon.py +0 -60
- micrOS/source/LM_ph_sensor.py +0 -51
- toolkit/workspace/precompiled/LM_catgame.py +0 -75
- toolkit/workspace/precompiled/LM_demo.py +0 -97
- toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
- toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
- /micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-8MBflash-20241129-v1.24.1.bin} +0 -0
- {microsdevtoolkit-2.10.6.data → microsdevtoolkit-2.11.0.data}/scripts/devToolKit.py +0 -0
- {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.11.0.dist-info}/WHEEL +0 -0
- {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.11.0.dist-info}/licenses/LICENSE +0 -0
- {microsdevtoolkit-2.10.6.dist-info → microsdevtoolkit-2.11.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import matplotlib.animation as animation
|
|
3
|
+
import multiprocessing as mp
|
|
4
|
+
from collections import deque
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
import matplotlib.dates as mdates
|
|
7
|
+
|
|
8
|
+
def visualizer_main(queue):
|
|
9
|
+
# Make figure wider and a bit taller
|
|
10
|
+
fig, (ax_accel, ax_gyro) = plt.subplots(2, 1, figsize=(14, 8))
|
|
11
|
+
plt.subplots_adjust(top=0.88, bottom=0.12, hspace=0.3)
|
|
12
|
+
|
|
13
|
+
history = 100
|
|
14
|
+
accel_data = {'x': deque([0] * history, maxlen=history),
|
|
15
|
+
'y': deque([0] * history, maxlen=history),
|
|
16
|
+
'z': deque([0] * history, maxlen=history)}
|
|
17
|
+
gyro_data = {'x': deque([0] * history, maxlen=history),
|
|
18
|
+
'y': deque([0] * history, maxlen=history),
|
|
19
|
+
'z': deque([0] * history, maxlen=history)}
|
|
20
|
+
time_axis = deque([datetime.now()] * history, maxlen=history)
|
|
21
|
+
|
|
22
|
+
# Increase line width here
|
|
23
|
+
line_width = 2.5
|
|
24
|
+
|
|
25
|
+
accel_lines = {
|
|
26
|
+
axis: ax_accel.plot([], [], label=f'accel_{axis}', linewidth=line_width)[0]
|
|
27
|
+
for axis in 'xyz'
|
|
28
|
+
}
|
|
29
|
+
gyro_lines = {
|
|
30
|
+
axis: ax_gyro.plot([], [], label=f'gyro_{axis}', linewidth=line_width)[0]
|
|
31
|
+
for axis in 'xyz'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
ax_accel.set_ylim(-2, 2)
|
|
35
|
+
ax_gyro.set_ylim(-300, 300)
|
|
36
|
+
|
|
37
|
+
for ax in [ax_accel, ax_gyro]:
|
|
38
|
+
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
|
|
39
|
+
ax.legend()
|
|
40
|
+
ax.grid(True)
|
|
41
|
+
ax.set_xlabel("Time (H:M:S)")
|
|
42
|
+
|
|
43
|
+
ax_accel.set_title("Acceleration")
|
|
44
|
+
ax_gyro.set_title("Gyroscope")
|
|
45
|
+
|
|
46
|
+
def update(_):
|
|
47
|
+
try:
|
|
48
|
+
while not queue.empty():
|
|
49
|
+
data = queue.get_nowait()
|
|
50
|
+
current_time = datetime.now()
|
|
51
|
+
time_axis.append(current_time)
|
|
52
|
+
|
|
53
|
+
for axis, val in zip('xyz', data['accel']):
|
|
54
|
+
accel_data[axis].append(val)
|
|
55
|
+
for axis, val in zip('xyz', data['gyro']):
|
|
56
|
+
gyro_data[axis].append(val)
|
|
57
|
+
except Exception as e:
|
|
58
|
+
print(f"Visualizer error: {e}")
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
for axis in 'xyz':
|
|
62
|
+
accel_lines[axis].set_data(time_axis, accel_data[axis])
|
|
63
|
+
gyro_lines[axis].set_data(time_axis, gyro_data[axis])
|
|
64
|
+
|
|
65
|
+
for ax in [ax_accel, ax_gyro]:
|
|
66
|
+
ax.set_xlim(time_axis[0], time_axis[-1])
|
|
67
|
+
ax.figure.autofmt_xdate()
|
|
68
|
+
|
|
69
|
+
return list(accel_lines.values()) + list(gyro_lines.values())
|
|
70
|
+
|
|
71
|
+
ani = animation.FuncAnimation(fig, update, interval=50)
|
|
72
|
+
plt.show()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
mp.set_start_method('spawn')
|
|
77
|
+
queue = mp.Queue()
|
|
78
|
+
visualizer_main(queue)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
toolkit/simulator_lib/machine.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
from sim_console import console
|
|
2
2
|
|
|
3
3
|
class NeoPixel:
|
|
4
4
|
__instance = None
|
|
@@ -17,9 +17,10 @@ class NeoPixel:
|
|
|
17
17
|
return cls.__pix_list[key]
|
|
18
18
|
|
|
19
19
|
def __setitem__(cls, key, value):
|
|
20
|
+
console(f"Update NeoPixel at index {key} to {value}")
|
|
20
21
|
cls.__pix_list[key] = value
|
|
21
22
|
|
|
22
23
|
def write(cls):
|
|
23
|
-
|
|
24
|
+
console(f"Neopixel write: {cls.__pix_list}")
|
|
24
25
|
|
|
25
26
|
|
toolkit/socketClient.py
CHANGED
|
@@ -424,7 +424,7 @@ def socket_commandline_args(arg_list):
|
|
|
424
424
|
return ' <a> '.join(command_buffer), return_action_dict
|
|
425
425
|
|
|
426
426
|
|
|
427
|
-
def run(arg_list=[], timeout=10):
|
|
427
|
+
def run(arg_list=[], timeout=10, verbose=False):
|
|
428
428
|
""" Run from code
|
|
429
429
|
- Handles extra command line arguments
|
|
430
430
|
"""
|
|
@@ -434,7 +434,8 @@ def run(arg_list=[], timeout=10):
|
|
|
434
434
|
output = False, ''
|
|
435
435
|
try:
|
|
436
436
|
#print("Socket run (args): {}".format(args))
|
|
437
|
-
|
|
437
|
+
verbose = verbose or action['verbose']
|
|
438
|
+
output = main(args, host=host, port=port, timeout=timeout, pwd=action['password'], verbose=verbose)
|
|
438
439
|
except Exception as e:
|
|
439
440
|
if "TimeOut" in str(e):
|
|
440
441
|
print("Resolve device by host ... {}.local {}:{}:{}".format(fid, host, port, uid))
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,10 +2,24 @@ import Espnow
|
|
|
2
2
|
|
|
3
3
|
def load():
|
|
4
4
|
"""
|
|
5
|
-
|
|
5
|
+
OBSOLETE - remove
|
|
6
|
+
[DEBUG ONLY] ENABLE ESPNOW IN NODE CONFIG INSTEAD OF HERE!
|
|
7
|
+
Initialize ESPNOW protocal
|
|
6
8
|
"""
|
|
7
9
|
return Espnow.initialize()
|
|
8
10
|
|
|
11
|
+
def start_server():
|
|
12
|
+
"""
|
|
13
|
+
OBSOLETE - remove
|
|
14
|
+
[DEBUG ONLY] ENABLE ESPNOW IN NODE CONFIG INSTEAD OF HERE!
|
|
15
|
+
Start ESPNOW server/listener
|
|
16
|
+
- this can receive espnow messages
|
|
17
|
+
- it includes Load Module execution logic (beta)
|
|
18
|
+
"""
|
|
19
|
+
now = Espnow.initialize()
|
|
20
|
+
return now.start_server()
|
|
21
|
+
|
|
22
|
+
|
|
9
23
|
def send(peer:bytes|str, msg:str='modules'):
|
|
10
24
|
"""
|
|
11
25
|
Send message to peer (by mac address)
|
|
@@ -15,15 +29,6 @@ def send(peer:bytes|str, msg:str='modules'):
|
|
|
15
29
|
now = Espnow.initialize()
|
|
16
30
|
return now.send(peer, msg)
|
|
17
31
|
|
|
18
|
-
def start_server():
|
|
19
|
-
"""
|
|
20
|
-
Start ESPNOW server/listener
|
|
21
|
-
- this can receive espnow messages
|
|
22
|
-
- it includes Load Module execution logic (beta)
|
|
23
|
-
"""
|
|
24
|
-
now = Espnow.initialize()
|
|
25
|
-
return now.start_server()
|
|
26
|
-
|
|
27
32
|
def stats():
|
|
28
33
|
"""
|
|
29
34
|
Get ESPNOW stats
|
|
@@ -24,8 +24,9 @@ def discover():
|
|
|
24
24
|
"""
|
|
25
25
|
Discover devices
|
|
26
26
|
"""
|
|
27
|
-
known_addresses = {hex(0x0A): "
|
|
28
|
-
hex(0x76): "
|
|
27
|
+
known_addresses = {hex(0x0A): "TRACKBALL", hex(0x3c): "OLED",
|
|
28
|
+
hex(0x76): "BME280", hex(0x10): 'VEML7700',
|
|
29
|
+
hex(0x6b): "QMI8658"}
|
|
29
30
|
devices = scan()
|
|
30
31
|
output = {"unknown": []}
|
|
31
32
|
for k in devices:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A simple driver for the QMI8658 IMU.
|
|
3
|
+
https://github.com/echo-lalia/qmi8658-micropython/blob/main/qmi8685.py
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import struct
|
|
7
|
+
import time
|
|
8
|
+
from machine import Pin, I2C
|
|
9
|
+
from micropython import const
|
|
10
|
+
from microIO import bind_pin, pinmap_search
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Sensor constants
|
|
14
|
+
_QMI8685_PARTID = const(0x05)
|
|
15
|
+
_REG_PARTID = const(0x00)
|
|
16
|
+
_REG_REVISION = const(0x01)
|
|
17
|
+
|
|
18
|
+
_REG_CTRL1 = const(0x02) # Serial interface and sensor enable
|
|
19
|
+
_REG_CTRL2 = const(0x03) # Accelerometer settings
|
|
20
|
+
_REG_CTRL3 = const(0x04) # Gyroscope settings
|
|
21
|
+
_REG_CTRL4 = const(0x05) # Magnetomer settings (support not implemented in this driver yet)
|
|
22
|
+
_REG_CTRL5 = const(0x06) # Sensor data processing settings
|
|
23
|
+
_REG_CTRL6 = const(0x07) # Attitude Engine ODR and Motion on Demand
|
|
24
|
+
_REG_CTRL7 = const(0x08) # Enable Sensors and Configure Data Reads
|
|
25
|
+
|
|
26
|
+
_REG_TEMP = const(0x33) # Temperature sensor.
|
|
27
|
+
|
|
28
|
+
_REG_AX_L = const(0x35) # Read accelerometer
|
|
29
|
+
_REG_AX_H = const(0x36)
|
|
30
|
+
_REG_AY_L = const(0x37)
|
|
31
|
+
_REG_AY_H = const(0x38)
|
|
32
|
+
_REG_AZ_L = const(0x39)
|
|
33
|
+
_REG_AZ_H = const(0x3A)
|
|
34
|
+
|
|
35
|
+
_REG_GX_L = const(0x3B) # read gyro
|
|
36
|
+
_REG_GX_H = const(0x3C)
|
|
37
|
+
_REG_GY_L = const(0x3D)
|
|
38
|
+
_REG_GY_H = const(0x3E)
|
|
39
|
+
_REG_GZ_L = const(0x3F)
|
|
40
|
+
_REG_GZ_H = const(0x40)
|
|
41
|
+
|
|
42
|
+
_QMI8658_I2CADDR_DEFAULT = const(0X6B)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
_ACCELSCALE_RANGE_2G = const(0b00)
|
|
46
|
+
_ACCELSCALE_RANGE_4G = const(0b01)
|
|
47
|
+
_ACCELSCALE_RANGE_8G = const(0b10)
|
|
48
|
+
_ACCELSCALE_RANGE_16G = const(0b11)
|
|
49
|
+
|
|
50
|
+
_GYROSCALE_RANGE_16DPS = const(0b000)
|
|
51
|
+
_GYROSCALE_RANGE_32DPS = const(0b001)
|
|
52
|
+
_GYROSCALE_RANGE_64DPS = const(0b010)
|
|
53
|
+
_GYROSCALE_RANGE_128DPS = const(0b011)
|
|
54
|
+
_GYROSCALE_RANGE_256DPS = const(0b100)
|
|
55
|
+
_GYROSCALE_RANGE_512DPS = const(0b101)
|
|
56
|
+
_GYROSCALE_RANGE_1024DPS = const(0b110)
|
|
57
|
+
_GYROSCALE_RANGE_2048DPS = const(0b111)
|
|
58
|
+
|
|
59
|
+
_ODR_8000HZ = const(0b0000)
|
|
60
|
+
_ODR_4000HZ = const(0b0001)
|
|
61
|
+
_ODR_2000HZ = const(0b0010)
|
|
62
|
+
_ODR_1000HZ = const(0b0011)
|
|
63
|
+
_ODR_500HZ = const(0b0100)
|
|
64
|
+
_ODR_250HZ = const(0b0101)
|
|
65
|
+
_ODR_125HZ = const(0b0110)
|
|
66
|
+
_ODR_62_5HZ = const(0b0111)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class QMI8658:
|
|
70
|
+
"""QMI8658 inertial measurement unit."""
|
|
71
|
+
INSTANCE = None
|
|
72
|
+
|
|
73
|
+
def __init__(
|
|
74
|
+
self,
|
|
75
|
+
i2c_bus: I2C,
|
|
76
|
+
address: int = _QMI8658_I2CADDR_DEFAULT,
|
|
77
|
+
accel_scale: int = _ACCELSCALE_RANGE_8G,
|
|
78
|
+
gyro_scale: int = _GYROSCALE_RANGE_256DPS):
|
|
79
|
+
"""Read from a sensor on the given I2C bus, at the given address."""
|
|
80
|
+
self.i2c = i2c_bus
|
|
81
|
+
self.address = address
|
|
82
|
+
# Cache the sensor instance globally for easy access
|
|
83
|
+
QMI8658.INSTANCE = self
|
|
84
|
+
|
|
85
|
+
# Verify sensor part ID
|
|
86
|
+
if self._read_u8(_REG_PARTID) != _QMI8685_PARTID:
|
|
87
|
+
raise AttributeError("Cannot find a QMI8658")
|
|
88
|
+
|
|
89
|
+
# Setup initial configuration
|
|
90
|
+
self._configure_sensor(accel_scale, gyro_scale)
|
|
91
|
+
|
|
92
|
+
# Configure scales/divisors for the driver
|
|
93
|
+
self.acc_scale_divisor = {
|
|
94
|
+
_ACCELSCALE_RANGE_2G: 1 << 14,
|
|
95
|
+
_ACCELSCALE_RANGE_4G: 1 << 13,
|
|
96
|
+
_ACCELSCALE_RANGE_8G: 1 << 12,
|
|
97
|
+
_ACCELSCALE_RANGE_16G: 1 << 11,
|
|
98
|
+
}[accel_scale]
|
|
99
|
+
|
|
100
|
+
self.gyro_scale_divisor = {
|
|
101
|
+
_GYROSCALE_RANGE_16DPS: 2048,
|
|
102
|
+
_GYROSCALE_RANGE_32DPS: 1024,
|
|
103
|
+
_GYROSCALE_RANGE_64DPS: 512,
|
|
104
|
+
_GYROSCALE_RANGE_128DPS: 256,
|
|
105
|
+
_GYROSCALE_RANGE_256DPS: 128,
|
|
106
|
+
_GYROSCALE_RANGE_512DPS: 64,
|
|
107
|
+
_GYROSCALE_RANGE_1024DPS: 32,
|
|
108
|
+
_GYROSCALE_RANGE_2048DPS: 16,
|
|
109
|
+
}[gyro_scale]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _configure_sensor(self, accel_scale: int, gyro_scale: int):
|
|
113
|
+
# Initialize accelerometer and gyroscope settings
|
|
114
|
+
self._write_u8(_REG_CTRL1, 0x60) # Set SPI auto increment and big endian (Ctrl 1)
|
|
115
|
+
self._write_u8(_REG_CTRL2, (accel_scale << 4) | _ODR_1000HZ) # Accel Config
|
|
116
|
+
self._write_u8(_REG_CTRL3, (gyro_scale << 4) | _ODR_1000HZ) # Gyro Config
|
|
117
|
+
self._write_u8(_REG_CTRL5, 0x01) # Low-pass filter enable
|
|
118
|
+
self._write_u8(_REG_CTRL7, 0x03) # Enable accel and gyro
|
|
119
|
+
time.sleep_ms(100)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# Helper functions for register operations
|
|
123
|
+
def _read_u8(self, reg:int) -> int:
|
|
124
|
+
return self.i2c.readfrom_mem(self.address, reg, 1)[0]
|
|
125
|
+
|
|
126
|
+
def _read_xyz(self, reg:int) -> tuple[int, int, int]:
|
|
127
|
+
data = self.i2c.readfrom_mem(self.address, reg, 6)
|
|
128
|
+
return struct.unpack('<hhh', data)
|
|
129
|
+
|
|
130
|
+
def _write_u8(self, reg: int, value: int):
|
|
131
|
+
self.i2c.writeto_mem(self.address, reg, bytes([value]))
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def temperature(self) -> float:
|
|
136
|
+
"""Get the device temperature."""
|
|
137
|
+
temp_raw = self._read_u8(_REG_TEMP)
|
|
138
|
+
return temp_raw / 256
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def acceleration(self) -> tuple[float, float, float]:
|
|
142
|
+
"""Get current acceleration reading."""
|
|
143
|
+
raw_accel = self._read_xyz(_REG_AX_L)
|
|
144
|
+
return tuple(val / self.acc_scale_divisor for val in raw_accel)
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def gyro(self) -> tuple[float, float, float]:
|
|
148
|
+
"""Get current gyroscope reading."""
|
|
149
|
+
raw_gyro = self._read_xyz(_REG_GX_L)
|
|
150
|
+
return tuple(val / self.gyro_scale_divisor for val in raw_gyro)
|
|
151
|
+
|
|
152
|
+
#######################
|
|
153
|
+
# Public functions #
|
|
154
|
+
#######################
|
|
155
|
+
|
|
156
|
+
def load():
|
|
157
|
+
"""
|
|
158
|
+
Load the QMI8658 sensor instance.
|
|
159
|
+
The QMI8658 is a motion sensor that measures acceleration, angular velocity (gyroscope), and temperature
|
|
160
|
+
"""
|
|
161
|
+
if QMI8658.INSTANCE is None:
|
|
162
|
+
QMI8658(I2C(0, sda=Pin(bind_pin('i2c_sda')), scl=Pin(bind_pin('i2c_scl'))))
|
|
163
|
+
return QMI8658.INSTANCE
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def temperature():
|
|
167
|
+
return load().temperature
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def acceleration():
|
|
171
|
+
return load().acceleration
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def gyro():
|
|
175
|
+
return load().gyro
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def measure():
|
|
179
|
+
inst = load()
|
|
180
|
+
return {"temp": inst.temperature, "accel": inst.acceleration, "gyro": inst.gyro}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
#######################
|
|
184
|
+
# LM helper functions #
|
|
185
|
+
#######################
|
|
186
|
+
|
|
187
|
+
def pinmap():
|
|
188
|
+
"""
|
|
189
|
+
[i] micrOS LM naming convention
|
|
190
|
+
Shows logical pins - pin number(s) used by this Load module
|
|
191
|
+
- info which pins to use for this application
|
|
192
|
+
:return dict: pin name (str) - pin value (int) pairs
|
|
193
|
+
"""
|
|
194
|
+
return pinmap_search(['i2c_scl', 'i2c_sda'])
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def help(widgets=False):
|
|
198
|
+
"""
|
|
199
|
+
[i] micrOS LM naming convention - built-in help message
|
|
200
|
+
:return tuple:
|
|
201
|
+
(widgets=False) list of functions implemented by this application
|
|
202
|
+
(widgets=True) list of widget json for UI generation
|
|
203
|
+
"""
|
|
204
|
+
return 'load', 'temperature', 'acceleration', 'gyro', 'measure', 'pinmap'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A MicroPython library for the TCS3472 light sensing chip
|
|
3
|
+
https://github.com/tti0/tcs3472-micropython
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2021 tti0
|
|
6
|
+
Licensed under the MIT License
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from machine import I2C, Pin
|
|
10
|
+
from microIO import bind_pin, pinmap_search
|
|
11
|
+
import struct
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TCS3472:
|
|
15
|
+
INSTANCE = None
|
|
16
|
+
|
|
17
|
+
def __init__(self, bus, address=0x29):
|
|
18
|
+
self._bus = bus
|
|
19
|
+
self._i2c_address = address
|
|
20
|
+
|
|
21
|
+
self._bus.start()
|
|
22
|
+
|
|
23
|
+
self._bus.writeto(self._i2c_address, b'\x80\x03')
|
|
24
|
+
self._bus.writeto(self._i2c_address, b'\x81\x2b')
|
|
25
|
+
|
|
26
|
+
TCS3472.INSTANCE = self
|
|
27
|
+
|
|
28
|
+
def scaled(self):
|
|
29
|
+
crgb = self.raw()
|
|
30
|
+
if crgb[0] > 0:
|
|
31
|
+
return tuple(float(x) / crgb[0] for x in crgb[1:])
|
|
32
|
+
|
|
33
|
+
return (0, 0, 0)
|
|
34
|
+
|
|
35
|
+
def rgb(self):
|
|
36
|
+
return tuple(int(x * 255) for x in self.scaled())
|
|
37
|
+
|
|
38
|
+
def light(self):
|
|
39
|
+
return self.raw()[0]
|
|
40
|
+
|
|
41
|
+
def brightness(self, level=65.535):
|
|
42
|
+
return int((self.light() / level))
|
|
43
|
+
|
|
44
|
+
def valid(self):
|
|
45
|
+
self._bus.writeto(self._i2c_address, b'\x93')
|
|
46
|
+
return self._bus.readfrom(self._i2c_address, 1)[0] & 1
|
|
47
|
+
|
|
48
|
+
def raw(self):
|
|
49
|
+
self._bus.writeto(self._i2c_address, b'\xb4')
|
|
50
|
+
return struct.unpack("<HHHH", self._bus.readfrom(self._i2c_address, 8))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
############################ Exposed functions ############################
|
|
54
|
+
|
|
55
|
+
def load():
|
|
56
|
+
"""
|
|
57
|
+
Load the TCS3472 Color sensor instance.
|
|
58
|
+
"""
|
|
59
|
+
if TCS3472.INSTANCE is None:
|
|
60
|
+
bus = I2C(sda=Pin(bind_pin('i2c_sda')), scl=Pin(bind_pin('i2c_scl')))
|
|
61
|
+
TCS3472.INSTANCE = TCS3472(bus)
|
|
62
|
+
return TCS3472.INSTANCE
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def pinmap():
|
|
66
|
+
return pinmap_search(['i2c_scl', 'i2c_sda'])
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def measure():
|
|
70
|
+
sensor = load()
|
|
71
|
+
return {"rgb": sensor.rgb(), "light": sensor.light(), "brightness": sensor.brightness()}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def help(widgest=False):
|
|
75
|
+
return 'load', 'measure'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
micrOS/source/LM_catgame.py
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
from random import randint
|
|
2
|
-
from LM_servo import sduty, deinit, pinmap as pm
|
|
3
|
-
from utime import sleep_ms
|
|
4
|
-
from Types import resolve
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def load():
|
|
8
|
-
"""
|
|
9
|
-
Initialize catgame-servo module
|
|
10
|
-
"""
|
|
11
|
-
return "catgame-servo module - loaded"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def game(repeat=10, delta=20):
|
|
15
|
-
"""
|
|
16
|
-
Servo cat toy "mover" - left-right
|
|
17
|
-
:param repeat int: repeat servo pos change
|
|
18
|
-
:param delta int: center(75) +/-delta(35)
|
|
19
|
-
:return str: verdict
|
|
20
|
-
"""
|
|
21
|
-
sduty(75)
|
|
22
|
-
for _ in range(0, repeat):
|
|
23
|
-
sduty(randint(75-delta, 75+delta))
|
|
24
|
-
sleep_ms(randint(20, 1500))
|
|
25
|
-
sduty(75)
|
|
26
|
-
return 'Game action'
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def live_game(chance=10):
|
|
30
|
-
"""
|
|
31
|
-
Generate game
|
|
32
|
-
:param chance int: percent value 0-100
|
|
33
|
-
:return str: verdict (action / no action)
|
|
34
|
-
"""
|
|
35
|
-
action = randint(1, 10)
|
|
36
|
-
if action <= int(chance/10):
|
|
37
|
-
return game(repeat=5)
|
|
38
|
-
return 'No action'
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def stop():
|
|
42
|
-
"""
|
|
43
|
-
Stop game - home position (75) + deinit
|
|
44
|
-
:return str: servo verdict
|
|
45
|
-
"""
|
|
46
|
-
out = sduty(75)
|
|
47
|
-
deinit()
|
|
48
|
-
return out
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
#######################
|
|
52
|
-
# LM helper functions #
|
|
53
|
-
#######################
|
|
54
|
-
|
|
55
|
-
def pinmap():
|
|
56
|
-
"""
|
|
57
|
-
[i] micrOS LM naming convention
|
|
58
|
-
Shows logical pins - pin number(s) used by this Load module
|
|
59
|
-
- info which pins to use for this application
|
|
60
|
-
:return dict: pin name (str) - pin value (int) pairs
|
|
61
|
-
"""
|
|
62
|
-
return pm()
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def help(widgets=False):
|
|
66
|
-
"""
|
|
67
|
-
[i] micrOS LM naming convention - built-in help message
|
|
68
|
-
:return tuple:
|
|
69
|
-
(widgets=False) list of functions implemented by this application
|
|
70
|
-
(widgets=True) list of widget json for UI generation
|
|
71
|
-
"""
|
|
72
|
-
return resolve(('BUTTON game repeat=10',
|
|
73
|
-
'SLIDER live_game chance=<10-90>',
|
|
74
|
-
'BUTTON stop', 'pinmap',
|
|
75
|
-
'load'), widgets=widgets)
|