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  }