mirror of https://github.com/periph/devices
bh1750: Add support for ambient light sensor (#302)
parent
28f7e8009b
commit
80fb33f17d
@ -0,0 +1,140 @@
|
|||||||
|
// Copyright 2018 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 bh1750
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"periph.io/x/periph/conn/i2c"
|
||||||
|
"periph.io/x/periph/conn/physic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2CAddr i2c default address.
|
||||||
|
const I2CAddr uint16 = 0x23
|
||||||
|
|
||||||
|
// AlternativeI2CAddr i2c alternative address.
|
||||||
|
const AlternativeI2CAddr uint16 = 0x5c
|
||||||
|
|
||||||
|
// Resolution represents the measurements modes.
|
||||||
|
type Resolution uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ContinuousHighResMode start measurement at 1lx resolution. Measurement time is approx 120ms.
|
||||||
|
ContinuousHighResMode Resolution = 0x10
|
||||||
|
|
||||||
|
// ContinuousHighResMode2 start measurement at 0.5lx resolution. Measurement time is approx 120ms.
|
||||||
|
ContinuousHighResMode2 Resolution = 0x11
|
||||||
|
|
||||||
|
// ContinuousLowResMode start measurement at 4lx resolution. Measurement time is approx 16ms.
|
||||||
|
ContinuousLowResMode Resolution = 0x13
|
||||||
|
|
||||||
|
// OneTimeHighResMode measurement at 1lx resolution and the device is automatically set to Power Down after measurement.
|
||||||
|
OneTimeHighResMode Resolution = 0x20
|
||||||
|
|
||||||
|
// OneTimeHighResMode2 measurement at 0.5lx resolution and the device is automatically set to Power Down after measurement.
|
||||||
|
OneTimeHighResMode2 Resolution = 0x21
|
||||||
|
|
||||||
|
// OneTimeLowResMode measurement at 4lx resolution and the device is automatically set to Power Down after measurement.
|
||||||
|
OneTimeLowResMode Resolution = 0x23
|
||||||
|
|
||||||
|
safetyTimeout = 20 * time.Millisecond
|
||||||
|
)
|
||||||
|
|
||||||
|
// Map of timeouts for measurement type.
|
||||||
|
var timeout = map[Resolution]time.Duration{
|
||||||
|
ContinuousHighResMode: 120*time.Millisecond + safetyTimeout,
|
||||||
|
ContinuousHighResMode2: 120*time.Millisecond + safetyTimeout,
|
||||||
|
ContinuousLowResMode: 16*time.Millisecond + safetyTimeout,
|
||||||
|
OneTimeHighResMode: 120*time.Millisecond + safetyTimeout,
|
||||||
|
OneTimeHighResMode2: 120*time.Millisecond + safetyTimeout,
|
||||||
|
OneTimeLowResMode: 16*time.Millisecond + safetyTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode - device mode.
|
||||||
|
type Mode uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PowerDown - no active state.
|
||||||
|
PowerDown Mode = 0x00
|
||||||
|
|
||||||
|
// PowerOn - waiting for measurement command.
|
||||||
|
PowerOn Mode = 0x01
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dataRegister uint8 = 0x00
|
||||||
|
measurementTimeRegister uint8 = 0x45
|
||||||
|
reset uint8 = 0x07
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dev is a handler to bh1750 controller
|
||||||
|
type Dev struct {
|
||||||
|
dev i2c.Dev
|
||||||
|
res Resolution
|
||||||
|
mode Mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewI2C opens a handle to an bh1750 sensor.
|
||||||
|
//
|
||||||
|
// To use on the default address, bh1750.I2CAddr must be passed as argument.
|
||||||
|
func NewI2C(bus i2c.Bus, address uint16) (*Dev, error) {
|
||||||
|
dev := &Dev{dev: i2c.Dev{Bus: bus, Addr: address}}
|
||||||
|
|
||||||
|
if err := dev.init(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dev, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dev) init() error {
|
||||||
|
if err := d.SetMode(PowerOn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.SetResolution(ContinuousHighResMode); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := d.dev.Write([]byte{reset})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMode set the sleep mode of the sensor.
|
||||||
|
func (d *Dev) SetMode(m Mode) error {
|
||||||
|
d.mode = m
|
||||||
|
_, err := d.dev.Write([]byte{reset})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResolution set the resolution mode of the sensor.
|
||||||
|
func (d *Dev) SetResolution(r Resolution) error {
|
||||||
|
d.res = r
|
||||||
|
_, err := d.dev.Write([]byte{byte(r)})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sense reads the light value from the bh1750 sensor.
|
||||||
|
func (d *Dev) Sense() (physic.LuminousFlux, error) {
|
||||||
|
if err := d.SetResolution(d.res); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(timeout[d.res])
|
||||||
|
|
||||||
|
buf := [2]byte{}
|
||||||
|
if err := d.dev.Tx([]byte{byte(d.res)}, buf[:]); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rawValue := binary.BigEndian.Uint16(buf[:])
|
||||||
|
lux := physic.LuminousFlux(float64(rawValue) / 1.2)
|
||||||
|
return lux * physic.Lumen, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Halt turn off device.
|
||||||
|
func (d *Dev) Halt() error {
|
||||||
|
return d.SetMode(PowerDown)
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2018 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 bh1750 controls a ROHM BH1750 ambient light sensor, over an i2c bus.
|
||||||
|
//
|
||||||
|
// Datasheet
|
||||||
|
//
|
||||||
|
// http://cpre.kmutnb.ac.th/esl/learning/bh1750-light-sensor/bh1750fvi-e_datasheet.pdf
|
||||||
|
package bh1750
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2018 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 bh1750_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"periph.io/x/periph/conn/i2c/i2creg"
|
||||||
|
"periph.io/x/periph/experimental/devices/bh1750"
|
||||||
|
"periph.io/x/periph/host"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example() {
|
||||||
|
// Make sure periph is initialized.
|
||||||
|
if _, err := host.Init(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open default I²C bus.
|
||||||
|
bus, err := i2creg.Open("")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to open I²C: %v", err)
|
||||||
|
}
|
||||||
|
defer bus.Close()
|
||||||
|
|
||||||
|
// Create a new light sensor.
|
||||||
|
sensor, err := bh1750.NewI2C(bus, bh1750.I2CAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read value from sensor.
|
||||||
|
measurement, err := sensor.Sense()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(measurement)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue