Skip to content

Commit

Permalink
upd
Browse files Browse the repository at this point in the history
  • Loading branch information
GyverLibs committed Oct 23, 2021
1 parent 1a07988 commit f01300b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 43 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ void loop() {
<a id="versions"></a>
## Версии
- v2.1 - исправлена getResultTimer
- v2.2 - улучшен и упрощён алгоритм
<a id="feedback"></a>
## Баги и обратная связь
Expand Down
9 changes: 4 additions & 5 deletions examples/relay_simulation/relay_simulation.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void setup() {
Serial.begin(9600);
regulator.setpoint = 40;
regulator.hysteresis = 5;
regulator.k = 0.5;
regulator.k = 0.6;
}

boolean state = 0;
Expand All @@ -23,9 +23,9 @@ void loop() {

Serial.print(value);
Serial.print(' ');
Serial.print(regulator.setpoint - 5 / 2);
Serial.print(regulator.setpoint - regulator.hysteresis / 2);
Serial.print(' ');
Serial.print(regulator.setpoint + 5 / 2);
Serial.print(regulator.setpoint + regulator.hysteresis / 2);
Serial.print(' ');
Serial.println(regulator.setpoint);
delay(100);
Expand All @@ -34,7 +34,6 @@ void loop() {
void process() {
static float coef = 0;
coef += state ? 0.3 : -0.6;
if (coef > 2.0) coef = 2.0;
if (coef < -3.0) coef = -3;
coef = constrain(coef, -3, 2);
value += coef;
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=GyverRelay
version=2.1
version=2.2
author=AlexGyver <[email protected]>
maintainer=AlexGyver <[email protected]>
sentence=Library for relay regulation algorithm
Expand Down
42 changes: 16 additions & 26 deletions src/GyverRelay.cpp
Original file line number Diff line number Diff line change
@@ -1,47 +1,37 @@
#include "GyverRelay.h"

GyverRelay::GyverRelay(boolean direction) {
_direction = direction;
output = !_direction; // выключить реле сразу
GyverRelay::GyverRelay(GR_dir dir = REVERSE) {
_dir = dir;
output = !_dir; // выключить реле сразу
}

void GyverRelay::setDirection(boolean dir) {
_direction = dir;
}

int signum(float val) {
return ((val > 0) ? 1 : ((val < 0) ? -1 : 0));
void GyverRelay::setDirection(GR_dir dir) {
_dir = dir;
}

// вернёт выход, принимает время итерации в секундах
boolean GyverRelay::compute(float dt) {
bool GyverRelay::compute(float dt) {
float signal;
if (dt > 0) {
float rate = (input - prevInput) / dt; // производная от величины (величина/секунду)
if (dt != 0 && k != 0) {
signal = input + (input - prevInput) * k / dt;
prevInput = input;
signal = input + rate * k;
} else {
signal = input;
}

// жуткая функция реле из лекций по ТАУ
int8_t F = (signum(signal - setpoint - hysteresis / 2) + signum(signal - setpoint + hysteresis / 2)) / 2;

if (F == 1) output = !_direction;
else if (F == -1) output = _direction;
} else signal = input;

if (signal < (setpoint - hysteresis / 2)) output = _dir;
else if (signal > (setpoint + hysteresis / 2)) output = !_dir;
return output;
}

boolean GyverRelay::getResult() {
GyverRelay::compute((millis() - prevTime) / 1000.0f);
bool GyverRelay::getResult() {
compute((millis() - prevTime) / 1000.0f);
prevTime = millis();
return output;
}

boolean GyverRelay::getResultTimer() {
bool GyverRelay::getResultTimer() {
if (millis() - prevTime > dT) {
prevTime = millis();
GyverRelay::compute((float)dT / 1000);
compute(dT / 1000.0);
}
return output;
}
25 changes: 14 additions & 11 deletions src/GyverRelay.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,35 @@
Версии:
v2.1 - исправлена getResultTimer
v2.2 - улучшен и упрощён алгоритм
*/

#ifndef GyverRelay_h
#define GyverRelay_h
#ifndef _GyverRelay_h
#define _GyverRelay_h
#include <Arduino.h>

#define NORMAL 0
#define REVERSE 1
enum GR_dir {
NORMAL,
REVERSE,
};

class GyverRelay {
public:
// принимает установку, ширину гистерезиса, направление (NORMAL, REVERSE)
// NORMAL - включаем нагрузку при переходе через значение снизу (пример: охлаждение)
// REVERSE - включаем нагрузку при переходе через значение сверху (пример: нагрев)
GyverRelay(boolean direction = REVERSE);
GyverRelay(GR_dir dir);

// расчёт возвращает состояние для управляющего устройства (реле, транзистор) (1 вкл, 0 выкл)
boolean compute(float dt = 0); // моментальный расчёт. Принимает dt в секундах для режима с ОС
boolean getResult(); // моментальный расчёт. Встроенный таймер для режима с ОС
boolean getResultTimer(); // расчёт по встроенному таймеру
bool compute(float dt = 0); // моментальный расчёт. Принимает dt в секундах для режима с ОС
bool getResult(); // моментальный расчёт. Встроенный таймер для режима с ОС
bool getResultTimer(); // расчёт по встроенному таймеру

void setDirection(boolean dir); // направление регулирования (NORMAL, REVERSE)
void setDirection(GR_dir dir); // направление регулирования (NORMAL, REVERSE)

float input = 0; // сигнал с датчика (например температура, которую мы регулируем)
float setpoint = 0; // заданная величина, которую должен поддерживать регулятор (температура)
boolean output = 0; // выход регулятора (0 или 1)
bool output = 0; // выход регулятора (0 или 1)

float hysteresis = 0; // ширина окна гистерезиса
float k = 0; // коэффициент усиления по скорости (по умолч. 0)
Expand All @@ -47,6 +50,6 @@ class GyverRelay {
private:
uint32_t prevTime = 0;
float prevInput = 0.0;
boolean _direction = false;
GR_dir _dir = REVERSE;
};
#endif

0 comments on commit f01300b

Please sign in to comment.