agrobot_base/Firmware/Modulos/SinaleiroModel_v2.h

153 lines
3.3 KiB
C
Raw Normal View History

#include "SerialService.h"
#include "Pinout.h"
#include "Utils.h"
#include "IComponenteCAN.h"
#ifndef SinaleiroModel
#define SinaleiroModel
class Sinaleiro_v2 : public ComponenteCAN {
public:
String ID;
uint8_t ID_Num = 0;
PinoModel _pino;
bool Iniciado = false;
int _StatusID = 0;
StatusLED _Status = Apagado;
StatusLED _StatusLeitura = Apagado;
int _Qtd = 0;
int _TempoMs = 0;
int _PausaMs = 0;
// controle interno (não era exposto antes)
bool _estadoAtual = false;
int _piscadasAtual = 0;
bool _emPausa = false;
unsigned long _lastMillis = 0;
Sinaleiro_v2() {}
Sinaleiro_v2(
const String& id,
uint8_t idNum,
int pino,
TiposBarramentos tipoBarramento
) :
ID(id),
ID_Num(idNum),
_pino(PinoModel(pino, tipoBarramento, _OUTPUT))
{}
void Inicializar() {
if (Iniciado) return;
if (_pino.Definido()) {
_pino.Conectar(false);
Iniciado = true;
}
}
void AtualizarEstado(unsigned long agora) {
if (!Iniciado) return;
if (_Status != StatusLED::Piscando) {
_pino.set(_Status == StatusLED::Aceso);
_StatusLeitura = _Status;
return;
}
// modo piscando
if (_piscadasAtual < _Qtd) {
if (!_emPausa && (agora - _lastMillis >= _TempoMs)) {
_estadoAtual = !_estadoAtual;
_pino.set(_estadoAtual);
_lastMillis = agora;
if (!_estadoAtual) {
_piscadasAtual++;
}
}
}
else {
// pausa
if (!_emPausa) {
_pino.set(false);
_emPausa = true;
_lastMillis = agora;
}
if (agora - _lastMillis >= _PausaMs) {
_emPausa = false;
_piscadasAtual = 0;
_lastMillis = agora;
}
}
_StatusLeitura = StatusLED::Piscando;
}
void ProcessarComando(std::vector<uint8_t>& data) {
if (!Iniciado) return;
if (data.size() < 7) return;
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)data[0];
uint8_t idNum = data[1];
if (idNum != ID_Num) return;
if (posicao == CanMessagePosicaoDados::Command1) {
_StatusID = data[2];
_Status = (StatusLED)data[3];
_Qtd = data[4];
_TempoMs = (uint16_t)data[5] * 10;
_PausaMs = (uint16_t)data[6] * 10;
// reset ciclo
_piscadasAtual = 0;
_emPausa = false;
_lastMillis = millis();
}
}
void RequisitarDados() {}
std::vector<uint8_t> MontarMensagemCAN(CanMessagePosicaoDados posicao) {
std::vector<uint8_t> data;
data.push_back((uint8_t)posicao);
data.push_back(ID_Num);
switch (posicao) {
case Status:
data.push_back(Iniciado ? 1 : 0);
break;
case Dados1:
data.push_back(_StatusID);
data.push_back(_StatusLeitura);
break;
}
return data;
}
};
class LedManager {
public:
std::vector<Sinaleiro_v2*> leds;
void Adicionar(Sinaleiro_v2* led) {
leds.push_back(led);
}
void Atualizar() {
unsigned long agora = millis();
for (auto* led : leds) {
if (led != nullptr && led->Iniciado) {
led->AtualizarEstado(agora);
}
}
}
};
#endif