gobot.io/x/gobot@v1.16.0/drivers/i2c/mpu6050_driver.go (about) 1 package i2c 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "time" 7 8 "gobot.io/x/gobot" 9 ) 10 11 const mpu6050Address = 0x68 12 13 const MPU6050_RA_ACCEL_XOUT_H = 0x3B 14 const MPU6050_RA_PWR_MGMT_1 = 0x6B 15 const MPU6050_PWR1_CLKSEL_BIT = 2 16 const MPU6050_PWR1_CLKSEL_LENGTH = 3 17 const MPU6050_CLOCK_PLL_XGYRO = 0x01 18 const MPU6050_GYRO_FS_250 = 0x00 19 const MPU6050_RA_GYRO_CONFIG = 0x1B 20 const MPU6050_GCONFIG_FS_SEL_LENGTH = 2 21 const MPU6050_GCONFIG_FS_SEL_BIT = 4 22 const MPU6050_RA_ACCEL_CONFIG = 0x1C 23 const MPU6050_ACONFIG_AFS_SEL_BIT = 4 24 const MPU6050_ACONFIG_AFS_SEL_LENGTH = 2 25 const MPU6050_ACCEL_FS_2 = 0x00 26 const MPU6050_PWR1_SLEEP_BIT = 6 27 const MPU6050_PWR1_ENABLE_BIT = 0 28 29 type ThreeDData struct { 30 X int16 31 Y int16 32 Z int16 33 } 34 35 // MPU6050Driver is a new Gobot Driver for an MPU6050 I2C Accelerometer/Gyroscope. 36 type MPU6050Driver struct { 37 name string 38 connector Connector 39 connection Connection 40 Config 41 interval time.Duration 42 Accelerometer ThreeDData 43 Gyroscope ThreeDData 44 Temperature int16 45 gobot.Eventer 46 } 47 48 // NewMPU6050Driver creates a new Gobot Driver for an MPU6050 I2C Accelerometer/Gyroscope. 49 // 50 // Params: 51 // conn Connector - the Adaptor to use with this Driver 52 // 53 // Optional params: 54 // i2c.WithBus(int): bus to use with this driver 55 // i2c.WithAddress(int): address to use with this driver 56 // 57 func NewMPU6050Driver(a Connector, options ...func(Config)) *MPU6050Driver { 58 m := &MPU6050Driver{ 59 name: gobot.DefaultName("MPU6050"), 60 connector: a, 61 Config: NewConfig(), 62 Eventer: gobot.NewEventer(), 63 } 64 65 for _, option := range options { 66 option(m) 67 } 68 69 // TODO: add commands to API 70 return m 71 } 72 73 // Name returns the name of the device. 74 func (h *MPU6050Driver) Name() string { return h.name } 75 76 // SetName sets the name of the device. 77 func (h *MPU6050Driver) SetName(n string) { h.name = n } 78 79 // Connection returns the connection for the device. 80 func (h *MPU6050Driver) Connection() gobot.Connection { return h.connector.(gobot.Connection) } 81 82 // Start writes initialization bytes to sensor 83 func (h *MPU6050Driver) Start() (err error) { 84 if err := h.initialize(); err != nil { 85 return err 86 } 87 88 return 89 } 90 91 // Halt returns true if devices is halted successfully 92 func (h *MPU6050Driver) Halt() (err error) { return } 93 94 // GetData fetches the latest data from the MPU6050 95 func (h *MPU6050Driver) GetData() (err error) { 96 if _, err = h.connection.Write([]byte{MPU6050_RA_ACCEL_XOUT_H}); err != nil { 97 return 98 } 99 100 data := make([]byte, 14) 101 _, err = h.connection.Read(data) 102 if err != nil { 103 return 104 } 105 106 buf := bytes.NewBuffer(data) 107 binary.Read(buf, binary.BigEndian, &h.Accelerometer) 108 binary.Read(buf, binary.BigEndian, &h.Temperature) 109 binary.Read(buf, binary.BigEndian, &h.Gyroscope) 110 h.convertToCelsius() 111 return 112 } 113 114 func (h *MPU6050Driver) initialize() (err error) { 115 bus := h.GetBusOrDefault(h.connector.GetDefaultBus()) 116 address := h.GetAddressOrDefault(mpu6050Address) 117 118 h.connection, err = h.connector.GetConnection(address, bus) 119 if err != nil { 120 return err 121 } 122 123 // setClockSource 124 if _, err = h.connection.Write([]byte{MPU6050_RA_PWR_MGMT_1, 125 MPU6050_PWR1_CLKSEL_BIT, 126 MPU6050_PWR1_CLKSEL_LENGTH, 127 MPU6050_CLOCK_PLL_XGYRO}); err != nil { 128 return 129 } 130 131 // setFullScaleGyroRange 132 if _, err = h.connection.Write([]byte{MPU6050_RA_GYRO_CONFIG, 133 MPU6050_GCONFIG_FS_SEL_BIT, 134 MPU6050_GCONFIG_FS_SEL_LENGTH, 135 MPU6050_GYRO_FS_250}); err != nil { 136 return 137 } 138 139 // setFullScaleAccelRange 140 if _, err = h.connection.Write([]byte{MPU6050_RA_ACCEL_CONFIG, 141 MPU6050_ACONFIG_AFS_SEL_BIT, 142 MPU6050_ACONFIG_AFS_SEL_LENGTH, 143 MPU6050_ACCEL_FS_2}); err != nil { 144 return 145 } 146 147 // setSleepEnabled 148 if _, err = h.connection.Write([]byte{MPU6050_RA_PWR_MGMT_1, 149 MPU6050_PWR1_ENABLE_BIT, 150 0}); err != nil { 151 return 152 } 153 154 return nil 155 } 156 157 // The temperature sensor is -40 to +85 degrees Celsius. 158 // It is a signed integer. 159 // According to the datasheet: 160 // 340 per degrees Celsius, -512 at 35 degrees. 161 // At 0 degrees: -512 - (340 * 35) = -12412 162 func (h *MPU6050Driver) convertToCelsius() { 163 h.Temperature = (h.Temperature + 12412) / 340 164 }