From 53fbc39809c5affe73468c02d143724a9229d28a Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 16 Nov 2018 14:55:29 +0100 Subject: [PATCH] mpu6050: add driver Only the accelerometer is supported at the moment. --- mpu6050/mpu6050.go | 48 +++++++++++++++++++ mpu6050/registers.go | 109 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 mpu6050/mpu6050.go create mode 100644 mpu6050/registers.go diff --git a/mpu6050/mpu6050.go b/mpu6050/mpu6050.go new file mode 100644 index 0000000..76dbb5b --- /dev/null +++ b/mpu6050/mpu6050.go @@ -0,0 +1,48 @@ +// Package mpu6050 provides a driver for the MPU6050 accelerometer and gyroscope +// made by InvenSense. +// +// Datasheets: +// https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf +// https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf +package mpu6050 + +import ( + "machine" +) + +// Device wraps an I2C connection to a MPU6050 device. +type Device struct { + bus machine.I2C +} + +// NewI2C creates a new MPU6050 connection. The I2C bus must already be +// configured. +// +// This function only creates the Device object, it does not touch the device. +func NewI2C(bus machine.I2C) Device { + return Device{bus} +} + +// Connected returns whether a MPU6050 has been found. +// It does a "who am I" request and checks the response. +func (d Device) Connected() bool { + data := []byte{0} + d.bus.ReadRegister(Address, WHO_AM_I, data) + return data[0] == 0x68 +} + +// Configure sets up the device for communication. +func (d Device) Configure() { + d.bus.WriteRegister(Address, PWR_MGMT_1, []uint8{0}) +} + +// ReadAcceleration reads the current acceleration from the device and returns +// it. +func (d Device) ReadAcceleration() (x int16, y int16, z int16) { + data := make([]byte, 6) + d.bus.ReadRegister(Address, ACCEL_XOUT_H, data) + x = int16((uint16(data[0]) << 8) | uint16(data[1])) + y = int16((uint16(data[2]) << 8) | uint16(data[3])) + z = int16((uint16(data[4]) << 8) | uint16(data[5])) + return +} diff --git a/mpu6050/registers.go b/mpu6050/registers.go new file mode 100644 index 0000000..dd487af --- /dev/null +++ b/mpu6050/registers.go @@ -0,0 +1,109 @@ +package mpu6050 + +// Constants/addresses used for I2C. + +// The I2C address which this device listens to. +const Address = 0x68 + +// Registers. Names, addresses and comments copied from the datasheet. +const ( + // Self test registers + SELF_TEST_X = 0x0D + SELF_TEST_Y = 0x0E + SELF_TEST_Z = 0x0F + SELF_TEST_A = 0x10 + + SMPLRT_DIV = 0x19 // Sample rate divider + CONFIG = 0x1A // Configuration + GYRO_CONFIG = 0x1B // Gyroscope configuration + ACCEL_CONFIG = 0x1C // Accelerometer configuration + FIFO_EN = 0x23 // FIFO enable + + // I2C pass-through configuration + I2C_MST_CTRL = 0x24 + I2C_SLV0_ADDR = 0x25 + I2C_SLV0_REG = 0x26 + I2C_SLV0_CTRL = 0x27 + I2C_SLV1_ADDR = 0x28 + I2C_SLV1_REG = 0x29 + I2C_SLV1_CTRL = 0x2A + I2C_SLV2_ADDR = 0x2B + I2C_SLV2_REG = 0x2C + I2C_SLV2_CTRL = 0x2D + I2C_SLV3_ADDR = 0x2E + I2C_SLV3_REG = 0x2F + I2C_SLV3_CTRL = 0x30 + I2C_SLV4_ADDR = 0x31 + I2C_SLV4_REG = 0x32 + I2C_SLV4_DO = 0x33 + I2C_SLV4_CTRL = 0x34 + I2C_SLV4_DI = 0x35 + I2C_MST_STATUS = 0x36 + + // Interrupt configuration + INT_PIN_CFG = 0x37 // Interrupt pin/bypass enable configuration + INT_ENABLE = 0x38 // Interrupt enable + INT_STATUS = 0x3A // Interrupt status + + // Accelerometer measurements + ACCEL_XOUT_H = 0x3B + ACCEL_XOUT_L = 0x3C + ACCEL_YOUT_H = 0x3D + ACCEL_YOUT_L = 0x3E + ACCEL_ZOUT_H = 0x3F + ACCEL_ZOUT_L = 0x40 + + // Temperature measurement + TEMP_OUT_H = 0x41 + TEMP_OUT_L = 0x42 + + // Gyroscope measurements + GYRO_XOUT_H = 0x43 + GYRO_XOUT_L = 0x44 + GYRO_YOUT_H = 0x45 + GYRO_YOUT_L = 0x46 + GYRO_ZOUT_H = 0x47 + GYRO_ZOUT_L = 0x48 + + // External sensor data + EXT_SENS_DATA_00 = 0x49 + EXT_SENS_DATA_01 = 0x4A + EXT_SENS_DATA_02 = 0x4B + EXT_SENS_DATA_03 = 0x4C + EXT_SENS_DATA_04 = 0x4D + EXT_SENS_DATA_05 = 0x4E + EXT_SENS_DATA_06 = 0x4F + EXT_SENS_DATA_07 = 0x50 + EXT_SENS_DATA_08 = 0x51 + EXT_SENS_DATA_09 = 0x52 + EXT_SENS_DATA_10 = 0x53 + EXT_SENS_DATA_11 = 0x54 + EXT_SENS_DATA_12 = 0x55 + EXT_SENS_DATA_13 = 0x56 + EXT_SENS_DATA_14 = 0x57 + EXT_SENS_DATA_15 = 0x58 + EXT_SENS_DATA_16 = 0x59 + EXT_SENS_DATA_17 = 0x5A + EXT_SENS_DATA_18 = 0x5B + EXT_SENS_DATA_19 = 0x5C + EXT_SENS_DATA_20 = 0x5D + EXT_SENS_DATA_21 = 0x5E + EXT_SENS_DATA_22 = 0x5F + EXT_SENS_DATA_23 = 0x60 + + // I2C slave data out + I2C_SLV0_DO = 0x63 + I2C_SLV1_DO = 0x64 + I2C_SLV2_DO = 0x65 + I2C_SLV3_DO = 0x66 + I2C_MST_DELAY_CT = 0x67 + + SIGNAL_PATH_RES = 0x68 // Signal path reset + USER_CTRL = 0x6A // User control + PWR_MGMT_1 = 0x6B // Power Management 1 + PWR_MGMT_2 = 0x6C // Power Management 2 + FIFO_COUNTH = 0x72 // FIFO count registers (high bits) + FIFO_COUNTL = 0x73 // FIFO count registers (low bits) + FIFO_R_W = 0x74 // FIFO read/write + WHO_AM_I = 0x75 // Who am I +)