bh1750: Add support for ambient light sensor (#302)

pull/1/head
Alvaro Viebrantz 8 years ago committed by M-A
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…
Cancel
Save