mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-25 05:31:24 +01:00
Expotential overcurrent handling #1
This commit is contained in:
parent
9d9c6edc2f
commit
0583fac416
8
Config.h
8
Config.h
@ -3,20 +3,24 @@
|
|||||||
|
|
||||||
// This hardware configuration would normally be setup using a bunch of #ifdefs.
|
// This hardware configuration would normally be setup using a bunch of #ifdefs.
|
||||||
|
|
||||||
|
const byte UNUSED_PIN = 255;
|
||||||
|
|
||||||
const byte MAIN_POWER_PIN = 4;
|
const byte MAIN_POWER_PIN = 4;
|
||||||
const byte MAIN_SIGNAL_PIN = 7;
|
const byte MAIN_SIGNAL_PIN = 7;
|
||||||
const byte MAIN_SIGNAL_PIN_ALT = 0; // for hardware that flipflops signal pins
|
const byte MAIN_SIGNAL_PIN_ALT = UNUSED_PIN; // for hardware that flipflops signal pins
|
||||||
const byte MAIN_SENSE_PIN = A0;
|
const byte MAIN_SENSE_PIN = A0;
|
||||||
const byte MAIN_BRAKE_PIN = 9;
|
const byte MAIN_BRAKE_PIN = 9;
|
||||||
|
const byte MAIN_FAULT_PIN = 12;
|
||||||
|
|
||||||
const int MAIN_MAX_MILLIAMPS=2000;
|
const int MAIN_MAX_MILLIAMPS=2000;
|
||||||
const float MAIN_SENSE_FACTOR=18; // analgRead(MAIN_SENSE_PIN) * MAIN_SENSE_FACTOR = milliamps
|
const float MAIN_SENSE_FACTOR=18; // analgRead(MAIN_SENSE_PIN) * MAIN_SENSE_FACTOR = milliamps
|
||||||
|
|
||||||
const byte PROG_POWER_PIN = 2;
|
const byte PROG_POWER_PIN = 2;
|
||||||
const byte PROG_SIGNAL_PIN = 8;
|
const byte PROG_SIGNAL_PIN = 8;
|
||||||
const byte PROG_SIGNAL_PIN_ALT = 0; // for hardware that flipflops signal pins
|
const byte PROG_SIGNAL_PIN_ALT = UNUSED_PIN; // for hardware that flipflops signal pins
|
||||||
const byte PROG_SENSE_PIN = A1;
|
const byte PROG_SENSE_PIN = A1;
|
||||||
const byte PROG_BRAKE_PIN = 10;
|
const byte PROG_BRAKE_PIN = 10;
|
||||||
|
const byte PROG_FAULT_PIN = UNUSED_PIN;
|
||||||
|
|
||||||
const int PROG_MAX_MILLIAMPS=250;
|
const int PROG_MAX_MILLIAMPS=250;
|
||||||
const float PROG_SENSE_FACTOR=18; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps
|
const float PROG_SENSE_FACTOR=18; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps
|
||||||
|
@ -114,9 +114,9 @@ void DCCEXParser::parse(Print & stream, const byte *com, bool banAsync) {
|
|||||||
asyncBanned=banAsync;
|
asyncBanned=banAsync;
|
||||||
(void) EEPROM; // tell compiler not to warn thi is unused
|
(void) EEPROM; // tell compiler not to warn thi is unused
|
||||||
int p[MAX_PARAMS];
|
int p[MAX_PARAMS];
|
||||||
byte params=splitValues(p, com);
|
|
||||||
|
|
||||||
if (com[0]=='<') com++;
|
while (com[0]=='<' || com[0]==' ') com++; // strip off any number of < or spaces
|
||||||
|
byte params=splitValues(p, com);
|
||||||
byte opcode=com[0];
|
byte opcode=com[0];
|
||||||
|
|
||||||
if (filterCallback) filterCallback(stream,opcode,params,p);
|
if (filterCallback) filterCallback(stream,opcode,params,p);
|
||||||
|
@ -72,8 +72,9 @@ POWERMODE DCCWaveform::getPowerMode() {
|
|||||||
|
|
||||||
void DCCWaveform::setPowerMode(POWERMODE mode) {
|
void DCCWaveform::setPowerMode(POWERMODE mode) {
|
||||||
powerMode = mode;
|
powerMode = mode;
|
||||||
Hardware::setPower(isMainTrack, mode == POWERMODE::ON);
|
bool ison = (mode == POWERMODE::ON);
|
||||||
Hardware::setBrake(isMainTrack, mode == POWERMODE::OFF);
|
Hardware::setPower(isMainTrack, ison);
|
||||||
|
Hardware::setBrake(isMainTrack, !ison);
|
||||||
if (mode == POWERMODE::ON) delay(200);
|
if (mode == POWERMODE::ON) delay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,11 +90,20 @@ void DCCWaveform::checkPowerOverload() {
|
|||||||
case POWERMODE::ON:
|
case POWERMODE::ON:
|
||||||
// Check current
|
// Check current
|
||||||
lastCurrent = Hardware::getCurrentMilliamps(isMainTrack);
|
lastCurrent = Hardware::getCurrentMilliamps(isMainTrack);
|
||||||
if (lastCurrent < POWER_SAMPLE_MAX) sampleDelay = POWER_SAMPLE_ON_WAIT;
|
if (lastCurrent < POWER_SAMPLE_MAX) {
|
||||||
else {
|
sampleDelay = POWER_SAMPLE_ON_WAIT;
|
||||||
|
if(power_good_counter<100) {
|
||||||
|
power_good_counter++;
|
||||||
|
} else {
|
||||||
|
if (power_sample_overload_wait>POWER_SAMPLE_OVERLOAD_WAIT)
|
||||||
|
power_sample_overload_wait=POWER_SAMPLE_OVERLOAD_WAIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
setPowerMode(POWERMODE::OVERLOAD);
|
setPowerMode(POWERMODE::OVERLOAD);
|
||||||
DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d ***\n"), isMainTrack ? F("MAIN") : F("PROG"), lastCurrent, POWER_SAMPLE_MAX);
|
DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d offtime=%l ***\n"), isMainTrack ? F("MAIN") : F("PROG"), lastCurrent, POWER_SAMPLE_MAX, power_sample_overload_wait);
|
||||||
sampleDelay = POWER_SAMPLE_OVERLOAD_WAIT;
|
power_good_counter=0;
|
||||||
|
sampleDelay = power_sample_overload_wait;
|
||||||
|
power_sample_overload_wait *= 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWERMODE::OVERLOAD:
|
case POWERMODE::OVERLOAD:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
const int POWER_SAMPLE_MAX = 1000; // XXX only until correct short detection on prog rail is implemented
|
const int POWER_SAMPLE_MAX = 1000; // XXX only until correct short detection on prog rail is implemented
|
||||||
const int POWER_SAMPLE_ON_WAIT = 100;
|
const int POWER_SAMPLE_ON_WAIT = 100;
|
||||||
const int POWER_SAMPLE_OFF_WAIT = 1000;
|
const int POWER_SAMPLE_OFF_WAIT = 1000;
|
||||||
const int POWER_SAMPLE_OVERLOAD_WAIT = 4000;
|
const int POWER_SAMPLE_OVERLOAD_WAIT = 20;
|
||||||
|
|
||||||
|
|
||||||
// ACK current analogRead values (vary depending on motor shield and cpu voltage)
|
// ACK current analogRead values (vary depending on motor shield and cpu voltage)
|
||||||
@ -78,6 +78,8 @@ class DCCWaveform {
|
|||||||
POWERMODE powerMode;
|
POWERMODE powerMode;
|
||||||
unsigned long lastSampleTaken;
|
unsigned long lastSampleTaken;
|
||||||
unsigned int sampleDelay;
|
unsigned int sampleDelay;
|
||||||
|
unsigned long power_sample_overload_wait = POWER_SAMPLE_OVERLOAD_WAIT;
|
||||||
|
unsigned int power_good_counter = 0;
|
||||||
|
|
||||||
// ACK management (Prog track only)
|
// ACK management (Prog track only)
|
||||||
bool ackPending;
|
bool ackPending;
|
||||||
|
14
Hardware.cpp
14
Hardware.cpp
@ -17,14 +17,16 @@ void Hardware::init() {
|
|||||||
pinMode(MAIN_POWER_PIN, OUTPUT);
|
pinMode(MAIN_POWER_PIN, OUTPUT);
|
||||||
pinMode(MAIN_BRAKE_PIN, OUTPUT);
|
pinMode(MAIN_BRAKE_PIN, OUTPUT);
|
||||||
pinMode(MAIN_SIGNAL_PIN, OUTPUT);
|
pinMode(MAIN_SIGNAL_PIN, OUTPUT);
|
||||||
if (MAIN_SIGNAL_PIN_ALT) pinMode(MAIN_SIGNAL_PIN_ALT, OUTPUT);
|
if (MAIN_SIGNAL_PIN_ALT != UNUSED_PIN) pinMode(MAIN_SIGNAL_PIN_ALT, OUTPUT);
|
||||||
pinMode(MAIN_SENSE_PIN, INPUT);
|
pinMode(MAIN_SENSE_PIN, INPUT);
|
||||||
|
if (MAIN_FAULT_PIN != UNUSED_PIN) pinMode(MAIN_FAULT_PIN, INPUT);
|
||||||
|
|
||||||
pinMode(PROG_POWER_PIN, OUTPUT);
|
pinMode(PROG_POWER_PIN, OUTPUT);
|
||||||
pinMode(PROG_BRAKE_PIN, OUTPUT);
|
pinMode(PROG_BRAKE_PIN, OUTPUT);
|
||||||
pinMode(PROG_SIGNAL_PIN, OUTPUT);
|
pinMode(PROG_SIGNAL_PIN, OUTPUT);
|
||||||
if (PROG_SIGNAL_PIN_ALT) pinMode(PROG_SIGNAL_PIN_ALT, OUTPUT);
|
if (PROG_SIGNAL_PIN_ALT != UNUSED_PIN) pinMode(PROG_SIGNAL_PIN_ALT, OUTPUT);
|
||||||
pinMode(PROG_SENSE_PIN, INPUT);
|
pinMode(PROG_SENSE_PIN, INPUT);
|
||||||
|
if (PROG_FAULT_PIN != UNUSED_PIN) pinMode(PROG_FAULT_PIN, INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hardware::setPower(bool isMainTrack, bool on) {
|
void Hardware::setPower(bool isMainTrack, bool on) {
|
||||||
@ -38,13 +40,19 @@ void Hardware::setSignal(bool isMainTrack, bool high) {
|
|||||||
byte pin = isMainTrack ? MAIN_SIGNAL_PIN : PROG_SIGNAL_PIN;
|
byte pin = isMainTrack ? MAIN_SIGNAL_PIN : PROG_SIGNAL_PIN;
|
||||||
byte pin2 = isMainTrack ? MAIN_SIGNAL_PIN_ALT : PROG_SIGNAL_PIN_ALT;
|
byte pin2 = isMainTrack ? MAIN_SIGNAL_PIN_ALT : PROG_SIGNAL_PIN_ALT;
|
||||||
WritePin(pin, high ? HIGH : LOW);
|
WritePin(pin, high ? HIGH : LOW);
|
||||||
if (pin2) WritePin(pin2, high ? LOW : HIGH);
|
if (pin2 != UNUSED_PIN) WritePin(pin2, high ? LOW : HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Hardware::getCurrentMilliamps(bool isMainTrack) {
|
int Hardware::getCurrentMilliamps(bool isMainTrack) {
|
||||||
byte pin = isMainTrack ? MAIN_SENSE_PIN : PROG_SENSE_PIN;
|
byte pin = isMainTrack ? MAIN_SENSE_PIN : PROG_SENSE_PIN;
|
||||||
float factor = isMainTrack ? MAIN_SENSE_FACTOR : PROG_SENSE_FACTOR;
|
float factor = isMainTrack ? MAIN_SENSE_FACTOR : PROG_SENSE_FACTOR;
|
||||||
|
// tooo much crap for a interrupt routine. Will see how that goes.
|
||||||
|
byte faultpin = isMainTrack ? MAIN_FAULT_PIN : PROG_FAULT_PIN;
|
||||||
|
byte signalpin = isMainTrack ? MAIN_SIGNAL_PIN : PROG_SIGNAL_PIN;
|
||||||
|
|
||||||
|
|
||||||
|
if (faultpin != UNUSED_PIN && digitalRead(faultpin) == LOW && digitalRead(signalpin) == HIGH)
|
||||||
|
return 6666;
|
||||||
// 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
|
||||||
// so analogReadFast is used here. (-2uS)
|
// so analogReadFast is used here. (-2uS)
|
||||||
|
@ -31,6 +31,7 @@ void StringFormatter::send2(Print & stream,const __FlashStringHelper* format, va
|
|||||||
case 's': stream.print(va_arg(args, char*)); break;
|
case 's': stream.print(va_arg(args, char*)); break;
|
||||||
case 'S': stream.print((const __FlashStringHelper*)va_arg(args, char*)); break;
|
case 'S': stream.print((const __FlashStringHelper*)va_arg(args, char*)); break;
|
||||||
case 'd': stream.print(va_arg(args, int), DEC); break;
|
case 'd': stream.print(va_arg(args, int), DEC); break;
|
||||||
|
case 'l': stream.print(va_arg(args, long), DEC); break;
|
||||||
case 'b': stream.print(va_arg(args, int), BIN); break;
|
case 'b': stream.print(va_arg(args, int), BIN); break;
|
||||||
case 'o': stream.print(va_arg(args, int), OCT); break;
|
case 'o': stream.print(va_arg(args, int), OCT); break;
|
||||||
case 'x': stream.print(va_arg(args, int), HEX); break;
|
case 'x': stream.print(va_arg(args, int), HEX); break;
|
||||||
|
Loading…
Reference in New Issue
Block a user