Bom dia! É a minha primeira postagem, então me desculpe se não segui alguma regra, mesmo tendo lido. Sou iniciante e estou tentando aprender sobre classes. O código abaixo está com erro na linha 71. Estou tentando fazer os leds piscarem ao apertar o botão, e se apertar o mesmo botão eles param. No entanto, gostaria de fazer isso usando a classe BotaoApertado dentro da classe PiscaLed (nem sei se é possível). Qualquer comentário de melhoria será muito bem vindo.
#define pinLedVm 10
#define pinLedAm 9
#define pinLedVd 8
#define botaoPlay 7
//**************************************************************************
class BotaoApertado {
public:
BotaoApertado(byte pinBotao);
bool debounce();
bool ouvirBotao();
private:
byte _pinBotao;
bool _estadoBotao;
unsigned long int _apertoBotao;
};
BotaoApertado::BotaoApertado(byte pinBotao) {
pinMode(pinBotao, INPUT_PULLUP);
_pinBotao = pinBotao;
_estadoBotao = false;
_apertoBotao = 0;
}
bool BotaoApertado::debounce() {
_apertoBotao = millis();
if (millis() - _apertoBotao < 400) return true;
else return false;
}
bool BotaoApertado::ouvirBotao() {
bool lido = !digitalRead(_pinBotao);
if (lido && debounce()) {
_estadoBotao = !_estadoBotao;
return true;
} else return false;
}
class PiscaLed {
public:
PiscaLed(byte pinLed, int tempo);
acenderLed();
apagarLed();
loop();
private:
byte _pinLed;
int _tempo;
bool _estadoLed;
unsigned long int _horarioMillis;
};
PiscaLed::PiscaLed(byte pinLed, int tempo) {
pinMode(pinLed, OUTPUT);
_pinLed = pinLed;
_tempo = tempo;
_estadoLed = false;
_horarioMillis = 0;
}
PiscaLed::acenderLed() {
digitalWrite(_pinLed, HIGH);
_horarioMillis = millis();
}
PiscaLed::apagarLed() {
digitalWrite(_pinLed, LOW);
_horarioMillis = millis();
}
PiscaLed::loop() {
if (BotaoApertado.ouvirBotao()) {
if (_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
acenderLed();
} else if (!_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
apagarLed();
}
} else digitalWrite(_pinLed, LOW);
}
//**************************************************************************
BotaoApertado b1(botaoPlay);
PiscaLed ledVm(pinLedVm, 500);
PiscaLed ledAm(pinLedAm, 600);
PiscaLed ledVd(pinLedVd, 700);
void setup() {
}
void loop() {
ledVm.loop();
ledAm.loop();
ledVd.loop();
}
b707
March 29, 2024, 6:49pm
2
Você pode passar um ponteiro para a classe BotaoApertado para o objeto PiscaLed.
No entanto, não entendo como você usará um mesmo BotaoApertado em três classes de PiscaLed ao mesmo tempo - não funcionará dessa maneira
Obrigado pela resposta. Mas tanto o PiscaLed quanto o BotaoApertado são classes nesse sketch, certo?
Imaginemos que ele controle apenas um Led, qualquer um deles. Consegue editar o código para fazer funcionar?
Ainda não aprendi sobre ponteiros.
b707
March 29, 2024, 7:14pm
4
não mudamos a classe BotaoApertado
class PiscaLed {
public:
PiscaLed(byte pinLed, int tempo, BotaoApertado* button);
acenderLed();
apagarLed();
loop();
private:
byte _pinLed;
int _tempo;
bool _estadoLed;
unsigned long int _horarioMillis;
BotaoApertado* _button;
};
PiscaLed::PiscaLed(byte pinLed, int tempo, BotaoApertado* button) {
pinMode(pinLed, OUTPUT);
_pinLed = pinLed;
_tempo = tempo;
_estadoLed = false;
_horarioMillis = 0;
_button = button;
}
PiscaLed::acenderLed() {
digitalWrite(_pinLed, HIGH);
_horarioMillis = millis();
}
PiscaLed::apagarLed() {
digitalWrite(_pinLed, LOW);
_horarioMillis = millis();
}
PiscaLed::loop() {
if (_button->ouvirBotao()) {
if (_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
acenderLed();
} else if (!_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
apagarLed();
}
} else digitalWrite(_pinLed, LOW);
}
//**************************************************************************
BotaoApertado b1(botaoPlay);
PiscaLed ledVm(pinLedVm, 500, &b1);
void setup() {
}
void loop() {
ledVm.loop();
}
O editor retornou o erro: "Compilation error: 'BotaoApertado' has not been declared". Não sei resolver por se tratar de ponteiros.
b707
March 30, 2024, 5:47am
6
Você deve incluir sua classe 'BotaoApertado' no código
Sorry, I do not speak Portugal
Ok amigo! Inclui a classe que faltava e o skech ficou dessa forma. Mas ainda está me retornando erro: "undefined reference to `BotaoApertado::BotaoApertado(unsigned char)'
collect2.exe: error: ld returned 1 exit status"
b707:
class PiscaLed {
public:
PiscaLed(byte pinLed, int tempo, BotaoApertado* button);
acenderLed();
apagarLed();
loop();
private:
byte _pinLed;
int _tempo;
bool _estadoLed;
unsigned long int _horarioMillis;
BotaoApertado* _button;
};
PiscaLed::PiscaLed(byte pinLed, int tempo, BotaoApertado* button) {
pinMode(pinLed, OUTPUT);
_pinLed = pinLed;
_tempo = tempo;
_estadoLed = false;
_horarioMillis = 0;
_button = button;
}
PiscaLed::acenderLed() {
digitalWrite(_pinLed, HIGH);
_horarioMillis = millis();
}
PiscaLed::apagarLed() {
digitalWrite(_pinLed, LOW);
_horarioMillis = millis();
}
PiscaLed::loop() {
if (_button->ouvirBotao()) {
if (_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
acenderLed();
} else if (!_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
apagarLed();
}
} else digitalWrite(_pinLed, LOW);
}
//**************************************************************************
BotaoApertado b1(botaoPlay);
PiscaLed ledVm(pinLedVm, 500, &b1);
void setup() {
}
void loop() {
ledVm.loop();
}
Experimenta trocar byte por unsigned char na definição do BotãoApertado.
Ou:
BotaoApertado b1((byte)botaoPlay);
Obrigado a todos que colaboraram!
Deixo abaixo a solução do código completa para contribuir com os demais aprendizes!
OBS.: Nesse caso tem que manter o botão apertado para o led piscar.
#define pinLedVm 10
#define botaoPlay 7
//*************************************************************************************************
class BotaoApertado {
public:
BotaoApertado(unsigned char pinBotao);
bool debounce();
bool ouvirBotao();
private:
byte _pinBotao;
bool _estadoBotao;
unsigned long int _apertoBotao;
};
BotaoApertado::BotaoApertado(unsigned char pinBotao) {
pinMode(pinBotao, INPUT_PULLUP);
_pinBotao = pinBotao;
_estadoBotao = false;
_apertoBotao = 0;
}
bool BotaoApertado::debounce() {
_apertoBotao = millis();
if (millis() - _apertoBotao < 400) return true;
else return false;
}
bool BotaoApertado::ouvirBotao() {
bool lido = !digitalRead(_pinBotao);
if (lido && debounce()) {
_estadoBotao = !_estadoBotao;
return true;
} else return false;
}
class PiscaLed {
public:
PiscaLed(byte pinLed, int tempo, BotaoApertado* button);
acenderLed();
apagarLed();
loop();
private:
byte _pinLed;
int _tempo;
bool _estadoLed;
unsigned long int _horarioMillis;
BotaoApertado* _button;
};
PiscaLed::PiscaLed(byte pinLed, int tempo, BotaoApertado* button) {
pinMode(pinLed, OUTPUT);
_pinLed = pinLed;
_tempo = tempo;
_estadoLed = false;
_horarioMillis = 0;
_button = button;
}
PiscaLed::acenderLed() {
digitalWrite(_pinLed, HIGH);
_horarioMillis = millis();
}
PiscaLed::apagarLed() {
digitalWrite(_pinLed, LOW);
_horarioMillis = millis();
}
PiscaLed::loop() {
if (_button->ouvirBotao()) {
if (_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
acenderLed();
} else if (!_estadoLed && (millis() - _horarioMillis) > _tempo) {
_estadoLed = !_estadoLed;
apagarLed();
}
} else digitalWrite(_pinLed, LOW);
}
//**************************************************************************
BotaoApertado b1(botaoPlay);
PiscaLed ledVm(pinLedVm, 500, &b1);
void setup() {
}
void loop() {
ledVm.loop();
}
b707
March 31, 2024, 5:27pm
10
O motivo do erro é que por algum motivo você alterou a descrição da classe BotaoApertado.
Foi originalmente descrito por você como BotaoApertado(byte pinBotao); tendo um parâmetro de tipo byte. Por que você mudou o parâmetro char?