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.
Adde unit tests for TH02 & Minor improvement
- Added ability to change sample resolution - Added unit tests for TH02Driver. The way the functions are written, it will be hard to get a fully working .Sample() coverage with my limited understanding of gobot's testing API. The chip is rather needy, and each sample requires multiple read and write steps, so getting both read and write for 2 independant measurements it a little over my head without some more code viewing. Id rather get this checked in and think of a better way to do this. Otherwise, this does test the functionality Signed-off-by: npotts <[email protected]>
- Loading branch information
1 parent
1d6b33a
commit bdca7a6
Showing
2 changed files
with
288 additions
and
16 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 |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (c) 2016-2017 Weston Schmidt <[email protected]> | ||
* Copyright (c) 2018 Nick Potts <[email protected]> | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
|
@@ -18,8 +18,9 @@ package i2c | |
|
||
// TH02Driver is a driver for the TH02-D based devices. | ||
// | ||
// This module was tested with AdaFruit Sensiron SHT32-D Breakout. | ||
// https://www.adafruit.com/products/2857 | ||
// This module was tested with a Grove "Temperature&Humidity Sensor (High-Accuracy & Mini ) v1.0" | ||
// from https://www.seeedstudio.com/Grove-Temperature-Humidity-Sensor-High-Accuracy-Min-p-1921.htm | ||
// Datasheet is at http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf | ||
|
||
import ( | ||
"fmt" | ||
|
@@ -30,30 +31,19 @@ import ( | |
|
||
const ( | ||
|
||
// TH02AddressA is the default address of device | ||
// TH02Address is the default address of device | ||
TH02Address = 0x40 | ||
|
||
//TH02ConfigReg is the configuration register | ||
TH02ConfigReg = 0x03 | ||
|
||
// TH02RegConfigHighAccuracyTemp is the CONFIG register to read temperature | ||
// TH02HighAccuracyTemp = 0x11 | ||
|
||
//TH02RegConfigHighAccuracyRH is the CONFIG register to read high accuracy RH | ||
// TH02HighAccuracyRH = 0x01 | ||
) | ||
|
||
//Accuracy constants for the TH02 devices | ||
const ( | ||
TH02HighAccuracy = 0 //High Accuracy | ||
TH02LowAccuracy = 1 //Lower Accuracy | ||
) | ||
|
||
var ( | ||
//ErrInvalidAccuracy = errors.New("Invalid accuracy") | ||
//ErrInvalidCrc = errors.New("Invalid crc") | ||
//ErrInvalidTemp = errors.New("Invalid temperature units") | ||
) | ||
|
||
// TH02Driver is a Driver for a TH02 humidity and temperature sensor | ||
type TH02Driver struct { | ||
Units string | ||
|
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,282 @@ | ||
package i2c | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"testing" | ||
"time" | ||
|
||
"gobot.io/x/gobot" | ||
"gobot.io/x/gobot/gobottest" | ||
) | ||
|
||
var _ gobot.Driver = (*TH02Driver)(nil) | ||
|
||
// // --------- HELPERS | ||
func initTestTH02Driver() *SHT3xDriver { | ||
driver, _ := initTestSHT3xDriverWithStubbedAdaptor() | ||
return driver | ||
} | ||
|
||
func initTestTH02DriverWithStubbedAdaptor() (*TH02Driver, *i2cTestAdaptor) { | ||
adaptor := newI2cTestAdaptor() | ||
return NewTH02Driver(adaptor), adaptor | ||
} | ||
|
||
// --------- TESTS | ||
|
||
func TestNewTH02Driver(t *testing.T) { | ||
i2cd := newI2cTestAdaptor() | ||
defer i2cd.Close() | ||
// Does it return a pointer to an instance of SHT3xDriver? | ||
var iface interface{} = NewTH02Driver(i2cd) | ||
_, ok := iface.(*TH02Driver) | ||
if !ok { | ||
t.Errorf("NewTH02Driver() should have returned a *NewTH02Driver") | ||
} | ||
b := NewTH02Driver(i2cd, func(Config) {}) | ||
gobottest.Refute(t, b.Connection(), nil) | ||
|
||
//cover some basically useless protions the Interface demands | ||
if name := b.Name(); name != b.name { | ||
t.Errorf("Didnt return the proper name. Got %q wanted %q", name, b.name) | ||
} | ||
|
||
if b.SetName("42"); b.name != "42" { | ||
t.Errorf("yikes - didnt set name.") | ||
} | ||
} | ||
|
||
func TestTH02Driver_Accuracy(t *testing.T) { | ||
i2cd := newI2cTestAdaptor() | ||
defer i2cd.Close() | ||
b := NewTH02Driver(i2cd) | ||
|
||
if b.SetAddress(0x42); b.addr != 0x42 { | ||
t.Error("Didnt set address as expected") | ||
} | ||
|
||
if b.SetAccuracy(0x42); b.accuracy != TH02HighAccuracy { | ||
t.Error("Setting an invalid accuracy should resolve to TH02HighAccuracy") | ||
} | ||
|
||
if b.SetAccuracy(TH02LowAccuracy); b.accuracy != TH02LowAccuracy { | ||
t.Error("Expected setting low accuracy to actually set to low accuracy") | ||
} | ||
|
||
if acc := b.Accuracy(); acc != TH02LowAccuracy { | ||
t.Errorf("Accuract() didnt return what was expected") | ||
} | ||
} | ||
|
||
func TestTH022DriverStart(t *testing.T) { | ||
b, _ := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, b.Start(), nil) | ||
} | ||
|
||
func TestTH02StartConnectError(t *testing.T) { | ||
d, adaptor := initTestTH02DriverWithStubbedAdaptor() | ||
adaptor.Testi2cConnectErr(true) | ||
gobottest.Assert(t, d.Start(), errors.New("Invalid i2c connection")) | ||
} | ||
|
||
func TestTH02DriverHalt(t *testing.T) { | ||
sht3x := initTestTH02Driver() | ||
gobottest.Assert(t, sht3x.Halt(), nil) | ||
} | ||
|
||
func TestTH02DriverOptions(t *testing.T) { | ||
d := NewTH02Driver(newI2cTestAdaptor(), WithBus(2)) | ||
gobottest.Assert(t, d.GetBusOrDefault(1), 2) | ||
d.Halt() | ||
} | ||
|
||
func TestTH02Driver_ReadData(t *testing.T) { | ||
d, i2cd := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, d.Start(), nil) | ||
|
||
type x struct { | ||
rd, wr func([]byte) (int, error) | ||
rtn uint16 | ||
errNil bool | ||
} | ||
|
||
tests := map[string]x{ | ||
"example RH": x{ | ||
rd: func(b []byte) (int, error) { | ||
copy(b, []byte{0x00, 0x07, 0xC0}) | ||
return 3, nil | ||
}, | ||
wr: func([]byte) (int, error) { | ||
return 1, nil | ||
}, | ||
errNil: true, | ||
rtn: 1984, | ||
}, | ||
"example T": x{ | ||
rd: func(b []byte) (int, error) { | ||
copy(b, []byte{0x00, 0x12, 0xC0}) | ||
return 3, nil | ||
}, | ||
wr: func([]byte) (int, error) { | ||
return 1, nil | ||
}, | ||
errNil: true, | ||
rtn: 4800, | ||
}, | ||
"timeout - no wait for ready": x{ | ||
rd: func(b []byte) (int, error) { | ||
time.Sleep(200 * time.Millisecond) | ||
copy(b, []byte{0x01}) | ||
return 1, fmt.Errorf("nope") | ||
}, | ||
wr: func([]byte) (int, error) { | ||
return 1, nil | ||
}, | ||
errNil: false, | ||
rtn: 0, | ||
}, | ||
"unable to write status register": x{ | ||
rd: func(b []byte) (int, error) { | ||
copy(b, []byte{0x00}) | ||
return 0, nil | ||
}, | ||
wr: func([]byte) (int, error) { | ||
return 0, fmt.Errorf("Nope") | ||
}, | ||
errNil: false, | ||
rtn: 0, | ||
}, | ||
"unable to read doesnt provide enought data": x{ | ||
rd: func(b []byte) (int, error) { | ||
copy(b, []byte{0x00, 0x01}) | ||
return 2, nil | ||
}, | ||
wr: func([]byte) (int, error) { | ||
return 1, nil | ||
}, | ||
errNil: false, | ||
rtn: 0, | ||
}, | ||
} | ||
|
||
for name, x := range tests { | ||
t.Log("Running", name) | ||
i2cd.i2cReadImpl = x.rd | ||
i2cd.i2cWriteImpl = x.wr | ||
got, err := d.readData() | ||
gobottest.Assert(t, err == nil, x.errNil) | ||
gobottest.Assert(t, got, x.rtn) | ||
} | ||
} | ||
|
||
func TestTH02Driver_waitForReady(t *testing.T) { | ||
d, i2cd := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, d.Start(), nil) | ||
|
||
i2cd.i2cReadImpl = func(b []byte) (int, error) { | ||
time.Sleep(50 * time.Millisecond) | ||
copy(b, []byte{0x01, 0x00}) | ||
return 3, nil | ||
} | ||
|
||
i2cd.i2cWriteImpl = func([]byte) (int, error) { | ||
return 1, nil | ||
} | ||
|
||
timeout := 10 * time.Microsecond | ||
if err := d.waitForReady(&timeout); err == nil { | ||
t.Error("Expected a timeout error") | ||
} | ||
} | ||
|
||
func TestTH02Driver_WriteRegister(t *testing.T) { | ||
d, i2cd := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, d.Start(), nil) | ||
|
||
i2cd.i2cWriteImpl = func([]byte) (int, error) { | ||
return 1, nil | ||
} | ||
|
||
if err := d.writeRegister(0x00, 0x00); err != nil { | ||
t.Errorf("expected a nil error write") | ||
} | ||
} | ||
|
||
func TestTH02Driver_Heater(t *testing.T) { | ||
d, i2cd := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, d.Start(), nil) | ||
|
||
i2cd.i2cReadImpl = func(b []byte) (int, error) { | ||
copy(b, []byte{0xff}) | ||
return 1, nil | ||
} | ||
|
||
i2cd.i2cWriteImpl = func([]byte) (int, error) { | ||
return 1, nil | ||
} | ||
|
||
on, err := d.Heater() | ||
gobottest.Assert(t, on, true) | ||
gobottest.Assert(t, err, nil) | ||
} | ||
func TestTH02Driver_SerialNumber(t *testing.T) { | ||
d, i2cd := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, d.Start(), nil) | ||
|
||
i2cd.i2cReadImpl = func(b []byte) (int, error) { | ||
copy(b, []byte{0x42}) | ||
return 1, nil | ||
} | ||
|
||
i2cd.i2cWriteImpl = func([]byte) (int, error) { | ||
return 1, nil | ||
} | ||
|
||
sn, err := d.SerialNumber() | ||
|
||
gobottest.Assert(t, sn, uint32((0x42)>>4)) | ||
gobottest.Assert(t, err, nil) | ||
} | ||
|
||
func TestTH02Driver_ApplySettings(t *testing.T) { | ||
d := &TH02Driver{} | ||
|
||
type x struct { | ||
acc, base, out byte | ||
heating bool | ||
} | ||
|
||
tests := map[string]x{ | ||
"low acc, heating": x{acc: TH02LowAccuracy, base: 0x00, heating: true, out: 0x01}, | ||
"high acc, no heating": x{acc: TH02HighAccuracy, base: 0x00, heating: false, out: 0x23}, | ||
} | ||
|
||
for name, x := range tests { | ||
t.Log(name) | ||
d.accuracy = x.acc | ||
d.heating = x.heating | ||
got := d.applysettings(x.base) | ||
gobottest.Assert(t, x.out, got) | ||
} | ||
} | ||
|
||
func TestTH02Driver_Sample(t *testing.T) { | ||
d, i2cd := initTestTH02DriverWithStubbedAdaptor() | ||
gobottest.Assert(t, d.Start(), nil) | ||
|
||
i2cd.i2cReadImpl = func(b []byte) (int, error) { | ||
copy(b, []byte{0x00, 0x00, 0x07, 0xC0}) | ||
return 4, nil | ||
} | ||
|
||
i2cd.i2cWriteImpl = func([]byte) (int, error) { | ||
return 1, nil | ||
} | ||
|
||
temp, rh, _ := d.Sample() | ||
|
||
gobottest.Assert(t, temp, float32(0)) | ||
gobottest.Assert(t, rh, float32(0)) | ||
|
||
} |