mirror of
https://github.com/kidoman/embd
synced 2024-12-22 12:50:19 +01:00
- use glog instead of Debug flag
- use glog instead of log - make code conform to the Go code guidelines
This commit is contained in:
parent
ca17879e6e
commit
9ab49745bc
@ -2,8 +2,9 @@
|
|||||||
package mcp4725
|
package mcp4725
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,9 +26,6 @@ type MCP4725 struct {
|
|||||||
|
|
||||||
initialized bool
|
initialized bool
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
// Debug turns on additional debug output.
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new MCP4725 sensor.
|
// New creates a new MCP4725 sensor.
|
||||||
@ -38,33 +36,32 @@ func New(bus embd.I2CBus, addr byte) *MCP4725 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *MCP4725) setup() (err error) {
|
func (d *MCP4725) setup() error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
if d.initialized {
|
if d.initialized {
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
|
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(1).Infof("mcp4725: general call reset")
|
||||||
log.Print("mcp4725: general call reset")
|
|
||||||
|
if err := d.Bus.WriteByteToReg(d.Addr, 0x00, powerUp); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, 0x00, powerUp); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, 0x00, genReset); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, 0x00, genReset); err != nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
d.initialized = true
|
d.initialized = true
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *MCP4725) setVoltage(voltage int, reg byte) (err error) {
|
func (d *MCP4725) setVoltage(voltage int, reg byte) error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if voltage > 4095 {
|
if voltage > 4095 {
|
||||||
voltage = 4095
|
voltage = 4095
|
||||||
@ -72,33 +69,32 @@ func (d *MCP4725) setVoltage(voltage int, reg byte) (err error) {
|
|||||||
if voltage < 0 {
|
if voltage < 0 {
|
||||||
voltage = 0
|
voltage = 0
|
||||||
}
|
}
|
||||||
if d.Debug {
|
|
||||||
log.Printf("mcp4725: setting voltage to %04d", voltage)
|
glog.V(2).Infof("mcp4725: setting voltage to %04d", voltage)
|
||||||
|
|
||||||
|
if err := d.Bus.WriteWordToReg(d.Addr, reg, uint16(voltage<<4)); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err = d.Bus.WriteWordToReg(d.Addr, reg, uint16(voltage<<4)); err != nil {
|
return nil
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVoltage sets the output voltage.
|
// SetVoltage sets the output voltage.
|
||||||
func (d *MCP4725) SetVoltage(voltage int) (err error) {
|
func (d *MCP4725) SetVoltage(voltage int) error {
|
||||||
return d.setVoltage(voltage, dacReg)
|
return d.setVoltage(voltage, dacReg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPersistedVoltage sets the voltage and programs the EEPROM so
|
// SetPersistedVoltage sets the voltage and programs the EEPROM so
|
||||||
// that the voltage is restored on reboot.
|
// that the voltage is restored on reboot.
|
||||||
func (d *MCP4725) SetPersistedVoltage(voltage int) (err error) {
|
func (d *MCP4725) SetPersistedVoltage(voltage int) error {
|
||||||
return d.setVoltage(voltage, programReg)
|
return d.setVoltage(voltage, programReg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close puts the DAC into power down mode.
|
// Close puts the DAC into power down mode.
|
||||||
func (d *MCP4725) Close() (err error) {
|
func (d *MCP4725) Close() error {
|
||||||
if d.Debug {
|
glog.V(1).Infof("mcp4725: powering down")
|
||||||
log.Print("mcp4725: powering down")
|
|
||||||
|
if err := d.Bus.WriteWordToReg(d.Addr, powerDown, 0); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err = d.Bus.WriteWordToReg(d.Addr, powerDown, 0); err != nil {
|
return nil
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
package pca9685
|
package pca9685
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
"github.com/kidoman/embd/util"
|
"github.com/kidoman/embd/util"
|
||||||
)
|
)
|
||||||
@ -34,8 +34,6 @@ type PCA9685 struct {
|
|||||||
|
|
||||||
initialized bool
|
initialized bool
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new PCA9685 interface.
|
// New creates a new PCA9685 interface.
|
||||||
@ -50,11 +48,11 @@ func (d *PCA9685) mode1Reg() (byte, error) {
|
|||||||
return d.Bus.ReadByteFromReg(d.Addr, mode1RegAddr)
|
return d.Bus.ReadByteFromReg(d.Addr, mode1RegAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PCA9685) setup() (err error) {
|
func (d *PCA9685) setup() error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
if d.initialized {
|
if d.initialized {
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
|
|
||||||
@ -63,56 +61,49 @@ func (d *PCA9685) setup() (err error) {
|
|||||||
|
|
||||||
mode1Reg, err := d.mode1Reg()
|
mode1Reg, err := d.mode1Reg()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: read MODE1 Reg [regAddr: %#02x] Value: [%v]", mode1RegAddr, mode1Reg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = d.sleep(); err != nil {
|
glog.V(1).Infof("pca9685: read MODE1 Reg [regAddr: %#02x] Value: [%v]", mode1RegAddr, mode1Reg)
|
||||||
return
|
|
||||||
|
if err := d.sleep(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Freq == 0 {
|
if d.Freq == 0 {
|
||||||
d.Freq = defaultFreq
|
d.Freq = defaultFreq
|
||||||
}
|
}
|
||||||
preScaleValue := byte(math.Floor(float64(clockFreq/(pwmControlPoints*d.Freq))+float64(0.5)) - 1)
|
preScaleValue := byte(math.Floor(float64(clockFreq/(pwmControlPoints*d.Freq))+float64(0.5)) - 1)
|
||||||
if d.Debug {
|
glog.V(1).Infof("pca9685: calculated prescale value = %#02x", preScaleValue)
|
||||||
log.Printf("pca9685: calculated prescale value = %#02x", preScaleValue)
|
if err := d.Bus.WriteByteToReg(d.Addr, preScaleRegAddr, byte(preScaleValue)); err != nil {
|
||||||
}
|
return err
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, preScaleRegAddr, byte(preScaleValue)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: prescale value [%#02x] written to PRE_SCALE Reg [regAddr: %#02x]", preScaleValue, preScaleRegAddr)
|
|
||||||
}
|
}
|
||||||
|
glog.V(1).Infof("pca9685: prescale value [%#02x] written to PRE_SCALE Reg [regAddr: %#02x]", preScaleValue, preScaleRegAddr)
|
||||||
|
|
||||||
if err = d.wake(); err != nil {
|
if err := d.wake(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newmode := ((mode1Reg | 0x01) & 0xDF)
|
newmode := ((mode1Reg | 0x01) & 0xDF)
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, newmode); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, newmode); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: new mode [%#02x] [disabling register auto increment] written to MODE1 Reg [regAddr: %#02x]", newmode, mode1RegAddr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glog.V(1).Infof("pca9685: new mode [%#02x] [disabling register auto increment] written to MODE1 Reg [regAddr: %#02x]", newmode, mode1RegAddr)
|
||||||
|
|
||||||
d.initialized = true
|
d.initialized = true
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: driver initialized with pwm freq: %v", d.Freq)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
glog.V(1).Infof("pca9685: driver initialized with pwm freq: %v", d.Freq)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPwm sets the ON and OFF time registers for pwm signal shaping.
|
// SetPwm sets the ON and OFF time registers for pwm signal shaping.
|
||||||
// channel: 0-15
|
// channel: 0-15
|
||||||
// onTime/offTime: 0-4095
|
// onTime/offTime: 0-4095
|
||||||
func (d *PCA9685) SetPwm(channel, onTime, offTime int) (err error) {
|
func (d *PCA9685) SetPwm(channel, onTime, offTime int) error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
onTimeLowReg := byte(pwm0OnLowReg + (4 * channel))
|
onTimeLowReg := byte(pwm0OnLowReg + (4 * channel))
|
||||||
@ -122,161 +113,136 @@ func (d *PCA9685) SetPwm(channel, onTime, offTime int) (err error) {
|
|||||||
offTimeLow := byte(offTime & 0xFF)
|
offTimeLow := byte(offTime & 0xFF)
|
||||||
offTimeHigh := byte(offTime >> 8)
|
offTimeHigh := byte(offTime >> 8)
|
||||||
|
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, onTimeLowReg, onTimeLow); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, onTimeLowReg, onTimeLow); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: writing on-time low [%#02x] to CHAN%v_ON_L reg [reg: %#02x]", onTimeLow, channel, onTimeLowReg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glog.V(2).Infof("pca9685: writing on-time low [%#02x] to CHAN%v_ON_L reg [reg: %#02x]", onTimeLow, channel, onTimeLowReg)
|
||||||
|
|
||||||
onTimeHighReg := onTimeLowReg + 1
|
onTimeHighReg := onTimeLowReg + 1
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, onTimeHighReg, onTimeHigh); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, onTimeHighReg, onTimeHigh); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: writing on-time high [%#02x] to CHAN%v_ON_H reg [reg: %#02x]", onTimeHigh, channel, onTimeHighReg)
|
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("pca9685: writing on-time high [%#02x] to CHAN%v_ON_H reg [reg: %#02x]", onTimeHigh, channel, onTimeHighReg)
|
||||||
|
|
||||||
offTimeLowReg := onTimeHighReg + 1
|
offTimeLowReg := onTimeHighReg + 1
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, offTimeLowReg, offTimeLow); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, offTimeLowReg, offTimeLow); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: writing off-time low [%#02x] to CHAN%v_OFF_L reg [reg: %#02x]", offTimeLow, channel, offTimeLowReg)
|
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("pca9685: writing off-time low [%#02x] to CHAN%v_OFF_L reg [reg: %#02x]", offTimeLow, channel, offTimeLowReg)
|
||||||
|
|
||||||
offTimeHighReg := offTimeLowReg + 1
|
offTimeHighReg := offTimeLowReg + 1
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, offTimeHighReg, offTimeHigh); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, offTimeHighReg, offTimeHigh); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: writing off-time high [%#02x] to CHAN%v_OFF_H reg [reg: %#02x]", offTimeHigh, channel, offTimeHighReg)
|
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("pca9685: writing off-time high [%#02x] to CHAN%v_OFF_H reg [reg: %#02x]", offTimeHigh, channel, offTimeHighReg)
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMicroseconds is a convinience method which allows easy servo control.
|
// SetMicroseconds is a convinience method which allows easy servo control.
|
||||||
func (d *PCA9685) SetMicroseconds(channel, us int) (err error) {
|
func (d *PCA9685) SetMicroseconds(channel, us int) error {
|
||||||
offTime := us * d.Freq * pwmControlPoints / 1000000
|
offTime := us * d.Freq * pwmControlPoints / 1000000
|
||||||
return d.SetPwm(channel, 0, offTime)
|
return d.SetPwm(channel, 0, offTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAnalog is a convinience method which allows easy manipulation of the PWM
|
// SetAnalog is a convinience method which allows easy manipulation of the PWM
|
||||||
// based on a (0-255) range value.
|
// based on a (0-255) range value.
|
||||||
func (d *PCA9685) SetAnalog(channel int, value byte) (err error) {
|
func (d *PCA9685) SetAnalog(channel int, value byte) error {
|
||||||
offTime := util.Map(int64(value), minAnalogValue, maxAnalogValue, 0, pwmControlPoints-1)
|
offTime := util.Map(int64(value), minAnalogValue, maxAnalogValue, 0, pwmControlPoints-1)
|
||||||
return d.SetPwm(channel, 0, int(offTime))
|
return d.SetPwm(channel, 0, int(offTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close stops the controller and resets mode and pwm controller registers.
|
// Close stops the controller and resets mode and pwm controller registers.
|
||||||
func (d *PCA9685) Close() (err error) {
|
func (d *PCA9685) Close() error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = d.sleep(); err != nil {
|
if err := d.sleep(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(1).Infof("pca9685: reset request received")
|
||||||
log.Println("pca9685: reset request received")
|
|
||||||
|
if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, 0x00); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, 0x00); err != nil {
|
glog.V(1).Infof("pca9685: cleaning up all PWM control registers")
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: cleaning up all PWM control registers")
|
|
||||||
}
|
|
||||||
|
|
||||||
for regAddr := 0x06; regAddr <= 0x45; regAddr++ {
|
for regAddr := 0x06; regAddr <= 0x45; regAddr++ {
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, byte(regAddr), 0x00); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, byte(regAddr), 0x00); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Debug {
|
if glog.V(1) {
|
||||||
log.Printf("pca9685: done Cleaning up all PWM control registers")
|
glog.Infof("pca9685: done Cleaning up all PWM control registers")
|
||||||
|
glog.Infof("pca9685: controller reset")
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Debug {
|
return nil
|
||||||
log.Println("pca9685: controller reset")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PCA9685) sleep() (err error) {
|
func (d *PCA9685) sleep() error {
|
||||||
if d.Debug {
|
glog.V(1).Infof("pca9685: sleep request received")
|
||||||
log.Println("pca9685: sleep request received")
|
|
||||||
}
|
|
||||||
|
|
||||||
mode1Reg, err := d.mode1Reg()
|
mode1Reg, err := d.mode1Reg()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
sleepmode := (mode1Reg & 0x7F) | 0x10
|
sleepmode := (mode1Reg & 0x7F) | 0x10
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, sleepmode); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, sleepmode); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if d.Debug {
|
if glog.V(1) {
|
||||||
log.Printf("pca9685: sleep mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", sleepmode, mode1RegAddr)
|
glog.Infof("pca9685: sleep mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", sleepmode, mode1RegAddr)
|
||||||
|
glog.Infoln("pca9685: controller set to Sleep mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Debug {
|
return nil
|
||||||
log.Println("pca9685: controller set to Sleep mode")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep puts the controller in sleep mode. Does not change the pwm control registers.
|
// Sleep puts the controller in sleep mode. Does not change the pwm control registers.
|
||||||
func (d *PCA9685) Sleep() (err error) {
|
func (d *PCA9685) Sleep() error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.sleep()
|
return d.sleep()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *PCA9685) wake() (err error) {
|
func (d *PCA9685) wake() error {
|
||||||
if d.Debug {
|
glog.V(1).Infoln("pca9685: wake request received")
|
||||||
log.Println("pca9685: wake request received")
|
|
||||||
}
|
|
||||||
|
|
||||||
mode1Reg, err := d.mode1Reg()
|
mode1Reg, err := d.mode1Reg()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
wakeMode := mode1Reg & 0xEF
|
wakeMode := mode1Reg & 0xEF
|
||||||
if (mode1Reg & 0x80) == 0x80 {
|
if (mode1Reg & 0x80) == 0x80 {
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, wakeMode); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, wakeMode); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: wake mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", wakeMode, mode1RegAddr)
|
|
||||||
}
|
}
|
||||||
|
glog.V(1).Infof("pca9685: wake mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", wakeMode, mode1RegAddr)
|
||||||
|
|
||||||
time.Sleep(500 * time.Microsecond)
|
time.Sleep(500 * time.Microsecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
restartOpCode := wakeMode | 0x80
|
restartOpCode := wakeMode | 0x80
|
||||||
if err = d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, restartOpCode); err != nil {
|
if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, restartOpCode); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("pca9685: restart mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", restartOpCode, mode1RegAddr)
|
|
||||||
}
|
}
|
||||||
|
glog.V(1).Infof("pca9685: restart mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", restartOpCode, mode1RegAddr)
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wake allows the controller to exit sleep mode and resume with PWM generation.
|
// Wake allows the controller to exit sleep mode and resume with PWM generation.
|
||||||
func (d *PCA9685) Wake() (err error) {
|
func (d *PCA9685) Wake() error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.wake()
|
return d.wake()
|
||||||
|
@ -5,17 +5,15 @@ package servoblaster
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServoBlaster represents a software RPi PWM/PCM based servo control module.
|
// ServoBlaster represents a software RPi PWM/PCM based servo control module.
|
||||||
type ServoBlaster struct {
|
type ServoBlaster struct {
|
||||||
initialized bool
|
initialized bool
|
||||||
fd *os.File
|
fd *os.File
|
||||||
|
|
||||||
// Debug level.
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new ServoBlaster instance.
|
// New creates a new ServoBlaster instance.
|
||||||
@ -23,34 +21,33 @@ func New() *ServoBlaster {
|
|||||||
return &ServoBlaster{}
|
return &ServoBlaster{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ServoBlaster) setup() (err error) {
|
func (d *ServoBlaster) setup() error {
|
||||||
if d.initialized {
|
if d.initialized {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
if d.fd, err = os.OpenFile("/dev/servoblaster", os.O_WRONLY, os.ModeExclusive); err != nil {
|
if d.fd, err = os.OpenFile("/dev/servoblaster", os.O_WRONLY, os.ModeExclusive); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.initialized = true
|
d.initialized = true
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMicroseconds sends a command to the PWM driver to generate a us wide pulse.
|
// SetMicroseconds sends a command to the PWM driver to generate a us wide pulse.
|
||||||
func (d *ServoBlaster) SetMicroseconds(channel, us int) (err error) {
|
func (d *ServoBlaster) SetMicroseconds(channel, us int) error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
cmd := fmt.Sprintf("%v=%vus\n", channel, us)
|
cmd := fmt.Sprintf("%v=%vus\n", channel, us)
|
||||||
if d.Debug {
|
glog.V(1).Infof("servoblaster: sending command %q", cmd)
|
||||||
log.Printf("servoblaster: sending command %q", cmd)
|
_, err := d.fd.WriteString(cmd)
|
||||||
}
|
return err
|
||||||
_, err = d.fd.WriteString(cmd)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the open driver handle.
|
// Close closes the open driver handle.
|
||||||
func (d *ServoBlaster) Close() (err error) {
|
func (d *ServoBlaster) Close() error {
|
||||||
if d.fd != nil {
|
if d.fd != nil {
|
||||||
err = d.fd.Close()
|
return d.fd.Close()
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
package servo
|
package servo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"github.com/kidoman/embd/util"
|
"github.com/kidoman/embd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,8 +21,6 @@ type Servo struct {
|
|||||||
Channel int
|
Channel int
|
||||||
|
|
||||||
Minus, Maxus int
|
Minus, Maxus int
|
||||||
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Servo interface.
|
// New creates a new Servo interface.
|
||||||
@ -40,9 +37,7 @@ func New(pwm PWM, channel int) *Servo {
|
|||||||
func (s *Servo) SetAngle(angle int) error {
|
func (s *Servo) SetAngle(angle int) error {
|
||||||
us := util.Map(int64(angle), 0, 180, int64(s.Minus), int64(s.Maxus))
|
us := util.Map(int64(angle), 0, 180, int64(s.Minus), int64(s.Maxus))
|
||||||
|
|
||||||
if s.Debug {
|
glog.V(1).Infof("servo: given angle %v calculated %v us", angle, us)
|
||||||
log.Printf("servo: given angle %v calculated %v us", angle, us)
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.PWM.SetMicroseconds(s.Channel, int(us))
|
return s.PWM.SetMicroseconds(s.Channel, int(us))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
@ -26,7 +26,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Lighting is %v lx", lighting)
|
fmt.Printf("Lighting is %v lx\n", lighting)
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
@ -24,19 +24,19 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
temp, err := baro.Temperature()
|
temp, err := baro.Temperature()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Temp is %v", temp)
|
fmt.Printf("Temp is %v\n", temp)
|
||||||
pressure, err := baro.Pressure()
|
pressure, err := baro.Pressure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Pressure is %v", pressure)
|
fmt.Printf("Pressure is %v\n", pressure)
|
||||||
altitude, err := baro.Altitude()
|
altitude, err := baro.Altitude()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Altitude is %v", altitude)
|
fmt.Printf("Altitude is %v\n", altitude)
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
@ -24,19 +24,19 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
temp, err := baro.Temperature()
|
temp, err := baro.Temperature()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Temp is %v", temp)
|
fmt.Printf("Temp is %v\n", temp)
|
||||||
pressure, err := baro.Pressure()
|
pressure, err := baro.Pressure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Pressure is %v", pressure)
|
fmt.Printf("Pressure is %v\n", pressure)
|
||||||
altitude, err := baro.Altitude()
|
altitude, err := baro.Altitude()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Altitude is %v", altitude)
|
fmt.Printf("Altitude is %v\n", altitude)
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
@ -21,7 +21,6 @@ func main() {
|
|||||||
bus := embd.NewI2CBus(1)
|
bus := embd.NewI2CBus(1)
|
||||||
|
|
||||||
gyro := l3gd20.New(bus, l3gd20.R250DPS)
|
gyro := l3gd20.New(bus, l3gd20.R250DPS)
|
||||||
gyro.Debug = true
|
|
||||||
defer gyro.Close()
|
defer gyro.Close()
|
||||||
|
|
||||||
gyro.Start()
|
gyro.Start()
|
||||||
@ -31,7 +30,7 @@ func main() {
|
|||||||
|
|
||||||
orientations, err := gyro.Orientations()
|
orientations, err := gyro.Orientations()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
timer := time.Tick(250 * time.Millisecond)
|
timer := time.Tick(250 * time.Millisecond)
|
||||||
@ -40,7 +39,7 @@ func main() {
|
|||||||
select {
|
select {
|
||||||
case <-timer:
|
case <-timer:
|
||||||
orientation := <-orientations
|
orientation := <-orientations
|
||||||
log.Printf("x: %v, y: %v, z: %v", orientation.X, orientation.Y, orientation.Z)
|
fmt.Printf("x: %v, y: %v, z: %v\n", orientation.X, orientation.Y, orientation.Z)
|
||||||
case <-quit:
|
case <-quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
@ -24,9 +24,9 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
heading, err := mems.Heading()
|
heading, err := mems.Heading()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Heading is %v", heading)
|
fmt.Printf("Heading is %v\n", heading)
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -33,7 +33,7 @@ func main() {
|
|||||||
default:
|
default:
|
||||||
voltage := rand.Intn(4096)
|
voltage := rand.Intn(4096)
|
||||||
if err := dac.SetVoltage(voltage); err != nil {
|
if err := dac.SetVoltage(voltage); err != nil {
|
||||||
log.Printf("mcp4725: %v", err)
|
fmt.Printf("mcp4725: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
@ -22,11 +21,10 @@ func main() {
|
|||||||
|
|
||||||
pca9685 := pca9685.New(bus, 0x41)
|
pca9685 := pca9685.New(bus, 0x41)
|
||||||
pca9685.Freq = 1000
|
pca9685.Freq = 1000
|
||||||
pca9685.Debug = true
|
|
||||||
defer pca9685.Close()
|
defer pca9685.Close()
|
||||||
|
|
||||||
if err := pca9685.SetPwm(15, 0, 2000); err != nil {
|
if err := pca9685.SetPwm(15, 0, 2000); err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
|
@ -22,11 +22,9 @@ func main() {
|
|||||||
|
|
||||||
pwm := pca9685.New(bus, 0x41)
|
pwm := pca9685.New(bus, 0x41)
|
||||||
pwm.Freq = 50
|
pwm.Freq = 50
|
||||||
pwm.Debug = true
|
|
||||||
defer pwm.Close()
|
defer pwm.Close()
|
||||||
|
|
||||||
servo := servo.New(pwm, 0)
|
servo := servo.New(pwm, 0)
|
||||||
servo.Debug = true
|
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt, os.Kill)
|
signal.Notify(c, os.Interrupt, os.Kill)
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
@ -14,11 +13,9 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
sb := servoblaster.New()
|
sb := servoblaster.New()
|
||||||
sb.Debug = true
|
|
||||||
defer sb.Close()
|
defer sb.Close()
|
||||||
|
|
||||||
servo := servo.New(sb, 0)
|
servo := servo.New(sb, 0)
|
||||||
servo.Debug = true
|
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt, os.Kill)
|
signal.Notify(c, os.Interrupt, os.Kill)
|
||||||
@ -43,7 +40,7 @@ func main() {
|
|||||||
err = servo.SetAngle(135)
|
err = servo.SetAngle(135)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
case <-c:
|
case <-c:
|
||||||
return
|
return
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
@ -21,8 +21,8 @@ func main() {
|
|||||||
|
|
||||||
sensor := tmp006.New(bus, 0x40)
|
sensor := tmp006.New(bus, 0x40)
|
||||||
if status, err := sensor.Present(); err != nil || !status {
|
if status, err := sensor.Present(); err != nil || !status {
|
||||||
log.Print("tmp006: not found")
|
fmt.Println("tmp006: not found")
|
||||||
log.Print(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer sensor.Close()
|
defer sensor.Close()
|
||||||
@ -35,9 +35,9 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case temp := <-sensor.ObjTemps():
|
case temp := <-sensor.ObjTemps():
|
||||||
log.Printf("tmp006: got obj temp %.2f", temp)
|
fmt.Printf("tmp006: got obj temp %.2f\n", temp)
|
||||||
case temp := <-sensor.RawDieTemps():
|
case temp := <-sensor.RawDieTemps():
|
||||||
log.Printf("tmp006: got die temp %.2f", temp)
|
fmt.Printf("tmp006: got die temp %.2f\n", temp)
|
||||||
case <-stop:
|
case <-stop:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
@ -31,9 +31,9 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
distance, err := rf.Distance()
|
distance, err := rf.Distance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("Distance is %v", distance)
|
fmt.Printf("Distance is %v\n", distance)
|
||||||
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
package bh1750fvi
|
package bh1750fvi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -61,35 +60,32 @@ func NewHigh2Mode(bus embd.I2CBus) *BH1750FVI {
|
|||||||
return New(High2, bus)
|
return New(High2, bus)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BH1750FVI) measureLighting() (lighting float64, err error) {
|
func (d *BH1750FVI) measureLighting() (float64, error) {
|
||||||
err = d.Bus.WriteByte(d.i2cAddr, d.operationCode)
|
if err := d.Bus.WriteByte(d.i2cAddr, d.operationCode); err != nil {
|
||||||
if err != nil {
|
return 0, err
|
||||||
log.Print("bh1750fvi: Failed to initialize sensor")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
time.Sleep(180 * time.Millisecond)
|
time.Sleep(180 * time.Millisecond)
|
||||||
|
|
||||||
var reading uint16
|
reading, err := d.Bus.ReadWordFromReg(d.i2cAddr, defReadReg)
|
||||||
if reading, err = d.Bus.ReadWordFromReg(d.i2cAddr, defReadReg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
lighting = float64(int16(reading)) / measurementAcuuracy
|
return float64(int16(reading)) / measurementAcuuracy, nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lighting returns the ambient lighting in lx.
|
// Lighting returns the ambient lighting in lx.
|
||||||
func (d *BH1750FVI) Lighting() (lighting float64, err error) {
|
func (d *BH1750FVI) Lighting() (float64, error) {
|
||||||
select {
|
select {
|
||||||
case lighting = <-d.lightingReadings:
|
case lighting := <-d.lightingReadings:
|
||||||
return
|
return lighting, nil
|
||||||
default:
|
default:
|
||||||
return d.measureLighting()
|
return d.measureLighting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts continuous sensor data acquisition loop.
|
// Run starts continuous sensor data acquisition loop.
|
||||||
func (d *BH1750FVI) Run() (err error) {
|
func (d *BH1750FVI) Run() {
|
||||||
go func() {
|
go func() {
|
||||||
d.quit = make(chan bool)
|
d.quit = make(chan bool)
|
||||||
|
|
||||||
@ -101,7 +97,8 @@ func (d *BH1750FVI) Run() (err error) {
|
|||||||
select {
|
select {
|
||||||
case d.lightingReadings <- lighting:
|
case d.lightingReadings <- lighting:
|
||||||
case <-timer:
|
case <-timer:
|
||||||
if l, err := d.measureLighting(); err == nil {
|
l, err := d.measureLighting()
|
||||||
|
if err == nil {
|
||||||
lighting = l
|
lighting = l
|
||||||
}
|
}
|
||||||
if err == nil && d.lightingReadings == nil {
|
if err == nil && d.lightingReadings == nil {
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
package bmp085
|
package bmp085
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,8 +43,6 @@ type BMP085 struct {
|
|||||||
Bus embd.I2CBus
|
Bus embd.I2CBus
|
||||||
Poll int
|
Poll int
|
||||||
|
|
||||||
Debug bool
|
|
||||||
|
|
||||||
oss uint
|
oss uint
|
||||||
|
|
||||||
ac1, ac2, ac3 int16
|
ac1, ac2, ac3 int16
|
||||||
@ -65,109 +63,109 @@ func New(bus embd.I2CBus) *BMP085 {
|
|||||||
return &BMP085{Bus: bus, Poll: pollDelay}
|
return &BMP085{Bus: bus, Poll: pollDelay}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) calibrate() (err error) {
|
func (d *BMP085) calibrate() error {
|
||||||
d.cmu.RLock()
|
d.cmu.RLock()
|
||||||
if d.calibrated {
|
if d.calibrated {
|
||||||
d.cmu.RUnlock()
|
d.cmu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.cmu.RUnlock()
|
d.cmu.RUnlock()
|
||||||
|
|
||||||
d.cmu.Lock()
|
d.cmu.Lock()
|
||||||
defer d.cmu.Unlock()
|
defer d.cmu.Unlock()
|
||||||
|
|
||||||
readInt16 := func(reg byte) (value int16, err error) {
|
readInt16 := func(reg byte) (int16, error) {
|
||||||
var v uint16
|
v, err := d.Bus.ReadWordFromReg(address, reg)
|
||||||
if v, err = d.Bus.ReadWordFromReg(address, reg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
value = int16(v)
|
return int16(v), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readUInt16 := func(reg byte) (value uint16, err error) {
|
readUInt16 := func(reg byte) (uint16, error) {
|
||||||
var v uint16
|
v, err := d.Bus.ReadWordFromReg(address, reg)
|
||||||
if v, err = d.Bus.ReadWordFromReg(address, reg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
value = uint16(v)
|
return uint16(v), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
d.ac1, err = readInt16(calAc1)
|
d.ac1, err = readInt16(calAc1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac2, err = readInt16(calAc2)
|
d.ac2, err = readInt16(calAc2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac3, err = readInt16(calAc3)
|
d.ac3, err = readInt16(calAc3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac4, err = readUInt16(calAc4)
|
d.ac4, err = readUInt16(calAc4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac5, err = readUInt16(calAc5)
|
d.ac5, err = readUInt16(calAc5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac6, err = readUInt16(calAc6)
|
d.ac6, err = readUInt16(calAc6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.b1, err = readInt16(calB1)
|
d.b1, err = readInt16(calB1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.b2, err = readInt16(calB2)
|
d.b2, err = readInt16(calB2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.mb, err = readInt16(calMB)
|
d.mb, err = readInt16(calMB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.mc, err = readInt16(calMC)
|
d.mc, err = readInt16(calMC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.md, err = readInt16(calMD)
|
d.md, err = readInt16(calMD)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.calibrated = true
|
d.calibrated = true
|
||||||
|
|
||||||
if d.Debug {
|
if glog.V(1) {
|
||||||
log.Print("bmp085: calibration data retrieved")
|
glog.Info("bmp085: calibration data retrieved")
|
||||||
log.Printf("bmp085: param AC1 = %v", d.ac1)
|
glog.Infof("bmp085: param AC1 = %v", d.ac1)
|
||||||
log.Printf("bmp085: param AC2 = %v", d.ac2)
|
glog.Infof("bmp085: param AC2 = %v", d.ac2)
|
||||||
log.Printf("bmp085: param AC3 = %v", d.ac3)
|
glog.Infof("bmp085: param AC3 = %v", d.ac3)
|
||||||
log.Printf("bmp085: param AC4 = %v", d.ac4)
|
glog.Infof("bmp085: param AC4 = %v", d.ac4)
|
||||||
log.Printf("bmp085: param AC5 = %v", d.ac5)
|
glog.Infof("bmp085: param AC5 = %v", d.ac5)
|
||||||
log.Printf("bmp085: param AC6 = %v", d.ac6)
|
glog.Infof("bmp085: param AC6 = %v", d.ac6)
|
||||||
log.Printf("bmp085: param B1 = %v", d.b1)
|
glog.Infof("bmp085: param B1 = %v", d.b1)
|
||||||
log.Printf("bmp085: param B2 = %v", d.b2)
|
glog.Infof("bmp085: param B2 = %v", d.b2)
|
||||||
log.Printf("bmp085: param MB = %v", d.mb)
|
glog.Infof("bmp085: param MB = %v", d.mb)
|
||||||
log.Printf("bmp085: param MC = %v", d.mc)
|
glog.Infof("bmp085: param MC = %v", d.mc)
|
||||||
log.Printf("bmp085: param MD = %v", d.md)
|
glog.Infof("bmp085: param MD = %v", d.md)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) readUncompensatedTemp() (temp uint16, err error) {
|
func (d *BMP085) readUncompensatedTemp() (uint16, error) {
|
||||||
if err = d.Bus.WriteByteToReg(address, control, readTempCmd); err != nil {
|
if err := d.Bus.WriteByteToReg(address, control, readTempCmd); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
time.Sleep(tempReadDelay)
|
time.Sleep(tempReadDelay)
|
||||||
if temp, err = d.Bus.ReadWordFromReg(address, tempData); err != nil {
|
temp, err := d.Bus.ReadWordFromReg(address, tempData)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) calcTemp(utemp uint16) uint16 {
|
func (d *BMP085) calcTemp(utemp uint16) uint16 {
|
||||||
@ -181,69 +179,59 @@ func (d *BMP085) calcTemp(utemp uint16) uint16 {
|
|||||||
return uint16((d.b5 + 8) >> 4)
|
return uint16((d.b5 + 8) >> 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) measureTemp() (temp uint16, err error) {
|
func (d *BMP085) measureTemp() (uint16, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var utemp uint16
|
utemp, err := d.readUncompensatedTemp()
|
||||||
if utemp, err = d.readUncompensatedTemp(); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: uncompensated temp: %v", utemp)
|
||||||
log.Printf("bcm085: uncompensated temp: %v", utemp)
|
temp := d.calcTemp(utemp)
|
||||||
}
|
glog.V(1).Infof("bcm085: compensated temp %v", temp)
|
||||||
temp = d.calcTemp(utemp)
|
return temp, nil
|
||||||
if d.Debug {
|
|
||||||
log.Printf("bcm085: compensated temp %v", temp)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temperature returns the current temperature reading.
|
// Temperature returns the current temperature reading.
|
||||||
func (d *BMP085) Temperature() (temp float64, err error) {
|
func (d *BMP085) Temperature() (float64, error) {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case t := <-d.temps:
|
case t := <-d.temps:
|
||||||
temp = float64(t) / 10
|
temp := float64(t) / 10
|
||||||
return
|
return temp, nil
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: no temps available... measuring")
|
||||||
log.Print("bcm085: no temps available... measuring")
|
t, err := d.measureTemp()
|
||||||
}
|
|
||||||
var t uint16
|
|
||||||
t, err = d.measureTemp()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
temp = float64(t) / 10
|
temp := float64(t) / 10
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) readUncompensatedPressure() (pressure uint32, err error) {
|
func (d *BMP085) readUncompensatedPressure() (uint32, error) {
|
||||||
if err = d.Bus.WriteByteToReg(address, control, byte(readPressureCmd+(d.oss<<6))); err != nil {
|
if err := d.Bus.WriteByteToReg(address, control, byte(readPressureCmd+(d.oss<<6))); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
time.Sleep(time.Duration(2+(3<<d.oss)) * time.Millisecond)
|
time.Sleep(time.Duration(2+(3<<d.oss)) * time.Millisecond)
|
||||||
|
|
||||||
data := make([]byte, 3)
|
data := make([]byte, 3)
|
||||||
if err = d.Bus.ReadFromReg(address, pressureData, data); err != nil {
|
if err := d.Bus.ReadFromReg(address, pressureData, data); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pressure = ((uint32(data[0]) << 16) | (uint32(data[1]) << 8) | uint32(data[2])) >> (8 - d.oss)
|
pressure := ((uint32(data[0]) << 16) | (uint32(data[1]) << 8) | uint32(data[2])) >> (8 - d.oss)
|
||||||
|
|
||||||
return
|
return pressure, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) calcPressure(upressure uint32) (p int32) {
|
func (d *BMP085) calcPressure(upressure uint32) int32 {
|
||||||
var x1, x2, x3 int32
|
var x1, x2, x3 int32
|
||||||
|
|
||||||
l := func(s string, v interface{}) {
|
l := func(s string, v interface{}) {
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: %v = %v", s, v)
|
||||||
log.Printf("bcm085: %v = %v", s, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b6 := d.b5 - 4000
|
b6 := d.b5 - 4000
|
||||||
@ -271,6 +259,7 @@ func (d *BMP085) calcPressure(upressure uint32) (p int32) {
|
|||||||
l("x3", x3)
|
l("x3", x3)
|
||||||
l("b4", b4)
|
l("b4", b4)
|
||||||
|
|
||||||
|
var p int32
|
||||||
b7 := (uint32(upressure-uint32(b3)) * (50000 >> d.oss))
|
b7 := (uint32(upressure-uint32(b3)) * (50000 >> d.oss))
|
||||||
if b7 < 0x80000000 {
|
if b7 < 0x80000000 {
|
||||||
p = int32((b7 << 1) / b4)
|
p = int32((b7 << 1) / b4)
|
||||||
@ -290,83 +279,70 @@ func (d *BMP085) calcPressure(upressure uint32) (p int32) {
|
|||||||
l("x3", x3)
|
l("x3", x3)
|
||||||
l("p", p)
|
l("p", p)
|
||||||
|
|
||||||
return
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) calcAltitude(pressure int32) float64 {
|
func (d *BMP085) calcAltitude(pressure int32) float64 {
|
||||||
return 44330 * (1 - math.Pow(float64(pressure)/p0, 0.190295))
|
return 44330 * (1 - math.Pow(float64(pressure)/p0, 0.190295))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP085) measurePressureAndAltitude() (pressure int32, altitude float64, err error) {
|
func (d *BMP085) measurePressureAndAltitude() (int32, float64, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var upressure uint32
|
upressure, err := d.readUncompensatedPressure()
|
||||||
if upressure, err = d.readUncompensatedPressure(); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: uncompensated pressure: %v", upressure)
|
||||||
log.Printf("bcm085: uncompensated pressure: %v", upressure)
|
pressure := d.calcPressure(upressure)
|
||||||
}
|
glog.V(1).Infof("bcm085: compensated pressure %v", pressure)
|
||||||
pressure = d.calcPressure(upressure)
|
altitude := d.calcAltitude(pressure)
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: calculated altitude %v", altitude)
|
||||||
log.Printf("bcm085: compensated pressure %v", pressure)
|
return pressure, altitude, nil
|
||||||
}
|
|
||||||
altitude = d.calcAltitude(pressure)
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("bcm085: calculated altitude %v", altitude)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pressure returns the current pressure reading.
|
// Pressure returns the current pressure reading.
|
||||||
func (d *BMP085) Pressure() (pressure int, err error) {
|
func (d *BMP085) Pressure() (int, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case p := <-d.pressures:
|
case p := <-d.pressures:
|
||||||
pressure = int(p)
|
return int(p), nil
|
||||||
return
|
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: no pressures available... measuring")
|
||||||
log.Print("bcm085: no pressures available... measuring")
|
p, _, err := d.measurePressureAndAltitude()
|
||||||
}
|
|
||||||
var p int32
|
|
||||||
p, _, err = d.measurePressureAndAltitude()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
pressure = int(p)
|
return int(p), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Altitude returns the current altitude reading.
|
// Altitude returns the current altitude reading.
|
||||||
func (d *BMP085) Altitude() (altitude float64, err error) {
|
func (d *BMP085) Altitude() (float64, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case altitude = <-d.altitudes:
|
case altitude := <-d.altitudes:
|
||||||
return
|
return altitude, nil
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(1).Info("bcm085: no altitudes available... measuring")
|
||||||
log.Print("bcm085: no altitudes available... measuring")
|
_, altitude, err := d.measurePressureAndAltitude()
|
||||||
}
|
|
||||||
_, altitude, err = d.measurePressureAndAltitude()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
return
|
return altitude, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts the sensor data acquisition loop.
|
// Run starts the sensor data acquisition loop.
|
||||||
func (d *BMP085) Run() (err error) {
|
func (d *BMP085) Run() {
|
||||||
go func() {
|
go func() {
|
||||||
d.quit = make(chan struct{})
|
d.quit = make(chan struct{})
|
||||||
timer := time.Tick(time.Duration(d.Poll) * time.Millisecond)
|
timer := time.Tick(time.Duration(d.Poll) * time.Millisecond)
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
package bmp180
|
package bmp180
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,8 +43,6 @@ type BMP180 struct {
|
|||||||
Bus embd.I2CBus
|
Bus embd.I2CBus
|
||||||
Poll int
|
Poll int
|
||||||
|
|
||||||
Debug bool
|
|
||||||
|
|
||||||
oss uint
|
oss uint
|
||||||
|
|
||||||
ac1, ac2, ac3 int16
|
ac1, ac2, ac3 int16
|
||||||
@ -65,109 +63,109 @@ func New(bus embd.I2CBus) *BMP180 {
|
|||||||
return &BMP180{Bus: bus, Poll: pollDelay}
|
return &BMP180{Bus: bus, Poll: pollDelay}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) calibrate() (err error) {
|
func (d *BMP180) calibrate() error {
|
||||||
d.cmu.RLock()
|
d.cmu.RLock()
|
||||||
if d.calibrated {
|
if d.calibrated {
|
||||||
d.cmu.RUnlock()
|
d.cmu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.cmu.RUnlock()
|
d.cmu.RUnlock()
|
||||||
|
|
||||||
d.cmu.Lock()
|
d.cmu.Lock()
|
||||||
defer d.cmu.Unlock()
|
defer d.cmu.Unlock()
|
||||||
|
|
||||||
readInt16 := func(reg byte) (value int16, err error) {
|
readInt16 := func(reg byte) (int16, error) {
|
||||||
var v uint16
|
v, err := d.Bus.ReadWordFromReg(address, reg)
|
||||||
if v, err = d.Bus.ReadWordFromReg(address, reg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
value = int16(v)
|
return int16(v), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readUInt16 := func(reg byte) (value uint16, err error) {
|
readUInt16 := func(reg byte) (uint16, error) {
|
||||||
var v uint16
|
v, err := d.Bus.ReadWordFromReg(address, reg)
|
||||||
if v, err = d.Bus.ReadWordFromReg(address, reg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
value = uint16(v)
|
return uint16(v), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
d.ac1, err = readInt16(calAc1)
|
d.ac1, err = readInt16(calAc1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac2, err = readInt16(calAc2)
|
d.ac2, err = readInt16(calAc2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac3, err = readInt16(calAc3)
|
d.ac3, err = readInt16(calAc3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac4, err = readUInt16(calAc4)
|
d.ac4, err = readUInt16(calAc4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac5, err = readUInt16(calAc5)
|
d.ac5, err = readUInt16(calAc5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.ac6, err = readUInt16(calAc6)
|
d.ac6, err = readUInt16(calAc6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.b1, err = readInt16(calB1)
|
d.b1, err = readInt16(calB1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.b2, err = readInt16(calB2)
|
d.b2, err = readInt16(calB2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.mb, err = readInt16(calMB)
|
d.mb, err = readInt16(calMB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.mc, err = readInt16(calMC)
|
d.mc, err = readInt16(calMC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.md, err = readInt16(calMD)
|
d.md, err = readInt16(calMD)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.calibrated = true
|
d.calibrated = true
|
||||||
|
|
||||||
if d.Debug {
|
if glog.V(1) {
|
||||||
log.Print("bmp085: calibration data retrieved")
|
glog.Info("bmp180: calibration data retrieved")
|
||||||
log.Printf("bmp085: param AC1 = %v", d.ac1)
|
glog.Infof("bmp180: param AC1 = %v", d.ac1)
|
||||||
log.Printf("bmp085: param AC2 = %v", d.ac2)
|
glog.Infof("bmp180: param AC2 = %v", d.ac2)
|
||||||
log.Printf("bmp085: param AC3 = %v", d.ac3)
|
glog.Infof("bmp180: param AC3 = %v", d.ac3)
|
||||||
log.Printf("bmp085: param AC4 = %v", d.ac4)
|
glog.Infof("bmp180: param AC4 = %v", d.ac4)
|
||||||
log.Printf("bmp085: param AC5 = %v", d.ac5)
|
glog.Infof("bmp180: param AC5 = %v", d.ac5)
|
||||||
log.Printf("bmp085: param AC6 = %v", d.ac6)
|
glog.Infof("bmp180: param AC6 = %v", d.ac6)
|
||||||
log.Printf("bmp085: param B1 = %v", d.b1)
|
glog.Infof("bmp180: param B1 = %v", d.b1)
|
||||||
log.Printf("bmp085: param B2 = %v", d.b2)
|
glog.Infof("bmp180: param B2 = %v", d.b2)
|
||||||
log.Printf("bmp085: param MB = %v", d.mb)
|
glog.Infof("bmp180: param MB = %v", d.mb)
|
||||||
log.Printf("bmp085: param MC = %v", d.mc)
|
glog.Infof("bmp180: param MC = %v", d.mc)
|
||||||
log.Printf("bmp085: param MD = %v", d.md)
|
glog.Infof("bmp180: param MD = %v", d.md)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) readUncompensatedTemp() (temp uint16, err error) {
|
func (d *BMP180) readUncompensatedTemp() (uint16, error) {
|
||||||
if err = d.Bus.WriteByteToReg(address, control, readTempCmd); err != nil {
|
if err := d.Bus.WriteByteToReg(address, control, readTempCmd); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
time.Sleep(tempReadDelay)
|
time.Sleep(tempReadDelay)
|
||||||
if temp, err = d.Bus.ReadWordFromReg(address, tempData); err != nil {
|
temp, err := d.Bus.ReadWordFromReg(address, tempData)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) calcTemp(utemp uint16) uint16 {
|
func (d *BMP180) calcTemp(utemp uint16) uint16 {
|
||||||
@ -181,69 +179,59 @@ func (d *BMP180) calcTemp(utemp uint16) uint16 {
|
|||||||
return uint16((d.b5 + 8) >> 4)
|
return uint16((d.b5 + 8) >> 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) measureTemp() (temp uint16, err error) {
|
func (d *BMP180) measureTemp() (uint16, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var utemp uint16
|
utemp, err := d.readUncompensatedTemp()
|
||||||
if utemp, err = d.readUncompensatedTemp(); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: uncompensated temp: %v", utemp)
|
||||||
log.Printf("bcm085: uncompensated temp: %v", utemp)
|
temp := d.calcTemp(utemp)
|
||||||
}
|
glog.V(1).Infof("bcm085: compensated temp %v", temp)
|
||||||
temp = d.calcTemp(utemp)
|
return temp, nil
|
||||||
if d.Debug {
|
|
||||||
log.Printf("bcm085: compensated temp %v", temp)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temperature returns the current temperature reading.
|
// Temperature returns the current temperature reading.
|
||||||
func (d *BMP180) Temperature() (temp float64, err error) {
|
func (d *BMP180) Temperature() (float64, error) {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case t := <-d.temps:
|
case t := <-d.temps:
|
||||||
temp = float64(t) / 10
|
temp := float64(t) / 10
|
||||||
return
|
return temp, nil
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: no temps available... measuring")
|
||||||
log.Print("bcm085: no temps available... measuring")
|
t, err := d.measureTemp()
|
||||||
}
|
|
||||||
var t uint16
|
|
||||||
t, err = d.measureTemp()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
temp = float64(t) / 10
|
temp := float64(t) / 10
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) readUncompensatedPressure() (pressure uint32, err error) {
|
func (d *BMP180) readUncompensatedPressure() (uint32, error) {
|
||||||
if err = d.Bus.WriteByteToReg(address, control, byte(readPressureCmd+(d.oss<<6))); err != nil {
|
if err := d.Bus.WriteByteToReg(address, control, byte(readPressureCmd+(d.oss<<6))); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
time.Sleep(time.Duration(2+(3<<d.oss)) * time.Millisecond)
|
time.Sleep(time.Duration(2+(3<<d.oss)) * time.Millisecond)
|
||||||
|
|
||||||
data := make([]byte, 3)
|
data := make([]byte, 3)
|
||||||
if err = d.Bus.ReadFromReg(address, pressureData, data); err != nil {
|
if err := d.Bus.ReadFromReg(address, pressureData, data); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pressure = ((uint32(data[0]) << 16) | (uint32(data[1]) << 8) | uint32(data[2])) >> (8 - d.oss)
|
pressure := ((uint32(data[0]) << 16) | (uint32(data[1]) << 8) | uint32(data[2])) >> (8 - d.oss)
|
||||||
|
|
||||||
return
|
return pressure, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) calcPressure(upressure uint32) (p int32) {
|
func (d *BMP180) calcPressure(upressure uint32) int32 {
|
||||||
var x1, x2, x3 int32
|
var x1, x2, x3 int32
|
||||||
|
|
||||||
l := func(s string, v interface{}) {
|
l := func(s string, v interface{}) {
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: %v = %v", s, v)
|
||||||
log.Printf("bcm085: %v = %v", s, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b6 := d.b5 - 4000
|
b6 := d.b5 - 4000
|
||||||
@ -271,6 +259,7 @@ func (d *BMP180) calcPressure(upressure uint32) (p int32) {
|
|||||||
l("x3", x3)
|
l("x3", x3)
|
||||||
l("b4", b4)
|
l("b4", b4)
|
||||||
|
|
||||||
|
var p int32
|
||||||
b7 := (uint32(upressure-uint32(b3)) * (50000 >> d.oss))
|
b7 := (uint32(upressure-uint32(b3)) * (50000 >> d.oss))
|
||||||
if b7 < 0x80000000 {
|
if b7 < 0x80000000 {
|
||||||
p = int32((b7 << 1) / b4)
|
p = int32((b7 << 1) / b4)
|
||||||
@ -290,83 +279,70 @@ func (d *BMP180) calcPressure(upressure uint32) (p int32) {
|
|||||||
l("x3", x3)
|
l("x3", x3)
|
||||||
l("p", p)
|
l("p", p)
|
||||||
|
|
||||||
return
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) calcAltitude(pressure int32) float64 {
|
func (d *BMP180) calcAltitude(pressure int32) float64 {
|
||||||
return 44330 * (1 - math.Pow(float64(pressure)/p0, 0.190295))
|
return 44330 * (1 - math.Pow(float64(pressure)/p0, 0.190295))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BMP180) measurePressureAndAltitude() (pressure int32, altitude float64, err error) {
|
func (d *BMP180) measurePressureAndAltitude() (int32, float64, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var upressure uint32
|
upressure, err := d.readUncompensatedPressure()
|
||||||
if upressure, err = d.readUncompensatedPressure(); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: uncompensated pressure: %v", upressure)
|
||||||
log.Printf("bcm085: uncompensated pressure: %v", upressure)
|
pressure := d.calcPressure(upressure)
|
||||||
}
|
glog.V(1).Infof("bcm085: compensated pressure %v", pressure)
|
||||||
pressure = d.calcPressure(upressure)
|
altitude := d.calcAltitude(pressure)
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: calculated altitude %v", altitude)
|
||||||
log.Printf("bcm085: compensated pressure %v", pressure)
|
return pressure, altitude, nil
|
||||||
}
|
|
||||||
altitude = d.calcAltitude(pressure)
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("bcm085: calculated altitude %v", altitude)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pressure returns the current pressure reading.
|
// Pressure returns the current pressure reading.
|
||||||
func (d *BMP180) Pressure() (pressure int, err error) {
|
func (d *BMP180) Pressure() (int, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case p := <-d.pressures:
|
case p := <-d.pressures:
|
||||||
pressure = int(p)
|
return int(p), nil
|
||||||
return
|
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(1).Infof("bcm085: no pressures available... measuring")
|
||||||
log.Print("bcm085: no pressures available... measuring")
|
p, _, err := d.measurePressureAndAltitude()
|
||||||
}
|
|
||||||
var p int32
|
|
||||||
p, _, err = d.measurePressureAndAltitude()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
pressure = int(p)
|
return int(p), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Altitude returns the current altitude reading.
|
// Altitude returns the current altitude reading.
|
||||||
func (d *BMP180) Altitude() (altitude float64, err error) {
|
func (d *BMP180) Altitude() (float64, error) {
|
||||||
if err = d.calibrate(); err != nil {
|
if err := d.calibrate(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case altitude = <-d.altitudes:
|
case altitude := <-d.altitudes:
|
||||||
return
|
return altitude, nil
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(1).Info("bcm085: no altitudes available... measuring")
|
||||||
log.Print("bcm085: no altitudes available... measuring")
|
_, altitude, err := d.measurePressureAndAltitude()
|
||||||
}
|
|
||||||
_, altitude, err = d.measurePressureAndAltitude()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
return
|
return altitude, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts the sensor data acquisition loop.
|
// Run starts the sensor data acquisition loop.
|
||||||
func (d *BMP180) Run() (err error) {
|
func (d *BMP180) Run() {
|
||||||
go func() {
|
go func() {
|
||||||
d.quit = make(chan struct{})
|
d.quit = make(chan struct{})
|
||||||
timer := time.Tick(time.Duration(d.Poll) * time.Millisecond)
|
timer := time.Tick(time.Duration(d.Poll) * time.Millisecond)
|
||||||
|
@ -3,11 +3,11 @@ package l3gd20
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -122,8 +122,6 @@ type L3GD20 struct {
|
|||||||
|
|
||||||
orientations chan Orientation
|
orientations chan Orientation
|
||||||
closing chan chan struct{}
|
closing chan chan struct{}
|
||||||
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new L3GD20 interface. The bus variable controls
|
// New creates a new L3GD20 interface. The bus variable controls
|
||||||
@ -132,7 +130,6 @@ func New(bus embd.I2CBus, Range *Range) *L3GD20 {
|
|||||||
return &L3GD20{
|
return &L3GD20{
|
||||||
Bus: bus,
|
Bus: bus,
|
||||||
Range: Range,
|
Range: Range,
|
||||||
Debug: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,42 +159,38 @@ func (vs values) mean() float64 {
|
|||||||
return sum / float64(len(vs))
|
return sum / float64(len(vs))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *L3GD20) calibrate(a *axis) (ac axisCalibration, err error) {
|
func (d *L3GD20) calibrate(a *axis) (axisCalibration, error) {
|
||||||
if d.Debug {
|
glog.V(1).Infof("l3gd20: calibrating %v axis", a)
|
||||||
log.Printf("l3gd20: calibrating %v axis", a)
|
|
||||||
}
|
|
||||||
|
|
||||||
values := make(values, 0)
|
values := make(values, 0)
|
||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
again:
|
again:
|
||||||
var available bool
|
available, err := d.axisStatus(a)
|
||||||
if available, err = d.axisStatus(a); err != nil {
|
if err != nil {
|
||||||
return
|
return axisCalibration{}, err
|
||||||
}
|
}
|
||||||
if !available {
|
if !available {
|
||||||
time.Sleep(100 * time.Microsecond)
|
time.Sleep(100 * time.Microsecond)
|
||||||
goto again
|
goto again
|
||||||
}
|
}
|
||||||
var value float64
|
value, err := d.readOrientationDelta(a)
|
||||||
if value, err = d.readOrientationDelta(a); err != nil {
|
if err != nil {
|
||||||
return
|
return axisCalibration{}, err
|
||||||
}
|
}
|
||||||
values = append(values, value)
|
values = append(values, value)
|
||||||
}
|
}
|
||||||
ac.min, ac.max, ac.mean = values.min(), values.max(), values.mean()
|
ac := axisCalibration{min: values.min(), max: values.max(), mean: values.mean()}
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(1).Infof("l3gd20: %v axis calibration (%v)", a, ac)
|
||||||
log.Printf("l3gd20: %v axis calibration (%v)", a, ac)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return ac, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *L3GD20) setup() (err error) {
|
func (d *L3GD20) setup() error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
if d.initialized {
|
if d.initialized {
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
|
|
||||||
@ -206,63 +199,66 @@ func (d *L3GD20) setup() (err error) {
|
|||||||
|
|
||||||
d.orientations = make(chan Orientation)
|
d.orientations = make(chan Orientation)
|
||||||
|
|
||||||
if err = d.Bus.WriteByteToReg(address, ctrlReg1, ctrlReg1Default); err != nil {
|
if err := d.Bus.WriteByteToReg(address, ctrlReg1, ctrlReg1Default); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if err = d.Bus.WriteByteToReg(address, ctrlReg4, d.Range.value); err != nil {
|
if err := d.Bus.WriteByteToReg(address, ctrlReg4, d.Range.value); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calibrate
|
// Calibrate
|
||||||
|
var err error
|
||||||
if d.xac, err = d.calibrate(ax); err != nil {
|
if d.xac, err = d.calibrate(ax); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if d.yac, err = d.calibrate(ay); err != nil {
|
if d.yac, err = d.calibrate(ay); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if d.zac, err = d.calibrate(az); err != nil {
|
if d.zac, err = d.calibrate(az); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.initialized = true
|
d.initialized = true
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *L3GD20) axisStatus(a *axis) (available bool, err error) {
|
func (d *L3GD20) axisStatus(a *axis) (bool, error) {
|
||||||
var data byte
|
data, err := d.Bus.ReadByteFromReg(address, statusReg)
|
||||||
if data, err = d.Bus.ReadByteFromReg(address, statusReg); err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if data&zyxAvailable == 0 {
|
if data&zyxAvailable == 0 {
|
||||||
return
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
available = data&a.availableMask != 0
|
available := data&a.availableMask != 0
|
||||||
|
|
||||||
return
|
return available, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *L3GD20) readOrientationDelta(a *axis) (value float64, err error) {
|
func (d *L3GD20) readOrientationDelta(a *axis) (float64, error) {
|
||||||
rl, rh := a.regs()
|
rl, rh := a.regs()
|
||||||
var l, h byte
|
l, err := d.Bus.ReadByteFromReg(address, rl)
|
||||||
if l, err = d.Bus.ReadByteFromReg(address, rl); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
if h, err = d.Bus.ReadByteFromReg(address, rh); err != nil {
|
h, err := d.Bus.ReadByteFromReg(address, rh)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
value = float64(int16(h)<<8 | int16(l))
|
value := float64(int16(h)<<8 | int16(l))
|
||||||
value *= d.Range.sensitivity
|
value *= d.Range.sensitivity
|
||||||
|
|
||||||
return
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *L3GD20) calibratedOrientationDelta(a *axis) (value float64, err error) {
|
func (d *L3GD20) calibratedOrientationDelta(a *axis) (float64, error) {
|
||||||
if value, err = d.readOrientationDelta(a); err != nil {
|
value, err := d.readOrientationDelta(a)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch a {
|
switch a {
|
||||||
@ -274,63 +270,64 @@ func (d *L3GD20) calibratedOrientationDelta(a *axis) (value float64, err error)
|
|||||||
value = d.zac.adjust(value)
|
value = d.zac.adjust(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *L3GD20) measureOrientationDelta() (dx, dy, dz float64, err error) {
|
func (d *L3GD20) measureOrientationDelta() (float64, float64, float64, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return 0, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if dx, err = d.calibratedOrientationDelta(ax); err != nil {
|
dx, err := d.calibratedOrientationDelta(ax)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, 0, 0, err
|
||||||
}
|
}
|
||||||
if dy, err = d.calibratedOrientationDelta(ay); err != nil {
|
dy, err := d.calibratedOrientationDelta(ay)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, 0, 0, err
|
||||||
}
|
}
|
||||||
if dz, err = d.calibratedOrientationDelta(az); err != nil {
|
dz, err := d.calibratedOrientationDelta(az)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return dx, dy, dz, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Orientation returns the current orientation reading.
|
// Orientation returns the current orientation reading.
|
||||||
func (d *L3GD20) OrientationDelta() (dx, dy, dz float64, err error) {
|
func (d *L3GD20) OrientationDelta() (float64, float64, float64, error) {
|
||||||
return d.measureOrientationDelta()
|
return d.measureOrientationDelta()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temperature returns the current temperature reading.
|
// Temperature returns the current temperature reading.
|
||||||
func (d *L3GD20) Temperature() (temp int, err error) {
|
func (d *L3GD20) Temperature() (int, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var data byte
|
data, err := d.Bus.ReadByteFromReg(address, tempData)
|
||||||
if data, err = d.Bus.ReadByteFromReg(address, tempData); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = int(int8(data))
|
temp := int(int8(data))
|
||||||
|
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Orientations returns a channel which will have the current temperature reading.
|
// Orientations returns a channel which will have the current temperature reading.
|
||||||
func (d *L3GD20) Orientations() (orientations <-chan Orientation, err error) {
|
func (d *L3GD20) Orientations() (<-chan Orientation, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
orientations = d.orientations
|
return d.orientations, nil
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the data acquisition loop.
|
// Start starts the data acquisition loop.
|
||||||
func (d *L3GD20) Start() (err error) {
|
func (d *L3GD20) Start() error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.closing = make(chan chan struct{})
|
d.closing = make(chan chan struct{})
|
||||||
@ -346,7 +343,7 @@ func (d *L3GD20) Start() (err error) {
|
|||||||
case <-timer:
|
case <-timer:
|
||||||
dx, dy, dz, err := d.measureOrientationDelta()
|
dx, dy, dz, err := d.measureOrientationDelta()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("l3gd20: %v", err)
|
glog.Errorf("l3gd20: %v", err)
|
||||||
} else {
|
} else {
|
||||||
x += dx * mult
|
x += dx * mult
|
||||||
y += dy * mult
|
y += dy * mult
|
||||||
@ -364,25 +361,25 @@ func (d *L3GD20) Start() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the data acquisition loop.
|
// Stop the data acquisition loop.
|
||||||
func (d *L3GD20) Stop() (err error) {
|
func (d *L3GD20) Stop() error {
|
||||||
if d.closing != nil {
|
if d.closing != nil {
|
||||||
waitc := make(chan struct{})
|
waitc := make(chan struct{})
|
||||||
d.closing <- waitc
|
d.closing <- waitc
|
||||||
<-waitc
|
<-waitc
|
||||||
d.closing = nil
|
d.closing = nil
|
||||||
}
|
}
|
||||||
if err = d.Bus.WriteByteToReg(address, ctrlReg1, ctrlReg1Finished); err != nil {
|
if err := d.Bus.WriteByteToReg(address, ctrlReg1, ctrlReg1Finished); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
d.initialized = false
|
d.initialized = false
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close.
|
// Close.
|
||||||
func (d *L3GD20) Close() (err error) {
|
func (d *L3GD20) Close() error {
|
||||||
return d.Stop()
|
return d.Stop()
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
package lsm303
|
package lsm303
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,8 +53,6 @@ type LSM303 struct {
|
|||||||
headings chan float64
|
headings chan float64
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new LSM303 interface. The bus variable controls
|
// New creates a new LSM303 interface. The bus variable controls
|
||||||
@ -118,15 +116,13 @@ func (d *LSM303) Heading() (float64, error) {
|
|||||||
case heading := <-d.headings:
|
case heading := <-d.headings:
|
||||||
return heading, nil
|
return heading, nil
|
||||||
default:
|
default:
|
||||||
if d.Debug {
|
glog.V(2).Infof("lsm303: no headings available... measuring")
|
||||||
log.Print("lsm303: no headings available... measuring")
|
|
||||||
}
|
|
||||||
return d.measureHeading()
|
return d.measureHeading()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts the sensor data acquisition loop.
|
// Run starts the sensor data acquisition loop.
|
||||||
func (d *LSM303) Run() (err error) {
|
func (d *LSM303) Run() error {
|
||||||
go func() {
|
go func() {
|
||||||
d.quit = make(chan struct{})
|
d.quit = make(chan struct{})
|
||||||
|
|
||||||
@ -153,7 +149,7 @@ func (d *LSM303) Run() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the sensor data acquisition loop and put the LSM303 into sleep mode.
|
// Close the sensor data acquisition loop and put the LSM303 into sleep mode.
|
||||||
|
@ -4,11 +4,11 @@ package tmp006
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -57,8 +57,6 @@ type TMP006 struct {
|
|||||||
Bus embd.I2CBus
|
Bus embd.I2CBus
|
||||||
// Addr of the sensor.
|
// Addr of the sensor.
|
||||||
Addr byte
|
Addr byte
|
||||||
// Debug turns on additional debug output.
|
|
||||||
Debug bool
|
|
||||||
// SampleRate specifies the sampling rate for the sensor.
|
// SampleRate specifies the sampling rate for the sensor.
|
||||||
SampleRate *SampleRate
|
SampleRate *SampleRate
|
||||||
|
|
||||||
@ -89,143 +87,122 @@ func (d *TMP006) validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close puts the device into low power mode.
|
// Close puts the device into low power mode.
|
||||||
func (d *TMP006) Close() (err error) {
|
func (d *TMP006) Close() error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if d.closing != nil {
|
if d.closing != nil {
|
||||||
waitc := make(chan struct{})
|
waitc := make(chan struct{})
|
||||||
d.closing <- waitc
|
d.closing <- waitc
|
||||||
<-waitc
|
<-waitc
|
||||||
}
|
}
|
||||||
if d.Debug {
|
glog.V(1).Infof("tmp006: resetting")
|
||||||
log.Print("tmp006: resetting")
|
if err := d.Bus.WriteWordToReg(d.Addr, configReg, reset); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if err = d.Bus.WriteWordToReg(d.Addr, configReg, reset); err != nil {
|
return nil
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Present checks if the device is present at the given address.
|
// Present checks if the device is present at the given address.
|
||||||
func (d *TMP006) Present() (status bool, err error) {
|
func (d *TMP006) Present() (bool, error) {
|
||||||
if err = d.validate(); err != nil {
|
if err := d.validate(); err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
var mid, did uint16
|
mid, err := d.Bus.ReadWordFromReg(d.Addr, manIdReg)
|
||||||
if mid, err = d.Bus.ReadWordFromReg(d.Addr, manIdReg); err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("tmp006: got manufacturer id %#04x", mid)
|
|
||||||
}
|
}
|
||||||
|
glog.V(1).Infof("tmp006: got manufacturer id %#04x", mid)
|
||||||
if mid != manId {
|
if mid != manId {
|
||||||
err = fmt.Errorf("tmp006: not found at %#02x, manufacturer id mismatch", d.Addr)
|
return false, fmt.Errorf("tmp006: not found at %#02x, manufacturer id mismatch", d.Addr)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if did, err = d.Bus.ReadWordFromReg(d.Addr, devIdReg); err != nil {
|
did, err := d.Bus.ReadWordFromReg(d.Addr, devIdReg)
|
||||||
return
|
if err != nil {
|
||||||
}
|
return false, err
|
||||||
if d.Debug {
|
|
||||||
log.Printf("tmp006: got device id %#04x", did)
|
|
||||||
}
|
}
|
||||||
|
glog.V(1).Infof("tmp006: got device id %#04x", did)
|
||||||
if did != devId {
|
if did != devId {
|
||||||
err = fmt.Errorf("tmp006: not found at %#02x, device id mismatch", d.Addr)
|
return false, fmt.Errorf("tmp006: not found at %#02x, device id mismatch", d.Addr)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status = true
|
return true, nil
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *TMP006) setup() (err error) {
|
func (d *TMP006) setup() error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
if d.initialized {
|
if d.initialized {
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
|
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
|
|
||||||
if err = d.validate(); err != nil {
|
if err := d.validate(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if d.SampleRate == nil {
|
if d.SampleRate == nil {
|
||||||
if d.Debug {
|
glog.V(1).Infof("tmp006: sample rate = nil, using SR16")
|
||||||
log.Printf("tmp006: sample rate = nil, using SR16")
|
|
||||||
}
|
|
||||||
d.SampleRate = SR16
|
d.SampleRate = SR16
|
||||||
}
|
}
|
||||||
if d.Debug {
|
glog.V(1).Infof("tmp006: configuring with %#04x", configRegDefault|d.SampleRate.enabler)
|
||||||
log.Printf("tmp006: configuring with %#04x", configRegDefault|d.SampleRate.enabler)
|
if err := d.Bus.WriteWordToReg(d.Addr, configReg, configRegDefault|d.SampleRate.enabler); err != nil {
|
||||||
}
|
return err
|
||||||
if err = d.Bus.WriteWordToReg(d.Addr, configReg, configRegDefault|d.SampleRate.enabler); err != nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d.initialized = true
|
d.initialized = true
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *TMP006) measureRawDieTemp() (temp float64, err error) {
|
func (d *TMP006) measureRawDieTemp() (float64, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
var raw uint16
|
raw, err := d.Bus.ReadWordFromReg(d.Addr, tempAmbReg)
|
||||||
if raw, err = d.Bus.ReadWordFromReg(d.Addr, tempAmbReg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
raw >>= 2
|
raw >>= 2
|
||||||
if d.Debug {
|
glog.V(2).Infof("tmp006: raw die temp %#04x", raw)
|
||||||
log.Printf("tmp006: raw die temp %#04x", raw)
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = float64(int16(raw)) * 0.03125
|
temp := float64(int16(raw)) * 0.03125
|
||||||
|
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *TMP006) measureRawVoltage() (volt int16, err error) {
|
func (d *TMP006) measureRawVoltage() (int16, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
var vlt uint16
|
vlt, err := d.Bus.ReadWordFromReg(d.Addr, vObjReg)
|
||||||
if vlt, err = d.Bus.ReadWordFromReg(d.Addr, vObjReg); err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
volt = int16(vlt)
|
volt := int16(vlt)
|
||||||
if d.Debug {
|
glog.V(2).Infof("tmp006: raw voltage %#04x", volt)
|
||||||
log.Printf("tmp006: raw voltage %#04x", volt)
|
return volt, nil
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *TMP006) measureObjTemp() (temp float64, err error) {
|
func (d *TMP006) measureObjTemp() (float64, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
tDie, err := d.measureRawDieTemp()
|
tDie, err := d.measureRawDieTemp()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
|
||||||
if d.Debug {
|
|
||||||
log.Printf("tmp006: tdie = %.2f C", tDie)
|
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("tmp006: tdie = %.2f C", tDie)
|
||||||
tDie += 273.15 // Convert to K
|
tDie += 273.15 // Convert to K
|
||||||
vo, err := d.measureRawVoltage()
|
vo, err := d.measureRawVoltage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
vObj := float64(vo)
|
vObj := float64(vo)
|
||||||
vObj *= 156.25 // 156.25 nV per LSB
|
vObj *= 156.25 // 156.25 nV per LSB
|
||||||
vObj /= 1000 // nV -> uV
|
vObj /= 1000 // nV -> uV
|
||||||
if d.Debug {
|
glog.V(2).Infof("tmp006: vObj = %.5f uV", vObj)
|
||||||
log.Printf("tmp006: vObj = %.5f uV", vObj)
|
|
||||||
}
|
|
||||||
vObj /= 1000 // uV -> mV
|
vObj /= 1000 // uV -> mV
|
||||||
vObj /= 1000 // mV -> V
|
vObj /= 1000 // mV -> V
|
||||||
|
|
||||||
@ -238,17 +215,17 @@ func (d *TMP006) measureObjTemp() (temp float64, err error) {
|
|||||||
Vos := b0 + b1*tdie_tref + b2*tdie_tref*tdie_tref
|
Vos := b0 + b1*tdie_tref + b2*tdie_tref*tdie_tref
|
||||||
fVobj := (vObj - Vos) + c2*(vObj-Vos)*(vObj-Vos)
|
fVobj := (vObj - Vos) + c2*(vObj-Vos)*(vObj-Vos)
|
||||||
|
|
||||||
temp = math.Sqrt(math.Sqrt(tDie*tDie*tDie*tDie + fVobj/s))
|
temp := math.Sqrt(math.Sqrt(tDie*tDie*tDie*tDie + fVobj/s))
|
||||||
temp -= 273.15
|
temp -= 273.15
|
||||||
|
|
||||||
return
|
return temp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RawDieTemp returns the current raw die temp reading.
|
// RawDieTemp returns the current raw die temp reading.
|
||||||
func (d *TMP006) RawDieTemp() (temp float64, err error) {
|
func (d *TMP006) RawDieTemp() (float64, error) {
|
||||||
select {
|
select {
|
||||||
case temp = <-d.rawDieTemps:
|
case temp := <-d.rawDieTemps:
|
||||||
return
|
return temp, nil
|
||||||
default:
|
default:
|
||||||
return d.measureRawDieTemp()
|
return d.measureRawDieTemp()
|
||||||
}
|
}
|
||||||
@ -260,10 +237,10 @@ func (d *TMP006) RawDieTemps() <-chan float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ObjTemp returns the current obj temp reading.
|
// ObjTemp returns the current obj temp reading.
|
||||||
func (d *TMP006) ObjTemp() (temp float64, err error) {
|
func (d *TMP006) ObjTemp() (float64, error) {
|
||||||
select {
|
select {
|
||||||
case temp = <-d.objTemps:
|
case temp := <-d.objTemps:
|
||||||
return
|
return temp, nil
|
||||||
default:
|
default:
|
||||||
return d.measureObjTemp()
|
return d.measureObjTemp()
|
||||||
}
|
}
|
||||||
@ -275,9 +252,9 @@ func (d *TMP006) ObjTemps() <-chan float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the data acquisition loop.
|
// Start starts the data acquisition loop.
|
||||||
func (d *TMP006) Start() (err error) {
|
func (d *TMP006) Start() error {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.rawDieTemps = make(chan float64)
|
d.rawDieTemps = make(chan float64)
|
||||||
@ -307,14 +284,14 @@ func (d *TMP006) Start() (err error) {
|
|||||||
case <-timer:
|
case <-timer:
|
||||||
var rdt float64
|
var rdt float64
|
||||||
if rdt, err = d.measureRawDieTemp(); err != nil {
|
if rdt, err = d.measureRawDieTemp(); err != nil {
|
||||||
log.Printf("tmp006: %v", err)
|
glog.Errorf("tmp006: %v", err)
|
||||||
} else {
|
} else {
|
||||||
rawDieTemp = rdt
|
rawDieTemp = rdt
|
||||||
rdtAvlb = true
|
rdtAvlb = true
|
||||||
}
|
}
|
||||||
var ot float64
|
var ot float64
|
||||||
if ot, err = d.measureObjTemp(); err != nil {
|
if ot, err = d.measureObjTemp(); err != nil {
|
||||||
log.Printf("tmp006: %v", err)
|
glog.Errorf("tmp006: %v", err)
|
||||||
} else {
|
} else {
|
||||||
objTemp = ot
|
objTemp = ot
|
||||||
otAvlb = true
|
otAvlb = true
|
||||||
@ -333,5 +310,5 @@ func (d *TMP006) Start() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
package us020
|
package us020
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,8 +37,6 @@ type US020 struct {
|
|||||||
|
|
||||||
initialized bool
|
initialized bool
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new US020 interface. The bus variable controls
|
// New creates a new US020 interface. The bus variable controls
|
||||||
@ -47,11 +45,11 @@ func New(echoPin, triggerPin embd.DigitalPin, thermometer Thermometer) *US020 {
|
|||||||
return &US020{EchoPin: echoPin, TriggerPin: triggerPin, Thermometer: thermometer}
|
return &US020{EchoPin: echoPin, TriggerPin: triggerPin, Thermometer: thermometer}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *US020) setup() (err error) {
|
func (d *US020) setup() error {
|
||||||
d.mu.RLock()
|
d.mu.RLock()
|
||||||
if d.initialized {
|
if d.initialized {
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d.mu.RUnlock()
|
d.mu.RUnlock()
|
||||||
|
|
||||||
@ -68,36 +66,30 @@ func (d *US020) setup() (err error) {
|
|||||||
if temp, err := d.Thermometer.Temperature(); err == nil {
|
if temp, err := d.Thermometer.Temperature(); err == nil {
|
||||||
d.speedSound = 331.3 + 0.606*temp
|
d.speedSound = 331.3 + 0.606*temp
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(1).Infof("us020: read a temperature of %v, so speed of sound = %v", temp, d.speedSound)
|
||||||
log.Printf("read a temperature of %v, so speed of sound = %v", temp, d.speedSound)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
d.speedSound = 340
|
d.speedSound = 340
|
||||||
}
|
}
|
||||||
|
|
||||||
d.initialized = true
|
d.initialized = true
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance computes the distance of the bot from the closest obstruction.
|
// Distance computes the distance of the bot from the closest obstruction.
|
||||||
func (d *US020) Distance() (distance float64, err error) {
|
func (d *US020) Distance() (float64, error) {
|
||||||
if err = d.setup(); err != nil {
|
if err := d.setup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(2).Infof("us020: trigerring pulse")
|
||||||
log.Print("us020: trigerring pulse")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a TRIGGER pulse
|
// Generate a TRIGGER pulse
|
||||||
d.TriggerPin.Write(embd.High)
|
d.TriggerPin.Write(embd.High)
|
||||||
time.Sleep(pulseDelay)
|
time.Sleep(pulseDelay)
|
||||||
d.TriggerPin.Write(embd.Low)
|
d.TriggerPin.Write(embd.Low)
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(2).Infof("us020: waiting for echo to go high")
|
||||||
log.Print("us020: waiting for echo to go high")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait until ECHO goes high
|
// Wait until ECHO goes high
|
||||||
for {
|
for {
|
||||||
@ -113,9 +105,7 @@ func (d *US020) Distance() (distance float64, err error) {
|
|||||||
|
|
||||||
startTime := time.Now() // Record time when ECHO goes high
|
startTime := time.Now() // Record time when ECHO goes high
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(2).Infof("us020: waiting for echo to go low")
|
||||||
log.Print("us020: waiting for echo to go low")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait until ECHO goes low
|
// Wait until ECHO goes low
|
||||||
for {
|
for {
|
||||||
@ -132,12 +122,12 @@ func (d *US020) Distance() (distance float64, err error) {
|
|||||||
duration := time.Since(startTime) // Calculate time lapsed for ECHO to transition from high to low
|
duration := time.Since(startTime) // Calculate time lapsed for ECHO to transition from high to low
|
||||||
|
|
||||||
// Calculate the distance based on the time computed
|
// Calculate the distance based on the time computed
|
||||||
distance = float64(duration.Nanoseconds()) / 10000000 * (d.speedSound / 2)
|
distance := float64(duration.Nanoseconds()) / 10000000 * (d.speedSound / 2)
|
||||||
|
|
||||||
return
|
return distance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close.
|
// Close.
|
||||||
func (d *US020) Close() {
|
func (d *US020) Close() error {
|
||||||
d.EchoPin.SetDirection(embd.Out)
|
return d.EchoPin.SetDirection(embd.Out)
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,6 @@ type WaterSensor struct {
|
|||||||
|
|
||||||
initialized bool
|
initialized bool
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
Debug bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new WaterSensor struct
|
// New creates a new WaterSensor struct
|
||||||
@ -48,9 +46,7 @@ func (d *WaterSensor) IsWet() (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Debug {
|
glog.V(1).Infof("watersensor: reading")
|
||||||
glog.Infof("watersensor: reading")
|
|
||||||
}
|
|
||||||
|
|
||||||
value, err := d.Pin.Read()
|
value, err := d.Pin.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user