mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-24 13:48:49 +08:00
raspi: export PiBlasterPeriod in Adaptor
By setting PiBlasterPeriod to a raspi.Adaptor, the PWM pin will now reflect the correct duty cycle to /dev/pi-blaster. Signed-off-by: Mark Kuo <starryalley@gmail.com>
This commit is contained in:
parent
a4d54794e0
commit
5ca29d0ba9
@ -9,13 +9,12 @@ import (
|
||||
"gobot.io/x/gobot/sysfs"
|
||||
)
|
||||
|
||||
const piBlasterPeriod = 10000000
|
||||
|
||||
// PWMPin is the Raspberry Pi implementation of the PWMPinner interface.
|
||||
// It uses Pi Blaster.
|
||||
type PWMPin struct {
|
||||
pin string
|
||||
dc uint32
|
||||
pin string
|
||||
dc uint32
|
||||
period uint32
|
||||
}
|
||||
|
||||
// NewPwmPin returns a new PWMPin
|
||||
@ -51,11 +50,19 @@ func (p *PWMPin) InvertPolarity(invert bool) (err error) {
|
||||
|
||||
// Period returns the current PWM period for pin
|
||||
func (p *PWMPin) Period() (period uint32, err error) {
|
||||
return piBlasterPeriod, nil
|
||||
if p.period == 0 {
|
||||
return p.period, errors.New("Raspi PWM pin period not set")
|
||||
}
|
||||
|
||||
return p.period, nil
|
||||
}
|
||||
|
||||
// SetPeriod does not do anything when using PiBlaster
|
||||
// SetPeriod uses PiBlaster setting and cannot be changed once set
|
||||
func (p *PWMPin) SetPeriod(period uint32) (err error) {
|
||||
if p.period != 0 {
|
||||
return errors.New("Cannot set the period of individual PWM pins on Raspi")
|
||||
}
|
||||
p.period = period
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -66,12 +73,16 @@ func (p *PWMPin) DutyCycle() (duty uint32, err error) {
|
||||
|
||||
// SetDutyCycle writes the duty cycle to the pin
|
||||
func (p *PWMPin) SetDutyCycle(duty uint32) (err error) {
|
||||
if duty > piBlasterPeriod {
|
||||
if p.period == 0 {
|
||||
return errors.New("Raspi PWM pin period not set")
|
||||
}
|
||||
|
||||
if duty > p.period {
|
||||
return errors.New("Duty cycle exceeds period.")
|
||||
}
|
||||
p.dc = duty
|
||||
|
||||
val := gobot.FromScale(float64(p.dc), 0, piBlasterPeriod)
|
||||
val := gobot.FromScale(float64(p.dc), 0, float64(p.period))
|
||||
|
||||
// never go below minimum allowed duty for pi blaster
|
||||
if val < 0.05 {
|
||||
|
@ -20,11 +20,14 @@ func TestPwmPin(t *testing.T) {
|
||||
val, _ = pin.Polarity()
|
||||
gobottest.Assert(t, val, "normal")
|
||||
|
||||
period, _ := pin.Period()
|
||||
gobottest.Assert(t, period, uint32(10000000))
|
||||
gobottest.Assert(t, pin.SetPeriod(1000), nil)
|
||||
period, err := pin.Period()
|
||||
gobottest.Assert(t, err, errors.New("Raspi PWM pin period not set"))
|
||||
gobottest.Assert(t, pin.SetDutyCycle(10000), errors.New("Raspi PWM pin period not set"))
|
||||
|
||||
gobottest.Assert(t, pin.SetPeriod(20000000), nil)
|
||||
period, _ = pin.Period()
|
||||
gobottest.Assert(t, period, uint32(10000000))
|
||||
gobottest.Assert(t, period, uint32(20000000))
|
||||
gobottest.Assert(t, pin.SetPeriod(10000000), errors.New("Cannot set the period of individual PWM pins on Raspi"))
|
||||
|
||||
dc, _ := pin.DutyCycle()
|
||||
gobottest.Assert(t, dc, uint32(0))
|
||||
|
@ -34,15 +34,17 @@ type Adaptor struct {
|
||||
spiDevices [2]spi.Connection
|
||||
spiDefaultMode int
|
||||
spiDefaultMaxSpeed int64
|
||||
PiBlasterPeriod uint32
|
||||
}
|
||||
|
||||
// NewAdaptor creates a Raspi Adaptor
|
||||
func NewAdaptor() *Adaptor {
|
||||
r := &Adaptor{
|
||||
mutex: &sync.Mutex{},
|
||||
name: gobot.DefaultName("RaspberryPi"),
|
||||
digitalPins: make(map[int]*sysfs.DigitalPin),
|
||||
pwmPins: make(map[int]*PWMPin),
|
||||
mutex: &sync.Mutex{},
|
||||
name: gobot.DefaultName("RaspberryPi"),
|
||||
digitalPins: make(map[int]*sysfs.DigitalPin),
|
||||
pwmPins: make(map[int]*PWMPin),
|
||||
PiBlasterPeriod: 10000000,
|
||||
}
|
||||
content, _ := readFile()
|
||||
for _, v := range strings.Split(string(content), "\n") {
|
||||
@ -261,6 +263,7 @@ func (r *Adaptor) PWMPin(pin string) (raspiPWMPin sysfs.PWMPinner, err error) {
|
||||
|
||||
if r.pwmPins[i] == nil {
|
||||
r.pwmPins[i] = NewPWMPin(strconv.Itoa(i))
|
||||
r.pwmPins[i].SetPeriod(r.PiBlasterPeriod)
|
||||
}
|
||||
|
||||
return r.pwmPins[i], nil
|
||||
@ -273,7 +276,7 @@ func (r *Adaptor) PwmWrite(pin string, val byte) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
duty := uint32(gobot.FromScale(float64(val), 0, 255) * piBlasterPeriod)
|
||||
duty := uint32(gobot.FromScale(float64(val), 0, 255) * float64(r.PiBlasterPeriod))
|
||||
return sysfsPin.SetDutyCycle(duty)
|
||||
}
|
||||
|
||||
@ -284,7 +287,7 @@ func (r *Adaptor) ServoWrite(pin string, angle byte) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
duty := uint32(gobot.FromScale(float64(angle), 0, 180) * piBlasterPeriod)
|
||||
duty := uint32(gobot.FromScale(float64(angle), 0, 180) * float64(r.PiBlasterPeriod))
|
||||
return sysfsPin.SetDutyCycle(duty)
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,7 @@ func TestAdaptorFinalize(t *testing.T) {
|
||||
|
||||
func TestAdaptorDigitalPWM(t *testing.T) {
|
||||
a := initTestAdaptor()
|
||||
a.PiBlasterPeriod = 20000000
|
||||
|
||||
gobottest.Assert(t, a.PwmWrite("7", 4), nil)
|
||||
|
||||
@ -118,6 +119,10 @@ func TestAdaptorDigitalPWM(t *testing.T) {
|
||||
})
|
||||
sysfs.SetFilesystem(fs)
|
||||
|
||||
pin, _ := a.PWMPin("7")
|
||||
period, _ := pin.Period()
|
||||
gobottest.Assert(t, period, uint32(20000000))
|
||||
|
||||
gobottest.Assert(t, a.PwmWrite("7", 255), nil)
|
||||
|
||||
gobottest.Assert(t, strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0], "4=1")
|
||||
@ -128,6 +133,14 @@ func TestAdaptorDigitalPWM(t *testing.T) {
|
||||
|
||||
gobottest.Assert(t, a.PwmWrite("notexist", 1), errors.New("Not a valid pin"))
|
||||
gobottest.Assert(t, a.ServoWrite("notexist", 1), errors.New("Not a valid pin"))
|
||||
|
||||
pin, _ = a.PWMPin("12")
|
||||
period, _ = pin.Period()
|
||||
gobottest.Assert(t, period, uint32(20000000))
|
||||
|
||||
gobottest.Assert(t, pin.SetDutyCycle(1.5*1000*1000), nil)
|
||||
|
||||
gobottest.Assert(t, strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0], "18=0.075")
|
||||
}
|
||||
|
||||
func TestAdaptorDigitalIO(t *testing.T) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user