Added Package and sample for bh1750Fvi

This commit is contained in:
Kunal Powar 2013-12-17 20:37:58 +05:30
parent 65b32143cf
commit 2ac61dad95
2 changed files with 204 additions and 0 deletions

29
samples/bh1750Fvi.go Normal file
View File

@ -0,0 +1,29 @@
package main
import (
"log"
"time"
"github.com/kid0m4n/go-rpi/i2c"
"github.com/kid0m4n/go-rpi/sensor/bh1750Fvi"
)
func main() {
bus, err := i2c.NewBus(1)
if err != nil {
log.Panic(err)
}
lightingSensor := bh1750Fvi.New("H", bus)
defer lightingSensor.Close()
for {
lighting, err := lightingSensor.Lighting()
if err != nil {
log.Panic(err)
}
log.Printf("Lighting is %v", lighting, "lx")
time.Sleep(500 * time.Millisecond)
}
}

View File

@ -0,0 +1,175 @@
// Package BH1750FVI allows interfacing with the BH1750FVI ambient light sensor through I2C protocol
package bh1750Fvi
import (
"log"
"sync"
"time"
"github.com/kid0m4n/go-rpi/i2c"
)
const (
measurementAcuuracy = 1.2 // [accuracy = sensorValue/actualValue] (min = 0.96, typ = 1.2, max = 1.44)
highResolutionReadAddress = 0x23
highResolutionOperationCode = 0x10
lowResolutionReadAddress = 0x5c
lowResolutionOperationCode = 0x23
highResolutionMode2ReadAddress = 0x23
highResolutionMode2OperationCode = 0x11
pollDelay = 150
)
type BH1750VI interface {
Start() error
Lighting() (lighting float64, err error)
Close()
SetPollDelay(delay int)
}
type bh1750vi struct {
bus i2c.Bus
mu *sync.RWMutex
lightingReadings chan float64
quit chan bool
ready bool
readRegisterAddress byte
operationCode byte
continuousMode bool
poll int
}
var Default = New("H", i2c.Default)
func New(mode string, bus i2c.Bus) BH1750VI {
/*
Supports three modes:
"L" -> Low resolution mode (4lx), takes 16ms
"H" -> High resolution mode (1lx), takes 120ms (recommended)
"H2" -> High resolution mode 2 (0.5lx), takes 120ms (only use for low light)
*/
switch mode {
case "L":
return &bh1750vi{bus: bus, readRegisterAddress: lowResolutionReadAddress, operationCode: lowResolutionOperationCode, continuousMode: false}
case "H":
return &bh1750vi{bus: bus, readRegisterAddress: highResolutionReadAddress, operationCode: highResolutionOperationCode, continuousMode: true}
case "H2":
return &bh1750vi{bus: bus, readRegisterAddress: highResolutionMode2ReadAddress, operationCode: highResolutionMode2OperationCode, continuousMode: true}
default:
return &bh1750vi{bus: bus, readRegisterAddress: highResolutionReadAddress, operationCode: highResolutionOperationCode, continuousMode: true}
}
}
func (sensor *bh1750vi) setup() (err error) {
sensor.mu.Lock()
if sensor.ready && sensor.continuousMode { //for Low resolution mode sensor has to be initialized for every read.
sensor.mu.Unlock()
return
}
defer sensor.mu.Unlock()
err = sensor.bus.WriteByte(sensor.readRegisterAddress, sensor.operationCode)
if err != nil {
log.Print("bh1750vi: Failed to initialize sensor")
return
}
sensor.ready = true
return
}
func (sensor *bh1750vi) measureLighting() (lighting float64, err error) {
if err = sensor.setup(); err != nil {
return
}
sensorData := make([]byte, 2)
if err = sensor.bus.ReadFromReg(sensor.readRegisterAddress, sensor.operationCode, sensorData); err != nil {
return
}
sensorReading := (int16(sensorData[0] << 8)) | (int16(sensorData[1]))
lighting = float64(sensorReading) / measurementAcuuracy
return
}
func (sensor *bh1750vi) Lighting() (lighting float64, err error) {
select {
case lighting = <-sensor.lightingReadings:
return
default:
return sensor.measureLighting()
}
}
func (sensor *bh1750vi) Start() (err error) {
go func() {
sensor.quit = make(chan bool)
timer := time.Tick(time.Duration(sensor.poll) * time.Millisecond)
var lighting float64
for {
select {
case sensor.lightingReadings <- lighting:
case <-timer:
if l, err := sensor.measureLighting(); err == nil {
lighting = l
}
if err == nil && sensor.lightingReadings == nil {
sensor.lightingReadings = make(chan float64)
}
case <-sensor.quit:
sensor.lightingReadings = nil
return
}
}
}()
return
}
func (sensor *bh1750vi) Close() {
if sensor.quit != nil {
sensor.quit <- true
}
return
}
func (sensor *bh1750vi) SetPollDelay(delay int) {
sensor.poll = delay
}
func SetPollDelay(delay int) {
Default.SetPollDelay(delay)
}
func Lighting() (lighting float64, err error) {
return Default.Lighting()
}
func Start() (err error) {
return Default.Start()
}
func Close() {
Default.Close()
}