This commit is contained in:
Kashyap Kopparam 2013-12-23 16:52:58 +05:30
commit 1746e906fe
3 changed files with 209 additions and 3 deletions

View File

@ -15,13 +15,13 @@ Use various sensors on the RaspberryPi with Golang (like a ninja!)
## Sensors supported
### BMP085
Barometric pressure sensor
[Documentation](http://godoc.org/github.com/kid0m4n/go-rpi/sensor/bmp085) [Datasheet](https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf)
### LSM303
Accelerometer and magnetometer
[Documentation](http://godoc.org/github.com/kid0m4n/go-rpi/sensor/lsm303) [Datasheet](https://www.sparkfun.com/datasheets/Sensors/Magneto/LSM303%20Datasheet.pdf)
@ -30,4 +30,10 @@ Use various sensors on the RaspberryPi with Golang (like a ninja!)
Ultrasonic proximity sensor
[Documentation](http://godoc.org/github.com/kid0m4n/go-rpi/sensor/us020) [Product Page](http://www.digibay.in/sensor/object-detection-and-proximity?product_id=239)
[Documentation](http://godoc.org/github.com/kid0m4n/go-rpi/sensor/us020) [Product Page](http://www.digibay.in/sensor/object-detection-and-proximity?product_id=239)
### BH1750FVI
Luminosity sensor
[Documentation](http://godoc.org/github.com/kid0m4n/go-rpi/sensor/us020) [Datasheet](http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf)

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(bh1750fvi.High, bus)
defer lightingSensor.Close()
for {
lighting, err := lightingSensor.Lighting()
if err != nil {
log.Panic(err)
}
log.Printf("Lighting is %v lx", lighting)
time.Sleep(500 * time.Millisecond)
}
}

View File

@ -0,0 +1,171 @@
// 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"
)
//accuracy = sensorValue/actualValue] (min = 0.96, typ = 1.2, max = 1.44
const (
High = "H"
High2 = "H2"
measurementAcuuracy = 1.2
defReadReg = 0x00
sensorI2cAddr = 0x23
highResOpCode = 0x10
highResMode2OpCode = 0x11
pollDelay = 150
)
// A BH1750FVI interface implements access to the sensor.
type BH1750FVI interface {
// Run starts continuous sensor data acquisition loop.
Run() error
// Lighting returns the ambient lighting in lx.
Lighting() (lighting float64, err error)
// Close.
Close()
// SetPollDelay sets the delay between run of data acquisition loop.
SetPollDelay(delay int)
}
type bh1750fvi struct {
bus i2c.Bus
mu *sync.RWMutex
lightingReadings chan float64
quit chan bool
i2cAddr byte
operationCode byte
poll int
}
// 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) BH1750FVI {
switch mode {
case High:
return &bh1750fvi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)}
case High2:
return &bh1750fvi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResMode2OpCode, mu: new(sync.RWMutex)}
default:
return &bh1750fvi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)}
}
}
// NewHighMode returns a BH1750FVI inteface on high resolution mode (1lx resolution)
func NewHighMode(bus i2c.Bus) BH1750FVI {
return New(High, bus)
}
// NewHighMode returns a BH1750FVI inteface on high resolution mode2 (0.5lx resolution)
func NewHigh2Mode(bus i2c.Bus) BH1750FVI {
return New(High2, bus)
}
func (d *bh1750fvi) measureLighting() (lighting float64, err error) {
err = d.bus.WriteByte(d.i2cAddr, d.operationCode)
if err != nil {
log.Print("bh1750fvi: Failed to initialize sensor")
return
}
time.Sleep(180 * time.Millisecond)
var sensorReading int
if sensorReading, err = d.bus.ReadInt(d.i2cAddr, defReadReg); err != nil {
return
}
lighting = float64(sensorReading) / measurementAcuuracy
return
}
// Lighting returns the ambient lighting in lx.
func (d *bh1750fvi) Lighting() (lighting float64, err error) {
select {
case lighting = <-d.lightingReadings:
return
default:
return d.measureLighting()
}
}
// Run starts continuous sensor data acquisition loop.
func (d *bh1750fvi) Run() (err error) {
go func() {
d.quit = make(chan bool)
timer := time.Tick(time.Duration(d.poll) * time.Millisecond)
var lighting float64
for {
select {
case d.lightingReadings <- lighting:
case <-timer:
if l, err := d.measureLighting(); err == nil {
lighting = l
}
if err == nil && d.lightingReadings == nil {
d.lightingReadings = make(chan float64)
}
case <-d.quit:
d.lightingReadings = nil
return
}
}
}()
return
}
// Close.
func (d *bh1750fvi) Close() {
if d.quit != nil {
d.quit <- true
}
return
}
// SetPollDelay sets the delay between run of data acquisition loop.
func (d *bh1750fvi) SetPollDelay(delay int) {
d.poll = delay
}
// SetPollDelay sets the delay between run of data acquisition loop.
func SetPollDelay(delay int) {
Default.SetPollDelay(delay)
}
// Lighting returns the ambient lighting in lx.
func Lighting() (lighting float64, err error) {
return Default.Lighting()
}
// Run starts continuous sensor data acquisition loop.
func Run() (err error) {
return Default.Run()
}
// Close.
func Close() {
Default.Close()
}