// Connects to an LSM6DSOX I2C a 6 axis Inertial Measurement Unit (IMU) package main import ( "fmt" "machine" "time" "tinygo.org/x/drivers/lsm6dsox" ) const ( PLOTTER = true SHOW_ACCELERATION = false SHOW_ROTATION = true SHOW_TEMPERATURE = false // calibration is naive, good enough for a demo: do not shake a second after flashing GYRO_CALIBRATION = true ) var cal = [...]float32{0, 0, 0} func main() { machine.I2C0.Configure(machine.I2CConfig{}) device := lsm6dsox.New(machine.I2C0) err := device.Configure(lsm6dsox.Configuration{ AccelRange: lsm6dsox.ACCEL_2G, AccelSampleRate: lsm6dsox.ACCEL_SR_104, GyroRange: lsm6dsox.GYRO_250DPS, GyroSampleRate: lsm6dsox.GYRO_SR_104, }) if err != nil { for { println("Failed to configure", err.Error()) time.Sleep(time.Second) } } for { if !device.Connected() { println("LSM6DSOX not connected") time.Sleep(time.Second) continue } // heuristic: after successful calibration the value can't be 0 if GYRO_CALIBRATION && cal[0] == 0 { calibrateGyro(device) } ax, ay, az, _ := device.ReadAcceleration() gx, gy, gz, _ := device.ReadRotation() t, _ := device.ReadTemperature() if PLOTTER { printPlotter(ax, ay, az, gx, gy, gz, t) time.Sleep(time.Millisecond * 100) } else { printMonitor(ax, ay, az, gx, gy, gz, t) time.Sleep(time.Millisecond * 1000) } } } func calibrateGyro(device *lsm6dsox.Device) { for i := 0; i < 100; i++ { gx, gy, gz, _ := device.ReadRotation() cal[0] += float32(gx) / 1000000 cal[1] += float32(gy) / 1000000 cal[2] += float32(gz) / 1000000 time.Sleep(time.Millisecond * 10) } cal[0] /= 100 cal[1] /= 100 cal[2] /= 100 } // Arduino IDE's Serial Plotter func printPlotter(ax, ay, az, gx, gy, gz, t int32) { if SHOW_ACCELERATION { fmt.Printf("AX:%f, AY:%f, AZ:%f,", axis(ax, 0), axis(ay, 0), axis(az, 0)) } if SHOW_ROTATION { fmt.Printf("GX:%f, GY:%f, GZ:%f,", axis(gx, cal[0]), axis(gy, cal[1]), axis(gz, cal[2])) } if SHOW_TEMPERATURE { fmt.Printf("T:%f", float32(t)/1000) } println() } // Any Serial Monitor func printMonitor(ax, ay, az, gx, gy, gz, t int32) { if SHOW_ACCELERATION { fmt.Printf("Acceleration: %f, %f, %f\r\n", axis(ax, 0), axis(ay, 0), axis(az, 0)) } if SHOW_ROTATION { fmt.Printf("Rotation: %f, %f, %f\r\n", axis(gx, cal[0]), axis(gy, cal[1]), axis(gz, cal[2])) } if SHOW_TEMPERATURE { fmt.Printf("Temperature C: %f\r\n", float32(t)/1000) } println() } func axis(raw int32, cal float32) float32 { return float32(raw)/1000000 - cal }