-Removed low resolution mode from bh1750fvi package

-Fixed bugs with i2c commands used for data acquisition
This commit is contained in:
Kunal Powar 2013-12-20 00:43:40 +05:30
parent 2ac61dad95
commit 898041c4ce
2 changed files with 72 additions and 76 deletions

View File

@ -14,8 +14,7 @@ func main() {
log.Panic(err) log.Panic(err)
} }
lightingSensor := bh1750Fvi.New("H", bus) lightingSensor := bh1750Fvi.New(bh1750Fvi.High, bus)
defer lightingSensor.Close() defer lightingSensor.Close()
for { for {
@ -23,7 +22,8 @@ func main() {
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
log.Printf("Lighting is %v", lighting, "lx") log.Printf("Lighting is %v lx", lighting)
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
} }
} }

View File

@ -1,4 +1,4 @@
// Package BH1750FVI allows interfacing with the BH1750FVI ambient light sensor through I2C protocol // Package BH1750FVI allows interfacing with the BH1750FVI ambient light sensor through I2C protocol.
package bh1750Fvi package bh1750Fvi
import ( import (
@ -9,28 +9,34 @@ import (
"github.com/kid0m4n/go-rpi/i2c" "github.com/kid0m4n/go-rpi/i2c"
) )
//accuracy = sensorValue/actualValue] (min = 0.96, typ = 1.2, max = 1.44
const ( const (
measurementAcuuracy = 1.2 // [accuracy = sensorValue/actualValue] (min = 0.96, typ = 1.2, max = 1.44) High = "H"
High2 = "H2"
highResolutionReadAddress = 0x23 measurementAcuuracy = 1.2
highResolutionOperationCode = 0x10 defReadReg = 0x00
lowResolutionReadAddress = 0x5c sensorI2cAddr = 0x23
lowResolutionOperationCode = 0x23
highResolutionMode2ReadAddress = 0x23 highResOpCode = 0x10
highResolutionMode2OperationCode = 0x11 highResMode2OpCode = 0x11
pollDelay = 150 pollDelay = 150
) )
// A BH1750VI interface implements access to the sensor.
type BH1750VI interface { type BH1750VI interface {
Start() error // Run starts continuous sensor data acquisition loop.
Run() error
// Lighting returns the ambient lighting in lx.
Lighting() (lighting float64, err error) Lighting() (lighting float64, err error)
// Close.
Close() Close()
// SetPollDelay sets the delay between run of data acquisition loop.
SetPollDelay(delay int) SetPollDelay(delay int)
} }
@ -41,105 +47,89 @@ type bh1750vi struct {
lightingReadings chan float64 lightingReadings chan float64
quit chan bool quit chan bool
ready bool i2cAddr byte
operationCode byte
readRegisterAddress byte
operationCode byte
continuousMode bool
poll int poll int
} }
var Default = New("H", i2c.Default) // Default instance for BH1750FVI sensor
var Default = New(High, i2c.Default)
// Supports three modes:
// "H" -> High resolution mode (1lx), takes 120ms (recommended).
// "H2" -> High resolution mode 2 (0.5lx), takes 120ms (only use for low light).
// New creates a new BH1750FVI interface according to the mode passed.
func New(mode string, bus i2c.Bus) BH1750VI { 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 { switch mode {
case "L": case High:
return &bh1750vi{bus: bus, readRegisterAddress: lowResolutionReadAddress, operationCode: lowResolutionOperationCode, continuousMode: false} return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)}
case "H": case High2:
return &bh1750vi{bus: bus, readRegisterAddress: highResolutionReadAddress, operationCode: highResolutionOperationCode, continuousMode: true} return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResMode2OpCode, mu: new(sync.RWMutex)}
case "H2":
return &bh1750vi{bus: bus, readRegisterAddress: highResolutionMode2ReadAddress, operationCode: highResolutionMode2OperationCode, continuousMode: true}
default: default:
return &bh1750vi{bus: bus, readRegisterAddress: highResolutionReadAddress, operationCode: highResolutionOperationCode, continuousMode: true} return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)}
} }
} }
func (sensor *bh1750vi) setup() (err error) { // NewHighMode returns a BH1750FVI inteface on high resolution mode (1lx resolution)
sensor.mu.Lock() func NewHighMode(bus i2c.Bus) BH1750VI {
return New(High, bus)
}
if sensor.ready && sensor.continuousMode { //for Low resolution mode sensor has to be initialized for every read. // NewHighMode returns a BH1750FVI inteface on high resolution mode2 (0.5lx resolution)
sensor.mu.Unlock() func NewHigh2Mode(bus i2c.Bus) BH1750VI {
return return New(High2, bus)
} }
defer sensor.mu.Unlock() func (d *bh1750vi) measureLighting() (lighting float64, err error) {
err = d.bus.WriteByte(d.i2cAddr, d.operationCode)
err = sensor.bus.WriteByte(sensor.readRegisterAddress, sensor.operationCode)
if err != nil { if err != nil {
log.Print("bh1750vi: Failed to initialize sensor") log.Print("bh1750vi: Failed to initialize sensor")
return return
} }
time.Sleep(180 * time.Millisecond)
sensor.ready = true var sensorReading int
return if sensorReading, err = d.bus.ReadInt(d.i2cAddr, defReadReg); err != nil {
}
func (sensor *bh1750vi) measureLighting() (lighting float64, err error) {
if err = sensor.setup(); err != nil {
return 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 lighting = float64(sensorReading) / measurementAcuuracy
return return
} }
func (sensor *bh1750vi) Lighting() (lighting float64, err error) { // Lighting returns the ambient lighting in lx.
func (d *bh1750vi) Lighting() (lighting float64, err error) {
select { select {
case lighting = <-sensor.lightingReadings: case lighting = <-d.lightingReadings:
return return
default: default:
return sensor.measureLighting() return d.measureLighting()
} }
} }
func (sensor *bh1750vi) Start() (err error) { // Run starts continuous sensor data acquisition loop.
func (d *bh1750vi) Run() (err error) {
go func() { go func() {
sensor.quit = make(chan bool) d.quit = make(chan bool)
timer := time.Tick(time.Duration(sensor.poll) * time.Millisecond) timer := time.Tick(time.Duration(d.poll) * time.Millisecond)
var lighting float64 var lighting float64
for { for {
select { select {
case sensor.lightingReadings <- lighting: case d.lightingReadings <- lighting:
case <-timer: case <-timer:
if l, err := sensor.measureLighting(); err == nil { if l, err := d.measureLighting(); err == nil {
lighting = l lighting = l
} }
if err == nil && sensor.lightingReadings == nil { if err == nil && d.lightingReadings == nil {
sensor.lightingReadings = make(chan float64) d.lightingReadings = make(chan float64)
} }
case <-sensor.quit: case <-d.quit:
sensor.lightingReadings = nil d.lightingReadings = nil
return return
} }
} }
@ -147,29 +137,35 @@ func (sensor *bh1750vi) Start() (err error) {
return return
} }
func (sensor *bh1750vi) Close() { // Close.
if sensor.quit != nil { func (d *bh1750vi) Close() {
sensor.quit <- true if d.quit != nil {
d.quit <- true
} }
return return
} }
func (sensor *bh1750vi) SetPollDelay(delay int) { // SetPollDelay sets the delay between run of data acquisition loop.
sensor.poll = delay func (d *bh1750vi) SetPollDelay(delay int) {
d.poll = delay
} }
// SetPollDelay sets the delay between run of data acquisition loop.
func SetPollDelay(delay int) { func SetPollDelay(delay int) {
Default.SetPollDelay(delay) Default.SetPollDelay(delay)
} }
// Lighting returns the ambient lighting in lx.
func Lighting() (lighting float64, err error) { func Lighting() (lighting float64, err error) {
return Default.Lighting() return Default.Lighting()
} }
func Start() (err error) { // Run starts continuous sensor data acquisition loop.
return Default.Start() func Run() (err error) {
return Default.Run()
} }
// Close.
func Close() { func Close() {
Default.Close() Default.Close()
} }