mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-24 13:21:23 +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;
|
||||
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::progTrack.setPowerMode(mode);
|
||||
|
@ -40,6 +40,7 @@ void DCCWaveform::begin(MotorDriver * mainDriver, MotorDriver * progDriver) {
|
||||
mainTrack.setPowerMode(POWERMODE::OFF);
|
||||
progTrack.setPowerMode(POWERMODE::OFF);
|
||||
MotorDriver::usePWM= mainDriver->isPWMCapable() && progDriver->isPWMCapable();
|
||||
MotorDriver::commonFaultPin = (mainDriver->getFaultPin() == progDriver->getFaultPin());
|
||||
if (MotorDriver::usePWM) DIAG(F("\nWaveform using PWM pins for accuracy."));
|
||||
else DIAG(F("\nWaveform accuracy limited by signal pin configuration."));
|
||||
DCCTimer::begin(DCCWaveform::interruptHandler);
|
||||
@ -125,10 +126,23 @@ void DCCWaveform::checkPowerOverload() {
|
||||
lastCurrent=motorDriver->getCurrentRaw();
|
||||
if (lastCurrent < 0) {
|
||||
// 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;
|
||||
}
|
||||
setPowerMode(POWERMODE::OVERLOAD); // Turn off, decide later how fast to turn on again
|
||||
if (MotorDriver::commonFaultPin) {
|
||||
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;
|
||||
if(power_good_counter<100)
|
||||
power_good_counter++;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define isLOW(fastpin) (!isHIGH(fastpin))
|
||||
|
||||
bool MotorDriver::usePWM=false;
|
||||
bool MotorDriver::commonFaultPin=false;
|
||||
|
||||
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) {
|
||||
@ -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 current = analogRead(currentPin);
|
||||
if (faultPin != UNUSED_PIN && isLOW(fastFaultPin) && isHIGH(fastPowerPin))
|
||||
return -current;
|
||||
return (current == 0 ? -1 : -current);
|
||||
return current;
|
||||
// IMPORTANT: This function can be called in Interrupt() time within the 56uS timer
|
||||
// The default analogRead takes ~100uS which is catastrphic
|
||||
|
@ -46,6 +46,10 @@ class MotorDriver {
|
||||
}
|
||||
bool isPWMCapable();
|
||||
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:
|
||||
void getFastPin(const FSH* type,int pin, bool input, FASTPIN & result);
|
||||
|
@ -30,7 +30,7 @@
|
||||
// Pololu Motor Shield
|
||||
#define POLOLU_MOTOR_SHIELD F("POLOLU_MOTOR_SHIELD"), \
|
||||
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
|
||||
// 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
|
||||
// a railcom cuotout in the future. For that one must wire the second ^D2 to pin 2 and define
|
||||
// the motor driver like this:
|
||||
// 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(4, 7, UNUSED_PIN, -9, A0, 18, 3000, 12), \
|
||||
// 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.
|
||||
|
||||
// Firebox Mk1
|
||||
|
@ -133,6 +133,8 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
||||
case 'P':
|
||||
if (cmd[1]=='P' && cmd[2]=='A' ) { //PPA power mode
|
||||
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);
|
||||
lastPowerState = (DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); //remember power state sent for comparison later
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user