You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devices/tmp102/tmp102_test.go

177 lines
5.8 KiB
Go

// Copyright 2024 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package tmp102
import (
"testing"
"time"
"periph.io/x/conn/v3/i2c/i2ctest"
"periph.io/x/conn/v3/physic"
)
const (
// Default value for alert low range value.
DefaultLow physic.Temperature = physic.ZeroCelsius + 75*physic.Kelvin
// Default value for alert high range value.
DefaultHigh physic.Temperature = physic.ZeroCelsius + 80*physic.Kelvin
addr uint16 = 0x48
)
func defaultOps() []i2ctest.IO {
ops := []i2ctest.IO{
{Addr: addr, W: []byte{_REGISTER_CONFIGURATION}},
{Addr: addr, W: []byte{_REGISTER_CONFIGURATION, 0x00, 0x80}}, // Write the config
{Addr: addr, W: []byte{_REGISTER_RANGE_LOW, 0x4b, 0x00}}, // Write the low alert temp
{Addr: addr, W: []byte{_REGISTER_RANGE_HIGH, 0x50, 0x00}}, // Write the high alert temp
}
return ops
}
// TestSenseContinous test the sense continuous function, which
// implicitly tests Sense() and countToTemperature().
func TestSenseContinuous(t *testing.T) {
// A set of counts, and the expected temperature value.
tests := []struct {
bits []byte
expected physic.Temperature
}{
{[]byte{0x64, 0x00}, physic.ZeroCelsius + 100*physic.Kelvin},
{[]byte{0x50, 0x00}, physic.ZeroCelsius + 80*physic.Kelvin},
{[]byte{0x32, 0x00}, physic.ZeroCelsius + 50*physic.Kelvin},
{[]byte{0x19, 0x00}, physic.ZeroCelsius + 25*physic.Kelvin},
{[]byte{0x00, 0x00}, physic.ZeroCelsius},
{[]byte{0xe7, 0x00}, physic.ZeroCelsius - 25*physic.Kelvin},
{[]byte{0xc9, 0x00}, physic.ZeroCelsius - 55*physic.Kelvin},
}
opts := Opts{
SampleRate: RateFourHertz,
AlertSetting: ModeComparator,
AlertLow: DefaultLow,
AlertHigh: DefaultHigh,
}
ops := defaultOps()
// Add the test values to our playback bus.
for _, test := range tests {
ops = append(ops, i2ctest.IO{Addr: addr, W: []byte{_REGISTER_TEMPERATURE}, R: test.bits})
}
pb := &i2ctest.Playback{Ops: ops, DontPanic: true, Count: 1}
defer pb.Close()
record := &i2ctest.Record{Bus: pb}
tmp102, err := NewI2C(record, addr, &opts)
if err != nil {
t.Error(err)
return
}
ch, err := tmp102.SenseContinuous(250 * time.Millisecond)
if err != nil {
t.Error(err)
return
}
for count := 0; count < len(tests); count++ {
env := <-ch
t.Logf("Temperature = %.4f", env.Temperature.Celsius())
if env.Temperature != tests[count].expected {
t.Errorf("Error testing. Read: %.4f Expected %.4f", env.Temperature.Celsius(), tests[count].expected.Celsius())
}
}
err = tmp102.Halt()
if err != nil {
t.Error(err)
}
t.Logf("record.ops=%#v", record.Ops)
}
func TestString(t *testing.T) {
ops := defaultOps()
pb := &i2ctest.Playback{Ops: ops, DontPanic: true, Count: 1}
defer pb.Close()
record := &i2ctest.Record{Bus: pb}
tmp102, err := NewI2C(record, addr, nil)
if err != nil {
t.Error(err)
return
}
s := tmp102.String()
t.Log(s)
if len(s) == 0 {
t.Error("invalid String() result")
}
}
func TestSetAlertMode(t *testing.T) {
ops := make([]i2ctest.IO, 0)
ops = append(ops, []i2ctest.IO{
{Addr: addr, W: []byte{_REGISTER_CONFIGURATION}, R: []byte{0x00, 0x00}}, // Read the device config.
{Addr: addr, W: []byte{_REGISTER_CONFIGURATION, 0x00, 0x80}}, // Set the device config.
{Addr: addr, W: []byte{_REGISTER_RANGE_LOW}, R: []byte{0x4b, 0}}, // Read the low limit register
{Addr: addr, W: []byte{_REGISTER_RANGE_HIGH}, R: []byte{0x50, 0}}, // Read the High Limit Register
{Addr: addr, W: []byte{_REGISTER_RANGE_LOW, 0x4b, 0x80}}, // Set the read of the low limit to 75C
{Addr: addr, W: []byte{_REGISTER_RANGE_HIGH, 0x4f, 0x80}}, // Set the read of the high limit to 80C
{Addr: addr, W: []byte{_REGISTER_CONFIGURATION, 0x02, 0x00}}, // Add 1/2 Degree C to the range low
{Addr: addr, W: []byte{_REGISTER_CONFIGURATION}, R: []byte{0x02, 0}}, // Read the confugration register.
{Addr: addr, W: []byte{_REGISTER_RANGE_LOW}, R: []byte{0x4b, 0x80}}, // Read the low temp register
{Addr: addr, W: []byte{_REGISTER_RANGE_HIGH}, R: []byte{0x4f, 0x80}}, // Read the high temp register
{Addr: addr, W: []byte{_REGISTER_RANGE_LOW, 0x4b, 0x00}}, // write it back to 75C
{Addr: addr, W: []byte{_REGISTER_RANGE_HIGH, 0x50, 0x00}}, // set it back to 80C
}...)
pb := &i2ctest.Playback{Ops: ops, DontPanic: true, Count: 1}
defer pb.Close()
record := &i2ctest.Record{Bus: pb}
defer t.Logf("record=%#v", record)
tmp102, err := NewI2C(record, addr, nil)
if err != nil {
t.Error(err)
return
}
mode, low, high, err := tmp102.GetAlertMode()
t.Logf("newMode=%d, newLow=%.4f, newHigh=%.4f", mode, low.Celsius(), high.Celsius())
if err != nil {
t.Error(err)
}
var newMode AlertMode
if mode == ModeComparator {
newMode = ModeInterrupt
} else {
newMode = ModeComparator
}
newLow := low + 500*physic.MilliKelvin
newHigh := high - 500*physic.MilliKelvin
t.Logf("newMode=%d, newLow=%.4f, newHigh=%.4f", newMode, newLow.Celsius(), newHigh.Celsius())
err = tmp102.SetAlertMode(newMode, newLow, newHigh)
if err != nil {
t.Error(err)
}
checkMode, checkLow, checkHigh, err := tmp102.GetAlertMode()
t.Logf("checkMode=%d checkLow=%.4f checkHigh=%.4f", checkMode, checkLow.Celsius(), checkHigh.Celsius())
if err != nil {
t.Error(err)
}
if checkMode != newMode || checkLow != newLow || checkHigh != newHigh {
t.Errorf("Error setting/reading alert mode. Received: Mode=%d, Low=%.4f, High=%.4f. Expected: Mode:%d, Low=%.4f, High=%.4f",
checkMode, checkLow.Celsius(), checkHigh.Celsius(),
newMode, newLow.Celsius(), newHigh.Celsius())
}
err = tmp102.SetAlertMode(mode, low, high)
if err != nil {
t.Error(err)
}
checkMode, _, _, _ = tmp102.GetAlertMode()
if checkMode != mode {
t.Errorf("Error resetting mode. Got %d Expected %d", checkMode, mode)
}
}