mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Add IMU app
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "IMU",
|
||||||
|
"publisher": "MicroPythonOS",
|
||||||
|
"short_description": "Inertial Measurement Unit Visualization",
|
||||||
|
"long_description": "Visualize data from the Intertial Measurement Unit, also known as the accellerometer.",
|
||||||
|
"icon_url": "https://apps.micropythonos.com/apps/com.micropythonos.helloworld/icons/com.micropythonos.imu.0.0.1_64x64.png",
|
||||||
|
"download_url": "https://apps.micropythonos.com/apps/com.micropythonos.helloworld/mpks/com.micropythonos.mu.0.0.1.mpk",
|
||||||
|
"fullname": "com.micropythonos.imu",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"category": "hardware",
|
||||||
|
"activities": [
|
||||||
|
{
|
||||||
|
"entrypoint": "assets/imu.py",
|
||||||
|
"classname": "IMU",
|
||||||
|
"intent_filters": [
|
||||||
|
{
|
||||||
|
"action": "main",
|
||||||
|
"category": "launcher"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
from mpos.apps import Activity
|
||||||
|
|
||||||
|
class IMU(Activity):
|
||||||
|
|
||||||
|
sensor = None
|
||||||
|
refresh_timer = None
|
||||||
|
|
||||||
|
# widgets:
|
||||||
|
sliderx = None
|
||||||
|
slidery = None
|
||||||
|
sliderz = None
|
||||||
|
slidergx = None
|
||||||
|
slidergy = None
|
||||||
|
slidergz = None
|
||||||
|
|
||||||
|
def onCreate(self):
|
||||||
|
screen = lv.obj()
|
||||||
|
self.templabel = lv.label(screen)
|
||||||
|
self.templabel.align(lv.ALIGN.TOP_MID, 0, 10)
|
||||||
|
self.sliderx = lv.slider(screen)
|
||||||
|
self.sliderx.align(lv.ALIGN.CENTER, 0, -60)
|
||||||
|
self.slidery = lv.slider(screen)
|
||||||
|
self.slidery.align(lv.ALIGN.CENTER, 0, -30)
|
||||||
|
self.sliderz = lv.slider(screen)
|
||||||
|
self.sliderz.align(lv.ALIGN.CENTER, 0, 0)
|
||||||
|
self.slidergx = lv.slider(screen)
|
||||||
|
self.slidergx.align(lv.ALIGN.CENTER, 0, 30)
|
||||||
|
self.slidergy = lv.slider(screen)
|
||||||
|
self.slidergy.align(lv.ALIGN.CENTER, 0, 60)
|
||||||
|
self.slidergz = lv.slider(screen)
|
||||||
|
self.slidergz.align(lv.ALIGN.CENTER, 0, 90)
|
||||||
|
try:
|
||||||
|
from machine import Pin, I2C
|
||||||
|
from qmi8658 import QMI8658
|
||||||
|
import machine
|
||||||
|
self.sensor = QMI8658(I2C(0, sda=machine.Pin(48), scl=machine.Pin(47)))
|
||||||
|
except Exception as e:
|
||||||
|
warning = f"Warning: could not initialize IMU hardware:\n{e}"
|
||||||
|
print(warning)
|
||||||
|
self.templabel.set_text(warning)
|
||||||
|
self.setContentView(screen)
|
||||||
|
|
||||||
|
def onStart(self, screen):
|
||||||
|
self.refresh_timer = lv.timer_create(self.refresh, 100, None)
|
||||||
|
|
||||||
|
def onStop(self, screen):
|
||||||
|
if self.refresh_timer:
|
||||||
|
self.refresh_timer.delete()
|
||||||
|
|
||||||
|
|
||||||
|
def map_nonlinear(self, value: float) -> int:
|
||||||
|
# Preserve sign and work with absolute value
|
||||||
|
sign = 1 if value >= 0 else -1
|
||||||
|
abs_value = abs(value)
|
||||||
|
# Apply non-linear transformation (square root) to absolute value
|
||||||
|
# Scale input range [0, 200] to [0, sqrt(200)] first
|
||||||
|
sqrt_value = (abs_value ** 0.5)
|
||||||
|
# Scale to output range [0, 100]
|
||||||
|
# Map [0, sqrt(200)] to [50, 100] for positive, [0, 50] for negative
|
||||||
|
max_sqrt = 200.0 ** 0.5 # Approx 14.142
|
||||||
|
scaled = (sqrt_value / max_sqrt) * 50.0 # Scale to [0, 50]
|
||||||
|
return int(50.0 + (sign * scaled)) # Shift to [0, 100]
|
||||||
|
|
||||||
|
def refresh(self, timer):
|
||||||
|
if self.sensor:
|
||||||
|
#print(f"""{sensor.temperature=} {sensor.acceleration=} {sensor.gyro=}""")
|
||||||
|
temp = self.sensor.temperature
|
||||||
|
ax = self.sensor.acceleration[0]
|
||||||
|
axp = int((ax * 100 + 100)/2)
|
||||||
|
ay = self.sensor.acceleration[1]
|
||||||
|
ayp = int((ay * 100 + 100)/2)
|
||||||
|
az = self.sensor.acceleration[2]
|
||||||
|
azp = int((az * 100 + 100)/2)
|
||||||
|
# values between -200 and 200 => /4 becomes -50 and 50 => +50 becomes 0 and 100
|
||||||
|
gx = self.map_nonlinear(self.sensor.gyro[0])
|
||||||
|
gy = self.map_nonlinear(self.sensor.gyro[1])
|
||||||
|
gz = self.map_nonlinear(self.sensor.gyro[2])
|
||||||
|
self.templabel.set_text(f"IMU chip temperature: {temp:.2f}°C")
|
||||||
|
else:
|
||||||
|
#temp = 12.34
|
||||||
|
import random
|
||||||
|
randomnr = random.randint(0,100)
|
||||||
|
axp = randomnr
|
||||||
|
ayp = 50
|
||||||
|
azp = 75
|
||||||
|
gx = 45
|
||||||
|
gy = 50
|
||||||
|
gz = 55
|
||||||
|
self.sliderx.set_value(axp, lv.ANIM.OFF)
|
||||||
|
self.slidery.set_value(ayp, lv.ANIM.OFF)
|
||||||
|
self.sliderz.set_value(azp, lv.ANIM.OFF)
|
||||||
|
self.slidergx.set_value(gx, lv.ANIM.OFF)
|
||||||
|
self.slidergy.set_value(gy, lv.ANIM.OFF)
|
||||||
|
self.slidergz.set_value(gz, lv.ANIM.OFF)
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
Reference in New Issue
Block a user