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/bmxx80/bmp180_test.go

416 lines
9.4 KiB
Go

// Copyright 2017 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 bmxx80
import (
"testing"
"time"
"periph.io/x/conn/v3/i2c/i2ctest"
"periph.io/x/conn/v3/physic"
)
var opts180 = &Opts{Temperature: O1x, Pressure: O1x}
func TestNew180_fail_read_chipid(t *testing.T) {
bus := i2ctest.Playback{
// Chip ID detection read fail.
Ops: []i2ctest.IO{},
DontPanic: true,
}
if _, err := NewI2C(&bus, 0x77, opts180); err == nil {
t.Fatal("can't read chip ID")
}
}
func TestNew180_bad_chipid(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Bad Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x61}},
},
}
if _, err := NewI2C(&bus, 0x77, opts180); err == nil {
t.Fatal("bad chip ID")
}
}
func TestNew180_fail_calib(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Fail to read calibration data.
},
DontPanic: true,
}
if _, err := NewI2C(&bus, 0x77, opts180); err == nil {
t.Fatal("can't read calibration")
}
}
func TestNew180_bad_calib(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255},
},
},
DontPanic: true,
}
if _, err := NewI2C(&bus, 0x77, opts180); err == nil {
t.Fatal("bad calibration")
}
}
func TestSense180_success(t *testing.T) {
values := []struct {
o Oversampling
c byte
p physic.Pressure
}{
{Oversampling(42), 0x34, 100567 * physic.Pascal},
{O1x, 0x34, 100567 * physic.Pascal},
{O2x, 0x74, 100567 * physic.Pascal},
{O4x, 0xB4, 100568 * physic.Pascal},
{O8x, 0xF4, 100568 * physic.Pascal},
}
for _, line := range values {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
// Request temperature.
{Addr: 0x77, W: []byte{0xF4, 0x2E}},
// Read temperature.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0x71, 0xBf}},
// Request pressure.
{Addr: 0x77, W: []byte{0xF4, line.c}},
// Read pressure.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0xAb, 0x96, 0}},
},
}
dev, err := NewI2C(&bus, 0x77, &Opts{Pressure: line.o})
if err != nil {
t.Fatal(err)
}
if s := dev.String(); s != "BMP180{playback(119)}" {
t.Fatal(s)
}
e := physic.Env{}
if err := dev.Sense(&e); err != nil {
t.Fatal(err)
}
if e.Temperature != 25300*physic.MilliCelsius+physic.ZeroCelsius {
t.Fatalf("temp %d", e.Temperature)
}
if e.Pressure != line.p {
t.Fatalf("pressure %d", e.Pressure)
}
if e.Humidity != 0 {
t.Fatalf("humidity %d", e.Humidity)
}
if err := dev.Halt(); err != nil {
t.Fatal(err)
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
}
func TestSense180_fail_1(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
// Request temperature fail.
},
DontPanic: true,
}
dev, err := NewI2C(&bus, 0x77, opts180)
if err != nil {
t.Fatal(err)
}
e := physic.Env{}
if dev.Sense(&e) == nil {
t.Fatal("sensing should have failed")
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestSense180_fail_2(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
// Request temperature.
{Addr: 0x77, W: []byte{0xF4, 0x2E}},
// Read temperature fail.
},
DontPanic: true,
}
dev, err := NewI2C(&bus, 0x77, opts180)
if err != nil {
t.Fatal(err)
}
e := physic.Env{}
if dev.Sense(&e) == nil {
t.Fatal("sensing should have failed")
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestSense180_fail_3(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
// Request temperature.
{Addr: 0x77, W: []byte{0xF4, 0x2E}},
// Read temperature fail.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0x71, 0xBf}},
// Request pressure fail.
},
DontPanic: true,
}
dev, err := NewI2C(&bus, 0x77, opts180)
if err != nil {
t.Fatal(err)
}
e := physic.Env{}
if dev.Sense(&e) == nil {
t.Fatal("sensing should have failed")
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestSense180_fail_4(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
// Request temperature.
{Addr: 0x77, W: []byte{0xF4, 0x2E}},
// Read temperature fail.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0x71, 0xBf}},
// Request pressure.
{Addr: 0x77, W: []byte{0xF4, 0x34}},
// Read pressure fail.
},
DontPanic: true,
}
dev, err := NewI2C(&bus, 0x77, opts180)
if err != nil {
t.Fatal(err)
}
e := physic.Env{}
if dev.Sense(&e) == nil {
t.Fatal("sensing should have failed")
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestSenseContinuous180_success(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
// Request temperature.
{Addr: 0x77, W: []byte{0xF4, 0x2E}},
// Read temperature.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0x71, 0xBf}},
// Request pressure.
{Addr: 0x77, W: []byte{0xF4, 0x34}},
// Read pressure.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0xAb, 0x96, 0}},
// Request temperature.
{Addr: 0x77, W: []byte{0xF4, 0x2E}},
// Read temperature.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0x71, 0xBf}},
// Request pressure.
{Addr: 0x77, W: []byte{0xF4, 0x34}},
// Read pressure.
{Addr: 0x77, W: []byte{0xF6}, R: []byte{0xAb, 0x96, 0}},
},
DontPanic: true,
}
dev, err := NewI2C(&bus, 0x77, opts180)
if err != nil {
t.Fatal(err)
}
c, err := dev.SenseContinuous(time.Minute)
if err != nil {
t.Fatal(err)
}
e := <-c
if e.Temperature != 25300*physic.MilliCelsius+physic.ZeroCelsius {
t.Fatalf("temp %d", e.Temperature)
}
if e.Pressure != 100567*physic.Pascal {
t.Fatalf("pressure %d", e.Pressure)
}
if e.Humidity != 0 {
t.Fatalf("humidity %d", e.Humidity)
}
if dev.Sense(&e) == nil {
t.Fatal("Sense() should have failed")
}
c2, err := dev.SenseContinuous(time.Minute)
if err != nil {
t.Fatal(err)
}
e = <-c2
if _, ok := <-c; ok {
t.Fatal("c should be closed")
}
if err := dev.Halt(); err != nil {
t.Fatal(err)
}
if _, ok := <-c2; ok {
t.Fatal("c2 should be closed")
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
func TestBmp180Precision(t *testing.T) {
bus := i2ctest.Playback{
Ops: []i2ctest.IO{
// Chip ID detection.
{Addr: 0x77, W: []byte{0xd0}, R: []byte{0x55}},
// Calibration data.
{
Addr: 0x77,
W: []byte{0xaa},
R: []byte{35, 136, 251, 103, 199, 169, 135, 91, 98, 137, 80, 22, 25, 115, 0, 46, 128, 0, 209, 246, 10, 123},
},
},
}
dev, err := NewI2C(&bus, 0x77, &DefaultOpts)
if err != nil {
t.Fatal(err)
}
e := physic.Env{}
dev.Precision(&e)
if e.Temperature != 100*physic.MilliKelvin {
t.Fatal(e.Temperature)
}
if e.Pressure != physic.Pascal {
t.Fatal(e.Pressure)
}
if e.Humidity != 0 {
t.Fatal(e.Humidity)
}
if err := bus.Close(); err != nil {
t.Fatal(err)
}
}
/*
func TestOversampling(t *testing.T) {
data := []struct {
o Oversampling
v int
s string
}{
{O1x, 1, "1x"},
{O2x, 2, "2x"},
{O4x, 4, "4x"},
{O8x, 8, "8x"},
{Oversampling(100), 0, "Oversampling(100)"},
}
for i, line := range data {
if s := line.o.String(); s != line.s {
t.Fatalf("#%d %s != %s", i, s, line.s)
}
}
}
*/
func TestCompensate180(t *testing.T) {
c := calibration180{
AC1: 408,
AC2: -72,
AC3: -14383,
AC4: 32741,
AC5: 32757,
AC6: 23153,
B1: 6190,
B2: 4,
MB: -32768,
MC: -8711,
MD: 2868,
}
if temp := c.compensateTemp(27898); temp != 150 {
t.Errorf("temperature is wrong, want %v, got %v", 150, temp)
}
if pressure := c.compensatePressure(23843, 27898, 0); pressure != 69964 {
t.Errorf("pressure is wrong, want %v, got %v", 69964, pressure)
}
}
func init() {
doSleep = func(time.Duration) {}
}