GY-63_MS5611/libraries/HeartBeat/HeartBeat.cpp
2022-11-09 10:31:43 +01:00

278 lines
4.4 KiB
C++

//
// FILE: HeartBeat.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.1
// PURPOSE: Arduino library for HeartBeat with frequency and dutyCycle
// DATE: 2019-06-12
// URL: https://github.com/RobTillaart/HeartBeat
//
// HISTORY: see changelog
#include "HeartBeat.h"
HeartBeat::HeartBeat()
{
}
void HeartBeat::begin(const uint8_t pin, float frequency)
{
_pin = pin;
pinMode(_pin, OUTPUT);
setFrequency(frequency);
enable();
}
void HeartBeat::setFrequency(float frequency)
{
_frequency = frequency;
if (_frequency < 0) _frequency = -frequency;
if (_frequency < 0.001) _frequency = 0.001;
_setFreqDuty();
}
void HeartBeat::setDutyCycle(float dutyCycle)
{
_dutyCycle = dutyCycle;
if (_dutyCycle < 0) _dutyCycle = 0;
if (_dutyCycle > 100) _dutyCycle = 100;
_setFreqDuty();
}
float HeartBeat::getFrequency()
{
return _frequency;
};
float HeartBeat::getDutyCycle()
{
return _dutyCycle;
};
void HeartBeat::enable()
{
_running = true;
};
void HeartBeat::disable()
{
_running = false;
};
bool HeartBeat::isEnabled()
{
return _running;
};
void HeartBeat::beat()
{
if (_running == false)
{
_state = LOW;
}
else
{
uint32_t now = micros();
if ((_state == LOW) && (now - _lastHeartBeat) < _dutyCycleLow) return;
if ((_state == HIGH) && (now - _lastHeartBeat) < _dutyCycleHigh) return;
_lastHeartBeat = now;
_state = !_state;
}
digitalWrite(_pin, _state);
}
uint8_t HeartBeat::getState()
{
return _state;
};
/////////////////////////////////
//
// PROTECTED
//
void HeartBeat::_setFreqDuty()
{
float time = 10000.0/_frequency;
_dutyCycleHigh = round(_dutyCycle * time);
_dutyCycleLow = round((100 - _dutyCycle) * time);
}
/////////////////////////////////////////////////////////////////////////////
//
// HEARTBEATDIAG
//
HeartBeatDiag::HeartBeatDiag():HeartBeat()
{
}
void HeartBeatDiag::beat()
{
// normal mode
if (_codeMask == 0)
{
_codeStart = 0;
HeartBeat::beat();
return;
}
// _code mode
if (_codeStart == 0)
{
// force a LOW first.
_codeStart = 1;
_lastHeartBeat = micros();
_state = LOW;
}
else
{
uint32_t period = (_dutyCycleLow + _dutyCycleHigh)/2;
uint32_t now = micros();
if ((now - _lastHeartBeat) < period) return;
_lastHeartBeat = now;
if (_state == LOW)
{
while (_codeMask > _code)
{
_codeMask /= 10;
}
if (_codeMask == 0) return;
_pulseLength = _code / _codeMask;
_code -= ( _pulseLength * _codeMask );
_state = HIGH;
}
else
{
_pulseLength--;
if (_pulseLength == 0)
{
_state = LOW;
}
}
}
digitalWrite(_pin, _state);
}
bool HeartBeatDiag::code(uint32_t pattern)
{
// already running an errorCode?
if (_code > 0) return false;
// pattern too long
if (pattern > 999999999) return false;
_code = pattern;
_codeMask = 100000000;
return true;
}
void HeartBeatDiag::codeOff()
{
_codeMask = 0;
}
/////////////////////////////////////////////////////////////////////////////
//
// HEARTBEATSL
//
// string LS version is simpler and somewhat smaller footprint,
//
#define HEARTBEATSL_SHORT 1
#define HEARTBEATSL_LONG 3
HeartBeatSL::HeartBeatSL():HeartBeat()
{
}
void HeartBeatSL::beat()
{
// normal mode
if (_codeMask == 0)
{
_codeStart = 0;
HeartBeat::beat();
return;
}
// _code mode
if (_codeStart == 0)
{
// force a LOW first.
_codeStart = 1;
_lastHeartBeat = micros();
_state = LOW;
}
else
{
uint32_t period = (_dutyCycleLow + _dutyCycleHigh)/2;
uint32_t now = micros();
if ((now - _lastHeartBeat) < period) return;
_lastHeartBeat = now;
if (_state == LOW)
{
_pulseLength = HEARTBEATSL_SHORT;
if (_code & _codeMask) // 1 ==> LONG
{
_pulseLength = HEARTBEATSL_LONG;
}
_codeMask >>= 1;
_state = HIGH;
}
else
{
_pulseLength--;
if (_pulseLength == 0)
{
_state = LOW;
}
}
}
digitalWrite(_pin, _state);
}
bool HeartBeatSL::code(const char * str)
{
// already running an errorCode?
if (_codeMask > 0) return false;
// pattern too long
uint8_t len = strlen(str);
if (len > 7) return false;
_code = 0;
_codeMask = 1 << len;
for (uint8_t i = 0; i < len; i++)
{
if (str[i] == 'L') _code |= 1;
_code <<= 1;
}
return true;
}
void HeartBeatSL::codeOff()
{
_codeMask = 0;
}
// -- END OF FILE --