-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVoltageControl.h
More file actions
148 lines (117 loc) · 4.67 KB
/
VoltageControl.h
File metadata and controls
148 lines (117 loc) · 4.67 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* VoltageControl.h
* Voltage Control class
*
* @author Nikolai Tikhonov aka Dragon_Knight <dubki4132@mail.ru>, https://vk.com/globalzone_edev
* @licenses MIT https://opensource.org/licenses/MIT
* @repo https://github.com/Dragon-Knight/VoltageControl
*/
#pragma once
template<uint8_t _id = 0>
class VoltageControl
{
public:
using request_t = int32_t (*)(uint8_t id);
using response_t = void (*)(uint8_t id, int32_t value, int8_t state);
VoltageControl()
{
return;
};
VoltageControl(request_t callback_req, uint16_t interval_req, response_t callback_res, bool once, uint32_t coefficient, int32_t vmin, int32_t vmax) : _data{callback_req, interval_req, 0, callback_res, once, 0, coefficient, vmin, vmax, false}
{
return;
};
// Указать колбэк-функцию запроса напряжения и интервал запроса в мс.
void SetRequest(request_t callback, uint16_t interval)
{
_data.request_callback = callback;
_data.request_interval = interval;
return;
};
// Указать колбэк-функцию изменения напряжения и интервал оповещения в мс.
void SetResponse(response_t callback, bool once = false)
{
_data.response_callback = callback;
_data.response_once = once;
return;
};
// Указать коэффициент пересчёта АЦП в мВ.
void SetCoefficient(uint32_t coefficient)
{
_data.coefficient = coefficient;
return;
};
// Указать минимально допустимое напряжение в мВ.
void SetMin(uint32_t vmin)
{
_data.vmin = vmin;
return;
};
// Указать максимально допустимое напряжение в мВ.
void SetMax(uint32_t vmax)
{
_data.vmax = vmax;
return;
};
// Запустить класс.
void SetStart()
{
_data.active = true;
return;
};
// Остановить класс.
void SetStop()
{
_data.active = false;
return;
};
// Проверить текущее напряжение на нахождение между vmin и vmax.
int8_t GetValid()
{
int32_t voltage = GetVoltage();
return ((voltage < _data.vmin) ? -1 : ((voltage > _data.vmax) ? 1 : 0));
};
// Вернуть текущее напряжение, в мВ.
int32_t GetVoltage()
{
uint32_t raw = _data.request_callback(_id);
return (raw * _data.coefficient) / 1000;
};
// Обработка класса.
void Processing(uint32_t currentTime = millis())
{
if(_data.active == false) return;
if(currentTime - _data.request_time < _data.request_interval) return;
{
_data.request_time = currentTime;
int32_t voltage = GetVoltage();
int8_t state = ((voltage < _data.vmin) ? -1 : ((voltage > _data.vmax) ? 1 : 0));
if( _data.response_once == false || (_data.response_once == true && _data.old_state != state) )
{
_data.response_callback(_id, voltage, state);
_data.old_state = state;
}
}
return;
};
// Утилита расчёта коэффициента по VRev, R1, R2 и уровню квантования.
// PS: Не стоит обращать внимание на тип float. Эта функция полностью просчитывается на этапе компиляции и возвращает тип uint32_t.
static inline uint32_t GetCoefficient(float vref, float r1 = 0, float r2 = 1, float quantization = 1024)
{
return ((vref / quantization) * ((r1 + r2) / r2)) + 0.5;
}
private:
struct data_t
{
request_t request_callback; // Колбэк-функция запроса напряжения.
uint16_t request_interval; // Интервал вызова колбэк-функции запроса напряжения.
uint32_t request_time; // Время последнего запроса напряжения.
response_t response_callback; // Колбэк-функция изменения напряжения.
bool response_once; // Флаг одиночного вызова при изменении состояния напряжения.
int8_t old_state; // Состояние предыдущего измерения. Только при response_once == true
uint32_t coefficient; // Коэффициент пересчёта значения АЦП в мВ.
int32_t vmin; // Минимально допустимое напряжение, в мВ.
int32_t vmax; // Максимально допустимое напряжение, в мВ.
bool active; // Флаг активности класса.
} _data;
};