mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-05-02 22:17:12 +08:00
212 lines
7.2 KiB
Go
212 lines
7.2 KiB
Go
package i2c
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gobot.io/x/gobot/v2"
|
|
"gobot.io/x/gobot/v2/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 = (*BMP280Driver)(nil)
|
|
|
|
func initTestBMP280WithStubbedAdaptor() (*BMP280Driver, *i2cTestAdaptor) {
|
|
adaptor := newI2cTestAdaptor()
|
|
return NewBMP280Driver(adaptor), adaptor
|
|
}
|
|
|
|
func TestNewBMP280Driver(t *testing.T) {
|
|
var di interface{} = NewBMP280Driver(newI2cTestAdaptor())
|
|
d, ok := di.(*BMP280Driver)
|
|
if !ok {
|
|
t.Errorf("NewBMP280Driver() should have returned a *BMP280Driver")
|
|
}
|
|
gobottest.Refute(t, d.Driver, nil)
|
|
gobottest.Assert(t, strings.HasPrefix(d.Name(), "BMP280"), true)
|
|
gobottest.Assert(t, d.defaultAddress, 0x77)
|
|
gobottest.Assert(t, d.ctrlPwrMode, uint8(0x03))
|
|
gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x05))
|
|
gobottest.Assert(t, d.ctrlTempOversamp, BMP280TemperatureOversampling(0x01))
|
|
gobottest.Assert(t, d.confFilter, BMP280IIRFilter(0x00))
|
|
gobottest.Refute(t, d.calCoeffs, nil)
|
|
}
|
|
|
|
func TestBMP280Options(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 := NewBMP280Driver(newI2cTestAdaptor(), WithBus(2), WithBMP280PressureOversampling(0x04))
|
|
gobottest.Assert(t, d.GetBusOrDefault(1), 2)
|
|
gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x04))
|
|
}
|
|
|
|
func TestWithBMP280TemperatureOversampling(t *testing.T) {
|
|
// arrange
|
|
d, a := initTestBMP280WithStubbedAdaptor()
|
|
a.written = []byte{} // reset writes of former test
|
|
const (
|
|
setVal = BMP280TemperatureOversampling(0x04) // 8 x
|
|
)
|
|
// act
|
|
WithBMP280TemperatureOversampling(setVal)(d)
|
|
// assert
|
|
gobottest.Assert(t, d.ctrlTempOversamp, setVal)
|
|
gobottest.Assert(t, len(a.written), 0)
|
|
}
|
|
|
|
func TestWithBMP280IIRFilter(t *testing.T) {
|
|
// arrange
|
|
d, a := initTestBMP280WithStubbedAdaptor()
|
|
a.written = []byte{} // reset writes of former test
|
|
const (
|
|
setVal = BMP280IIRFilter(0x02) // 4 x
|
|
)
|
|
// act
|
|
WithBMP280IIRFilter(setVal)(d)
|
|
// assert
|
|
gobottest.Assert(t, d.confFilter, setVal)
|
|
gobottest.Assert(t, len(a.written), 0)
|
|
}
|
|
|
|
func TestBMP280Measurements(t *testing.T) {
|
|
d, adaptor := initTestBMP280WithStubbedAdaptor()
|
|
adaptor.i2cReadImpl = func(b []byte) (int, error) {
|
|
buf := new(bytes.Buffer)
|
|
// Values produced by dumping data from actual sensor
|
|
if adaptor.written[len(adaptor.written)-1] == bmp280RegCalib00 {
|
|
buf.Write([]byte{126, 109, 214, 102, 50, 0, 54, 149, 220, 213, 208, 11, 64, 30, 166, 255, 249, 255, 172, 38, 10, 216, 189, 16})
|
|
} else if adaptor.written[len(adaptor.written)-1] == bmp280RegTempData {
|
|
buf.Write([]byte{128, 243, 0})
|
|
} else if adaptor.written[len(adaptor.written)-1] == bmp280RegPressureData {
|
|
buf.Write([]byte{77, 23, 48})
|
|
}
|
|
copy(b, buf.Bytes())
|
|
return buf.Len(), nil
|
|
}
|
|
d.Start()
|
|
temp, err := d.Temperature()
|
|
gobottest.Assert(t, err, nil)
|
|
gobottest.Assert(t, temp, float32(25.014637))
|
|
pressure, err := d.Pressure()
|
|
gobottest.Assert(t, err, nil)
|
|
gobottest.Assert(t, pressure, float32(99545.414))
|
|
alt, err := d.Altitude()
|
|
gobottest.Assert(t, err, nil)
|
|
gobottest.Assert(t, alt, float32(149.22713))
|
|
}
|
|
|
|
func TestBMP280TemperatureWriteError(t *testing.T) {
|
|
d, adaptor := initTestBMP280WithStubbedAdaptor()
|
|
d.Start()
|
|
|
|
adaptor.i2cWriteImpl = func([]byte) (int, error) {
|
|
return 0, errors.New("write error")
|
|
}
|
|
temp, err := d.Temperature()
|
|
gobottest.Assert(t, err, errors.New("write error"))
|
|
gobottest.Assert(t, temp, float32(0.0))
|
|
}
|
|
|
|
func TestBMP280TemperatureReadError(t *testing.T) {
|
|
d, adaptor := initTestBMP280WithStubbedAdaptor()
|
|
d.Start()
|
|
|
|
adaptor.i2cReadImpl = func([]byte) (int, error) {
|
|
return 0, errors.New("read error")
|
|
}
|
|
temp, err := d.Temperature()
|
|
gobottest.Assert(t, err, errors.New("read error"))
|
|
gobottest.Assert(t, temp, float32(0.0))
|
|
}
|
|
|
|
func TestBMP280PressureWriteError(t *testing.T) {
|
|
d, adaptor := initTestBMP280WithStubbedAdaptor()
|
|
d.Start()
|
|
|
|
adaptor.i2cWriteImpl = func([]byte) (int, error) {
|
|
return 0, errors.New("write error")
|
|
}
|
|
press, err := d.Pressure()
|
|
gobottest.Assert(t, err, errors.New("write error"))
|
|
gobottest.Assert(t, press, float32(0.0))
|
|
}
|
|
|
|
func TestBMP280PressureReadError(t *testing.T) {
|
|
d, adaptor := initTestBMP280WithStubbedAdaptor()
|
|
d.Start()
|
|
|
|
adaptor.i2cReadImpl = func([]byte) (int, error) {
|
|
return 0, errors.New("read error")
|
|
}
|
|
press, err := d.Pressure()
|
|
gobottest.Assert(t, err, errors.New("read error"))
|
|
gobottest.Assert(t, press, float32(0.0))
|
|
}
|
|
|
|
func TestBMP280_initialization(t *testing.T) {
|
|
// sequence to read and write in initialization():
|
|
// * read 24 bytes (12 x 16 bit calibration data), starting from TC1 register (0x88)
|
|
// * fill calibration struct with data (LSByte read first)
|
|
// * prepare the content of control register
|
|
// * write the control register (0xF4)
|
|
// * prepare the content of config register
|
|
// * write the config register (0xF5)
|
|
// arrange
|
|
d, a := initTestBMP280WithStubbedAdaptor()
|
|
a.written = []byte{} // reset writes of former test
|
|
const (
|
|
wantCalibReg = uint8(0x88)
|
|
wantCtrlReg = uint8(0xF4)
|
|
wantCtrlRegVal = uint8(0x37) // normal power mode, 16 x pressure and 1 x temperature oversampling
|
|
wantConfReg = uint8(0xF5)
|
|
wantConfRegVal = uint8(0x00) // no SPI, no filter, smallest standby (unused, because normal power mode)
|
|
)
|
|
// Values from the datasheet example.
|
|
t1 := []uint8{0x70, 0x6B}
|
|
t2 := []uint8{0x43, 0x67}
|
|
t3 := []uint8{0x18, 0xFC}
|
|
p1 := []uint8{0x7D, 0x8E}
|
|
p2 := []uint8{0x43, 0xD6}
|
|
p3 := []uint8{0xD0, 0x0B}
|
|
p4 := []uint8{0x27, 0x0B}
|
|
p5 := []uint8{0x8C, 0x00}
|
|
p6 := []uint8{0xF9, 0xFF}
|
|
p7 := []uint8{0x8C, 0x3C}
|
|
p8 := []uint8{0xF8, 0xC6}
|
|
p9 := []uint8{0x70, 0x17}
|
|
returnRead := append(append(append(append(append(append(t1, t2...), t3...), p1...), p2...), p3...), p4...)
|
|
returnRead = append(append(append(append(append(returnRead, p5...), p6...), p7...), p8...), p9...)
|
|
numCallsRead := 0
|
|
a.i2cReadImpl = func(b []byte) (int, error) {
|
|
numCallsRead++
|
|
copy(b, returnRead)
|
|
return len(b), nil
|
|
}
|
|
// act, assert - initialization() must be called on Start()
|
|
err := d.Start()
|
|
// assert
|
|
gobottest.Assert(t, err, nil)
|
|
gobottest.Assert(t, numCallsRead, 1)
|
|
gobottest.Assert(t, len(a.written), 5)
|
|
gobottest.Assert(t, a.written[0], wantCalibReg)
|
|
gobottest.Assert(t, a.written[1], wantCtrlReg)
|
|
gobottest.Assert(t, a.written[2], wantCtrlRegVal)
|
|
gobottest.Assert(t, a.written[3], wantConfReg)
|
|
gobottest.Assert(t, a.written[4], wantConfRegVal)
|
|
gobottest.Assert(t, d.calCoeffs.t1, uint16(27504))
|
|
gobottest.Assert(t, d.calCoeffs.t2, int16(26435))
|
|
gobottest.Assert(t, d.calCoeffs.t3, int16(-1000))
|
|
gobottest.Assert(t, d.calCoeffs.p1, uint16(36477))
|
|
gobottest.Assert(t, d.calCoeffs.p2, int16(-10685))
|
|
gobottest.Assert(t, d.calCoeffs.p3, int16(3024))
|
|
gobottest.Assert(t, d.calCoeffs.p4, int16(2855))
|
|
gobottest.Assert(t, d.calCoeffs.p5, int16(140))
|
|
gobottest.Assert(t, d.calCoeffs.p6, int16(-7))
|
|
gobottest.Assert(t, d.calCoeffs.p7, int16(15500))
|
|
gobottest.Assert(t, d.calCoeffs.p8, int16(-14600))
|
|
gobottest.Assert(t, d.calCoeffs.p9, int16(6000))
|
|
}
|