mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-24 21:21:24 +01:00
Make defaults for PWM (servo) positions 0 (PWM off) if not configured.
When writing to a PWM device (servo or LED for example), it is possible to request the target position in the call, or to ask for a SET or RESET position. In the latter case, the positions corresponding to SET and RESET must be known, i.e. preconfigured. Defaults were assigned for this, but because the correct values will depend on the hardware device being driven, the defaults have been removed. In addition, the <T> command, when defining a servo turnout, now configures the PWM positions (not required by <T> commands, but desirable for consistency with other commands).
This commit is contained in:
parent
09eae0ea91
commit
1bb7b5cc77
10
IODevice.h
10
IODevice.h
@ -120,9 +120,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// User-friendly function for configuring a servo pin.
|
// User-friendly function for configuring a servo pin.
|
||||||
inline static bool configureServo(VPIN vpin, uint16_t activePosition, uint16_t inactivePosition, uint8_t profile, uint8_t initialState=0) {
|
inline static bool configureServo(VPIN vpin, uint16_t activePosition, uint16_t inactivePosition, uint8_t profile, uint16_t duration, uint8_t initialState=0) {
|
||||||
int params[] = {(int)activePosition, (int)inactivePosition, profile, initialState};
|
int params[] = {(int)activePosition, (int)inactivePosition, profile, (int)duration, initialState};
|
||||||
return IODevice::configure(vpin, CONFIGURE_SERVO, 4, params);
|
return IODevice::configure(vpin, CONFIGURE_SERVO, 5, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write invokes the IODevice instance's _write method.
|
// write invokes the IODevice instance's _write method.
|
||||||
@ -285,13 +285,11 @@ private:
|
|||||||
uint16_t stepNumber; // Index of current step (starting from 0)
|
uint16_t stepNumber; // Index of current step (starting from 0)
|
||||||
uint16_t numSteps; // Number of steps in animation, or 0 if none in progress.
|
uint16_t numSteps; // Number of steps in animation, or 0 if none in progress.
|
||||||
uint8_t currentProfile; // profile being used for current animation.
|
uint8_t currentProfile; // profile being used for current animation.
|
||||||
|
uint16_t duration; // time (tenths of a second) for animation to complete.
|
||||||
}; // 14 bytes per element, i.e. per pin in use
|
}; // 14 bytes per element, i.e. per pin in use
|
||||||
|
|
||||||
struct ServoData *_servoData [16];
|
struct ServoData *_servoData [16];
|
||||||
|
|
||||||
static const uint16_t _defaultActivePosition = 410;
|
|
||||||
static const uint16_t _defaultInactivePosition = 205;
|
|
||||||
|
|
||||||
static const uint8_t _catchupSteps = 5; // number of steps to wait before switching servo off
|
static const uint8_t _catchupSteps = 5; // number of steps to wait before switching servo off
|
||||||
static const byte FLASH _bounceProfile[30];
|
static const byte FLASH _bounceProfile[30];
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ void PCA9685::create(VPIN firstVpin, int nPins, uint8_t I2CAddress) {
|
|||||||
// Configure a port on the PCA9685.
|
// Configure a port on the PCA9685.
|
||||||
bool PCA9685::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCount, int params[]) {
|
bool PCA9685::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCount, int params[]) {
|
||||||
if (configType != CONFIGURE_SERVO) return false;
|
if (configType != CONFIGURE_SERVO) return false;
|
||||||
if (paramCount != 4) return false;
|
if (paramCount != 5) return false;
|
||||||
#ifdef DIAG_IO
|
#ifdef DIAG_IO
|
||||||
DIAG(F("PCA9685 Configure VPIN:%d Apos:%d Ipos:%d Profile:%d state:%d"),
|
DIAG(F("PCA9685 Configure VPIN:%d Apos:%d Ipos:%d Profile:%d Duration:%d state:%d"),
|
||||||
vpin, params[0], params[1], params[2], params[3]);
|
vpin, params[0], params[1], params[2], params[3], params[4]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int8_t pin = vpin - _firstVpin;
|
int8_t pin = vpin - _firstVpin;
|
||||||
@ -62,12 +62,13 @@ bool PCA9685::_configure(VPIN vpin, ConfigTypeEnum configType, int paramCount, i
|
|||||||
s->activePosition = params[0];
|
s->activePosition = params[0];
|
||||||
s->inactivePosition = params[1];
|
s->inactivePosition = params[1];
|
||||||
s->profile = params[2];
|
s->profile = params[2];
|
||||||
int state = params[3];
|
s->duration = params[3];
|
||||||
|
int state = params[4];
|
||||||
|
|
||||||
if (state != -1) {
|
if (state != -1) {
|
||||||
// Position servo to initial state
|
// Position servo to initial state
|
||||||
_writeAnalogue(vpin, state ? s->activePosition : s->inactivePosition, 0, 0);
|
_writeAnalogue(vpin, state ? s->activePosition : s->inactivePosition, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,13 +120,10 @@ void PCA9685::_write(VPIN vpin, int value) {
|
|||||||
if (value) value = 1;
|
if (value) value = 1;
|
||||||
|
|
||||||
struct ServoData *s = _servoData[pin];
|
struct ServoData *s = _servoData[pin];
|
||||||
if (s == NULL) {
|
if (s != NULL) {
|
||||||
// Pin not configured, just write default positions to servo controller
|
// Use configured parameters
|
||||||
writeDevice(pin, value ? _defaultActivePosition : _defaultInactivePosition);
|
_writeAnalogue(vpin, value ? s->activePosition : s->inactivePosition, s->profile, s->duration);
|
||||||
} else {
|
} // else { /* ignorethe request */ }
|
||||||
// Use configured parameters for advanced transitions
|
|
||||||
_writeAnalogue(vpin, value ? s->activePosition : s->inactivePosition, s->profile, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Device-specific writeAnalogue function, invoked from IODevice::writeAnalogue().
|
// Device-specific writeAnalogue function, invoked from IODevice::writeAnalogue().
|
||||||
@ -152,8 +150,8 @@ void PCA9685::_writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t dur
|
|||||||
// Servo pin not configured, so configure now using defaults
|
// Servo pin not configured, so configure now using defaults
|
||||||
s = _servoData[pin] = (struct ServoData *) calloc(sizeof(struct ServoData), 1);
|
s = _servoData[pin] = (struct ServoData *) calloc(sizeof(struct ServoData), 1);
|
||||||
if (s == NULL) return; // Check for memory allocation failure
|
if (s == NULL) return; // Check for memory allocation failure
|
||||||
s->activePosition = _defaultActivePosition;
|
s->activePosition = 0;
|
||||||
s->inactivePosition = _defaultInactivePosition;
|
s->inactivePosition = 0;
|
||||||
s->currentPosition = value;
|
s->currentPosition = value;
|
||||||
s->profile = Instant; // Use instant profile (but not this time)
|
s->profile = Instant; // Use instant profile (but not this time)
|
||||||
}
|
}
|
||||||
|
@ -249,9 +249,10 @@
|
|||||||
// Don't touch the _closed parameter, retain the original value.
|
// Don't touch the _closed parameter, retain the original value.
|
||||||
|
|
||||||
// We don't really need to do the following, since a call to IODevice::_writeAnalogue
|
// We don't really need to do the following, since a call to IODevice::_writeAnalogue
|
||||||
// will provide all the data that is required!
|
// will provide all the data that is required! However, if someone has configured
|
||||||
// int params[] = {(int)thrownPosition, (int)closedPosition, profile, closed};
|
// a Turnout, we should ensure that the SET() RESET() and other commands that use write()
|
||||||
// IODevice::configure(vpin, IODevice::CONFIGURE_SERVO, 4, params);
|
// behave consistently with the turnout commands.
|
||||||
|
IODevice::configureServo(vpin, thrownPosition, closedPosition, profile, 0, closed);
|
||||||
|
|
||||||
// Set position directly to specified position - we don't know where it is moving from.
|
// Set position directly to specified position - we don't know where it is moving from.
|
||||||
IODevice::writeAnalogue(vpin, closed ? closedPosition : thrownPosition, PCA9685::Instant);
|
IODevice::writeAnalogue(vpin, closed ? closedPosition : thrownPosition, PCA9685::Instant);
|
||||||
|
Loading…
Reference in New Issue
Block a user