1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-05-04 22:17:39 +08:00

Merge pull request #594 from starryalley/master

raspi: export PiBlasterPeriod in Adaptor
This commit is contained in:
Ron Evans 2018-08-22 12:49:13 +02:00 committed by GitHub
commit 12d8825066
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 18 deletions

View File

@ -9,13 +9,12 @@ import (
"gobot.io/x/gobot/sysfs" "gobot.io/x/gobot/sysfs"
) )
const piBlasterPeriod = 10000000
// PWMPin is the Raspberry Pi implementation of the PWMPinner interface. // PWMPin is the Raspberry Pi implementation of the PWMPinner interface.
// It uses Pi Blaster. // It uses Pi Blaster.
type PWMPin struct { type PWMPin struct {
pin string pin string
dc uint32 dc uint32
period uint32
} }
// NewPwmPin returns a new PWMPin // 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 // Period returns the current PWM period for pin
func (p *PWMPin) Period() (period uint32, err error) { 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")
} }
// SetPeriod does not do anything when using PiBlaster return p.period, nil
}
// SetPeriod uses PiBlaster setting and cannot be changed once set
func (p *PWMPin) SetPeriod(period uint32) (err error) { 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 return nil
} }
@ -66,12 +73,16 @@ func (p *PWMPin) DutyCycle() (duty uint32, err error) {
// SetDutyCycle writes the duty cycle to the pin // SetDutyCycle writes the duty cycle to the pin
func (p *PWMPin) SetDutyCycle(duty uint32) (err error) { 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.") return errors.New("Duty cycle exceeds period.")
} }
p.dc = duty 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 // never go below minimum allowed duty for pi blaster
if val < 0.05 { if val < 0.05 {

View File

@ -20,11 +20,14 @@ func TestPwmPin(t *testing.T) {
val, _ = pin.Polarity() val, _ = pin.Polarity()
gobottest.Assert(t, val, "normal") gobottest.Assert(t, val, "normal")
period, _ := pin.Period() period, err := pin.Period()
gobottest.Assert(t, period, uint32(10000000)) gobottest.Assert(t, err, errors.New("Raspi PWM pin period not set"))
gobottest.Assert(t, pin.SetPeriod(1000), nil) gobottest.Assert(t, pin.SetDutyCycle(10000), errors.New("Raspi PWM pin period not set"))
gobottest.Assert(t, pin.SetPeriod(20000000), nil)
period, _ = pin.Period() 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() dc, _ := pin.DutyCycle()
gobottest.Assert(t, dc, uint32(0)) gobottest.Assert(t, dc, uint32(0))

View File

@ -34,6 +34,7 @@ type Adaptor struct {
spiDevices [2]spi.Connection spiDevices [2]spi.Connection
spiDefaultMode int spiDefaultMode int
spiDefaultMaxSpeed int64 spiDefaultMaxSpeed int64
PiBlasterPeriod uint32
} }
// NewAdaptor creates a Raspi Adaptor // NewAdaptor creates a Raspi Adaptor
@ -43,6 +44,7 @@ func NewAdaptor() *Adaptor {
name: gobot.DefaultName("RaspberryPi"), name: gobot.DefaultName("RaspberryPi"),
digitalPins: make(map[int]*sysfs.DigitalPin), digitalPins: make(map[int]*sysfs.DigitalPin),
pwmPins: make(map[int]*PWMPin), pwmPins: make(map[int]*PWMPin),
PiBlasterPeriod: 10000000,
} }
content, _ := readFile() content, _ := readFile()
for _, v := range strings.Split(string(content), "\n") { 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 { if r.pwmPins[i] == nil {
r.pwmPins[i] = NewPWMPin(strconv.Itoa(i)) r.pwmPins[i] = NewPWMPin(strconv.Itoa(i))
r.pwmPins[i].SetPeriod(r.PiBlasterPeriod)
} }
return r.pwmPins[i], nil return r.pwmPins[i], nil
@ -273,7 +276,7 @@ func (r *Adaptor) PwmWrite(pin string, val byte) (err error) {
return err 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) return sysfsPin.SetDutyCycle(duty)
} }
@ -284,7 +287,7 @@ func (r *Adaptor) ServoWrite(pin string, angle byte) (err error) {
return err 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) return sysfsPin.SetDutyCycle(duty)
} }

View File

@ -110,6 +110,7 @@ func TestAdaptorFinalize(t *testing.T) {
func TestAdaptorDigitalPWM(t *testing.T) { func TestAdaptorDigitalPWM(t *testing.T) {
a := initTestAdaptor() a := initTestAdaptor()
a.PiBlasterPeriod = 20000000
gobottest.Assert(t, a.PwmWrite("7", 4), nil) gobottest.Assert(t, a.PwmWrite("7", 4), nil)
@ -118,6 +119,10 @@ func TestAdaptorDigitalPWM(t *testing.T) {
}) })
sysfs.SetFilesystem(fs) 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, a.PwmWrite("7", 255), nil)
gobottest.Assert(t, strings.Split(fs.Files["/dev/pi-blaster"].Contents, "\n")[0], "4=1") 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.PwmWrite("notexist", 1), errors.New("Not a valid pin"))
gobottest.Assert(t, a.ServoWrite("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) { func TestAdaptorDigitalIO(t *testing.T) {