cleanup driver and sample, additional documentation
This commit is contained in:
parent
d3629908d4
commit
698d1685f0
|
@ -1,41 +1,49 @@
|
|||
package i2c
|
||||
|
||||
// INA3221Driver is a driver for the Texas Instruments INA3221 device. The INA3221 is a three-channel
|
||||
// current and bus voltage monitor with an I2C and SMBUS compatible interface.
|
||||
//
|
||||
// INA3221 data sheet and specifications can be found at http://www.ti.com/product/INA3221
|
||||
//
|
||||
// This module was tested with SwitchDoc Labs INA3221 breakout board found at http://www.switchdoc.com/
|
||||
|
||||
import (
|
||||
"gobot.io/x/gobot"
|
||||
)
|
||||
|
||||
type Channel uint8
|
||||
// INA3221Channel type that defines which INA3221 channel to read from.
|
||||
type INA3221Channel uint8
|
||||
|
||||
const (
|
||||
// I2C ADDRESS/BITS
|
||||
INA3221_ADDRESS uint8 = 0x40 //1000000 (A0+A1=GND)
|
||||
INA3221_READ uint8 = 0x01
|
||||
INA3221_REG_CONFIG uint8 = 0x00 // CONFIG REGISTER (R/W)
|
||||
INA3221_CONFIG_RESET uint16 = 0x8000 //Reset Bit
|
||||
INA3221_CONFIG_ENABLE_CHAN1 uint16 = 0x4000 //Enable Channel 1
|
||||
INA3221_CONFIG_ENABLE_CHAN2 uint16 = 0x2000 //Enable Channel 2
|
||||
INA3221_CONFIG_ENABLE_CHAN3 uint16 = 0x1000 //Enable Channel 3
|
||||
INA3221_CONFIG_AVG2 uint16 = 0x0800 //AVG Samples Bit 2 - See table 3 spec
|
||||
INA3221_CONFIG_AVG1 uint16 = 0x0400 //AVG Samples Bit 1 - See table 3 spec
|
||||
INA3221_CONFIG_AVG0 uint16 = 0x0200 //AVG Samples Bit 0 - See table 3 spec
|
||||
INA3221_CONFIG_VBUS_CT2 uint16 = 0x0100 //VBUS bit 2 Conversion time - See table 4 spec
|
||||
INA3221_CONFIG_VBUS_CT1 uint16 = 0x0080 //VBUS bit 1 Conversion time - See table 4 spec
|
||||
INA3221_CONFIG_VBUS_CT0 uint16 = 0x0040 //VBUS bit 0 Conversion time - See table 4 spec
|
||||
INA3221_CONFIG_VSH_CT2 uint16 = 0x0020 //Vshunt bit 2 Conversion time - See table 5 spec
|
||||
INA3221_CONFIG_VSH_CT1 uint16 = 0x0010 //Vshunt bit 1 Conversion time - See table 5 spec
|
||||
INA3221_CONFIG_VSH_CT0 uint16 = 0x0008 //Vshunt bit 0 Conversion time - See table 5 spec
|
||||
INA3221_CONFIG_MODE_2 uint16 = 0x0004 //Operating Mode bit 2 - See table 6 spec
|
||||
INA3221_CONFIG_MODE_1 uint16 = 0x0002 //Operating Mode bit 1 - See table 6 spec
|
||||
INA3221_CONFIG_MODE_0 uint16 = 0x0001 //Operating Mode bit 0 - See table 6 spec
|
||||
INA3221_REG_SHUNTVOLTAGE_1 uint8 = 0x01 // SHUNT VOLTAGE REGISTER (R)
|
||||
INA3221_REG_BUSVOLTAGE_1 uint8 = 0x02 // BUS VOLTAGE REGISTER (R)
|
||||
SHUNT_RESISTOR_VALUE float64 = 0.1 //default shunt resistor value of 0.1 Ohm
|
||||
ina3221Address uint8 = 0x40 // 1000000 (A0+A1=GND)
|
||||
ina3221Read uint8 = 0x01
|
||||
ina3221RegConfig uint8 = 0x00 // CONFIG REGISTER (R/W)
|
||||
ina3221ConfigReset uint16 = 0x8000 // Reset Bit
|
||||
ina3221ConfigEnableChan1 uint16 = 0x4000 // Enable INA3221 Channel 1
|
||||
ina3221ConfigEnableChan2 uint16 = 0x2000 // Enable INA3221 Channel 2
|
||||
ina3221ConfigEnableChan3 uint16 = 0x1000 // Enable INA3221 Channel 3
|
||||
ina3221ConfigAvg2 uint16 = 0x0800 // AVG Samples Bit 2 - See table 3 spec
|
||||
ina3221ConfigAvg1 uint16 = 0x0400 // AVG Samples Bit 1 - See table 3 spec
|
||||
ina3221ConfigAvg0 uint16 = 0x0200 // AVG Samples Bit 0 - See table 3 spec
|
||||
ina3221ConfigVBusCT2 uint16 = 0x0100 // VBUS bit 2 Conversion time - See table 4 spec
|
||||
ina3221ConfigVBusCT1 uint16 = 0x0080 // VBUS bit 1 Conversion time - See table 4 spec
|
||||
ina3221ConfigVBusCT0 uint16 = 0x0040 // VBUS bit 0 Conversion time - See table 4 spec
|
||||
ina3221ConfigVShCT2 uint16 = 0x0020 // Vshunt bit 2 Conversion time - See table 5 spec
|
||||
ina3221ConfigVShCT1 uint16 = 0x0010 // Vshunt bit 1 Conversion time - See table 5 spec
|
||||
ina3221ConfigVShCT0 uint16 = 0x0008 // Vshunt bit 0 Conversion time - See table 5 spec
|
||||
ina3221ConfigMode2 uint16 = 0x0004 // Operating Mode bit 2 - See table 6 spec
|
||||
ina3221ConfigMode1 uint16 = 0x0002 // Operating Mode bit 1 - See table 6 spec
|
||||
ina3221ConfigMode0 uint16 = 0x0001 // Operating Mode bit 0 - See table 6 spec
|
||||
ina3221RegShuntVoltage1 uint8 = 0x01 // SHUNT VOLTAGE REGISTER (R)
|
||||
ina3221RegBusVoltage1 uint8 = 0x02 // BUS VOLTAGE REGISTER (R)
|
||||
ina3221ShuntResistorValue float64 = 0.1 // default shunt resistor value of 0.1 Ohm
|
||||
|
||||
INA3221Channel1 Channel = 1
|
||||
INA3221Channel2 Channel = 2
|
||||
INA3221Channel3 Channel = 3
|
||||
INA3221Channel1 INA3221Channel = 1
|
||||
INA3221Channel2 INA3221Channel = 2
|
||||
INA3221Channel3 INA3221Channel = 3
|
||||
)
|
||||
|
||||
// INA3221Driver is a driver for the INA3221 three-channel current and bus voltage monitoring device.
|
||||
type INA3221Driver struct {
|
||||
name string
|
||||
connector Connector
|
||||
|
@ -44,11 +52,18 @@ type INA3221Driver struct {
|
|||
halt chan bool
|
||||
}
|
||||
|
||||
// NewINA3221Driver creates a new driver with the specified i2c interface.
|
||||
// Params:
|
||||
// conn Connector - the Adaptor to use with this Driver
|
||||
//
|
||||
// Optional params:
|
||||
// i2c.WithBus(int): bus to use with this driver
|
||||
// i2c.WithAddress(int): address to use with this driver
|
||||
func NewINA3221Driver(c Connector, options ...func(Config)) *INA3221Driver {
|
||||
i := &INA3221Driver{
|
||||
name: "Ina3221",
|
||||
name: gobot.DefaultName("INA3221"),
|
||||
connector: c,
|
||||
Config: NewConfig(),
|
||||
Config: NewConfig(),
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
|
@ -77,7 +92,7 @@ func (i *INA3221Driver) Connection() gobot.Connection {
|
|||
func (i *INA3221Driver) Start() error {
|
||||
var err error
|
||||
bus := i.GetBusOrDefault(i.connector.GetDefaultBus())
|
||||
address := i.GetAddressOrDefault(int(INA3221_ADDRESS))
|
||||
address := i.GetAddressOrDefault(int(ina3221Address))
|
||||
|
||||
if i.connection, err = i.connector.GetConnection(address, bus); err != nil {
|
||||
return err
|
||||
|
@ -96,7 +111,7 @@ func (i *INA3221Driver) Halt() error {
|
|||
}
|
||||
|
||||
// GetBusVoltage gets the bus voltage in Volts
|
||||
func (i *INA3221Driver) GetBusVoltage(channel Channel) (float64, error) {
|
||||
func (i *INA3221Driver) GetBusVoltage(channel INA3221Channel) (float64, error) {
|
||||
value, err := i.getBusVoltageRaw(channel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -106,7 +121,7 @@ func (i *INA3221Driver) GetBusVoltage(channel Channel) (float64, error) {
|
|||
}
|
||||
|
||||
// GetShuntVoltage Gets the shunt voltage in mV
|
||||
func (i *INA3221Driver) GetShuntVoltage(channel Channel) (float64, error) {
|
||||
func (i *INA3221Driver) GetShuntVoltage(channel INA3221Channel) (float64, error) {
|
||||
value, err := i.getShuntVoltageRaw(channel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -116,18 +131,18 @@ func (i *INA3221Driver) GetShuntVoltage(channel Channel) (float64, error) {
|
|||
}
|
||||
|
||||
// GetCurrent gets the current value in mA, taking into account the config settings and current LSB
|
||||
func (i *INA3221Driver) GetCurrent(channel Channel) (float64, error) {
|
||||
func (i *INA3221Driver) GetCurrent(channel INA3221Channel) (float64, error) {
|
||||
value, err := i.GetShuntVoltage(channel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
ma := value / SHUNT_RESISTOR_VALUE
|
||||
ma := value / ina3221ShuntResistorValue
|
||||
return ma, nil
|
||||
}
|
||||
|
||||
// GetLoadVoltage gets the load voltage in mV
|
||||
func (i *INA3221Driver) GetLoadVoltage(channel Channel) (float64, error) {
|
||||
func (i *INA3221Driver) GetLoadVoltage(channel INA3221Channel) (float64, error) {
|
||||
bv, err := i.GetBusVoltage(channel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -142,46 +157,56 @@ func (i *INA3221Driver) GetLoadVoltage(channel Channel) (float64, error) {
|
|||
}
|
||||
|
||||
// getBusVoltageRaw gets the raw bus voltage (16-bit signed integer, so +-32767)
|
||||
func (i *INA3221Driver) getBusVoltageRaw(channel Channel) (int16, error) {
|
||||
val, err := i.connection.ReadWordData(INA3221_REG_BUSVOLTAGE_1 + (uint8(channel)-1)*2)
|
||||
func (i *INA3221Driver) getBusVoltageRaw(channel INA3221Channel) (uint16, error) {
|
||||
val, err := i.readWordFromRegister(ina3221RegBusVoltage1 + (uint8(channel)-1)*2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
value := int32(val)
|
||||
value := uint32(val)
|
||||
if value > 0x7FFF {
|
||||
value -= 0x10000
|
||||
}
|
||||
|
||||
return int16(value), nil
|
||||
return uint16(value), nil
|
||||
}
|
||||
|
||||
// getShuntVoltageRaw gets the raw shunt voltage (16-bit signed integer, so +-32767)
|
||||
func (i *INA3221Driver) getShuntVoltageRaw(channel Channel) (int16, error) {
|
||||
v, err := i.connection.ReadWordData(INA3221_REG_SHUNTVOLTAGE_1 + (uint8(channel)-1)*2)
|
||||
func (i *INA3221Driver) getShuntVoltageRaw(channel INA3221Channel) (uint16, error) {
|
||||
val, err := i.readWordFromRegister(ina3221RegShuntVoltage1 + (uint8(channel)-1)*2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
value := int32(v)
|
||||
value := uint32(val)
|
||||
if value > 0x7FFF {
|
||||
value -= 0x10000
|
||||
}
|
||||
|
||||
return int16(value), nil
|
||||
return uint16(value), nil
|
||||
}
|
||||
|
||||
// initialize initializes the device
|
||||
// reads word from supplied register address
|
||||
func (i *INA3221Driver) readWordFromRegister(reg uint8) (uint16, error) {
|
||||
val, err := i.connection.ReadWordData(reg)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return uint16((val << 8) | ((val >> 8) & 0xFF)), nil
|
||||
}
|
||||
|
||||
// initialize initializes the INA3221 device
|
||||
func (i *INA3221Driver) initialize() error {
|
||||
config := INA3221_CONFIG_ENABLE_CHAN1 |
|
||||
INA3221_CONFIG_ENABLE_CHAN2 |
|
||||
INA3221_CONFIG_ENABLE_CHAN3 |
|
||||
INA3221_CONFIG_AVG1 |
|
||||
INA3221_CONFIG_VBUS_CT2 |
|
||||
INA3221_CONFIG_VSH_CT2 |
|
||||
INA3221_CONFIG_MODE_2 |
|
||||
INA3221_CONFIG_MODE_1 |
|
||||
INA3221_CONFIG_MODE_0
|
||||
config := ina3221ConfigEnableChan1 |
|
||||
ina3221ConfigEnableChan2 |
|
||||
ina3221ConfigEnableChan3 |
|
||||
ina3221ConfigAvg1 |
|
||||
ina3221ConfigVBusCT2 |
|
||||
ina3221ConfigVShCT2 |
|
||||
ina3221ConfigMode2 |
|
||||
ina3221ConfigMode1 |
|
||||
ina3221ConfigMode0
|
||||
|
||||
return i.connection.WriteWordData(INA3221_REG_CONFIG, config)
|
||||
return i.connection.WriteWordData(ina3221RegConfig, config)
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@ package i2c
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"errors"
|
||||
"gobot.io/x/gobot"
|
||||
"gobot.io/x/gobot/gobottest"
|
||||
"errors"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
var _ gobot.Driver = (*INA3221Driver)(nil)
|
||||
|
||||
func initTestINA3221Driver() (*INA3221Driver) {
|
||||
func initTestINA3221Driver() *INA3221Driver {
|
||||
d, _ := initTestINA3221DriverWithStubbedAdaptor()
|
||||
return d
|
||||
}
|
||||
|
@ -56,21 +55,3 @@ func TestINA3221Driver_Halt(t *testing.T) {
|
|||
d := initTestINA3221Driver()
|
||||
gobottest.Assert(t, d.Halt(), nil)
|
||||
}
|
||||
|
||||
//func TestINA3221Driver_Measurements(t *testing.T) {
|
||||
// d, a := initTestINA3221DriverWithStubbedAdaptor()
|
||||
// a.i2cReadImpl = func(b []byte) (int, error) {
|
||||
// buf := new(bytes.Buffer)
|
||||
// if a.written[len(a.written)-1] == INA3221_REG_BUSVOLTAGE_1 {
|
||||
// buf.Write([]byte{0x09, 0x33})
|
||||
// }
|
||||
// copy(b, buf.Bytes())
|
||||
// return buf.Len(), nil
|
||||
// }
|
||||
//
|
||||
// d.Start()
|
||||
//
|
||||
// bv, err := d.GetBusVoltage(INA3221Channel1)
|
||||
// gobottest.Assert(t, err, nil)
|
||||
// t.Logf("bv1: %f", bv)
|
||||
//}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gobot.io/x/gobot"
|
||||
"gobot.io/x/gobot/drivers/i2c"
|
||||
"gobot.io/x/gobot/platforms/raspi"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -17,33 +17,35 @@ func main() {
|
|||
work := func() {
|
||||
|
||||
gobot.Every(5*time.Second, func() {
|
||||
bv, err := ina.GetBusVoltage(i2c.INA3221Channel1)
|
||||
if err != nil {
|
||||
for _, ch := range []i2c.INA3221Channel{i2c.INA3221Channel1, i2c.INA3221Channel2, i2c.INA3221Channel3} {
|
||||
val, err := ina.GetBusVoltage(ch)
|
||||
if err != nil {
|
||||
fmt.Printf("INA3221Channel %v Bus Voltage error: %v\n", ch, err)
|
||||
}
|
||||
fmt.Printf("INA3221Channel %v Bus Voltage: %fV\n", ch, val)
|
||||
|
||||
val, err = ina.GetShuntVoltage(ch)
|
||||
if err != nil {
|
||||
fmt.Printf("INA3221Channel %v Shunt Voltage error: %v\n", ch, err)
|
||||
}
|
||||
fmt.Printf("INA3221Channel %v Shunt Voltage: %fV\n", ch, val)
|
||||
|
||||
val, err = ina.GetCurrent(ch)
|
||||
if err != nil {
|
||||
fmt.Printf("INA3221Channel %v Current error: %v\n", ch, err)
|
||||
}
|
||||
fmt.Printf("INA3221Channel %v Current: %fmA\n", ch, val)
|
||||
|
||||
val, err = ina.GetLoadVoltage(ch)
|
||||
if err != nil {
|
||||
fmt.Printf("INA3221Channel %v Load Voltage error: %v\n", ch, err)
|
||||
}
|
||||
fmt.Printf("INA3221Channel %v Load Voltage: %fV\n", ch, val)
|
||||
}
|
||||
log.Printf("Ch 1 Bus Voltage: %f", bv)
|
||||
|
||||
sv, err := ina.GetShuntVoltage(i2c.INA3221Channel1)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
log.Printf("Ch 1 Shunt Voltage: %f", sv)
|
||||
|
||||
ma, err := ina.GetCurrent(i2c.INA3221Channel1)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
log.Printf("Ch 1 Current: %f", ma)
|
||||
|
||||
lv, err := ina.GetLoadVoltage(i2c.INA3221Channel1)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
log.Printf("Ch 1 Load Voltage: %f", lv)
|
||||
})
|
||||
}
|
||||
|
||||
robot := gobot.NewRobot("ina3221Robot",
|
||||
robot := gobot.NewRobot("INA3221 Robot",
|
||||
[]gobot.Connection{r},
|
||||
[]gobot.Device{ina},
|
||||
work,
|
||||
|
|
Loading…
Reference in New Issue