gobot.io/x/gobot/v2@v2.1.0/drivers/i2c/ads1x15_driver_1015_test.go (about)

     1  package i2c
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  	"testing"
     7  
     8  	"gobot.io/x/gobot/v2/gobottest"
     9  )
    10  
    11  func initTestADS1015DriverWithStubbedAdaptor() (*ADS1x15Driver, *i2cTestAdaptor) {
    12  	a := newI2cTestAdaptor()
    13  	d := NewADS1015Driver(a)
    14  	if err := d.Start(); err != nil {
    15  		panic(err)
    16  	}
    17  	return d, a
    18  }
    19  
    20  func TestNewADS1015Driver(t *testing.T) {
    21  	var di interface{} = NewADS1015Driver(newI2cTestAdaptor())
    22  	d, ok := di.(*ADS1x15Driver)
    23  	if !ok {
    24  		t.Errorf("NewADS1015Driver() should have returned a *ADS1x15Driver")
    25  	}
    26  	gobottest.Refute(t, d.Driver, nil)
    27  	gobottest.Assert(t, strings.HasPrefix(d.Name(), "ADS1015"), true)
    28  	for i := 0; i <= 3; i++ {
    29  		gobottest.Assert(t, d.channelCfgs[i].gain, 1)
    30  		gobottest.Assert(t, d.channelCfgs[i].dataRate, 1600)
    31  	}
    32  }
    33  
    34  func TestADS1015Options(t *testing.T) {
    35  	// This is a general test, that options are applied in constructor by using the common WithBus() option and
    36  	// least one of this driver. Further tests for options can also be done by call of "WithOption(val)(d)".
    37  	d := NewADS1015Driver(newI2cTestAdaptor(), WithBus(2), WithADS1x15Gain(2), WithADS1x15DataRate(920))
    38  	gobottest.Assert(t, d.GetBusOrDefault(1), 2)
    39  	for i := 0; i <= 3; i++ {
    40  		gobottest.Assert(t, d.channelCfgs[i].gain, 2)
    41  		gobottest.Assert(t, d.channelCfgs[i].dataRate, 920)
    42  	}
    43  }
    44  
    45  func TestADS1015WithADS1x15BestGainForVoltage(t *testing.T) {
    46  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
    47  	WithADS1x15BestGainForVoltage(1.01)(d)
    48  	for i := 0; i <= 3; i++ {
    49  		gobottest.Assert(t, d.channelCfgs[i].gain, 3)
    50  	}
    51  }
    52  
    53  func TestADS1015WithADS1x15ChannelBestGainForVoltage(t *testing.T) {
    54  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
    55  	WithADS1x15ChannelBestGainForVoltage(0, 1.0)(d)
    56  	WithADS1x15ChannelBestGainForVoltage(1, 2.5)(d)
    57  	WithADS1x15ChannelBestGainForVoltage(2, 3.3)(d)
    58  	WithADS1x15ChannelBestGainForVoltage(3, 5.0)(d)
    59  	gobottest.Assert(t, d.channelCfgs[0].gain, 3)
    60  	gobottest.Assert(t, d.channelCfgs[1].gain, 1)
    61  	gobottest.Assert(t, d.channelCfgs[2].gain, 1)
    62  	gobottest.Assert(t, d.channelCfgs[3].gain, 0)
    63  }
    64  
    65  func TestADS1015AnalogRead(t *testing.T) {
    66  	d, a := initTestADS1015DriverWithStubbedAdaptor()
    67  	WithADS1x15WaitSingleCycle()(d)
    68  
    69  	a.i2cReadImpl = func(b []byte) (int, error) {
    70  		copy(b, []byte{0x7F, 0xFF})
    71  		return 2, nil
    72  	}
    73  
    74  	val, err := d.AnalogRead("0")
    75  	gobottest.Assert(t, val, 32767)
    76  	gobottest.Assert(t, err, nil)
    77  
    78  	val, err = d.AnalogRead("1")
    79  	gobottest.Assert(t, val, 32767)
    80  	gobottest.Assert(t, err, nil)
    81  
    82  	val, err = d.AnalogRead("2")
    83  	gobottest.Assert(t, val, 32767)
    84  	gobottest.Assert(t, err, nil)
    85  
    86  	val, err = d.AnalogRead("3")
    87  	gobottest.Assert(t, val, 32767)
    88  	gobottest.Assert(t, err, nil)
    89  
    90  	val, err = d.AnalogRead("0-1")
    91  	gobottest.Assert(t, val, 32767)
    92  	gobottest.Assert(t, err, nil)
    93  
    94  	val, err = d.AnalogRead("0-3")
    95  	gobottest.Assert(t, val, 32767)
    96  	gobottest.Assert(t, err, nil)
    97  
    98  	val, err = d.AnalogRead("1-3")
    99  	gobottest.Assert(t, val, 32767)
   100  	gobottest.Assert(t, err, nil)
   101  
   102  	val, err = d.AnalogRead("2-3")
   103  	gobottest.Assert(t, val, 32767)
   104  	gobottest.Assert(t, err, nil)
   105  
   106  	_, err = d.AnalogRead("3-2")
   107  	gobottest.Refute(t, err.Error(), nil)
   108  }
   109  
   110  func TestADS1x15AnalogReadError(t *testing.T) {
   111  	d, a := initTestADS1015DriverWithStubbedAdaptor()
   112  
   113  	a.i2cReadImpl = func(b []byte) (int, error) {
   114  		return 0, errors.New("read error")
   115  	}
   116  
   117  	_, err := d.AnalogRead("0")
   118  	gobottest.Assert(t, err, errors.New("read error"))
   119  }
   120  
   121  func TestADS1x15AnalogReadInvalidPin(t *testing.T) {
   122  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
   123  
   124  	_, err := d.AnalogRead("99")
   125  	gobottest.Assert(t, err, errors.New("Invalid channel (99), must be between 0 and 3"))
   126  }
   127  
   128  func TestADS1x15AnalogReadWriteError(t *testing.T) {
   129  	d, a := initTestADS1015DriverWithStubbedAdaptor()
   130  
   131  	a.i2cWriteImpl = func([]byte) (int, error) {
   132  		return 0, errors.New("write error")
   133  	}
   134  
   135  	_, err := d.AnalogRead("0")
   136  	gobottest.Assert(t, err, errors.New("write error"))
   137  
   138  	_, err = d.AnalogRead("0-1")
   139  	gobottest.Assert(t, err, errors.New("write error"))
   140  
   141  	_, err = d.AnalogRead("2-3")
   142  	gobottest.Assert(t, err, errors.New("write error"))
   143  }
   144  
   145  func TestADS1x15ReadInvalidChannel(t *testing.T) {
   146  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
   147  
   148  	_, err := d.Read(9, 1, 1600)
   149  	gobottest.Assert(t, err, errors.New("Invalid channel (9), must be between 0 and 3"))
   150  }
   151  
   152  func TestADS1x15ReadInvalidGain(t *testing.T) {
   153  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
   154  
   155  	_, err := d.Read(0, 8, 1600)
   156  	gobottest.Assert(t, err, errors.New("Gain (8) must be one of: [0 1 2 3 4 5 6 7]"))
   157  }
   158  
   159  func TestADS1x15ReadInvalidDataRate(t *testing.T) {
   160  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
   161  
   162  	_, err := d.Read(0, 1, 321)
   163  	gobottest.Assert(t, err, errors.New("Invalid data rate (321). Accepted values: [128 250 490 920 1600 2400 3300]"))
   164  }
   165  
   166  func TestADS1x15ReadDifferenceInvalidChannel(t *testing.T) {
   167  	d, _ := initTestADS1015DriverWithStubbedAdaptor()
   168  
   169  	_, err := d.ReadDifference(9, 1, 1600)
   170  	gobottest.Assert(t, err, errors.New("Invalid channel (9), must be between 0 and 3"))
   171  }
   172  
   173  func TestADS1015_rawRead(t *testing.T) {
   174  	// sequence to read:
   175  	// * prepare config register content (mode, input, gain, data rate, comparator)
   176  	// * write config register (16 bit, MSByte first)
   177  	// * read config register (16 bit, MSByte first) and wait for bit 15 is set
   178  	// * read conversion register (16 bit, MSByte first) for the value
   179  	// * apply two's complement converter, relates to one digit resolution (1/2^15), voltage multiplier
   180  	var tests = map[string]struct {
   181  		input      []uint8
   182  		gain       int
   183  		dataRate   int
   184  		want       int
   185  		wantConfig []uint8
   186  	}{
   187  		"+FS": {
   188  			input:      []uint8{0x7F, 0xFF},
   189  			gain:       0,
   190  			dataRate:   128,
   191  			want:       (1<<15 - 1),
   192  			wantConfig: []uint8{0x91, 0x03},
   193  		},
   194  		"+1": {
   195  			input:      []uint8{0x00, 0x01},
   196  			gain:       0,
   197  			dataRate:   250,
   198  			want:       1,
   199  			wantConfig: []uint8{0x91, 0x23},
   200  		},
   201  		"+-0": {
   202  			input:      []uint8{0x00, 0x00},
   203  			gain:       0,
   204  			dataRate:   490,
   205  			want:       0,
   206  			wantConfig: []uint8{0x91, 0x43},
   207  		},
   208  		"-1": {
   209  			input:      []uint8{0xFF, 0xFF},
   210  			gain:       0,
   211  			dataRate:   920,
   212  			want:       -1,
   213  			wantConfig: []uint8{0x91, 0x63},
   214  		},
   215  		"-FS": {
   216  			input:      []uint8{0x80, 0x00},
   217  			gain:       0,
   218  			dataRate:   1600,
   219  			want:       -(1 << 15),
   220  			wantConfig: []uint8{0x91, 0x83},
   221  		},
   222  		"+FS gain 1": {
   223  			input:      []uint8{0x7F, 0xFF},
   224  			gain:       1,
   225  			dataRate:   2400,
   226  			want:       (1<<15 - 1),
   227  			wantConfig: []uint8{0x93, 0xA3},
   228  		},
   229  		"+FS gain 3": {
   230  			input:      []uint8{0x7F, 0xFF},
   231  			gain:       3,
   232  			dataRate:   3300,
   233  			want:       (1<<15 - 1),
   234  			wantConfig: []uint8{0x97, 0xC3},
   235  		},
   236  		"+FS gain 5": {
   237  			input:      []uint8{0x7F, 0xFF},
   238  			gain:       5,
   239  			dataRate:   2400,
   240  			want:       (1<<15 - 1),
   241  			wantConfig: []uint8{0x9B, 0xA3},
   242  		},
   243  		"+FS gain 7": {
   244  			input:      []uint8{0x7F, 0xFF},
   245  			gain:       7,
   246  			dataRate:   1600,
   247  			want:       (1<<15 - 1),
   248  			wantConfig: []uint8{0x9F, 0x83},
   249  		},
   250  	}
   251  	d, a := initTestADS1015DriverWithStubbedAdaptor()
   252  	// arrange
   253  	channel := 0
   254  	channelOffset := 1
   255  	for name, tt := range tests {
   256  		t.Run(name, func(t *testing.T) {
   257  			a.written = []byte{} // reset writes of Start() and former test
   258  			// arrange reads
   259  			conversion := []uint8{0x00, 0x00}   // a conversion is in progress
   260  			noConversion := []uint8{0x80, 0x00} // no conversion in progress
   261  			returnRead := [3][]uint8{conversion, noConversion, tt.input}
   262  			numCallsRead := 0
   263  			a.i2cReadImpl = func(b []byte) (int, error) {
   264  				numCallsRead++
   265  				retRead := returnRead[numCallsRead-1]
   266  				copy(b, retRead)
   267  				return len(b), nil
   268  			}
   269  			// act
   270  			got, err := d.rawRead(channel, channelOffset, tt.gain, tt.dataRate)
   271  			// assert
   272  			gobottest.Assert(t, err, nil)
   273  			gobottest.Assert(t, got, tt.want)
   274  			gobottest.Assert(t, numCallsRead, 3)
   275  			gobottest.Assert(t, len(a.written), 6)
   276  			gobottest.Assert(t, a.written[0], uint8(ads1x15PointerConfig))
   277  			gobottest.Assert(t, a.written[1], tt.wantConfig[0])            // MSByte: OS, MUX, PGA, MODE
   278  			gobottest.Assert(t, a.written[2], tt.wantConfig[1])            // LSByte: DR, COMP_*
   279  			gobottest.Assert(t, a.written[3], uint8(ads1x15PointerConfig)) // first check for no conversion
   280  			gobottest.Assert(t, a.written[4], uint8(ads1x15PointerConfig)) // second check for no conversion
   281  			gobottest.Assert(t, a.written[5], uint8(ads1x15PointerConversion))
   282  		})
   283  	}
   284  }