2019-12-27 17:23:08 +00:00
|
|
|
// Copyright 2018 The Periph Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed under the Apache License, Version 2.0
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package pca9685
|
|
|
|
|
|
|
|
import (
|
2021-09-01 19:34:31 +00:00
|
|
|
"periph.io/x/conn/v3/gpio"
|
|
|
|
"periph.io/x/conn/v3/physic"
|
2019-12-27 17:23:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ServoGroup a group of servos connected to a pca9685 module
|
|
|
|
type ServoGroup struct {
|
|
|
|
*Dev
|
|
|
|
minPwm gpio.Duty
|
|
|
|
maxPwm gpio.Duty
|
|
|
|
minAngle physic.Angle
|
|
|
|
maxAngle physic.Angle
|
|
|
|
}
|
|
|
|
|
|
|
|
// Servo individual servo from a group of servos connected to a pca9685 module
|
|
|
|
type Servo struct {
|
|
|
|
group *ServoGroup
|
|
|
|
channel int
|
|
|
|
minAngle physic.Angle
|
|
|
|
maxAngle physic.Angle
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewServoGroup returns a servo group connected through the pca9685 module
|
|
|
|
// some pwm and angle limits can be set
|
|
|
|
func NewServoGroup(dev *Dev, minPwm, maxPwm gpio.Duty, minAngle, maxAngle physic.Angle) *ServoGroup {
|
|
|
|
return &ServoGroup{
|
|
|
|
Dev: dev,
|
|
|
|
minPwm: minPwm,
|
|
|
|
maxPwm: maxPwm,
|
|
|
|
minAngle: minAngle,
|
|
|
|
maxAngle: maxAngle,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetMinMaxPwm change pwm and angle limits
|
|
|
|
func (s *ServoGroup) SetMinMaxPwm(minAngle, maxAngle physic.Angle, minPwm, maxPwm gpio.Duty) {
|
|
|
|
s.maxPwm = maxPwm
|
|
|
|
s.minPwm = minPwm
|
|
|
|
s.minAngle = minAngle
|
|
|
|
s.maxAngle = maxAngle
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetAngle set an angle in a given channel of the servo group
|
|
|
|
func (s *ServoGroup) SetAngle(channel int, angle physic.Angle) error {
|
|
|
|
value := mapValue(int(angle), int(s.minAngle), int(s.maxAngle), int(s.minPwm), int(s.maxPwm))
|
|
|
|
return s.Dev.SetPwm(channel, 0, gpio.Duty(value))
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetServo returns a individual Servo to be controlled
|
|
|
|
func (s *ServoGroup) GetServo(channel int) *Servo {
|
|
|
|
return &Servo{
|
|
|
|
group: s,
|
|
|
|
channel: channel,
|
|
|
|
minAngle: s.minAngle,
|
|
|
|
maxAngle: s.maxAngle,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetMinMaxAngle change angle limits for the servo
|
|
|
|
func (s *Servo) SetMinMaxAngle(min, max physic.Angle) {
|
|
|
|
s.minAngle = min
|
|
|
|
s.maxAngle = max
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetAngle set an angle on the servo
|
|
|
|
// will consider the angle limits set
|
|
|
|
func (s *Servo) SetAngle(angle physic.Angle) error {
|
|
|
|
if angle < s.minAngle {
|
|
|
|
angle = s.minAngle
|
|
|
|
}
|
|
|
|
if angle > s.maxAngle {
|
|
|
|
angle = s.maxAngle
|
|
|
|
}
|
|
|
|
return s.group.SetAngle(s.channel, angle)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetPwm set an pmw value to the servo
|
|
|
|
func (s *Servo) SetPwm(pwm gpio.Duty) error {
|
|
|
|
return s.group.SetPwm(s.channel, 0, pwm)
|
|
|
|
}
|
|
|
|
|
|
|
|
func mapValue(x, inMin, inMax, outMin, outMax int) int {
|
|
|
|
return (x-inMin)*(outMax-outMin)/(inMax-inMin) + outMin
|
|
|
|
}
|