From ae59464442072dddf02aa177c5f56e088aa9ea7d Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 11 Feb 2017 10:37:34 +0100 Subject: [PATCH] i2c: ensure all current i2c drivers (except for wiichuck) use a standard i2c style request/response interaction pattern Signed-off-by: deadprogram --- drivers/i2c/mpl115a2_driver.go | 82 ++++++++++++++--------------- drivers/i2c/mpl115a2_driver_test.go | 11 ++-- drivers/i2c/mpu6050_driver.go | 50 ++++++++---------- drivers/i2c/mpu6050_driver_test.go | 14 ++++- examples/chip_mpu6050.go | 2 + examples/firmata_mpl115a2.go | 2 + examples/firmata_mpu6050.go | 2 + 7 files changed, 89 insertions(+), 74 deletions(-) diff --git a/drivers/i2c/mpl115a2_driver.go b/drivers/i2c/mpl115a2_driver.go index 58fb886b..9c9a16b5 100644 --- a/drivers/i2c/mpl115a2_driver.go +++ b/drivers/i2c/mpl115a2_driver.go @@ -29,7 +29,6 @@ type MPL115A2Driver struct { connector Connector connection Connection Config - interval time.Duration gobot.Eventer A0 float32 B1 float32 @@ -39,7 +38,9 @@ type MPL115A2Driver struct { Temperature float32 } -// NewMPL115A2Driver creates a new driver with specified i2c interface +// NewMPL115A2Driver creates a new Gobot Driver for an MPL115A2 +// I2C Pressure/Temperature sensor. +// // Params: // conn Connector - the Adaptor to use with this Driver // @@ -53,7 +54,6 @@ func NewMPL115A2Driver(a Connector, options ...func(Config)) *MPL115A2Driver { connector: a, Config: NewConfig(), Eventer: gobot.NewEventer(), - interval: 10 * time.Millisecond, } for _, option := range options { @@ -78,55 +78,53 @@ func (h *MPL115A2Driver) Connection() gobot.Connection { return h.connector.(gob // Start writes initialization bytes and reads from adaptor // using specified interval to accelerometer andtemperature data func (h *MPL115A2Driver) Start() (err error) { - var temperature uint16 - var pressure uint16 - var pressureComp float32 - if err := h.initialization(); err != nil { return err } - go func() { - for { - if _, err := h.connection.Write([]byte{MPL115A2_REGISTER_STARTCONVERSION, 0}); err != nil { - h.Publish(h.Event(Error), err) - continue - - } - time.Sleep(5 * time.Millisecond) - - if _, err := h.connection.Write([]byte{MPL115A2_REGISTER_PRESSURE_MSB}); err != nil { - h.Publish(h.Event(Error), err) - continue - } - - data := []byte{0, 0, 0, 0} - bytesRead, err := h.connection.Read(data) - if err != nil { - h.Publish(h.Event(Error), err) - continue - } - if bytesRead == 4 { - buf := bytes.NewBuffer(data) - binary.Read(buf, binary.BigEndian, &pressure) - binary.Read(buf, binary.BigEndian, &temperature) - - temperature = temperature >> 6 - pressure = pressure >> 6 - - pressureComp = float32(h.A0) + (float32(h.B1)+float32(h.C12)*float32(temperature))*float32(pressure) + float32(h.B2)*float32(temperature) - h.Pressure = (65.0/1023.0)*pressureComp + 50.0 - h.Temperature = ((float32(temperature) - 498.0) / -5.35) + 25.0 - } - time.Sleep(h.interval) - } - }() return } // Halt returns true if devices is halted successfully func (h *MPL115A2Driver) Halt() (err error) { return } +// GetData fetches the latest data from the MPL115A2 +func (h *MPL115A2Driver) GetData() error { + var temperature uint16 + var pressure uint16 + var pressureComp float32 + + if _, err := h.connection.Write([]byte{MPL115A2_REGISTER_STARTCONVERSION, 0}); err != nil { + return err + } + time.Sleep(5 * time.Millisecond) + + if _, err := h.connection.Write([]byte{MPL115A2_REGISTER_PRESSURE_MSB}); err != nil { + return err + } + + data := []byte{0, 0, 0, 0} + bytesRead, err := h.connection.Read(data) + if err != nil { + return err + } + + if bytesRead == 4 { + buf := bytes.NewBuffer(data) + binary.Read(buf, binary.BigEndian, &pressure) + binary.Read(buf, binary.BigEndian, &temperature) + + temperature = temperature >> 6 + pressure = pressure >> 6 + + pressureComp = float32(h.A0) + (float32(h.B1)+float32(h.C12)*float32(temperature))*float32(pressure) + float32(h.B2)*float32(temperature) + h.Pressure = (65.0/1023.0)*pressureComp + 50.0 + h.Temperature = ((float32(temperature) - 498.0) / -5.35) + 25.0 + } + + return nil +} + func (h *MPL115A2Driver) initialization() (err error) { var coA0 int16 var coB1 int16 diff --git a/drivers/i2c/mpl115a2_driver_test.go b/drivers/i2c/mpl115a2_driver_test.go index 92a99d3c..a3e9b917 100644 --- a/drivers/i2c/mpl115a2_driver_test.go +++ b/drivers/i2c/mpl115a2_driver_test.go @@ -3,7 +3,6 @@ package i2c import ( "strings" "testing" - "time" "gobot.io/x/gobot" "gobot.io/x/gobot/gobottest" @@ -42,14 +41,20 @@ func TestMPL115A2Driver(t *testing.T) { } func TestMPL115A2DriverStart(t *testing.T) { + mpl, _ := initTestMPL115A2DriverWithStubbedAdaptor() + + gobottest.Assert(t, mpl.Start(), nil) +} + +func TestMPL115A2DriverReadData(t *testing.T) { mpl, adaptor := initTestMPL115A2DriverWithStubbedAdaptor() adaptor.i2cReadImpl = func(b []byte) (int, error) { copy(b, []byte{0x00, 0x01, 0x02, 0x04}) return 4, nil } - gobottest.Assert(t, mpl.Start(), nil) - time.Sleep(100 * time.Millisecond) + mpl.Start() + mpl.GetData() gobottest.Assert(t, mpl.Pressure, float32(50.007942)) gobottest.Assert(t, mpl.Temperature, float32(116.58878)) } diff --git a/drivers/i2c/mpu6050_driver.go b/drivers/i2c/mpu6050_driver.go index 3fb4b4b0..a8799b4b 100644 --- a/drivers/i2c/mpu6050_driver.go +++ b/drivers/i2c/mpu6050_driver.go @@ -44,7 +44,8 @@ type MPU6050Driver struct { gobot.Eventer } -// NewMPU6050Driver creates a new driver with specified i2c interface +// NewMPU6050Driver creates a new Gobot Driver for an MPU6050 I2C Accelerometer/Gyroscope. +// // Params: // conn Connector - the Adaptor to use with this Driver // @@ -57,7 +58,6 @@ func NewMPU6050Driver(a Connector, options ...func(Config)) *MPU6050Driver { name: gobot.DefaultName("MPU6050"), connector: a, Config: NewConfig(), - interval: 10 * time.Millisecond, Eventer: gobot.NewEventer(), } @@ -66,8 +66,6 @@ func NewMPU6050Driver(a Connector, options ...func(Config)) *MPU6050Driver { } // TODO: add commands to API - - m.AddEvent(Error) return m } @@ -80,40 +78,38 @@ func (h *MPU6050Driver) SetName(n string) { h.name = n } // Connection returns the connection for the device. func (h *MPU6050Driver) Connection() gobot.Connection { return h.connector.(gobot.Connection) } -// Start writes initialization bytes and reads from adaptor -// using specified interval to accelerometer andtemperature data +// Start writes initialization bytes to sensor func (h *MPU6050Driver) Start() (err error) { if err := h.initialize(); err != nil { return err } - go func() { - for { - if _, err := h.connection.Write([]byte{MPU6050_RA_ACCEL_XOUT_H}); err != nil { - h.Publish(h.Event(Error), err) - continue - } - - data := make([]byte, 14) - _, err := h.connection.Read(data) - if err != nil { - h.Publish(h.Event(Error), err) - continue - } - buf := bytes.NewBuffer(data) - binary.Read(buf, binary.BigEndian, &h.Accelerometer) - binary.Read(buf, binary.BigEndian, &h.Temperature) - binary.Read(buf, binary.BigEndian, &h.Gyroscope) - h.convertToCelsius() - time.Sleep(h.interval) - } - }() return } // Halt returns true if devices is halted successfully func (h *MPU6050Driver) Halt() (err error) { return } +// GetData fetches the latest data from the MPU6050 +func (h *MPU6050Driver) GetData() (err error) { + if _, err = h.connection.Write([]byte{MPU6050_RA_ACCEL_XOUT_H}); err != nil { + return + } + + data := make([]byte, 14) + _, err = h.connection.Read(data) + if err != nil { + return + } + + buf := bytes.NewBuffer(data) + binary.Read(buf, binary.BigEndian, &h.Accelerometer) + binary.Read(buf, binary.BigEndian, &h.Temperature) + binary.Read(buf, binary.BigEndian, &h.Gyroscope) + h.convertToCelsius() + return +} + func (h *MPU6050Driver) initialize() (err error) { bus := h.GetBusOrDefault(h.connector.GetDefaultBus()) address := h.GetAddressOrDefault(mpu6050Address) diff --git a/drivers/i2c/mpu6050_driver_test.go b/drivers/i2c/mpu6050_driver_test.go index b740152e..39bb7f78 100644 --- a/drivers/i2c/mpu6050_driver_test.go +++ b/drivers/i2c/mpu6050_driver_test.go @@ -3,7 +3,6 @@ package i2c import ( "strings" "testing" - "time" "gobot.io/x/gobot" "gobot.io/x/gobot/gobottest" @@ -36,7 +35,6 @@ func TestNewMPU6050Driver(t *testing.T) { func TestMPU6050Driver(t *testing.T) { mpu := initTestMPU6050Driver() gobottest.Refute(t, mpu.Connection(), nil) - gobottest.Assert(t, mpu.interval, 10*time.Millisecond) mpu = NewMPU6050Driver(newI2cTestAdaptor(), WithBus(2)) gobottest.Assert(t, mpu.GetBusOrDefault(1), 2) @@ -57,3 +55,15 @@ func TestMPU6050DriverHalt(t *testing.T) { gobottest.Assert(t, mpu.Halt(), nil) } + +func TestMPU6050DriverReadData(t *testing.T) { + mpu, adaptor := initTestMPU6050DriverWithStubbedAdaptor() + + adaptor.i2cReadImpl = func(b []byte) (int, error) { + copy(b, []byte{0x00, 0x01, 0x02, 0x04}) + return 4, nil + } + mpu.Start() + mpu.GetData() + gobottest.Assert(t, mpu.Temperature, int16(36)) +} diff --git a/examples/chip_mpu6050.go b/examples/chip_mpu6050.go index f174c309..c07996ba 100644 --- a/examples/chip_mpu6050.go +++ b/examples/chip_mpu6050.go @@ -15,6 +15,8 @@ func main() { work := func() { gobot.Every(100*time.Millisecond, func() { + mpu6050.GetData() + fmt.Println("Accelerometer", mpu6050.Accelerometer) fmt.Println("Gyroscope", mpu6050.Gyroscope) fmt.Println("Temperature", mpu6050.Temperature) diff --git a/examples/firmata_mpl115a2.go b/examples/firmata_mpl115a2.go index a90f5e3c..42462c87 100644 --- a/examples/firmata_mpl115a2.go +++ b/examples/firmata_mpl115a2.go @@ -15,6 +15,8 @@ func main() { work := func() { gobot.Every(1*time.Second, func() { + mpl115a2.GetData() + fmt.Println("Pressure", mpl115a2.Pressure) fmt.Println("Temperature", mpl115a2.Temperature) }) diff --git a/examples/firmata_mpu6050.go b/examples/firmata_mpu6050.go index 72b7b193..014ea4d4 100644 --- a/examples/firmata_mpu6050.go +++ b/examples/firmata_mpu6050.go @@ -15,6 +15,8 @@ func main() { work := func() { gobot.Every(100*time.Millisecond, func() { + mpu6050.GetData() + fmt.Println("Accelerometer", mpu6050.Accelerometer) fmt.Println("Gyroscope", mpu6050.Gyroscope) fmt.Println("Temperature", mpu6050.Temperature)