gobot.io/x/gobot/v2@v2.1.0/drivers/i2c/bmp280_driver_test.go (about) 1 package i2c 2 3 import ( 4 "bytes" 5 "errors" 6 "strings" 7 "testing" 8 9 "gobot.io/x/gobot/v2" 10 "gobot.io/x/gobot/v2/gobottest" 11 ) 12 13 // this ensures that the implementation is based on i2c.Driver, which implements the gobot.Driver 14 // and tests all implementations, so no further tests needed here for gobot.Driver interface 15 var _ gobot.Driver = (*BMP280Driver)(nil) 16 17 func initTestBMP280WithStubbedAdaptor() (*BMP280Driver, *i2cTestAdaptor) { 18 adaptor := newI2cTestAdaptor() 19 return NewBMP280Driver(adaptor), adaptor 20 } 21 22 func TestNewBMP280Driver(t *testing.T) { 23 var di interface{} = NewBMP280Driver(newI2cTestAdaptor()) 24 d, ok := di.(*BMP280Driver) 25 if !ok { 26 t.Errorf("NewBMP280Driver() should have returned a *BMP280Driver") 27 } 28 gobottest.Refute(t, d.Driver, nil) 29 gobottest.Assert(t, strings.HasPrefix(d.Name(), "BMP280"), true) 30 gobottest.Assert(t, d.defaultAddress, 0x77) 31 gobottest.Assert(t, d.ctrlPwrMode, uint8(0x03)) 32 gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x05)) 33 gobottest.Assert(t, d.ctrlTempOversamp, BMP280TemperatureOversampling(0x01)) 34 gobottest.Assert(t, d.confFilter, BMP280IIRFilter(0x00)) 35 gobottest.Refute(t, d.calCoeffs, nil) 36 } 37 38 func TestBMP280Options(t *testing.T) { 39 // This is a general test, that options are applied in constructor by using the common WithBus() option and 40 // least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)". 41 d := NewBMP280Driver(newI2cTestAdaptor(), WithBus(2), WithBMP280PressureOversampling(0x04)) 42 gobottest.Assert(t, d.GetBusOrDefault(1), 2) 43 gobottest.Assert(t, d.ctrlPressOversamp, BMP280PressureOversampling(0x04)) 44 } 45 46 func TestWithBMP280TemperatureOversampling(t *testing.T) { 47 // arrange 48 d, a := initTestBMP280WithStubbedAdaptor() 49 a.written = []byte{} // reset writes of former test 50 const ( 51 setVal = BMP280TemperatureOversampling(0x04) // 8 x 52 ) 53 // act 54 WithBMP280TemperatureOversampling(setVal)(d) 55 // assert 56 gobottest.Assert(t, d.ctrlTempOversamp, setVal) 57 gobottest.Assert(t, len(a.written), 0) 58 } 59 60 func TestWithBMP280IIRFilter(t *testing.T) { 61 // arrange 62 d, a := initTestBMP280WithStubbedAdaptor() 63 a.written = []byte{} // reset writes of former test 64 const ( 65 setVal = BMP280IIRFilter(0x02) // 4 x 66 ) 67 // act 68 WithBMP280IIRFilter(setVal)(d) 69 // assert 70 gobottest.Assert(t, d.confFilter, setVal) 71 gobottest.Assert(t, len(a.written), 0) 72 } 73 74 func TestBMP280Measurements(t *testing.T) { 75 d, adaptor := initTestBMP280WithStubbedAdaptor() 76 adaptor.i2cReadImpl = func(b []byte) (int, error) { 77 buf := new(bytes.Buffer) 78 // Values produced by dumping data from actual sensor 79 if adaptor.written[len(adaptor.written)-1] == bmp280RegCalib00 { 80 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}) 81 } else if adaptor.written[len(adaptor.written)-1] == bmp280RegTempData { 82 buf.Write([]byte{128, 243, 0}) 83 } else if adaptor.written[len(adaptor.written)-1] == bmp280RegPressureData { 84 buf.Write([]byte{77, 23, 48}) 85 } 86 copy(b, buf.Bytes()) 87 return buf.Len(), nil 88 } 89 d.Start() 90 temp, err := d.Temperature() 91 gobottest.Assert(t, err, nil) 92 gobottest.Assert(t, temp, float32(25.014637)) 93 pressure, err := d.Pressure() 94 gobottest.Assert(t, err, nil) 95 gobottest.Assert(t, pressure, float32(99545.414)) 96 alt, err := d.Altitude() 97 gobottest.Assert(t, err, nil) 98 gobottest.Assert(t, alt, float32(149.22713)) 99 } 100 101 func TestBMP280TemperatureWriteError(t *testing.T) { 102 d, adaptor := initTestBMP280WithStubbedAdaptor() 103 d.Start() 104 105 adaptor.i2cWriteImpl = func([]byte) (int, error) { 106 return 0, errors.New("write error") 107 } 108 temp, err := d.Temperature() 109 gobottest.Assert(t, err, errors.New("write error")) 110 gobottest.Assert(t, temp, float32(0.0)) 111 } 112 113 func TestBMP280TemperatureReadError(t *testing.T) { 114 d, adaptor := initTestBMP280WithStubbedAdaptor() 115 d.Start() 116 117 adaptor.i2cReadImpl = func([]byte) (int, error) { 118 return 0, errors.New("read error") 119 } 120 temp, err := d.Temperature() 121 gobottest.Assert(t, err, errors.New("read error")) 122 gobottest.Assert(t, temp, float32(0.0)) 123 } 124 125 func TestBMP280PressureWriteError(t *testing.T) { 126 d, adaptor := initTestBMP280WithStubbedAdaptor() 127 d.Start() 128 129 adaptor.i2cWriteImpl = func([]byte) (int, error) { 130 return 0, errors.New("write error") 131 } 132 press, err := d.Pressure() 133 gobottest.Assert(t, err, errors.New("write error")) 134 gobottest.Assert(t, press, float32(0.0)) 135 } 136 137 func TestBMP280PressureReadError(t *testing.T) { 138 d, adaptor := initTestBMP280WithStubbedAdaptor() 139 d.Start() 140 141 adaptor.i2cReadImpl = func([]byte) (int, error) { 142 return 0, errors.New("read error") 143 } 144 press, err := d.Pressure() 145 gobottest.Assert(t, err, errors.New("read error")) 146 gobottest.Assert(t, press, float32(0.0)) 147 } 148 149 func TestBMP280_initialization(t *testing.T) { 150 // sequence to read and write in initialization(): 151 // * read 24 bytes (12 x 16 bit calibration data), starting from TC1 register (0x88) 152 // * fill calibration struct with data (LSByte read first) 153 // * prepare the content of control register 154 // * write the control register (0xF4) 155 // * prepare the content of config register 156 // * write the config register (0xF5) 157 // arrange 158 d, a := initTestBMP280WithStubbedAdaptor() 159 a.written = []byte{} // reset writes of former test 160 const ( 161 wantCalibReg = uint8(0x88) 162 wantCtrlReg = uint8(0xF4) 163 wantCtrlRegVal = uint8(0x37) // normal power mode, 16 x pressure and 1 x temperature oversampling 164 wantConfReg = uint8(0xF5) 165 wantConfRegVal = uint8(0x00) // no SPI, no filter, smallest standby (unused, because normal power mode) 166 ) 167 // Values from the datasheet example. 168 t1 := []uint8{0x70, 0x6B} 169 t2 := []uint8{0x43, 0x67} 170 t3 := []uint8{0x18, 0xFC} 171 p1 := []uint8{0x7D, 0x8E} 172 p2 := []uint8{0x43, 0xD6} 173 p3 := []uint8{0xD0, 0x0B} 174 p4 := []uint8{0x27, 0x0B} 175 p5 := []uint8{0x8C, 0x00} 176 p6 := []uint8{0xF9, 0xFF} 177 p7 := []uint8{0x8C, 0x3C} 178 p8 := []uint8{0xF8, 0xC6} 179 p9 := []uint8{0x70, 0x17} 180 returnRead := append(append(append(append(append(append(t1, t2...), t3...), p1...), p2...), p3...), p4...) 181 returnRead = append(append(append(append(append(returnRead, p5...), p6...), p7...), p8...), p9...) 182 numCallsRead := 0 183 a.i2cReadImpl = func(b []byte) (int, error) { 184 numCallsRead++ 185 copy(b, returnRead) 186 return len(b), nil 187 } 188 // act, assert - initialization() must be called on Start() 189 err := d.Start() 190 // assert 191 gobottest.Assert(t, err, nil) 192 gobottest.Assert(t, numCallsRead, 1) 193 gobottest.Assert(t, len(a.written), 5) 194 gobottest.Assert(t, a.written[0], wantCalibReg) 195 gobottest.Assert(t, a.written[1], wantCtrlReg) 196 gobottest.Assert(t, a.written[2], wantCtrlRegVal) 197 gobottest.Assert(t, a.written[3], wantConfReg) 198 gobottest.Assert(t, a.written[4], wantConfRegVal) 199 gobottest.Assert(t, d.calCoeffs.t1, uint16(27504)) 200 gobottest.Assert(t, d.calCoeffs.t2, int16(26435)) 201 gobottest.Assert(t, d.calCoeffs.t3, int16(-1000)) 202 gobottest.Assert(t, d.calCoeffs.p1, uint16(36477)) 203 gobottest.Assert(t, d.calCoeffs.p2, int16(-10685)) 204 gobottest.Assert(t, d.calCoeffs.p3, int16(3024)) 205 gobottest.Assert(t, d.calCoeffs.p4, int16(2855)) 206 gobottest.Assert(t, d.calCoeffs.p5, int16(140)) 207 gobottest.Assert(t, d.calCoeffs.p6, int16(-7)) 208 gobottest.Assert(t, d.calCoeffs.p7, int16(15500)) 209 gobottest.Assert(t, d.calCoeffs.p8, int16(-14600)) 210 gobottest.Assert(t, d.calCoeffs.p9, int16(6000)) 211 }