From b47d768de2ce0a0d62603e645b4883835b745738 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 29 Aug 2021 23:47:01 +0200 Subject: [PATCH 1/4] only on pololu board this makes sense --- MotorDriver.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MotorDriver.cpp b/MotorDriver.cpp index f51ee04..3df35c2 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -89,8 +89,11 @@ void MotorDriver::setPower(bool on) { if (on) { // toggle brake before turning power on - resets overcurrent error // on the Pololu board if brake is wired to ^D2. - setBrake(true); - setBrake(false); + // Yes, this is an ugly special case + if (brakePin == 4 && invertBrake) { + setBrake(true); + setBrake(false); + } setHIGH(fastPowerPin); } else setLOW(fastPowerPin); From fafa9d8477f86ca6f444a614db92e2174d9427e5 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 30 Aug 2021 22:26:20 +0200 Subject: [PATCH 2/4] DCdistrict prototypr --- DCC.cpp | 22 ++++++++++++++++++++++ DCCWaveform.cpp | 2 ++ DCCWaveform.h | 3 ++- MotorDriver.cpp | 32 ++++++++++++++++++++++++++------ MotorDriver.h | 3 ++- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/DCC.cpp b/DCC.cpp index 226425b..77c92c8 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -57,8 +57,15 @@ void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriv EEStore::init(); DCCWaveform::begin(mainDriver,progDriver); +#ifdef DCdistrict + DCCWaveform::mainTrack.motorDriver->setBrake(255); +#else + DCCWaveform::mainTrack.motorDriver->setBrake(0); +#endif + DCCWaveform::progTrack.motorDriver->setBrake(0); } + void DCC::setJoinRelayPin(byte joinRelayPin) { joinRelay=joinRelayPin; if (joinRelay!=UNUSED_PIN) { @@ -68,6 +75,21 @@ void DCC::setJoinRelayPin(byte joinRelayPin) { } void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) { +#ifdef DCdistrict + if (cab == DCdistrict) { + uint8_t brake; + if (tSpeed <= 1) + brake = 255; + else if (tSpeed >= 126) + brake = 0; + else + brake = 2 * (127-tSpeed); + DCCWaveform::mainTrack.motorDriver->setSignal(tDirection); + DCCWaveform::mainTrack.motorDriver->setBrake(brake); + } +#else + #error fooar +#endif byte speedCode = (tSpeed & 0x7F) + tDirection * 128; setThrottle2(cab, speedCode); // retain speed for loco reminders diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index df88e5d..9de9442 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -65,7 +65,9 @@ void DCCWaveform::interruptHandler() { byte sigProg=progTrackSyncMain? sigMain : signalTransform[progTrack.state]; // Set the signal state for both tracks +#ifndef DCdistrict mainTrack.motorDriver->setSignal(sigMain); +#endif progTrack.motorDriver->setSignal(sigProg); // Move on in the state engine diff --git a/DCCWaveform.h b/DCCWaveform.h index 29d6a29..0cbb5ff 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -107,6 +107,7 @@ class DCCWaveform { inline void setMaxAckPulseDuration(unsigned int i) { maxAckPulseDuration = i; } + MotorDriver* motorDriver; private: @@ -121,7 +122,7 @@ class DCCWaveform { void checkAck(); bool isMainTrack; - MotorDriver* motorDriver; +// MotorDriver* motorDriver; // Transmission controller byte transmitPacket[MAX_PACKET_SIZE+1]; // +1 for checksum byte transmitLength; diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 3df35c2..6da3b53 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -31,6 +31,7 @@ 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) { + brakePWM=false; powerPin=power_pin; getFastPin(F("POWER"),powerPin,fastPowerPin); pinMode(powerPin, OUTPUT); @@ -53,7 +54,7 @@ MotorDriver::MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, int8 brakePin=invertBrake ? 0-brake_pin : brake_pin; getFastPin(F("BRAKE"),brakePin,fastBrakePin); pinMode(brakePin, OUTPUT); - setBrake(false); +// setBrake(0); moved out to DCC::begin } else brakePin=UNUSED_PIN; @@ -91,8 +92,8 @@ void MotorDriver::setPower(bool on) { // on the Pololu board if brake is wired to ^D2. // Yes, this is an ugly special case if (brakePin == 4 && invertBrake) { - setBrake(true); - setBrake(false); + setBrake(255); + setBrake(0); } setHIGH(fastPowerPin); } @@ -107,10 +108,29 @@ void MotorDriver::setPower(bool on) { // (HIGH == release brake) and setBrake does // compensate for that. // -void MotorDriver::setBrake(bool on) { +void MotorDriver::setBrake(uint8_t intensity) { if (brakePin == UNUSED_PIN) return; - if (on ^ invertBrake) setHIGH(fastBrakePin); - else setLOW(fastBrakePin); + DIAG(F("Brake pin=%d val=%d"),brakePin,intensity); + if (invertBrake) + intensity = 255 - intensity; + if (intensity == 255) { + if (brakePWM) { + digitalWrite(brakePin, HIGH); + brakePWM = false; + } else + setHIGH(fastBrakePin); + return; + } + if (intensity == 0) { + if (brakePWM) { + digitalWrite(brakePin, LOW); + brakePWM = false; + } else + setLOW(fastBrakePin); + return; + } + brakePWM = true; + analogWrite(brakePin, intensity); } void MotorDriver::setSignal( bool high) { diff --git a/MotorDriver.h b/MotorDriver.h index 08db049..a750fe4 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -46,7 +46,7 @@ class MotorDriver { byte current_pin, float senseFactor, unsigned int tripMilliamps, byte faultPin); virtual void setPower( bool on); virtual void setSignal( bool high); - virtual void setBrake( bool on); + virtual void setBrake(uint8_t); virtual int getCurrentRaw(); virtual unsigned int raw2mA( int raw); virtual int mA2raw( unsigned int mA); @@ -69,6 +69,7 @@ class MotorDriver { FASTPIN fastPowerPin,fastSignalPin, fastSignalPin2, fastBrakePin,fastFaultPin; bool dualSignal; // true to use signalPin2 bool invertBrake; // brake pin passed as negative means pin is inverted + bool brakePWM; // brake is used for PWM float senseFactor; int senseOffset; unsigned int tripMilliamps; From 66cf6d632b5f8ab11fa22bbf7149d7342a5ccf32 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 30 Aug 2021 22:36:27 +0200 Subject: [PATCH 3/4] DCdistrict config --- config.example.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config.example.h b/config.example.h index 1d1977a..1581c16 100644 --- a/config.example.h +++ b/config.example.h @@ -23,6 +23,14 @@ The configuration file for DCC-EX Command Station **********************************************************************/ +// TO GET THE DC district feature put this in your config.h: +// +//#define BRAKE_MOTOR_SHIELD F("BRAKE_MOTOR_SHIELD"), \ +// new MotorDriver(3, 12, UNUSED_PIN, 9, A0, 2.99, 2000, UNUSED_PIN), \ +// new MotorDriver(11, 13, UNUSED_PIN, UNUSED_PIN, A1, 2.99, 2000, UNUSED_PIN) +//#define MOTOR_SHIELD_TYPE BRAKE_MOTOR_SHIELD +//#define DCdistrict 2 + ///////////////////////////////////////////////////////////////////////////////////// // NOTE: Before connecting these boards and selecting one in this software // check the quick install guides!!! Some of these boards require a voltage From 414e109f9dcecb4bb07aea5f09a55f32bc9bdbfc Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sat, 4 Sep 2021 09:05:01 +0200 Subject: [PATCH 4/4] pwmSpeed() as access method instead of public pointer --- DCC.cpp | 16 ++++------------ DCCWaveform.h | 24 ++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/DCC.cpp b/DCC.cpp index 77c92c8..801e64d 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -58,11 +58,11 @@ void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriv DCCWaveform::begin(mainDriver,progDriver); #ifdef DCdistrict - DCCWaveform::mainTrack.motorDriver->setBrake(255); + DCCWaveform::mainTrack.pwmSpeed(0); #else - DCCWaveform::mainTrack.motorDriver->setBrake(0); + DCCWaveform::mainTrack.pwmSpeed(255); #endif - DCCWaveform::progTrack.motorDriver->setBrake(0); + DCCWaveform::progTrack.pwmSpeed(255); } @@ -77,15 +77,7 @@ void DCC::setJoinRelayPin(byte joinRelayPin) { void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) { #ifdef DCdistrict if (cab == DCdistrict) { - uint8_t brake; - if (tSpeed <= 1) - brake = 255; - else if (tSpeed >= 126) - brake = 0; - else - brake = 2 * (127-tSpeed); - DCCWaveform::mainTrack.motorDriver->setSignal(tDirection); - DCCWaveform::mainTrack.motorDriver->setBrake(brake); + DCCWaveform::mainTrack.pwmSpeed(tSpeed, tDirection); } #else #error fooar diff --git a/DCCWaveform.h b/DCCWaveform.h index 0cbb5ff..db58574 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -107,7 +107,27 @@ class DCCWaveform { inline void setMaxAckPulseDuration(unsigned int i) { maxAckPulseDuration = i; } - MotorDriver* motorDriver; +#ifdef DCdistrict + inline void pwmSpeed(uint8_t tSpeed) { + // DCC Speed with 0,1 stop and speed steps 2 to 127 + uint8_t brake; + if (!motorDriver) + return; + if (tSpeed <= 1) + brake = 255; + else if (tSpeed >= 127) + brake = 0; + else + brake = 2 * (128-tSpeed); + motorDriver->setBrake(brake); + } + inline void pwmSpeed(uint8_t tSpeed, bool tDirection) { + if (!motorDriver) + return; + pwmSpeed(tSpeed); + motorDriver->setSignal(tDirection); + } +#endif private: @@ -122,7 +142,7 @@ class DCCWaveform { void checkAck(); bool isMainTrack; -// MotorDriver* motorDriver; + MotorDriver* motorDriver; // Transmission controller byte transmitPacket[MAX_PACKET_SIZE+1]; // +1 for checksum byte transmitLength;