-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathTimeprop.cpp
94 lines (86 loc) · 2.88 KB
/
Timeprop.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* Copyright 2018 Colin Law
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* See Timeprop.h for Usage
*
**/
#include "Timeprop.h"
void Timeprop::initialise( int cycleTime, int deadTime, unsigned char invert, float fallbackPower, int maxUpdateInterval,
unsigned long nowSecs) {
m_cycleTime = cycleTime;
m_deadTime = deadTime;
m_invert = invert;
m_fallbackPower = fallbackPower;
m_maxUpdateInterval = maxUpdateInterval;
m_dtoc = (float)deadTime/cycleTime;
m_opState = 0;
setPower(m_fallbackPower, nowSecs);
}
/* set current power required 0:1, given power and current time in seconds */
void Timeprop::setPower( float power, unsigned long nowSecs ) {
if (power < 0.0) {
power = 0.0;
} else if (power >= 1.0) {
power = 1.0;
}
m_power = power;
m_lastPowerUpdateTime = nowSecs;
};
/* called regularly to provide new output value */
/* returns new o/p state 0, 1 */
int Timeprop::tick( unsigned long nowSecs) {
int newState;
float wave;
float direction;
float effectivePower;
// check whether too long has elapsed since power was last updated
if (m_maxUpdateInterval > 0 && nowSecs - m_lastPowerUpdateTime > m_maxUpdateInterval) {
// yes, go to fallback power
setPower(m_fallbackPower, nowSecs);
}
wave = (nowSecs % m_cycleTime)/(float)m_cycleTime;
// determine direction of travel and convert to triangular wave
if (wave < 0.5) {
direction = 1; // on the way up
wave = wave*2;
} else {
direction = -1; // on the way down
wave = (1 - wave)*2;
}
// if a dead_time has been supplied for this o/p then adjust power accordingly
if (m_deadTime > 0 && m_power > 0.0 && m_power < 1.0) {
effectivePower = (1.0-2.0*m_dtoc)*m_power + m_dtoc;
} else {
effectivePower = m_power;
}
// cope with end cases in case values outside 0..1
if (effectivePower <= 0.0) {
newState = 0; // no heat
} else if (effectivePower >= 1.0) {
newState = 1; // full heat
} else {
// only allow power to come on on the way down and off on the way up, to reduce short pulses
if (effectivePower >= wave && direction == -1) {
newState = 1;
} else if (effectivePower <= wave && direction == 1) {
newState = 0;
} else {
// otherwise leave it as it is
newState = m_opState;
}
}
m_opState = newState;
return m_invert ? (1-m_opState) : m_opState;
}