Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Diff: Libs/DC_DC/DC_DC.cpp
- Revision:
- 38:8efacce315ae
- Parent:
- 36:0afc0fc8f86b
--- a/Libs/DC_DC/DC_DC.cpp Thu Jan 22 07:59:48 2015 +0000
+++ b/Libs/DC_DC/DC_DC.cpp Sat Feb 07 08:54:51 2015 +0000
@@ -4,78 +4,118 @@
#define TURN_OFF dcdcControl = 1; isControlPinOn = false;
#define TURN_ON dcdcControl = 0; isControlPinOn = true;
-const float CURRENT_MULTIPLIER_DEFAULT = 41.35338345864663; // Full scale amps
-const float CURRENT_OFFSET_DEFAULT = 0.0909090909090909; // Float adc reading for 0 amps
+const float CURRENT_MULTIPLIER_DEFAULT = 41.35338345864663; // Full scale amps
+const float CURRENT_OFFSET_DEFAULT = 0.0909090909090909; // Float adc reading for 0 amps
-const float DC_DC_ON_THRESHOLD = 0.5; // Current draw required in order to declare it as on
-const int STARTUP_DELAY_MS = 1000; // DC-DC converter startup time in milliseconds
-const float OVER_CURRENT_THRESHOLD = 25; // Overcurrent threshold
-const float CURRENT_SENSOR_LLIM = -1.0; // Lowest allowable reading before declaring sensor broken
-const float CURRENT_SENSOR_ULIM = 33; // Sensor is at 5V rail, broken
-const int STOP_DELAY_MS = 1000; // Amount of time given to turn-off before flagging error
+const float CURRENT_SENSOR_LLIM = -1.0; // Lowest allowable reading before declaring sensor broken
+const float CURRENT_SENSOR_ULIM = 33; // Sensor is at 5V rail, broken
-DC_DC::DC_DC(PinName _dcdcPin, PinName _dcdcCurrent, PinName _fan1, PinName _fan2, PinName _pump1, PinName _pump2, float period, float slew) :
+DC_DC::DC_DC(PinName _dcdcPin, PinName _dcdcCurrent, PinName _fan1, PinName _fan2, PinName _pump1, PinName _pump2, float period, float slew, unsigned int size) :
dcdcControl(_dcdcPin, 1), dcdcCurrent(_dcdcCurrent), fan1(_fan1, period, slew), fan2(_fan2, period, slew), pump1(_pump1, period, slew), pump2(_pump2, period, slew)
{
TURN_OFF
currentOffset = CURRENT_OFFSET_DEFAULT;
- starting = false;
- stopping = false;
buffTracker = 0;
wait_ms(10); // Make sure Hall effect IC is ready
startTimer.reset();
stopTimer.reset();
status=0;
+ _size = 0;
+ onThreshold = 0;
+ startDelay = 0;
+ stopDelay = 0;
+ overCurrent = 0;
+
+ filterBuff = new float[size];
+ if (filterBuff == 0) {
+ error("DC-DC failed to allocate memory");
+ }
+ _size = size;
// Fill up the buffer
- for (int i = 0; i < DC_DC_FILTER_TAPS; i++) {
+ for (int i = 0; i < _size; i++) {
filterBuff[i] = (dcdcCurrent - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
wait_ms(10);
}
- updateCurrent(); // Compute avg
- sample(); // Use sample() function to check for errors
- if (!critError) { // If no errors, zero the sensor
- currentOffset = (current / CURRENT_MULTIPLIER_DEFAULT) + CURRENT_OFFSET_DEFAULT;
- }
+ // Compute the zero
+ currentOffset = (current / CURRENT_MULTIPLIER_DEFAULT) + CURRENT_OFFSET_DEFAULT;
// Correct the buffer for the new zero
- for (int i = 0; i < DC_DC_FILTER_TAPS; i++) {
+ for (int i = 0; i < _size; i++) {
filterBuff[i] = ((CURRENT_OFFSET_DEFAULT - currentOffset) * CURRENT_MULTIPLIER_DEFAULT) + filterBuff[i];
}
}
+void DC_DC::setup(float* _onThreshold, float* _overCurrent, float* _startDelay, float* _stopDelay) {
+ onThreshold = _onThreshold;
+ overCurrent = _overCurrent;
+ startDelay = _startDelay;
+ startDelay = _startDelay;
+}
+
+bool DC_DC::size(unsigned int size) {
+ if (_size == size) return false;
+
+ // Get recent
+ updateCurrent();
+ float avg = getCurrent();
+
+ // Allocate new
+ float* newBuff = new float[size];
+ if (newBuff == 0) return false; // Not found, nothing has been changed
+ else {
+ delete[] filterBuff; // Free old
+ __disable_irq();
+
+ _size = size; // Set size
+ filterBuff = newBuff; // Transfer to new
+ for (int i = 0; i < size; i++) filterBuff[i] = avg; // Pre-fill with old average
+
+ __enable_irq();
+ return true;
+ }
+}
void DC_DC::updateCurrent()
{
float avg=0;
- for (int i = 0; i < DC_DC_FILTER_TAPS; i++) {
+ for (int i = 0; i < _size; i++) {
avg += filterBuff[i];
}
- avg /= DC_DC_FILTER_TAPS;
+ avg /= _size;
current = avg;
}
void DC_DC::set(bool on)
{
+ if (onThreshold == 0) return; // Not setup yet
+
// Do nothing if already on
if (on && isControlPinOn) return;
- // Do nothing if already off
- if (!on && !isControlPinOn) return;
+ // Double check if already off
+ if (!on && !isControlPinOn) {
+ fan1.directOff();
+ fan2.directOff();
+ pump1.directOff();
+ pump2.directOff();
+ TURN_OFF
+ }
// If start requested and no error
- if (on && !critError) {
- starting = true;
+ if (on && !critError && !(status & POWER_DOWN)) {
+ status |= POWER_UP;
+ status &= ~POWER_DOWN;
TURN_ON
startTimer.reset();
startTimer.start();
stopTimer.stop();
stopTimer.reset();
- stopping = false;
- // If stop requested
+ // If stop requested
} else {
- stopping = true;
+ status &= ~POWER_UP;
+ status |= POWER_DOWN;
fan1.directOff();
fan2.directOff();
pump1.directOff();
@@ -85,7 +125,6 @@
stopTimer.start();
startTimer.stop();
startTimer.reset();
- starting = false;
}
}
@@ -94,61 +133,44 @@
// Get next current sample
float curr = (dcdcCurrent.read() - currentOffset) * CURRENT_MULTIPLIER_DEFAULT;
- filterBuff[buffTracker] = curr; // Add to buffer filter
- buffTracker++;
- if (buffTracker >= DC_DC_FILTER_TAPS) buffTracker = 0;
+ filterBuff[buffTracker++] = curr; // Add to buffer filter
+ buffTracker %= _size;
updateCurrent(); // Compute average
+ if (onThreshold == 0) return; // Not setup yet
+
// Update status
- register char stat = status & 0xF0; // The upper 4 bits (locking errors)
- if (current >= DC_DC_ON_THRESHOLD) stat |= ConvOn; // The converter is actually on (positive current)
- if (isControlPinOn) stat |= SetOn; // The converter is set on
+ char stat = 0;
+ if (current >= *onThreshold) stat |= CONV_ON; // The converter is actually on (positive current)
+ if (isControlPinOn) stat |= SET_ON; // The converter is set on
// During Timed Startup Phase
- if (starting) {
- stat |= PowerUp; // Indicate state in status byte
- if (startTimer.read_ms() >= STARTUP_DELAY_MS) { // Start time elapsed
- if (stat & ConvOn) { // Positive current detected
- startTimer.stop(); // Stop timer
- startTimer.reset(); // Reset to zero
- starting = false; // Indicate running
- } else {
- startTimer.stop();
+ if (stat & POWER_UP) {
+ if (startTimer.read() >= *startDelay) { // Start time elapsed
+ if (stat & CONV_ON) { // Positive current detected
+ startTimer.stop(); // Stop timer
startTimer.reset();
- stat |= FailStart; // Failed to start
+ stat &= ~POWER_UP; // Done power-up
}
}
- } else stat &= ~PowerUp;
+ }
// During Timed Stopping Phase
- if (stopping) {
- stat |= PowerDown; // Indicate state in status byte
- if (stopTimer.read_ms() >= STOP_DELAY_MS) { // Stop time elapsed
- if (stat & ConvOn) { // Converter still on
- stopTimer.stop();
+ if (stat & POWER_DOWN) {
+ if (stopTimer.read() >= *stopDelay) { // Stop time elapsed
+ if (!(stat & CONV_ON)) { // Current dropped, its off
+ stopTimer.stop(); // Stop timer
stopTimer.reset();
- stat |= FailStop; // It didn't turn off even after timer expired!
- } else { // Its actually off
- stopping = false;
- stopTimer.stop();
- stopTimer.reset();
+ stat &= ~POWER_DOWN; // Done power-down
}
}
- } else stat &= ~PowerDown;
-
- // While in steady state
- if (!stopping && !starting) {
- if ((stat & SetOn) && !(stat & ConvOn)) stat |= FailStart; // Should be running but its not
- else stat &= ~FailStart;
- if (!(stat & SetOn) && (stat & ConvOn)) stat |= FailStop; // Should be stopped but its not
- else stat &= ~FailStop;
}
- if (current < CURRENT_SENSOR_LLIM || current > CURRENT_SENSOR_ULIM) stat |= SensorFault; // Sensor out of range
- else if (current > OVER_CURRENT_THRESHOLD) stat |= OverCurrent; // Over current
+ if (current < CURRENT_SENSOR_LLIM || current > CURRENT_SENSOR_ULIM) stat |= SENSOR_FAULT; // Sensor out of range
+ else if (current > *overCurrent) stat |= OVER_CURRENT; // Over current
// Process critical error conditions
- if (stat & (SensorFault | OverCurrent)) critError = true;
+ if (stat & (SENSOR_FAULT | OVER_CURRENT)) critError = true;
else critError = false;
status = stat;
@@ -161,16 +183,26 @@
TURN_OFF
startTimer.stop();
startTimer.reset();
- starting = false;
+ }
+
+ // Don't allow to run if still powering on or off
+ if (stat & (POWER_UP | POWER_DOWN)) {
+ fan1.directOff();
+ fan2.directOff();
+ pump1.directOff();
+ pump2.directOff();
}
}
void DC_DC::setPwm(enum Channel_T chan, float duty)
{
- // Do nothing if error present, starting in startup, or DC-DC not actually on, or not set on
- if (critError || starting || stopping || !(status & ConvOn) || !isControlPinOn) return;
-
- else {
+ // Off if error present, starting in startup, or DC-DC not actually on, or not set on
+ if (!onThreshold || critError || !(status & CONV_ON) || !isControlPinOn || (status & (POWER_UP | POWER_DOWN))) {
+ fan1.directOff();
+ fan2.directOff();
+ pump1.directOff();
+ pump2.directOff();
+ } else {
if (chan == FAN1) fan1.write(duty);
if (chan == FAN2) fan2.write(duty);
if (chan == PUMP1) pump1.write(duty);
@@ -179,9 +211,9 @@
}
float DC_DC::readPwm(enum Channel_T chan)
{
- if (chan == FAN1) return fan1.readRaw();
- if (chan == FAN2) return fan2.readRaw();
- if (chan == PUMP1) return pump1.readRaw();
- if (chan == PUMP2) return pump2.readRaw();
+ if (chan == FAN1) return fan1.readRaw();
+ if (chan == FAN2) return fan2.readRaw();
+ if (chan == PUMP1) return pump1.readRaw();
+ if (chan == PUMP2) return pump2.readRaw();
else return 0;
}
\ No newline at end of file
