-
Notifications
You must be signed in to change notification settings - Fork 13
/
FanController.cpp
107 lines (95 loc) · 2.61 KB
/
FanController.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
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "Arduino.h"
#include "FanController.h"
#if defined(ARDUINO_ARCH_ESP32)
#include <analogWrite.h>
#endif
#if defined(ESP8266)
#define ISR_PREFIX ICACHE_RAM_ATTR
#else
#define ISR_PREFIX
#endif
FanController::FanController(byte sensorPin, unsigned int sensorThreshold, byte pwmPin)
{
_sensorPin = sensorPin;
_sensorInterruptPin = digitalPinToInterrupt(sensorPin);
_sensorThreshold = sensorThreshold;
_pwmPin = pwmPin;
pinMode(pwmPin, OUTPUT);
_pwmDutyCycle = 100;
}
void FanController::begin()
{
static byte instance;
_instance = instance;
_instances[instance] = this;
#if defined(ARDUINO_ARCH_ESP32)
analogWriteResolution(10);
analogWriteFrequency(25000);
#endif
digitalWrite(_sensorPin, HIGH);
setDutyCycle(_pwmDutyCycle);
_attachInterrupt();
instance++;
}
unsigned int FanController::getSpeed() {
unsigned int elapsed = millis() - _lastMillis;
if (elapsed > _sensorThreshold)
{
detachInterrupt(_sensorInterruptPin);
double correctionFactor = 1000.0 / elapsed;
_lastReading = correctionFactor * _halfRevs / 2 * 60;
_halfRevs = 0;
_lastMillis = millis();
_attachInterrupt();
}
return _lastReading;
}
void FanController::setDutyCycle(byte dutyCycle) {
_pwmDutyCycle = min((int)dutyCycle, 100);
analogWrite(_pwmPin, 2.55 * _pwmDutyCycle);
}
byte FanController::getDutyCycle() {
return _pwmDutyCycle;
}
void FanController::_attachInterrupt()
{
switch (_instance)
{
case 0:
attachInterrupt(_sensorInterruptPin, _triggerExt0, FALLING);
break;
case 1:
attachInterrupt(_sensorInterruptPin, _triggerExt1, FALLING);
break;
case 2:
attachInterrupt(_sensorInterruptPin, _triggerExt2, FALLING);
break;
case 3:
attachInterrupt(_sensorInterruptPin, _triggerExt3, FALLING);
break;
case 4:
attachInterrupt(_sensorInterruptPin, _triggerExt4, FALLING);
break;
case 5:
attachInterrupt(_sensorInterruptPin, _triggerExt5, FALLING);
break;
}
}
FanController * FanController::_instances[6];
void FanController::_trigger()
{
_halfRevs++;
}
void FanController::_triggerCaller(byte instance)
{
if (FanController::_instances[instance] != nullptr)
{
FanController::_instances[instance]->_trigger();
}
}
ISR_PREFIX void FanController::_triggerExt0() { FanController::_triggerCaller(0); }
ISR_PREFIX void FanController::_triggerExt1() { FanController::_triggerCaller(1); }
ISR_PREFIX void FanController::_triggerExt2() { FanController::_triggerCaller(2); }
ISR_PREFIX void FanController::_triggerExt3() { FanController::_triggerCaller(3); }
ISR_PREFIX void FanController::_triggerExt4() { FanController::_triggerCaller(4); }
ISR_PREFIX void FanController::_triggerExt5() { FanController::_triggerCaller(5); }