|
| 1 | +frommpos.appsimportActivity |
| 2 | + |
| 3 | +classIMU(Activity): |
| 4 | + |
| 5 | +sensor=None |
| 6 | +refresh_timer=None |
| 7 | + |
| 8 | +# widgets: |
| 9 | +sliderx=None |
| 10 | +slidery=None |
| 11 | +sliderz=None |
| 12 | +slidergx=None |
| 13 | +slidergy=None |
| 14 | +slidergz=None |
| 15 | + |
| 16 | +defonCreate(self): |
| 17 | +screen=lv.obj() |
| 18 | +self.templabel=lv.label(screen) |
| 19 | +self.templabel.align(lv.ALIGN.TOP_MID,0,10) |
| 20 | +self.sliderx=lv.slider(screen) |
| 21 | +self.sliderx.align(lv.ALIGN.CENTER,0,-60) |
| 22 | +self.slidery=lv.slider(screen) |
| 23 | +self.slidery.align(lv.ALIGN.CENTER,0,-30) |
| 24 | +self.sliderz=lv.slider(screen) |
| 25 | +self.sliderz.align(lv.ALIGN.CENTER,0,0) |
| 26 | +self.slidergx=lv.slider(screen) |
| 27 | +self.slidergx.align(lv.ALIGN.CENTER,0,30) |
| 28 | +self.slidergy=lv.slider(screen) |
| 29 | +self.slidergy.align(lv.ALIGN.CENTER,0,60) |
| 30 | +self.slidergz=lv.slider(screen) |
| 31 | +self.slidergz.align(lv.ALIGN.CENTER,0,90) |
| 32 | +try: |
| 33 | +frommachineimportPin,I2C |
| 34 | +fromqmi8658importQMI8658 |
| 35 | +importmachine |
| 36 | +self.sensor=QMI8658(I2C(0,sda=machine.Pin(48),scl=machine.Pin(47))) |
| 37 | +exceptExceptionase: |
| 38 | +warning=f"Warning: could not initialize IMU hardware:\n{e}" |
| 39 | +print(warning) |
| 40 | +self.templabel.set_text(warning) |
| 41 | +self.setContentView(screen) |
| 42 | + |
| 43 | +defonStart(self,screen): |
| 44 | +self.refresh_timer=lv.timer_create(self.refresh,100,None) |
| 45 | + |
| 46 | +defonStop(self,screen): |
| 47 | +ifself.refresh_timer: |
| 48 | +self.refresh_timer.delete() |
| 49 | + |
| 50 | + |
| 51 | +defmap_nonlinear(self,value:float)->int: |
| 52 | +# Preserve sign and work with absolute value |
| 53 | +sign=1ifvalue>=0else-1 |
| 54 | +abs_value=abs(value) |
| 55 | +# Apply non-linear transformation (square root) to absolute value |
| 56 | +# Scale input range [0, 200] to [0, sqrt(200)] first |
| 57 | +sqrt_value= (abs_value**0.5) |
| 58 | +# Scale to output range [0, 100] |
| 59 | +# Map [0, sqrt(200)] to [50, 100] for positive, [0, 50] for negative |
| 60 | +max_sqrt=200.0**0.5# Approx 14.142 |
| 61 | +scaled= (sqrt_value/max_sqrt)*50.0# Scale to [0, 50] |
| 62 | +returnint(50.0+ (sign*scaled))# Shift to [0, 100] |
| 63 | + |
| 64 | +defrefresh(self,timer): |
| 65 | +ifself.sensor: |
| 66 | +#print(f"""{sensor.temperature=} {sensor.acceleration=} {sensor.gyro=}""") |
| 67 | +temp=self.sensor.temperature |
| 68 | +ax=self.sensor.acceleration[0] |
| 69 | +axp=int((ax*100+100)/2) |
| 70 | +ay=self.sensor.acceleration[1] |
| 71 | +ayp=int((ay*100+100)/2) |
| 72 | +az=self.sensor.acceleration[2] |
| 73 | +azp=int((az*100+100)/2) |
| 74 | +# values between -200 and 200 => /4 becomes -50 and 50 => +50 becomes 0 and 100 |
| 75 | +gx=self.map_nonlinear(self.sensor.gyro[0]) |
| 76 | +gy=self.map_nonlinear(self.sensor.gyro[1]) |
| 77 | +gz=self.map_nonlinear(self.sensor.gyro[2]) |
| 78 | +self.templabel.set_text(f"IMU chip temperature:{temp:.2f}°C") |
| 79 | +else: |
| 80 | +#temp = 12.34 |
| 81 | +importrandom |
| 82 | +randomnr=random.randint(0,100) |
| 83 | +axp=randomnr |
| 84 | +ayp=50 |
| 85 | +azp=75 |
| 86 | +gx=45 |
| 87 | +gy=50 |
| 88 | +gz=55 |
| 89 | +self.sliderx.set_value(axp,lv.ANIM.OFF) |
| 90 | +self.slidery.set_value(ayp,lv.ANIM.OFF) |
| 91 | +self.sliderz.set_value(azp,lv.ANIM.OFF) |
| 92 | +self.slidergx.set_value(gx,lv.ANIM.OFF) |
| 93 | +self.slidergy.set_value(gy,lv.ANIM.OFF) |
| 94 | +self.slidergz.set_value(gz,lv.ANIM.OFF) |
| 95 | + |