mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-24 13:21:23 +01:00
stash incomplete
This commit is contained in:
parent
a217031f24
commit
ddc3917519
@ -20,19 +20,26 @@
|
|||||||
#include "Hardware.h"
|
#include "Hardware.h"
|
||||||
#include "DCCWaveform.h"
|
#include "DCCWaveform.h"
|
||||||
#include "DIAG.h"
|
#include "DIAG.h"
|
||||||
|
#include <ArduinoTimers.h> // use IDE menu Tools..Manage Libraries to locate and install TimerOne
|
||||||
|
|
||||||
DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true, (int)(MAIN_MAX_MILLIAMPS / MAIN_SENSE_FACTOR));
|
|
||||||
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false, (int)(PROG_MAX_MILLIAMPS / PROG_SENSE_FACTOR));
|
DCCWaveform DCCWaveform::mainTrack=NULL;
|
||||||
|
DCCWaveform DCCWaveform::progTrack=NULL;
|
||||||
|
|
||||||
const int ACK_MIN_PULSE_RAW=65 / PROG_SENSE_FACTOR;
|
const int ACK_MIN_PULSE_RAW=65 / PROG_SENSE_FACTOR;
|
||||||
|
|
||||||
bool DCCWaveform::progTrackSyncMain=false;
|
bool DCCWaveform::progTrackSyncMain=false;
|
||||||
|
|
||||||
void DCCWaveform::begin() {
|
void DCCWaveform::begin(MotorDriver mainDriver, MotorDriver progDriver) {
|
||||||
Hardware::init();
|
|
||||||
Hardware::setCallback(58, interruptHandler);
|
mainTrack=new DCCWaveform(PREAMBLE_BITS_MAIN, true, mainDriver);
|
||||||
mainTrack.beginTrack();
|
progTrack=new DCCWaveform(PREAMBLE_BITS_PROG, false, progDriver);
|
||||||
progTrack.beginTrack();
|
progTrack.beginTrack(progDriver);
|
||||||
|
TimerA.initialize();
|
||||||
|
TimerA.setPeriod(58);
|
||||||
|
TimerA.attachInterrupt(interruptHandler);
|
||||||
|
TimerA.start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCCWaveform::loop() {
|
void DCCWaveform::loop() {
|
||||||
@ -66,8 +73,9 @@ void DCCWaveform::interruptHandler() {
|
|||||||
const byte bitMask[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
const byte bitMask[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||||
|
|
||||||
|
|
||||||
DCCWaveform::DCCWaveform( byte preambleBits, bool isMain, int rawCurrentTrip) {
|
DCCWaveform::DCCWaveform( byte preambleBits, bool isMain, MotorDriver driver) {
|
||||||
// establish appropriate pins
|
// establish appropriate pins
|
||||||
|
motorDriver=driver;
|
||||||
rawCurrentTripValue=rawCurrentTrip;
|
rawCurrentTripValue=rawCurrentTrip;
|
||||||
isMainTrack = isMain;
|
isMainTrack = isMain;
|
||||||
packetPending = false;
|
packetPending = false;
|
||||||
@ -80,11 +88,8 @@ DCCWaveform::DCCWaveform( byte preambleBits, bool isMain, int rawCurrentTrip) {
|
|||||||
bits_sent = 0;
|
bits_sent = 0;
|
||||||
sampleDelay = 0;
|
sampleDelay = 0;
|
||||||
lastSampleTaken = millis();
|
lastSampleTaken = millis();
|
||||||
ackPending=false;
|
ackPending=false;
|
||||||
}
|
setPowerMode(POWERMODE::ON);
|
||||||
void DCCWaveform::beginTrack() {
|
|
||||||
setPowerMode(POWERMODE::ON);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
POWERMODE DCCWaveform::getPowerMode() {
|
POWERMODE DCCWaveform::getPowerMode() {
|
||||||
@ -94,8 +99,7 @@ POWERMODE DCCWaveform::getPowerMode() {
|
|||||||
void DCCWaveform::setPowerMode(POWERMODE mode) {
|
void DCCWaveform::setPowerMode(POWERMODE mode) {
|
||||||
powerMode = mode;
|
powerMode = mode;
|
||||||
bool ison = (mode == POWERMODE::ON);
|
bool ison = (mode == POWERMODE::ON);
|
||||||
Hardware::setPower(isMainTrack, ison);
|
driver.setPower( ison);
|
||||||
Hardware::setBrake(isMainTrack, !ison);
|
|
||||||
if (mode == POWERMODE::ON) delay(200);
|
if (mode == POWERMODE::ON) delay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +108,7 @@ void DCCWaveform::checkPowerOverload() {
|
|||||||
|
|
||||||
if (millis() - lastSampleTaken < sampleDelay) return;
|
if (millis() - lastSampleTaken < sampleDelay) return;
|
||||||
lastSampleTaken = millis();
|
lastSampleTaken = millis();
|
||||||
int tripValue= rawCurrentTripValue;
|
int tripValue= driver.rawCurrentTripValue;
|
||||||
if (!isMainTrack && (ackPending || progTrackSyncMain)) tripValue=ACK_CURRENT_TRIP;
|
if (!isMainTrack && (ackPending || progTrackSyncMain)) tripValue=ACK_CURRENT_TRIP;
|
||||||
|
|
||||||
switch (powerMode) {
|
switch (powerMode) {
|
||||||
@ -113,7 +117,7 @@ void DCCWaveform::checkPowerOverload() {
|
|||||||
break;
|
break;
|
||||||
case POWERMODE::ON:
|
case POWERMODE::ON:
|
||||||
// Check current
|
// Check current
|
||||||
lastCurrent = Hardware::getCurrentRaw(isMainTrack);
|
lastCurrent = driver.getCurrentRaw();
|
||||||
if (lastCurrent <= tripValue) {
|
if (lastCurrent <= tripValue) {
|
||||||
sampleDelay = POWER_SAMPLE_ON_WAIT;
|
sampleDelay = POWER_SAMPLE_ON_WAIT;
|
||||||
if(power_good_counter<100)
|
if(power_good_counter<100)
|
||||||
@ -122,8 +126,8 @@ void DCCWaveform::checkPowerOverload() {
|
|||||||
if (power_sample_overload_wait>POWER_SAMPLE_OVERLOAD_WAIT) power_sample_overload_wait=POWER_SAMPLE_OVERLOAD_WAIT;
|
if (power_sample_overload_wait>POWER_SAMPLE_OVERLOAD_WAIT) power_sample_overload_wait=POWER_SAMPLE_OVERLOAD_WAIT;
|
||||||
} else {
|
} else {
|
||||||
setPowerMode(POWERMODE::OVERLOAD);
|
setPowerMode(POWERMODE::OVERLOAD);
|
||||||
unsigned int mA=Hardware::getCurrentMilliamps(isMainTrack,lastCurrent);
|
unsigned int mA=driver.convertRawToMilliamps(lastCurrent);
|
||||||
unsigned int maxmA=Hardware::getCurrentMilliamps(isMainTrack,tripValue);
|
unsigned int maxmA=driver.convertRawToMilliamps(tripValue);
|
||||||
DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d offtime=%l ***\n"), isMainTrack ? F("MAIN") : F("PROG"), mA, maxmA, power_sample_overload_wait);
|
DIAG(F("\n*** %S TRACK POWER OVERLOAD current=%d max=%d offtime=%l ***\n"), isMainTrack ? F("MAIN") : F("PROG"), mA, maxmA, power_sample_overload_wait);
|
||||||
power_good_counter=0;
|
power_good_counter=0;
|
||||||
sampleDelay = power_sample_overload_wait;
|
sampleDelay = power_sample_overload_wait;
|
||||||
@ -183,10 +187,11 @@ void DCCWaveform::setSignal(bool high) {
|
|||||||
if (progTrackSyncMain) {
|
if (progTrackSyncMain) {
|
||||||
if (!isMainTrack) return; // ignore PROG track waveform while in sync
|
if (!isMainTrack) return; // ignore PROG track waveform while in sync
|
||||||
// set both tracks to same signal
|
// set both tracks to same signal
|
||||||
Hardware::setSyncSignal(high);
|
driver.setSyncSignal(high);
|
||||||
|
progTrack.driver.setSignal(high);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Hardware::setSignal(isMainTrack,high);
|
driver.setSignal(high);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCCWaveform::interrupt2() {
|
void DCCWaveform::interrupt2() {
|
||||||
@ -264,8 +269,8 @@ int DCCWaveform::getLastCurrent() {
|
|||||||
|
|
||||||
void DCCWaveform::setAckBaseline(bool debug) {
|
void DCCWaveform::setAckBaseline(bool debug) {
|
||||||
if (isMainTrack) return;
|
if (isMainTrack) return;
|
||||||
ackThreshold=Hardware::getCurrentRaw(false) + ACK_MIN_PULSE_RAW;
|
ackThreshold=driver.getCurrentRaw() + ACK_MIN_PULSE_RAW;
|
||||||
if (debug) DIAG(F("\nACK-BASELINE %d/%dmA"),ackThreshold,Hardware::getCurrentMilliamps(false,ackThreshold));
|
if (debug) DIAG(F("\nACK-BASELINE %d/%dmA"),ackThreshold,driver.convertRawToMilliamps(ackThreshold));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCCWaveform::setAckPending(bool debug) {
|
void DCCWaveform::setAckPending(bool debug) {
|
||||||
|
77
MotorDriver.cpp
Normal file
77
MotorDriver.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* © 2020, Chris Harlow. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of Asbelos DCC API
|
||||||
|
*
|
||||||
|
* This is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* It is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "MotorDriver.h"
|
||||||
|
#include "AnalogReadFast.h"
|
||||||
|
#include "DIAG.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_AVR)
|
||||||
|
#include <DIO2.h> // use IDE menu Tools..Manage Libraries to locate and install DIO2
|
||||||
|
#define WritePin digitalWrite2
|
||||||
|
#define ReadPin digitalRead2
|
||||||
|
#else
|
||||||
|
#define WritePin digitalWrite
|
||||||
|
#define ReadPin digitalRead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MotorDriver::MotorDriver(byte power_pin, int signal_pin, int signal_pin2, int brake_pin, int current_pin, float sense_factor, int fault_pin) {
|
||||||
|
powerPin=power_pin;
|
||||||
|
signalPin=signal_pin;
|
||||||
|
signalPin2=signal_pin2;
|
||||||
|
brakePin=brake_pin;
|
||||||
|
currentPin=current_pin;
|
||||||
|
senseFactor=sense_factor;
|
||||||
|
faultPin=fault_pin;
|
||||||
|
I32=(int) (32000 / sensefactor);
|
||||||
|
|
||||||
|
pinMode(powerPin, OUTPUT);
|
||||||
|
pinMode(brakePin, OUTPUT);
|
||||||
|
pinMode(signalPin, OUTPUT);
|
||||||
|
if (signalPin2 != UNUSED_PIN) pinMode(signalPin2, OUTPUT);
|
||||||
|
pinMode(currentPin, INPUT);
|
||||||
|
if (faultPin != UNUSED_PIN) pinMode(faultPin, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorDriver::setPower(bool on) {
|
||||||
|
WritePin(powerPin, on ? HIGH : LOW);
|
||||||
|
}
|
||||||
|
void MotorDriver::setBrake( bool on) {
|
||||||
|
WritePin(brakePin, on ? HIGH : LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorDriver::setSignal( bool high) {
|
||||||
|
WritePin(signalPin, high ? HIGH : LOW);
|
||||||
|
if (signalPin2 != UNUSED_PIN) WritePin(signalPin2, high ? LOW : HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MotorDriver::getCurrentRaw() {
|
||||||
|
if (faultPin != UNUSED_PIN && ReadPin(faultPin) == LOW && ReadPin(powerPin) == HIGH)
|
||||||
|
return I32:
|
||||||
|
|
||||||
|
// IMPORTANT: This function can be called in Interrupt() time within the 56uS timer
|
||||||
|
// The default analogRead takes ~100uS which is catastrphic
|
||||||
|
// so analogReadFast is used here. (-2uS)
|
||||||
|
return analogReadFast(sensePin);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int MortorDriver::convertRawToMilliamps( int raw) {
|
||||||
|
return (unsigned int)(raw * senseFactor);
|
||||||
|
}
|
35
MotorDriver.h
Normal file
35
MotorDriver.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* © 2020, Chris Harlow. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of Asbelos DCC API
|
||||||
|
*
|
||||||
|
* This is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* It is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef MotorDriver_h
|
||||||
|
#define MotorDriver_h
|
||||||
|
// Virtualised Motor shield 1-track hardware Interface
|
||||||
|
class MotorDriver {
|
||||||
|
public:
|
||||||
|
MotorDriver(byte power_pin, byte signal_pin, byte signal_pin2, byte brake_pin, byte current_pin, float senseFactor, byte faultPin);
|
||||||
|
void setPower( bool on);
|
||||||
|
void setSignal( bool high);
|
||||||
|
void setBrake( bool on);
|
||||||
|
int getCurrentRaw();
|
||||||
|
unsigned int convertToMilliamps( int rawValue);
|
||||||
|
private:
|
||||||
|
byte powerPin, signalPin, signalPin2, brakePin,currentPin,faultPin;
|
||||||
|
float senseFactor;
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user