mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-24 21:21:24 +01:00
Handle shields with common fault pins (Pololu)
This commit is contained in:
parent
8240a24193
commit
9368a69e30
@ -436,7 +436,8 @@ void DCCEXParser::parse(Print *stream, byte *com, bool blocking)
|
|||||||
{
|
{
|
||||||
POWERMODE mode = opcode == '1' ? POWERMODE::ON : POWERMODE::OFF;
|
POWERMODE mode = opcode == '1' ? POWERMODE::ON : POWERMODE::OFF;
|
||||||
DCC::setProgTrackSyncMain(false); // Only <1 JOIN> will set this on, all others set it off
|
DCC::setProgTrackSyncMain(false); // Only <1 JOIN> will set this on, all others set it off
|
||||||
if (params == 0)
|
if (params == 0 ||
|
||||||
|
(MotorDriver::commonFaultPin && p[0] != HASH_KEYWORD_JOIN)) // commonFaultPin prevents individual track handling
|
||||||
{
|
{
|
||||||
DCCWaveform::mainTrack.setPowerMode(mode);
|
DCCWaveform::mainTrack.setPowerMode(mode);
|
||||||
DCCWaveform::progTrack.setPowerMode(mode);
|
DCCWaveform::progTrack.setPowerMode(mode);
|
||||||
|
@ -40,6 +40,7 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
|
|||||||
mainTrack.setPowerMode(POWERMODE::OFF);
|
mainTrack.setPowerMode(POWERMODE::OFF);
|
||||||
progTrack.setPowerMode(POWERMODE::OFF);
|
progTrack.setPowerMode(POWERMODE::OFF);
|
||||||
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
|
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
|
||||||
|
MotorDriver::commonFaultPin = (mainDriver->getFaultPin() == progDriver->getFaultPin());
|
||||||
if (MotorDriver::usePWM) DIAG(F("\nWaveform using PWM pins for accuracy."));
|
if (MotorDriver::usePWM) DIAG(F("\nWaveform using PWM pins for accuracy."));
|
||||||
else DIAG(F("\nWaveform accuracy limited by signal pin configuration."));
|
else DIAG(F("\nWaveform accuracy limited by signal pin configuration."));
|
||||||
DCCTimer::begin(DCCWaveform::interruptHandler);
|
DCCTimer::begin(DCCWaveform::interruptHandler);
|
||||||
@ -125,10 +126,23 @@ void DCCWaveform::checkPowerOverload() {
|
|||||||
lastCurrent=motorDriver->getCurrentRaw();
|
lastCurrent=motorDriver->getCurrentRaw();
|
||||||
if (lastCurrent < 0) {
|
if (lastCurrent < 0) {
|
||||||
// We have a fault pin condition to take care of
|
// We have a fault pin condition to take care of
|
||||||
DIAG(F("\n*** %S FAULT PIN ACTIVE TOGGLE POWER ON THIS OR BOTH TRACKS ***\n"), isMainTrack ? F("MAIN") : F("PROG"));
|
|
||||||
lastCurrent = -lastCurrent;
|
lastCurrent = -lastCurrent;
|
||||||
}
|
setPowerMode(POWERMODE::OVERLOAD); // Turn off, decide later how fast to turn on again
|
||||||
|
if (MotorDriver::commonFaultPin) {
|
||||||
if (lastCurrent <= tripValue) {
|
if (lastCurrent <= tripValue) {
|
||||||
|
setPowerMode(POWERMODE::ON); // maybe other track
|
||||||
|
}
|
||||||
|
// Write this after the fact as we want to turn on as fast as possible
|
||||||
|
// because we don't know which output actually triggered the fault pin
|
||||||
|
DIAG(F("\n*** COMMON FAULT PIN ACTIVE - TOGGLED POWER on %S ***\n"), isMainTrack ? F("MAIN") : F("PROG"));
|
||||||
|
} else {
|
||||||
|
DIAG(F("\n*** %S FAULT PIN ACTIVE - OVERLOAD ***\n"), isMainTrack ? F("MAIN") : F("PROG"));
|
||||||
|
if (lastCurrent < tripValue) {
|
||||||
|
lastCurrent = tripValue; // exaggerate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastCurrent < tripValue) {
|
||||||
sampleDelay = POWER_SAMPLE_ON_WAIT;
|
sampleDelay = POWER_SAMPLE_ON_WAIT;
|
||||||
if(power_good_counter<100)
|
if(power_good_counter<100)
|
||||||
power_good_counter++;
|
power_good_counter++;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define isLOW(fastpin) (!isHIGH(fastpin))
|
#define isLOW(fastpin) (!isHIGH(fastpin))
|
||||||
|
|
||||||
bool MotorDriver::usePWM=false;
|
bool MotorDriver::usePWM=false;
|
||||||
|
bool MotorDriver::commonFaultPin=false;
|
||||||
|
|
||||||
MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin,
|
MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin,
|
||||||
byte current_pin, float sense_factor, unsigned int trip_milliamps, byte fault_pin) {
|
byte current_pin, float sense_factor, unsigned int trip_milliamps, byte fault_pin) {
|
||||||
@ -116,10 +117,15 @@ void MotorDriver::setSignal( bool high) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the current reading as pin reading 0 to 1023. If the fault
|
||||||
|
* pin is activated return a negative current to show active fault pin.
|
||||||
|
* As there is no -0, ceat a little and return -1 in that case.
|
||||||
|
*/
|
||||||
int MotorDriver::getCurrentRaw() {
|
int MotorDriver::getCurrentRaw() {
|
||||||
int current = analogRead(currentPin);
|
int current = analogRead(currentPin);
|
||||||
if (faultPin != UNUSED_PIN && isLOW(fastFaultPin) && isHIGH(fastPowerPin))
|
if (faultPin != UNUSED_PIN && isLOW(fastFaultPin) && isHIGH(fastPowerPin))
|
||||||
return -current;
|
return (current == 0 ? -1 : -current);
|
||||||
return current;
|
return current;
|
||||||
// IMPORTANT: This function can be called in Interrupt() time within the 56uS timer
|
// IMPORTANT: This function can be called in Interrupt() time within the 56uS timer
|
||||||
// The default analogRead takes ~100uS which is catastrphic
|
// The default analogRead takes ~100uS which is catastrphic
|
||||||
|
@ -46,6 +46,10 @@ class MotorDriver {
|
|||||||
}
|
}
|
||||||
bool isPWMCapable();
|
bool isPWMCapable();
|
||||||
static bool usePWM;
|
static bool usePWM;
|
||||||
|
static bool commonFaultPin; // This is a stupid motor shield which has only a common fault pin for both outputs
|
||||||
|
inline byte getFaultPin() {
|
||||||
|
return faultPin;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getFastPin(const FSH* type,int pin, bool input, FASTPIN & result);
|
void getFastPin(const FSH* type,int pin, bool input, FASTPIN & result);
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
// Pololu Motor Shield
|
// Pololu Motor Shield
|
||||||
#define POLOLU_MOTOR_SHIELD F("POLOLU_MOTOR_SHIELD"), \
|
#define POLOLU_MOTOR_SHIELD F("POLOLU_MOTOR_SHIELD"), \
|
||||||
new MotorDriver( 9, 7, UNUSED_PIN, -4, A0, 18, 3000, 12), \
|
new MotorDriver( 9, 7, UNUSED_PIN, -4, A0, 18, 3000, 12), \
|
||||||
new MotorDriver(10, 8, UNUSED_PIN, UNUSED_PIN, A1, 18, 3000, UNUSED_PIN)
|
new MotorDriver(10, 8, UNUSED_PIN, UNUSED_PIN, A1, 18, 3000, 12)
|
||||||
//
|
//
|
||||||
// Actually, on the Pololu MC33926 shield the enable lines are tied together on pin 4 and the
|
// Actually, on the Pololu MC33926 shield the enable lines are tied together on pin 4 and the
|
||||||
// pins 9 and 10 work as "inverted brake" but as we turn on and off the tracks individually
|
// pins 9 and 10 work as "inverted brake" but as we turn on and off the tracks individually
|
||||||
@ -38,8 +38,8 @@
|
|||||||
// version of the code always will be high. That means this config is not usable for generating
|
// version of the code always will be high. That means this config is not usable for generating
|
||||||
// a railcom cuotout in the future. For that one must wire the second ^D2 to pin 2 and define
|
// a railcom cuotout in the future. For that one must wire the second ^D2 to pin 2 and define
|
||||||
// the motor driver like this:
|
// the motor driver like this:
|
||||||
// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12)
|
// new MotorDriver(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12), \
|
||||||
// new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, UNUSED_PIN)
|
// new MotorDriver(2, 8, UNUSED_PIN, -10, A1, 18, 3000, 12)
|
||||||
// See Pololu dial_mc33926_shield_schematic.pdf and truth table on page 17 of the MC33926 data sheet.
|
// See Pololu dial_mc33926_shield_schematic.pdf and truth table on page 17 of the MC33926 data sheet.
|
||||||
|
|
||||||
// Firebox Mk1
|
// Firebox Mk1
|
||||||
|
@ -133,6 +133,8 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
|||||||
case 'P':
|
case 'P':
|
||||||
if (cmd[1]=='P' && cmd[2]=='A' ) { //PPA power mode
|
if (cmd[1]=='P' && cmd[2]=='A' ) { //PPA power mode
|
||||||
DCCWaveform::mainTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
DCCWaveform::mainTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
||||||
|
if (MotorDriver::commonFaultPin) // commonFaultPin prevents individual track handling
|
||||||
|
DCCWaveform::progTrack.setPowerMode(cmd[3]=='1'?POWERMODE::ON:POWERMODE::OFF);
|
||||||
StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON);
|
StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON);
|
||||||
lastPowerState = (DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); //remember power state sent for comparison later
|
lastPowerState = (DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); //remember power state sent for comparison later
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user