Skip to content

Commit

Permalink
Improve: use base driver for all I2C devices
Browse files Browse the repository at this point in the history
  • Loading branch information
gen2thomas authored Dec 10, 2022
1 parent 3559e78 commit cef0406
Show file tree
Hide file tree
Showing 64 changed files with 1,441 additions and 2,198 deletions.
6 changes: 3 additions & 3 deletions drivers/i2c/adafruit_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func (a *AdafruitMotorHatDriver) startDriver(connection Connection) (err error)

// Start initializes both I2C-addressable Adafruit Motor HAT drivers
func (a *AdafruitMotorHatDriver) Start() (err error) {
bus := a.GetBusOrDefault(a.connector.DefaultBus())
bus := a.GetBusOrDefault(a.connector.DefaultI2cBus())

err = a.startServoHat(bus)
if adafruitDebug && err != nil {
Expand All @@ -216,7 +216,7 @@ func (a *AdafruitMotorHatDriver) Start() (err error) {

// startServoHat starts the Servo motors connection.
func (a *AdafruitMotorHatDriver) startServoHat(bus int) (err error) {
if a.servoHatConnection, err = a.connector.GetConnection(servoHatAddress, bus); err != nil {
if a.servoHatConnection, err = a.connector.GetI2cConnection(servoHatAddress, bus); err != nil {
return
}

Expand All @@ -229,7 +229,7 @@ func (a *AdafruitMotorHatDriver) startServoHat(bus int) (err error) {

// startMotorHat starts the DC motors connection.
func (a *AdafruitMotorHatDriver) startMotorHat(bus int) (err error) {
if a.motorHatConnection, err = a.connector.GetConnection(motorHatAddress, bus); err != nil {
if a.motorHatConnection, err = a.connector.GetI2cConnection(motorHatAddress, bus); err != nil {
return
}

Expand Down
9 changes: 4 additions & 5 deletions drivers/i2c/adafruit_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"gobot.io/x/gobot/gobottest"
)

// this ensures that the implementation implements the gobot.Driver interface
var _ gobot.Driver = (*AdafruitMotorHatDriver)(nil)

// --------- HELPERS
Expand All @@ -24,14 +25,12 @@ func initTestAdafruitMotorHatDriverWithStubbedAdaptor() (*AdafruitMotorHatDriver

// --------- TESTS
func TestNewAdafruitMotorHatDriver(t *testing.T) {
var adafruit interface{} = NewAdafruitMotorHatDriver(newI2cTestAdaptor())
_, ok := adafruit.(*AdafruitMotorHatDriver)
var di interface{} = NewAdafruitMotorHatDriver(newI2cTestAdaptor())
d, ok := di.(*AdafruitMotorHatDriver)
if !ok {
t.Errorf("AdafruitMotorHatDriver() should have returned a *AdafruitMotorHatDriver")
}

a := NewAdafruitMotorHatDriver(newI2cTestAdaptor())
gobottest.Assert(t, strings.HasPrefix(a.Name(), "AdafruitMotorHat"), true)
gobottest.Assert(t, strings.HasPrefix(d.Name(), "AdafruitMotorHat"), true)
}

// Methods
Expand Down
1 change: 1 addition & 0 deletions drivers/i2c/adxl345_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestNewADXL345Driver(t *testing.T) {
}
gobottest.Refute(t, d.Driver, nil)
gobottest.Assert(t, strings.HasPrefix(d.Name(), "ADXL345"), true)
gobottest.Assert(t, d.defaultAddress, 0x53)
gobottest.Assert(t, d.powerCtl.measure, uint8(1))
gobottest.Assert(t, d.dataFormat.fullScaleRange, ADXL345FsRangeConfig(0x00))
gobottest.Assert(t, d.bwRate.rate, ADXL345RateConfig(0x0A))
Expand Down
68 changes: 20 additions & 48 deletions drivers/i2c/bh1750_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package i2c
import (
"errors"
"time"

"gobot.io/x/gobot"
)

const bh1750Address = 0x23
const bh1750DefaultAddress = 0x23

const (
BH1750_POWER_DOWN = 0x00
Expand All @@ -24,68 +22,33 @@ const (
// BH1750Driver is a driver for the BH1750 digital Ambient Light Sensor IC for I²C bus interface.
//
type BH1750Driver struct {
name string
connector Connector
connection Connection
mode byte
Config
*Driver
mode byte
}

// NewBH1750Driver creates a new driver with specified i2c interface
// Params:
// conn Connector - the Adaptor to use with this Driver
// c Connector - the Adaptor to use with this Driver
//
// Optional params:
// i2c.WithBus(int): bus to use with this driver
// i2c.WithAddress(int): address to use with this driver
//
func NewBH1750Driver(a Connector, options ...func(Config)) *BH1750Driver {
m := &BH1750Driver{
name: gobot.DefaultName("BH1750"),
connector: a,
Config: NewConfig(),
mode: BH1750_CONTINUOUS_HIGH_RES_MODE,
func NewBH1750Driver(c Connector, options ...func(Config)) *BH1750Driver {
h := &BH1750Driver{
Driver: NewDriver(c, "BH1750", bh1750DefaultAddress),
mode: BH1750_CONTINUOUS_HIGH_RES_MODE,
}
h.afterStart = h.initialize

for _, option := range options {
option(m)
option(h)
}

// TODO: add commands for API
return m
}

// Name returns the Name for the Driver
func (h *BH1750Driver) Name() string { return h.name }

// SetName sets the Name for the Driver
func (h *BH1750Driver) SetName(n string) { h.name = n }

// Connection returns the connection for the Driver
func (h *BH1750Driver) Connection() gobot.Connection { return h.connector.(gobot.Connection) }

// Start initialized the bh1750
func (h *BH1750Driver) Start() (err error) {
bus := h.GetBusOrDefault(h.connector.DefaultBus())
address := h.GetAddressOrDefault(bh1750Address)

h.connection, err = h.connector.GetConnection(address, bus)
if err != nil {
return err
}

err = h.connection.WriteByte(h.mode)
time.Sleep(10 * time.Microsecond)
if err != nil {
return err
}

return
return h
}

// Halt returns true if devices is halted successfully
func (h *BH1750Driver) Halt() (err error) { return }

// RawSensorData returns the raw value from the bh1750
func (h *BH1750Driver) RawSensorData() (level int, err error) {

Expand All @@ -111,3 +74,12 @@ func (h *BH1750Driver) Lux() (lux int, err error) {

return
}

func (h *BH1750Driver) initialize() error {
err := h.connection.WriteByte(h.mode)
time.Sleep(10 * time.Microsecond)
if err != nil {
return err
}
return nil
}
105 changes: 34 additions & 71 deletions drivers/i2c/bh1750_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,85 +11,56 @@ import (
"gobot.io/x/gobot/gobottest"
)

// this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver
// and tests all implementations, so no further tests needed here for gobot.Driver interface
var _ gobot.Driver = (*BH1750Driver)(nil)

// --------- HELPERS
func initTestBH1750Driver() (driver *BH1750Driver) {
driver, _ = initTestBH1750DriverWithStubbedAdaptor()
return
}

func initTestBH1750DriverWithStubbedAdaptor() (*BH1750Driver, *i2cTestAdaptor) {
adaptor := newI2cTestAdaptor()
return NewBH1750Driver(adaptor), adaptor
a := newI2cTestAdaptor()
d := NewBH1750Driver(a)
if err := d.Start(); err != nil {
panic(err)
}
return d, a
}

// --------- TESTS

func TestNewBH1750Driver(t *testing.T) {
// Does it return a pointer to an instance of BH1750Driver?
var mma interface{} = NewBH1750Driver(newI2cTestAdaptor())
_, ok := mma.(*BH1750Driver)
var di interface{} = NewBH1750Driver(newI2cTestAdaptor())
d, ok := di.(*BH1750Driver)
if !ok {
t.Errorf("NewBH1750Driver() should have returned a *BH1750Driver")
}
gobottest.Refute(t, d.Driver, nil)
gobottest.Assert(t, strings.HasPrefix(d.Name(), "BH1750"), true)
gobottest.Assert(t, d.defaultAddress, 0x23)
}

// Methods
func TestBH1750Driver(t *testing.T) {
mma := initTestBH1750Driver()

gobottest.Refute(t, mma.Connection(), nil)
gobottest.Assert(t, strings.HasPrefix(mma.Name(), "BH1750"), true)
}

func TestBH1750DriverSetName(t *testing.T) {
d := initTestBH1750Driver()
d.SetName("TESTME")
gobottest.Assert(t, d.Name(), "TESTME")
}

func TestBH1750DriverOptions(t *testing.T) {
func TestBH1750Options(t *testing.T) {
// This is a general test, that options are applied in constructor by using the common WithBus() option and
// least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)".
d := NewBH1750Driver(newI2cTestAdaptor(), WithBus(2))
gobottest.Assert(t, d.GetBusOrDefault(1), 2)
}

func TestBH1750DriverStart(t *testing.T) {
d := initTestBH1750Driver()
func TestBH1750Start(t *testing.T) {
d := NewBH1750Driver(newI2cTestAdaptor())
gobottest.Assert(t, d.Start(), nil)
}

func TestBH1750StartConnectError(t *testing.T) {
d, adaptor := initTestBH1750DriverWithStubbedAdaptor()
adaptor.Testi2cConnectErr(true)
gobottest.Assert(t, d.Start(), errors.New("Invalid i2c connection"))
}

func TestBH1750DriverStartWriteError(t *testing.T) {
mma, adaptor := initTestBH1750DriverWithStubbedAdaptor()
adaptor.i2cWriteImpl = func([]byte) (int, error) {
return 0, errors.New("write error")
}
gobottest.Assert(t, mma.Start(), errors.New("write error"))
}

func TestBH1750DriverHalt(t *testing.T) {
d := initTestBH1750Driver()
func TestBH1750Halt(t *testing.T) {
d, _ := initTestBH1750DriverWithStubbedAdaptor()
gobottest.Assert(t, d.Halt(), nil)
}

func TestBH1750DriverNullLux(t *testing.T) {
func TestBH1750NullLux(t *testing.T) {
d, _ := initTestBH1750DriverWithStubbedAdaptor()
d.Start()
lux, _ := d.Lux()
gobottest.Assert(t, lux, 0)
}

func TestBH1750DriverLux(t *testing.T) {
d, adaptor := initTestBH1750DriverWithStubbedAdaptor()
d.Start()

adaptor.i2cReadImpl = func(b []byte) (int, error) {
func TestBH1750Lux(t *testing.T) {
d, a := initTestBH1750DriverWithStubbedAdaptor()
a.i2cReadImpl = func(b []byte) (int, error) {
buf := new(bytes.Buffer)
buf.Write([]byte{0x05, 0xb0})
copy(b, buf.Bytes())
Expand All @@ -100,18 +71,15 @@ func TestBH1750DriverLux(t *testing.T) {
gobottest.Assert(t, lux, 1213)
}

func TestBH1750DriverNullRawSensorData(t *testing.T) {
func TestBH1750NullRawSensorData(t *testing.T) {
d, _ := initTestBH1750DriverWithStubbedAdaptor()
d.Start()
level, _ := d.RawSensorData()
gobottest.Assert(t, level, 0)
}

func TestBH1750DriverRawSensorData(t *testing.T) {
d, adaptor := initTestBH1750DriverWithStubbedAdaptor()
d.Start()

adaptor.i2cReadImpl = func(b []byte) (int, error) {
func TestBH1750RawSensorData(t *testing.T) {
d, a := initTestBH1750DriverWithStubbedAdaptor()
a.i2cReadImpl = func(b []byte) (int, error) {
buf := new(bytes.Buffer)
buf.Write([]byte{0x05, 0xb0})
copy(b, buf.Bytes())
Expand All @@ -122,27 +90,22 @@ func TestBH1750DriverRawSensorData(t *testing.T) {
gobottest.Assert(t, level, 1456)
}

func TestBH1750DriverLuxError(t *testing.T) {
d, adaptor := initTestBH1750DriverWithStubbedAdaptor()
d.Start()

adaptor.i2cReadImpl = func(b []byte) (int, error) {
func TestBH1750LuxError(t *testing.T) {
d, a := initTestBH1750DriverWithStubbedAdaptor()
a.i2cReadImpl = func(b []byte) (int, error) {
return 0, errors.New("wrong number of bytes read")
}

_, err := d.Lux()
gobottest.Assert(t, err, errors.New("wrong number of bytes read"))
}

func TestBH1750DriverRawSensorDataError(t *testing.T) {
d, adaptor := initTestBH1750DriverWithStubbedAdaptor()
d.Start()

adaptor.i2cReadImpl = func(b []byte) (int, error) {
func TestBH1750RawSensorDataError(t *testing.T) {
d, a := initTestBH1750DriverWithStubbedAdaptor()
a.i2cReadImpl = func(b []byte) (int, error) {
return 0, errors.New("wrong number of bytes read")
}

_, err := d.RawSensorData()
gobottest.Assert(t, err, errors.New("wrong number of bytes read"))
}

Loading

0 comments on commit cef0406

Please sign in to comment.