forked from hybridgroup/gobot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added basic driver for BH1750 (light sensor), board GY-302
- Loading branch information
1 parent
6fb9c39
commit c2e6910
Showing
2 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package i2c | ||
|
||
import ( | ||
"time" | ||
"errors" | ||
|
||
"gobot.io/x/gobot" | ||
) | ||
|
||
const bh1750Address = 0x23 | ||
|
||
const ( | ||
BH1750_POWER_DOWN = 0x00 | ||
BH1750_POWER_ON = 0x01 | ||
BH1750_RESET = 0x07 | ||
BH1750_CONTINUOUS_HIGH_RES_MODE = 0x10 | ||
BH1750_CONTINUOUS_HIGH_RES_MODE_2 = 0x11 | ||
BH1750_CONTINUOUS_LOW_RES_MODE = 0x13 | ||
BH1750_ONE_TIME_HIGH_RES_MODE = 0x20 | ||
BH1750_ONE_TIME_HIGH_RES_MODE_2 = 0x21 | ||
BH1750_ONE_TIME_LOW_RES_MODE = 0x23 | ||
) | ||
|
||
type BH1750Driver struct { | ||
name string | ||
connector Connector | ||
connection Connection | ||
mode byte | ||
Config | ||
} | ||
|
||
// NewBH1750Driver creates a new driver with specified i2c interface | ||
// Params: | ||
// conn 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, | ||
} | ||
|
||
for _, option := range options { | ||
option(m) | ||
} | ||
|
||
// 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.GetDefaultBus()) | ||
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 | ||
} | ||
|
||
// Halt returns true if devices is halted successfully | ||
func (h *BH1750Driver) Halt() (err error) { return } | ||
|
||
func (h *BH1750Driver) RawSensorData() (level int, err error) { | ||
|
||
buf := []byte{0, 0} | ||
bytesRead, err := h.connection.Read(buf) | ||
if bytesRead != 2 { | ||
err = errors.New("wrong number of bytes read") | ||
return | ||
} | ||
if err != nil { | ||
return | ||
} | ||
level = int(buf[0])<<8 | int(buf[1]) | ||
|
||
return | ||
} | ||
|
||
func (h *BH1750Driver) Lux() (lux int, err error) { | ||
|
||
lux, err = h.RawSensorData() | ||
lux = int(float64(lux) / 1.2) | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package i2c | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
"testing" | ||
|
||
"bytes" | ||
|
||
"gobot.io/x/gobot" | ||
"gobot.io/x/gobot/gobottest" | ||
) | ||
|
||
var _ gobot.Driver = (*BH1750Driver)(nil) | ||
|
||
// --------- HELPERS | ||
func initTestBH1750Driver() (driver *BH1750Driver) { | ||
driver, _ = initTestBH1750DriverWithStubbedAdaptor() | ||
return | ||
} | ||
|
||
func initTestBH1750DriverWithStubbedAdaptor() (*BH1750Driver, *i2cTestAdaptor) { | ||
adaptor := newI2cTestAdaptor() | ||
return NewBH1750Driver(adaptor), adaptor | ||
} | ||
|
||
// --------- TESTS | ||
|
||
func TestNewBH1750Driver(t *testing.T) { | ||
// Does it return a pointer to an instance of BH1750Driver? | ||
var mma interface{} = NewBH1750Driver(newI2cTestAdaptor()) | ||
_, ok := mma.(*BH1750Driver) | ||
if !ok { | ||
t.Errorf("NewBH1750Driver() should have returned a *BH1750Driver") | ||
} | ||
} | ||
|
||
// 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) { | ||
d := NewBH1750Driver(newI2cTestAdaptor(), WithBus(2)) | ||
gobottest.Assert(t, d.GetBusOrDefault(1), 2) | ||
} | ||
|
||
func TestBH1750DriverStart(t *testing.T) { | ||
d := initTestBH1750Driver() | ||
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() | ||
gobottest.Assert(t, d.Halt(), nil) | ||
} | ||
|
||
func TestBH1750DriverNullLux(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) { | ||
buf := new(bytes.Buffer) | ||
buf.Write([]byte{0x05, 0xb0}) | ||
copy(b, buf.Bytes()) | ||
return buf.Len(), nil | ||
} | ||
|
||
lux, _ := d.Lux() | ||
gobottest.Assert(t, lux, 1213) | ||
} | ||
|
||
func TestBH1750DriverNullRawSensorData(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) { | ||
buf := new(bytes.Buffer) | ||
buf.Write([]byte{0x05, 0xb0}) | ||
copy(b, buf.Bytes()) | ||
return buf.Len(), nil | ||
} | ||
|
||
level, _ := d.RawSensorData() | ||
gobottest.Assert(t, level, 1456) | ||
} | ||
|
||
func TestBH1750DriverLuxError(t *testing.T) { | ||
d, adaptor := initTestBH1750DriverWithStubbedAdaptor() | ||
d.Start() | ||
|
||
adaptor.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) { | ||
return 0, errors.New("wrong number of bytes read") | ||
} | ||
|
||
_, err := d.RawSensorData() | ||
gobottest.Assert(t, err, errors.New("wrong number of bytes read")) | ||
} | ||
|