i2c: ensure all current i2c drivers (except for wiichuck) use a standard i2c style request/response interaction pattern

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram 2017-02-11 10:37:34 +01:00
parent 804344873c
commit ae59464442
7 changed files with 89 additions and 74 deletions

View File

@ -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

View File

@ -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))
}

View File

@ -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)

View File

@ -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))
}

View File

@ -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)

View File

@ -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)
})

View File

@ -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)