micrOSDevToolKit 2.10.5__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.

Files changed (110) hide show
  1. env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
  2. env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +17 -1
  3. micrOS/micropython/esp32c6-GENERIC-20250415-v1.25.0.bin +0 -0
  4. micrOS/micropython/esp32s3-4MBflash-20241129-v1.24.1.bin +0 -0
  5. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +47 -51
  6. micrOS/source/Common.py +262 -87
  7. micrOS/source/Debug.py +44 -88
  8. micrOS/source/Espnow.py +1 -1
  9. micrOS/source/Files.py +21 -2
  10. micrOS/source/Hooks.py +60 -17
  11. micrOS/source/IO_esp32c6.py +16 -0
  12. micrOS/source/IO_esp32s3.py +37 -1
  13. micrOS/source/IO_m5stamp.py +35 -1
  14. micrOS/source/IO_qtpy.py +22 -17
  15. micrOS/source/IO_s3matrix.py +21 -0
  16. micrOS/source/IO_tinypico.py +38 -0
  17. micrOS/source/LM_VL53L0X.py +1 -1
  18. micrOS/source/LM_buzzer.py +6 -7
  19. micrOS/source/LM_cct.py +6 -5
  20. micrOS/source/LM_dimmer.py +6 -5
  21. micrOS/source/LM_espnow.py +15 -10
  22. micrOS/source/LM_i2c.py +3 -2
  23. micrOS/source/LM_neoeffects.py +173 -230
  24. micrOS/source/LM_neomatrix.py +305 -0
  25. micrOS/source/LM_neopixel.py +10 -10
  26. micrOS/source/LM_oled_ui.py +18 -5
  27. micrOS/source/LM_pacman.py +25 -21
  28. micrOS/source/LM_qmi8658.py +204 -0
  29. micrOS/source/LM_rest.py +3 -3
  30. micrOS/source/LM_rgb.py +6 -6
  31. micrOS/source/LM_roboarm.py +5 -4
  32. micrOS/source/LM_switch.py +6 -4
  33. micrOS/source/LM_tcs3472.py +75 -0
  34. micrOS/source/LM_telegram.py +5 -4
  35. micrOS/source/Logger.py +46 -32
  36. micrOS/source/Shell.py +11 -10
  37. micrOS/source/Tasks.py +7 -4
  38. micrOS/source/Time.py +5 -3
  39. micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
  40. micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
  41. micrOS/source/micrOS.py +5 -2
  42. micrOS/source/microIO.py +8 -6
  43. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/METADATA +2 -1
  44. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/RECORD +101 -96
  45. toolkit/DevEnvUSB.py +5 -0
  46. toolkit/Gateway.py +3 -3
  47. toolkit/LM_to_compile.dat +1 -0
  48. toolkit/dashboard_apps/NeoEffectsDemo.py +8 -15
  49. toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
  50. toolkit/dashboard_apps/_app_base.py +2 -2
  51. toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
  52. toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
  53. toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
  54. toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
  55. toolkit/simulator_lib/__pycache__/sim_console.cpython-312.pyc +0 -0
  56. toolkit/simulator_lib/machine.py +0 -1
  57. toolkit/simulator_lib/neopixel.py +3 -2
  58. toolkit/socketClient.py +3 -2
  59. toolkit/user_data/webhooks/generic.py +1 -1
  60. toolkit/user_data/webhooks/macro.py +1 -1
  61. toolkit/user_data/webhooks/template.py +1 -1
  62. toolkit/workspace/precompiled/Common.mpy +0 -0
  63. toolkit/workspace/precompiled/Debug.mpy +0 -0
  64. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  65. toolkit/workspace/precompiled/Files.mpy +0 -0
  66. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  67. toolkit/workspace/precompiled/IO_esp32c6.mpy +0 -0
  68. toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
  69. toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
  70. toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
  71. toolkit/workspace/precompiled/IO_s3matrix.mpy +0 -0
  72. toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
  73. toolkit/workspace/precompiled/LM_VL53L0X.py +1 -1
  74. toolkit/workspace/precompiled/LM_buzzer.mpy +0 -0
  75. toolkit/workspace/precompiled/LM_cct.mpy +0 -0
  76. toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
  77. toolkit/workspace/precompiled/LM_espnow.py +15 -10
  78. toolkit/workspace/precompiled/LM_i2c.py +3 -2
  79. toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
  80. toolkit/workspace/precompiled/LM_neomatrix.mpy +0 -0
  81. toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
  82. toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
  83. toolkit/workspace/precompiled/LM_pacman.mpy +0 -0
  84. toolkit/workspace/precompiled/LM_qmi8658.py +204 -0
  85. toolkit/workspace/precompiled/LM_rest.mpy +0 -0
  86. toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
  87. toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
  88. toolkit/workspace/precompiled/LM_switch.mpy +0 -0
  89. toolkit/workspace/precompiled/LM_tcs3472.py +75 -0
  90. toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
  91. toolkit/workspace/precompiled/Logger.mpy +0 -0
  92. toolkit/workspace/precompiled/Shell.mpy +0 -0
  93. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  94. toolkit/workspace/precompiled/Time.mpy +0 -0
  95. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  96. toolkit/workspace/precompiled/microIO.mpy +0 -0
  97. micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
  98. micrOS/source/LM_catgame.py +0 -75
  99. micrOS/source/LM_demo.py +0 -97
  100. micrOS/source/LM_intercon.py +0 -60
  101. micrOS/source/LM_ph_sensor.py +0 -51
  102. toolkit/workspace/precompiled/LM_catgame.py +0 -75
  103. toolkit/workspace/precompiled/LM_demo.py +0 -97
  104. toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
  105. toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
  106. /micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-8MBflash-20241129-v1.24.1.bin} +0 -0
  107. {microsdevtoolkit-2.10.5.data → microsdevtoolkit-2.11.0.data}/scripts/devToolKit.py +0 -0
  108. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/WHEEL +0 -0
  109. {microsdevtoolkit-2.10.5.dist-info → microsdevtoolkit-2.11.0.dist-info}/licenses/LICENSE +0 -0
  110. {microsdevtoolkit-2.10.5.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)
@@ -2,7 +2,6 @@ from threading import Thread
2
2
  import time
3
3
  import micropython
4
4
  from sim_console import console
5
- import sys
6
5
 
7
6
 
8
7
  def machine(*args, **kwargs):
@@ -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
- pass
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
- output = main(args, host=host, port=port, timeout=timeout, pwd=action['password'], verbose=action['verbose'])
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))
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  Generic webhook for socketClient that can invoke LoadModule calls remotely from any device.
5
- Example: http://10.0.1.61:5000/webhooks/generic/TinyDevBoard+system+clock
5
+ Example: http://10.0.1.61:5005/webhooks/generic/TinyDevBoard+system+clock
6
6
  """
7
7
 
8
8
  import sys, os
@@ -3,7 +3,7 @@
3
3
  """
4
4
  Template for webhook creation
5
5
  - replies with basic response message
6
- Example: http://10.0.1.61:5000/webhooks/template
6
+ Example: http://10.0.1.61:5005/webhooks/template
7
7
  """
8
8
 
9
9
  import sys, os
@@ -3,7 +3,7 @@
3
3
  """
4
4
  Template for webhook creation
5
5
  - replies with basic response message
6
- Example: http://10.0.1.61:5000/webhooks/template
6
+ Example: http://10.0.1.61:5005/webhooks/template
7
7
  """
8
8
 
9
9
  import sys, os
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -343,7 +343,7 @@ class VL53L0X:
343
343
 
344
344
  def measure():
345
345
  """
346
- Experimental
346
+ Experimental - Time of Flight Distance Sensor
347
347
  """
348
348
  global __TOF_OBJ
349
349
  if __TOF_OBJ is None:
Binary file
Binary file
Binary file
@@ -2,10 +2,24 @@ import Espnow
2
2
 
3
3
  def load():
4
4
  """
5
- Initialize ESPNOW protocal
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): "trackball", hex(0x3c): "oled",
28
- hex(0x76): "bme280", hex(0x10): 'veml7700'}
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
@@ -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
@@ -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)