From 69655b6c0333dc33da5669191a073b639b7bc579 Mon Sep 17 00:00:00 2001 From: Cullen Jennings Date: Thu, 19 May 2016 19:48:57 -0600 Subject: [PATCH 1/3] Add basic support for INA219 current sensor --- CONTRIBUTORS | 1 + samples/.gitignore | 1 + samples/ina219.go | 49 +++++++++++++++ sensor/ina219/ina219.go | 131 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 samples/ina219.go create mode 100644 sensor/ina219/ina219.go diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f44d830..a4e1e42 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -6,3 +6,4 @@ Nikesh Vora Steve Beaulac Al S-M Ben Delarre +Cullen Jennings diff --git a/samples/.gitignore b/samples/.gitignore index af9b180..5158351 100644 --- a/samples/.gitignore +++ b/samples/.gitignore @@ -8,6 +8,7 @@ gpio gpiodetect gpiodirect gpioshort +ina219 l3gd20 led ledshort diff --git a/samples/ina219.go b/samples/ina219.go new file mode 100644 index 0000000..43de691 --- /dev/null +++ b/samples/ina219.go @@ -0,0 +1,49 @@ +// +build ignore + +package main + +import ( + "flag" + "fmt" + "time" + + "github.com/kidoman/embd" + "github.com/kidoman/embd/sensor/ina219" + + _ "github.com/kidoman/embd/host/all" +) + +func main() { + flag.Parse() + + if err := embd.InitI2C(); err != nil { + panic(err) + } + defer embd.CloseI2C() + + bus := embd.NewI2CBus(1) + + ina := ina219.New(bus, 0x40, 0.1) + defer ina.Close() + + for { + sv, err := ina.ShuntVoltage() + if err != nil { + panic(err) + } + + v, err := ina.Voltage() + if err != nil { + panic(err) + } + + c, err := ina.Current() + if err != nil { + panic(err) + } + + fmt.Printf("Shunt Voltage=%v Voltage=%v Current=%v\n", sv, v, c) + + time.Sleep(500 * time.Millisecond) + } +} diff --git a/sensor/ina219/ina219.go b/sensor/ina219/ina219.go new file mode 100644 index 0000000..5cc76c3 --- /dev/null +++ b/sensor/ina219/ina219.go @@ -0,0 +1,131 @@ +// Package ina219 allows interfacing with Texas Instruments INA219 current +// monitor. This is a high side current and voltage monitor with and I2C +// interfcace. + +// TODO - add options to config voltage range, sensitivity and averaging + +package ina219 + +import ( + "math" + "sync" + + "github.com/golang/glog" + "github.com/kidoman/embd" +) + +const ( + configReg = 0x00 + shuntVReg = 0x01 + busVReg = 0x02 + powerReg = 0x03 + currentReg = 0x04 + calibReg = 0x05 +) + +// INA219 represents a Bosch INA219 current sensor. +type INA219 struct { + Bus embd.I2CBus + + address byte + shuntResitance float64 + + initialized bool + mu sync.RWMutex +} + +func New(bus embd.I2CBus, addr byte, shunt float64) *INA219 { + ina := INA219{ + Bus: bus, + address: addr, + shuntResitance: shunt, + } + return &ina +} + +func (d *INA219) setup() error { + d.mu.RLock() + if d.initialized { + d.mu.RUnlock() + return nil + } + d.mu.RUnlock() + + d.mu.Lock() + defer d.mu.Unlock() + + config := uint16(0x219F) // 12, bit no integration, 32v bus range , 40mV shunt range + err := d.Bus.WriteWordToReg(d.address, configReg, config) + if err != nil { + return err + } + + calib := uint16(0.5 + 40.96/d.shuntResitance) + + err = d.Bus.WriteWordToReg(d.address, calibReg, calib) // .1 ohm sense resitor + if err != nil { + return err + } + + glog.V(1).Infof("ina219: initaliized") + + d.initialized = true + + return nil +} + +func (d *INA219) ShuntVoltage() (float64, error) { + if err := d.setup(); err != nil { + return math.NaN(), err + } + + v, err := d.Bus.ReadWordFromReg(d.address, shuntVReg) + if err != nil { + return math.NaN(), err + } + + voltage := float64(v) / 100000.0 + + return voltage, nil +} + +func (d *INA219) Voltage() (float64, error) { + if err := d.setup(); err != nil { + return math.NaN(), err + } + + v, err := d.Bus.ReadWordFromReg(d.address, busVReg) + if err != nil { + return math.NaN(), err + } + + voltage := float64(v>>3) / 250.0 + + return voltage, nil +} + +func (d *INA219) Current() (float64, error) { + if err := d.setup(); err != nil { + return math.NaN(), err + } + + v, err := d.Bus.ReadWordFromReg(d.address, currentReg) + if err != nil { + return math.NaN(), err + } + + current := float64(v) / 1000.0 + + return current, nil +} + +// Close +func (d *INA219) Close() error { + // put in power down mode + config := uint16(0x0000) + err := d.Bus.WriteWordToReg(d.address, configReg, config) + if err != nil { + return err + } + return nil +} From e87156263cdf33d930efc5fc438208f99a557112 Mon Sep 17 00:00:00 2001 From: Cullen Jennings Date: Sun, 22 May 2016 09:33:55 -0600 Subject: [PATCH 2/3] fix bug with negative currents and add Power --- samples/ina219.go | 9 +++++++-- sensor/ina219/ina219.go | 27 +++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/samples/ina219.go b/samples/ina219.go index 43de691..c73d963 100644 --- a/samples/ina219.go +++ b/samples/ina219.go @@ -23,7 +23,7 @@ func main() { bus := embd.NewI2CBus(1) - ina := ina219.New(bus, 0x40, 0.1) + ina := ina219.New(bus, 0x40, 0.001) defer ina.Close() for { @@ -42,7 +42,12 @@ func main() { panic(err) } - fmt.Printf("Shunt Voltage=%v Voltage=%v Current=%v\n", sv, v, c) + p, err := ina.Power() + if err != nil { + panic(err) + } + + fmt.Printf("Shunt Voltage=%v Voltage=%v Current=%v Power=%v \n", sv, v, c, p) time.Sleep(500 * time.Millisecond) } diff --git a/sensor/ina219/ina219.go b/sensor/ina219/ina219.go index 5cc76c3..795bdba 100644 --- a/sensor/ina219/ina219.go +++ b/sensor/ina219/ina219.go @@ -3,6 +3,7 @@ // interfcace. // TODO - add options to config voltage range, sensitivity and averaging +// TODO - add documentation package ina219 @@ -54,7 +55,10 @@ func (d *INA219) setup() error { d.mu.Lock() defer d.mu.Unlock() - config := uint16(0x219F) // 12, bit no integration, 32v bus range , 40mV shunt range + //config := uint16(0x219F) // 12, bit no integration, 32v bus range , 40mV shunt range + //config := uint16(0x2777) // 12, bit 64x integration, 32v bus range , 40mV shunt range + config := uint16(0x2F77) // 12, bit 64x integration, 32v bus range , 80mV shunt range + err := d.Bus.WriteWordToReg(d.address, configReg, config) if err != nil { return err @@ -62,7 +66,7 @@ func (d *INA219) setup() error { calib := uint16(0.5 + 40.96/d.shuntResitance) - err = d.Bus.WriteWordToReg(d.address, calibReg, calib) // .1 ohm sense resitor + err = d.Bus.WriteWordToReg(d.address, calibReg, calib) if err != nil { return err } @@ -84,7 +88,7 @@ func (d *INA219) ShuntVoltage() (float64, error) { return math.NaN(), err } - voltage := float64(v) / 100000.0 + voltage := float64( int16(v) ) / 100000.0 return voltage, nil } @@ -114,7 +118,22 @@ func (d *INA219) Current() (float64, error) { return math.NaN(), err } - current := float64(v) / 1000.0 + current := float64( int16(v) ) / 1000.0 + + return current, nil +} + +func (d *INA219) Power() (float64, error) { + if err := d.setup(); err != nil { + return math.NaN(), err + } + + v, err := d.Bus.ReadWordFromReg(d.address, powerReg) + if err != nil { + return math.NaN(), err + } + + current := float64( int16(v) ) / 50.0 return current, nil } From 802db1c399293f459c3a829f2fdd9e0c75a29562 Mon Sep 17 00:00:00 2001 From: Cullen Jennings Date: Sun, 22 May 2016 09:39:30 -0600 Subject: [PATCH 3/3] reformat --- sensor/ina219/ina219.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sensor/ina219/ina219.go b/sensor/ina219/ina219.go index 795bdba..88c0fd2 100644 --- a/sensor/ina219/ina219.go +++ b/sensor/ina219/ina219.go @@ -3,6 +3,7 @@ // interfcace. // TODO - add options to config voltage range, sensitivity and averaging +// TODO - Current and Power can overflow within normal ranges // TODO - add documentation package ina219 @@ -24,7 +25,7 @@ const ( calibReg = 0x05 ) -// INA219 represents a Bosch INA219 current sensor. +// INA219 represents an INA219 current sensor. type INA219 struct { Bus embd.I2CBus @@ -58,7 +59,7 @@ func (d *INA219) setup() error { //config := uint16(0x219F) // 12, bit no integration, 32v bus range , 40mV shunt range //config := uint16(0x2777) // 12, bit 64x integration, 32v bus range , 40mV shunt range config := uint16(0x2F77) // 12, bit 64x integration, 32v bus range , 80mV shunt range - + err := d.Bus.WriteWordToReg(d.address, configReg, config) if err != nil { return err @@ -66,7 +67,7 @@ func (d *INA219) setup() error { calib := uint16(0.5 + 40.96/d.shuntResitance) - err = d.Bus.WriteWordToReg(d.address, calibReg, calib) + err = d.Bus.WriteWordToReg(d.address, calibReg, calib) if err != nil { return err } @@ -88,7 +89,7 @@ func (d *INA219) ShuntVoltage() (float64, error) { return math.NaN(), err } - voltage := float64( int16(v) ) / 100000.0 + voltage := float64(int16(v)) / 100000.0 return voltage, nil } @@ -118,7 +119,7 @@ func (d *INA219) Current() (float64, error) { return math.NaN(), err } - current := float64( int16(v) ) / 1000.0 + current := float64(int16(v)) / 1000.0 return current, nil } @@ -133,7 +134,7 @@ func (d *INA219) Power() (float64, error) { return math.NaN(), err } - current := float64( int16(v) ) / 50.0 + current := float64(int16(v)) / 50.0 return current, nil }