2013-12-13 05:51:22 +05:30
|
|
|
// Package us020 allows interfacing with the US020 ultrasonic range finder.
|
|
|
|
package us020
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
"github.com/golang/glog"
|
2014-03-03 00:51:23 +05:30
|
|
|
"github.com/kidoman/embd"
|
2013-12-13 05:51:22 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2014-01-09 03:39:06 +05:30
|
|
|
pulseDelay = 30000 * time.Nanosecond
|
|
|
|
defaultTemp = 25
|
2013-12-13 05:51:22 +05:30
|
|
|
)
|
|
|
|
|
2014-01-09 03:39:06 +05:30
|
|
|
type Thermometer interface {
|
|
|
|
Temperature() (float64, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
type nullThermometer struct {
|
|
|
|
}
|
2014-01-08 20:18:40 +05:30
|
|
|
|
2014-01-09 03:39:06 +05:30
|
|
|
func (*nullThermometer) Temperature() (float64, error) {
|
|
|
|
return defaultTemp, nil
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
2014-01-09 03:39:06 +05:30
|
|
|
var NullThermometer = &nullThermometer{}
|
|
|
|
|
|
|
|
// US020 represents a US020 ultrasonic range finder.
|
|
|
|
type US020 struct {
|
2014-03-03 00:51:23 +05:30
|
|
|
EchoPin, TriggerPin embd.DigitalPin
|
2014-01-09 03:39:06 +05:30
|
|
|
|
|
|
|
Thermometer Thermometer
|
2013-12-13 05:51:22 +05:30
|
|
|
|
|
|
|
speedSound float64
|
|
|
|
|
|
|
|
initialized bool
|
2014-01-09 03:39:06 +05:30
|
|
|
mu sync.RWMutex
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
// New creates a new US020 interface. The bus variable controls
|
|
|
|
// the I2C bus used to communicate with the device.
|
2014-03-03 00:51:23 +05:30
|
|
|
func New(echoPin, triggerPin embd.DigitalPin, thermometer Thermometer) *US020 {
|
2014-02-27 04:24:53 +05:30
|
|
|
return &US020{EchoPin: echoPin, TriggerPin: triggerPin, Thermometer: thermometer}
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
func (d *US020) setup() error {
|
2013-12-13 05:51:22 +05:30
|
|
|
d.mu.RLock()
|
|
|
|
if d.initialized {
|
|
|
|
d.mu.RUnlock()
|
2014-03-31 18:46:04 +05:30
|
|
|
return nil
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
d.mu.RUnlock()
|
|
|
|
|
|
|
|
d.mu.Lock()
|
|
|
|
defer d.mu.Unlock()
|
|
|
|
|
2014-03-03 00:51:23 +05:30
|
|
|
d.TriggerPin.SetDirection(embd.Out)
|
|
|
|
d.EchoPin.SetDirection(embd.In)
|
2013-12-13 07:40:25 +05:30
|
|
|
|
2014-01-09 03:39:06 +05:30
|
|
|
if d.Thermometer == nil {
|
|
|
|
d.Thermometer = NullThermometer
|
|
|
|
}
|
|
|
|
|
|
|
|
if temp, err := d.Thermometer.Temperature(); err == nil {
|
|
|
|
d.speedSound = 331.3 + 0.606*temp
|
2013-12-13 07:40:25 +05:30
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
glog.V(1).Infof("us020: read a temperature of %v, so speed of sound = %v", temp, d.speedSound)
|
2014-01-09 03:39:06 +05:30
|
|
|
} else {
|
|
|
|
d.speedSound = 340
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
d.initialized = true
|
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
return nil
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
// Distance computes the distance of the bot from the closest obstruction.
|
2014-03-31 18:46:04 +05:30
|
|
|
func (d *US020) Distance() (float64, error) {
|
|
|
|
if err := d.setup(); err != nil {
|
|
|
|
return 0, err
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
glog.V(2).Infof("us020: trigerring pulse")
|
2013-12-13 07:40:25 +05:30
|
|
|
|
2013-12-13 05:51:22 +05:30
|
|
|
// Generate a TRIGGER pulse
|
2014-03-03 00:51:23 +05:30
|
|
|
d.TriggerPin.Write(embd.High)
|
2013-12-13 05:51:22 +05:30
|
|
|
time.Sleep(pulseDelay)
|
2014-03-03 00:51:23 +05:30
|
|
|
d.TriggerPin.Write(embd.Low)
|
2013-12-13 05:51:22 +05:30
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
glog.V(2).Infof("us020: waiting for echo to go high")
|
2013-12-13 07:40:25 +05:30
|
|
|
|
2014-04-05 04:06:40 +05:30
|
|
|
duration, err := d.EchoPin.TimePulse(embd.High)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate the distance based on the time computed
|
2014-03-31 18:46:04 +05:30
|
|
|
distance := float64(duration.Nanoseconds()) / 10000000 * (d.speedSound / 2)
|
2013-12-13 05:51:22 +05:30
|
|
|
|
2014-03-31 18:46:04 +05:30
|
|
|
return distance, nil
|
2013-12-13 05:51:22 +05:30
|
|
|
}
|
2014-01-08 20:18:40 +05:30
|
|
|
|
2014-01-09 03:39:06 +05:30
|
|
|
// Close.
|
2014-03-31 18:46:04 +05:30
|
|
|
func (d *US020) Close() error {
|
|
|
|
return d.EchoPin.SetDirection(embd.Out)
|
2014-01-08 20:18:40 +05:30
|
|
|
}
|