From 2ac61dad95f0a876e724671afefc5f07a6da4e54 Mon Sep 17 00:00:00 2001 From: Kunal Powar Date: Tue, 17 Dec 2013 20:37:58 +0530 Subject: [PATCH 1/4] Added Package and sample for bh1750Fvi --- samples/bh1750Fvi.go | 29 ++++++ sensor/bh1750Fvi/bh1750Fvi.go | 175 ++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 samples/bh1750Fvi.go create mode 100644 sensor/bh1750Fvi/bh1750Fvi.go diff --git a/samples/bh1750Fvi.go b/samples/bh1750Fvi.go new file mode 100644 index 0000000..b4badf6 --- /dev/null +++ b/samples/bh1750Fvi.go @@ -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) + } +} diff --git a/sensor/bh1750Fvi/bh1750Fvi.go b/sensor/bh1750Fvi/bh1750Fvi.go new file mode 100644 index 0000000..a2ba548 --- /dev/null +++ b/sensor/bh1750Fvi/bh1750Fvi.go @@ -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() +} From 898041c4ce1aca33cdebb7f66137bdc7b1921983 Mon Sep 17 00:00:00 2001 From: Kunal Powar Date: Fri, 20 Dec 2013 00:43:40 +0530 Subject: [PATCH 2/4] -Removed low resolution mode from bh1750fvi package -Fixed bugs with i2c commands used for data acquisition --- samples/bh1750Fvi.go | 6 +- sensor/bh1750Fvi/bh1750Fvi.go | 142 +++++++++++++++++----------------- 2 files changed, 72 insertions(+), 76 deletions(-) diff --git a/samples/bh1750Fvi.go b/samples/bh1750Fvi.go index b4badf6..c19b867 100644 --- a/samples/bh1750Fvi.go +++ b/samples/bh1750Fvi.go @@ -14,8 +14,7 @@ func main() { log.Panic(err) } - lightingSensor := bh1750Fvi.New("H", bus) - + lightingSensor := bh1750Fvi.New(bh1750Fvi.High, bus) defer lightingSensor.Close() for { @@ -23,7 +22,8 @@ func main() { if err != nil { log.Panic(err) } - log.Printf("Lighting is %v", lighting, "lx") + log.Printf("Lighting is %v lx", lighting) + time.Sleep(500 * time.Millisecond) } } diff --git a/sensor/bh1750Fvi/bh1750Fvi.go b/sensor/bh1750Fvi/bh1750Fvi.go index a2ba548..5558539 100644 --- a/sensor/bh1750Fvi/bh1750Fvi.go +++ b/sensor/bh1750Fvi/bh1750Fvi.go @@ -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 import ( @@ -9,28 +9,34 @@ import ( "github.com/kid0m4n/go-rpi/i2c" ) +//accuracy = sensorValue/actualValue] (min = 0.96, typ = 1.2, max = 1.44 const ( - measurementAcuuracy = 1.2 // [accuracy = sensorValue/actualValue] (min = 0.96, typ = 1.2, max = 1.44) + High = "H" + High2 = "H2" - highResolutionReadAddress = 0x23 - highResolutionOperationCode = 0x10 + measurementAcuuracy = 1.2 + defReadReg = 0x00 - lowResolutionReadAddress = 0x5c - lowResolutionOperationCode = 0x23 + sensorI2cAddr = 0x23 - highResolutionMode2ReadAddress = 0x23 - highResolutionMode2OperationCode = 0x11 + highResOpCode = 0x10 + highResMode2OpCode = 0x11 pollDelay = 150 ) +// A BH1750VI interface implements access to the sensor. 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) + // Close. Close() + // SetPollDelay sets the delay between run of data acquisition loop. SetPollDelay(delay int) } @@ -41,105 +47,89 @@ type bh1750vi struct { lightingReadings chan float64 quit chan bool - ready bool - - readRegisterAddress byte - operationCode byte - - continuousMode bool + i2cAddr byte + operationCode byte 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 { - - /* - 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} + case High: + return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)} + case High2: + return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResMode2OpCode, mu: new(sync.RWMutex)} 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) { - sensor.mu.Lock() +// NewHighMode returns a BH1750FVI inteface on high resolution mode (1lx resolution) +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. - sensor.mu.Unlock() - return - } +// NewHighMode returns a BH1750FVI inteface on high resolution mode2 (0.5lx resolution) +func NewHigh2Mode(bus i2c.Bus) BH1750VI { + return New(High2, bus) +} - defer sensor.mu.Unlock() - - err = sensor.bus.WriteByte(sensor.readRegisterAddress, sensor.operationCode) +func (d *bh1750vi) measureLighting() (lighting float64, err error) { + err = d.bus.WriteByte(d.i2cAddr, d.operationCode) if err != nil { log.Print("bh1750vi: Failed to initialize sensor") return } + time.Sleep(180 * time.Millisecond) - sensor.ready = true - return -} - -func (sensor *bh1750vi) measureLighting() (lighting float64, err error) { - if err = sensor.setup(); err != nil { + var sensorReading int + if sensorReading, err = d.bus.ReadInt(d.i2cAddr, defReadReg); 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) { +// Lighting returns the ambient lighting in lx. +func (d *bh1750vi) Lighting() (lighting float64, err error) { select { - case lighting = <-sensor.lightingReadings: + case lighting = <-d.lightingReadings: return 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() { - 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 for { select { - case sensor.lightingReadings <- lighting: + case d.lightingReadings <- lighting: case <-timer: - if l, err := sensor.measureLighting(); err == nil { + if l, err := d.measureLighting(); err == nil { lighting = l } - if err == nil && sensor.lightingReadings == nil { - sensor.lightingReadings = make(chan float64) + if err == nil && d.lightingReadings == nil { + d.lightingReadings = make(chan float64) } - case <-sensor.quit: - sensor.lightingReadings = nil + case <-d.quit: + d.lightingReadings = nil return } } @@ -147,29 +137,35 @@ func (sensor *bh1750vi) Start() (err error) { return } -func (sensor *bh1750vi) Close() { - if sensor.quit != nil { - sensor.quit <- true +// Close. +func (d *bh1750vi) Close() { + if d.quit != nil { + d.quit <- true } return } -func (sensor *bh1750vi) SetPollDelay(delay int) { - sensor.poll = delay +// SetPollDelay sets the delay between run of data acquisition loop. +func (d *bh1750vi) 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() } -func Start() (err error) { - return Default.Start() +// Run starts continuous sensor data acquisition loop. +func Run() (err error) { + return Default.Run() } +// Close. func Close() { Default.Close() } From c8d703cbdfb445e96da95d66e3968910326a057e Mon Sep 17 00:00:00 2001 From: Karan Misra Date: Sat, 21 Dec 2013 01:52:36 +0530 Subject: [PATCH 3/4] lowercase package name --- samples/{bh1750Fvi.go => bh1750fvi.go} | 4 +-- .../bh1750Fvi.go => bh1750fvi/bh1750fvi.go} | 32 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) rename samples/{bh1750Fvi.go => bh1750fvi.go} (78%) rename sensor/{bh1750Fvi/bh1750Fvi.go => bh1750fvi/bh1750fvi.go} (77%) diff --git a/samples/bh1750Fvi.go b/samples/bh1750fvi.go similarity index 78% rename from samples/bh1750Fvi.go rename to samples/bh1750fvi.go index c19b867..50dc54d 100644 --- a/samples/bh1750Fvi.go +++ b/samples/bh1750fvi.go @@ -5,7 +5,7 @@ import ( "time" "github.com/kid0m4n/go-rpi/i2c" - "github.com/kid0m4n/go-rpi/sensor/bh1750Fvi" + "github.com/kid0m4n/go-rpi/sensor/bh1750fvi" ) func main() { @@ -14,7 +14,7 @@ func main() { log.Panic(err) } - lightingSensor := bh1750Fvi.New(bh1750Fvi.High, bus) + lightingSensor := bh1750fvi.New(bh1750fvi.High, bus) defer lightingSensor.Close() for { diff --git a/sensor/bh1750Fvi/bh1750Fvi.go b/sensor/bh1750fvi/bh1750fvi.go similarity index 77% rename from sensor/bh1750Fvi/bh1750Fvi.go rename to sensor/bh1750fvi/bh1750fvi.go index 5558539..93c8d50 100644 --- a/sensor/bh1750Fvi/bh1750Fvi.go +++ b/sensor/bh1750fvi/bh1750fvi.go @@ -1,5 +1,5 @@ // Package BH1750FVI allows interfacing with the BH1750FVI ambient light sensor through I2C protocol. -package bh1750Fvi +package bh1750fvi import ( "log" @@ -25,8 +25,8 @@ const ( pollDelay = 150 ) -// A BH1750VI interface implements access to the sensor. -type BH1750VI interface { +// A BH1750FVI interface implements access to the sensor. +type BH1750FVI interface { // Run starts continuous sensor data acquisition loop. Run() error @@ -40,7 +40,7 @@ type BH1750VI interface { SetPollDelay(delay int) } -type bh1750vi struct { +type bh1750fvi struct { bus i2c.Bus mu *sync.RWMutex @@ -61,31 +61,31 @@ var Default = New(High, i2c.Default) // "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) BH1750FVI { switch mode { case High: - return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)} + return &bh1750fvi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)} case High2: - return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResMode2OpCode, mu: new(sync.RWMutex)} + return &bh1750fvi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResMode2OpCode, mu: new(sync.RWMutex)} default: - return &bh1750vi{bus: bus, i2cAddr: sensorI2cAddr, operationCode: highResOpCode, mu: new(sync.RWMutex)} + 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) BH1750VI { +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) BH1750VI { +func NewHigh2Mode(bus i2c.Bus) BH1750FVI { return New(High2, bus) } -func (d *bh1750vi) measureLighting() (lighting float64, err error) { +func (d *bh1750fvi) measureLighting() (lighting float64, err error) { err = d.bus.WriteByte(d.i2cAddr, d.operationCode) if err != nil { - log.Print("bh1750vi: Failed to initialize sensor") + log.Print("bh1750fvi: Failed to initialize sensor") return } time.Sleep(180 * time.Millisecond) @@ -100,7 +100,7 @@ func (d *bh1750vi) measureLighting() (lighting float64, err error) { } // Lighting returns the ambient lighting in lx. -func (d *bh1750vi) Lighting() (lighting float64, err error) { +func (d *bh1750fvi) Lighting() (lighting float64, err error) { select { case lighting = <-d.lightingReadings: return @@ -110,7 +110,7 @@ func (d *bh1750vi) Lighting() (lighting float64, err error) { } // Run starts continuous sensor data acquisition loop. -func (d *bh1750vi) Run() (err error) { +func (d *bh1750fvi) Run() (err error) { go func() { d.quit = make(chan bool) @@ -138,7 +138,7 @@ func (d *bh1750vi) Run() (err error) { } // Close. -func (d *bh1750vi) Close() { +func (d *bh1750fvi) Close() { if d.quit != nil { d.quit <- true } @@ -146,7 +146,7 @@ func (d *bh1750vi) Close() { } // SetPollDelay sets the delay between run of data acquisition loop. -func (d *bh1750vi) SetPollDelay(delay int) { +func (d *bh1750fvi) SetPollDelay(delay int) { d.poll = delay } From ece0e14ce24131b64eb09cd12d8acf31ad91476b Mon Sep 17 00:00:00 2001 From: Karan Misra Date: Sat, 21 Dec 2013 02:06:06 +0530 Subject: [PATCH 4/4] add the message about the bh1750fvi support --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5a2178f..45672d7 100644 --- a/README.md +++ b/README.md @@ -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) \ No newline at end of file + [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)