Sunday, April 10, 2022

Raspberry Pi Pico/CircuitPython act as IMU USB Mouse, read LSM303 Accelerometer and report as mouse movement.

Base on cpyPico_lsm303_accel_inclinometer.py exercise in last post "Raspberry Pi Pico/CircuitPython, access LSM303(Accelerometer/Magnetometer) and L3GD20(Gyroscope)", added with adafruit_hid.mouse library, it is modified to act as IMU USB Mouse. User hold the 10DOF module, change orientation to move mouse pointer.


cpyPico_lsm303_accel_inclinometer_mouse.py
"""
Raspberry Pi Pico + LSM303
Act as usb_hid,
read Accelerometer and report mouse movement.

ref:
https://docs.circuitpython.org/projects/hid/en/latest/_modules/adafruit_hid/mouse.html
"""
import time
from math import atan2, degrees
import board
import adafruit_lsm303_accel
import busio
import usb_hid
from adafruit_hid.mouse import Mouse

mouse = Mouse(usb_hid.devices)

SDA=board.GP8
SCL=board.GP9
i2c = busio.I2C(SCL,SDA)  # uses board.SCL and board.SDA
sensor = adafruit_lsm303_accel.LSM303_Accel(i2c)

def vector_2_degrees(x, y):
    angle = degrees(atan2(y, x))
    if angle < 0:
        angle += 360
    return angle

def get_inclination(_sensor):
    x, y, z = _sensor.acceleration
    return vector_2_degrees(x, z), vector_2_degrees(y, z)

while True:
    angle_xz, angle_yz = get_inclination(sensor)
    #print("XZ angle = {:6.2f}deg   YZ angle = {:6.2f}deg".format(angle_xz, angle_yz))
    print(angle_xz, angle_yz)
    
    #LEFT/RIGHT
    if angle_xz > 120:
        mouse.move(x=+3)
    elif angle_xz > 105:
        mouse.move(x=+1)
    elif angle_xz < 60:
        mouse.move(x=-3)
    elif angle_xz < 75:
        mouse.move(x=-1)
        
    #UP/DOWN
    if angle_yz > 120:
        mouse.move(y=-3)
    elif angle_yz > 105:
        mouse.move(y=-1)
    elif angle_yz < 60:
        mouse.move(y=+3)
    elif angle_yz < 75:
        mouse.move(y=+1)

    time.sleep(0.02)

related:
XIAO BLE Sense (Arduino framework) IMU USB Mouse

No comments: