#include "RTClib.h"
#include <SD.h>
#include <LiquidCrystal_I2C.h>
// Definições de pinos
const int chipSelect = 10;
const byte but_voltar = 2;
const byte but_subir = 3;
const byte but_descer = 4;
const byte but_entrar = 5;
// Entradas analógicas
#define entrada_0 A0
#define entrada_1 A1
#define entrada_2 A2
// LCD
LiquidCrystal_I2C lcd(0x27,16,2);
// RTC
//RTC_DS3231 rtc; // Descomente se for usar o DS3231
RTC_DS1307 rtc;
//char diaDaSemana[7][3] = {"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"};
// Cartão SD
File Log;
// Variáveis de controle
unsigned long tempo_atual;
unsigned long inicio_tela;
bool cont_repouso;
bool repouso_forcado;
unsigned long ultima_piscada;
unsigned long piscado;
unsigned long intervalo_piscar;
bool ocioso;
bool registrando_log;
byte indice_atual;
byte no_menu;
bool dois_pontos_visivel;
byte entrada_leitura;
int tempo_amostragem = 1;
byte cont_entrada;
// Botões (estados)
bool voltar;
bool subir;
bool descer;
bool entrar;
// Smile (caracteres personalizados)
byte bits_olho_aberto[8] = {B00000,B00100,B01110,B01110,B01110,B01110,B00100,B00000};
byte bits_olho_aberto_dir[8] = {B00000,B00011,B00111,B00111,B00111,B00111,B00011,B00000};
byte bits_olho_aberto_dir_baix[8] = {B00000,B00000,B00000,B00011,B00111,B00111,B00111,B00111};
byte bits_boca_feliz_1[8] = {B00000,B00000,B10000,B01111,B00111,B00000,B00000,B00000};
byte bits_boca_feliz_2[8] = {B00000,B00000,B00001,B11110,B11100,B00000,B00000,B00000};
byte bits_boca_feliz_dir_1[8] = {B00000,B00000,B01100,B00111,B00001,B00000,B00000,B00000};
byte bits_boca_feliz_dir_2[8] = {B00000,B00000,B00001,B11111,B11110,B00000,B00000,B00000};
const bool carac_olho_aberto = 0;
const bool carac_olho_aberto_dir = 1;
const byte carac_olho_aberto_dir_baix = 2;
const byte carac_boca_feliz_1 = 3;
const byte carac_boca_feliz_2 = 4;
const byte carac_boca_feliz_dir_1 = 5;
const byte carac_boca_feliz_dir_2 = 6;
// Smile (estado)
bool status_olho_aberto = true;
bool smile_on = false;
byte smi_olhar = carac_olho_aberto;
byte smi_boca_1 = carac_boca_feliz_1;
byte smi_boca_2 = carac_boca_feliz_2;
// Protótipos de funções
void smile();
void smi_piscar();
void smi_att_face();
void smi_olhando();
void repouso();
void detectar_atividade();
void lendo_botoes();
void botoes_low();
bool indice_impar(byte indice_atual);
void cursor(byte indice_atual);
void deslocar_texto(const char* texto, int linha, unsigned long intervalo_deslocamento);
void menus();
void menu_principal();
void menu_relogio();
void tempo_ajustado();
void m_log_entrada();
void entrada_definida();
void entrada_analogica();
void m_log_amostragem();
void registando();
void registro();
void parar_registro();
void menu_log();
void menu_rf();
void menu_pulsos();
void menu_pwm_mono();
void menu_pwm_tri();
void setup() {
Serial.begin(115200);
randomSeed(analogRead(A0));
// Inicialização dos pinos dos botões
pinMode(but_voltar, INPUT);
pinMode(but_subir , INPUT);
pinMode(but_descer, INPUT);
pinMode(but_entrar, INPUT);
// Inicialização do LCD
lcd.init();
lcd.backlight();
// Inicialização do RTC
if (!rtc.begin()) {
Serial.println(F("Inicialização do relogio falhou!"));
while (1);
}
Serial.println(F("Relogio inicializado."));
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//rtc.adjust(DateTime(2024, 9, 16, 15, 3, 40));
// Inicialização do cartão SD
if (!SD.begin(chipSelect)) {
Serial.println(F("Inicialização do cartão SD falhou!"));
while (1);
}
Serial.println(F("Cartão SD inicializado."));
if (!SD.exists("Log.txt")) {
Log = SD.open("Log.txt", FILE_WRITE);
if (Log) {
Log.close();
Serial.println(F("Arquivo de log inicializado."));
} else {
Serial.println(F("Erro ao criar Log.txt"));
}
}
// Criando caracteres personalizados para o Smile
lcd.createChar(carac_olho_aberto, bits_olho_aberto);
lcd.createChar(carac_olho_aberto_dir, bits_olho_aberto_dir);
lcd.createChar(carac_olho_aberto_dir_baix, bits_olho_aberto_dir_baix);
lcd.createChar(carac_boca_feliz_1, bits_boca_feliz_1);
lcd.createChar(carac_boca_feliz_2, bits_boca_feliz_2);
lcd.createChar(carac_boca_feliz_dir_1, bits_boca_feliz_dir_1);
lcd.createChar(carac_boca_feliz_dir_2, bits_boca_feliz_dir_2);
// Boas vindas
lcd.setCursor(7, 0);
lcd.print(F("Oie!!!"));
lcd.setCursor(4, 1);
lcd.print(F("Iniciando"));
// Exibindo Smile
lcd.setCursor(1, 0);
lcd.write(byte(carac_olho_aberto));
lcd.setCursor(2, 0);
lcd.write(byte(carac_olho_aberto));
lcd.setCursor(1, 1);
lcd.write(byte(carac_boca_feliz_1));
lcd.setCursor(2, 1);
lcd.write(byte(carac_boca_feliz_2));
delay(400);
lcd.setCursor(13, 1);
lcd.print(F("."));
delay(400);
// Piscadinha
lcd.setCursor(2, 0);
lcd.write(byte(95));
delay(300);
lcd.setCursor(2, 0);
lcd.write(byte(carac_olho_aberto));
delay(100);
lcd.setCursor(14, 1);
lcd.print(F("."));
delay(400);
lcd.setCursor(15, 1);
lcd.print(F("."));
delay(400);
lcd.clear();
Serial.println(F("Programa inicializado."));
}
// Funções do Smile
void smile(){
smi_olhando();
if (!smile_on){
smi_att_face();
}
if ((tempo_atual - ultima_piscada) > (intervalo_piscar)){
smi_piscar();
}
}
void smi_piscar(){
static unsigned long tempo_q_olho_fechou;
const byte tempo_com_olho_fechado = 150;
if (status_olho_aberto){
lcd.setCursor(2, 0);
lcd.write(byte(95));
lcd.setCursor(1, 0);
lcd.write(byte(95));
tempo_q_olho_fechou = millis();
status_olho_aberto = false;
} else if ((tempo_atual - tempo_q_olho_fechou) > (tempo_com_olho_fechado)){
smi_att_face();
ultima_piscada = millis();
if ((ocioso) && (smi_olhar == carac_olho_aberto_dir_baix)){
intervalo_piscar = 700;
} else {
intervalo_piscar = random(1, 11)*500;
}
status_olho_aberto = true;
}
}
void smi_att_face(){
lcd.setCursor(2, 0);
lcd.write(byte(smi_olhar));
lcd.setCursor(1, 0);
lcd.write(byte(smi_olhar));
lcd.setCursor(1, 1);
lcd.write(byte(smi_boca_1));
lcd.setCursor(2, 1);
lcd.write(byte(smi_boca_2));
smile_on = true;
}
void smi_olhando(){
byte aux = random(1, 100);
const unsigned int tempo_foco = 3000;
const unsigned int tempo_distracao = 9000;
static unsigned long inicio_foco = 0;
static bool em_foco = false;
static bool em_distracao = false;
// Verificar se algum botão foi pressionado
if ((voltar || subir || descer || entrar)) {
if ((!em_foco && !em_distracao) && (aux <= 60)){
em_foco = true;
em_distracao = false;
inicio_foco = millis();
//Serial.println("Focado");
}
}
if (em_foco) {
if (millis() - inicio_foco >= tempo_foco) {
em_foco = false;
em_distracao = true;
intervalo_piscar = 0;
inicio_foco = millis();
//Serial.println("Distraído");
}
if (indice_impar(indice_atual)){
smi_olhar = carac_olho_aberto_dir;
smi_boca_1 = carac_boca_feliz_dir_1;
smi_boca_2 = carac_boca_feliz_dir_2;
smi_att_face();
return;
} else {
smi_olhar = carac_olho_aberto_dir_baix;
smi_boca_1 = carac_boca_feliz_dir_1;
smi_boca_2 = carac_boca_feliz_dir_2;
smi_att_face();
return;
}
} else if(em_distracao) {
if (millis() - inicio_foco >= tempo_distracao) {
em_distracao = false;
}
}
byte porcent_olhar_baix = indice_impar(indice_atual) ? 70 : 95;
aux = random(1, 100);
if (ocioso) {
if (aux <= 80){
smi_olhar = carac_olho_aberto;
smi_boca_1 = carac_boca_feliz_1;
smi_boca_2 = carac_boca_feliz_2;
} else {
smi_olhar = carac_olho_aberto_dir_baix;
smi_boca_1 = carac_boca_feliz_dir_1;
smi_boca_2 = carac_boca_feliz_dir_2;
}
} else {
if (aux <= 65){
smi_olhar = carac_olho_aberto;
smi_boca_1 = carac_boca_feliz_1;
smi_boca_2 = carac_boca_feliz_2;
} else if(aux <= porcent_olhar_baix){
smi_olhar = carac_olho_aberto_dir_baix;
smi_boca_1 = carac_boca_feliz_dir_1;
smi_boca_2 = carac_boca_feliz_dir_2;
} else {
smi_olhar = carac_olho_aberto_dir;
smi_boca_1 = carac_boca_feliz_dir_1;
smi_boca_2 = carac_boca_feliz_dir_2;
}
}
}
// Definições de estados
void repouso(){
smile();
DateTime now = rtc.now();
if (!cont_repouso){
lcd.setCursor(7, 0);
lcd.print(F("Hora:"));
}
char buffer[3];
sprintf(buffer, "%02d", now.hour());
lcd.setCursor(7, 1);
lcd.print(buffer);
if (tempo_atual - piscado >= 500) {
dois_pontos_visivel = !dois_pontos_visivel;
lcd.setCursor(9, 1);
lcd.print(dois_pontos_visivel ? F(":") : F(" "));
piscado = tempo_atual;
}
sprintf(buffer, "%02d", now.minute());
lcd.setCursor(10, 1);
lcd.print(buffer);
cont_repouso = true;
}
void detectar_atividade(){
bool aux_ocioso = ocioso;
const unsigned int tempo_ate_repouso = 30000; // 30 segundos
static unsigned long ultima_atividade = tempo_ate_repouso;
if((repouso_forcado) && (no_menu == 0)){
ultima_atividade = tempo_atual + tempo_ate_repouso + 1;
repouso_forcado = false;
ocioso = true;
} else if ((voltar || subir || descer || entrar)) {
ultima_atividade = millis();
ocioso = false;
} else if (((tempo_atual - ultima_atividade) > (tempo_ate_repouso))
&& (tempo_atual > tempo_ate_repouso)){
ocioso = true;
}
if (aux_ocioso != ocioso){
botoes_low();
lcd.clear();
//smile_on = false;
intervalo_piscar = 0;
cont_repouso = false;
}
}
void lendo_botoes(){
const byte tempo_bounce = 250;
static unsigned long ultimo_voltar = 0;
static unsigned long ultimo_subir = 0;
static unsigned long ultimo_descer = 0;
static unsigned long ultimo_entrar = 0;
voltar = digitalRead(but_voltar);
subir = digitalRead(but_subir);
descer = digitalRead(but_descer);
entrar = digitalRead(but_entrar);
if ((voltar) && ((tempo_atual - ultimo_voltar) > tempo_bounce)){
ultimo_voltar = millis();
} else {
voltar = LOW;
}
if ((subir) && ((tempo_atual - ultimo_subir) > tempo_bounce)){
ultimo_subir = millis();
} else {
subir = LOW;
}
if ((descer) && ((tempo_atual - ultimo_descer) > tempo_bounce)){
ultimo_descer = millis();
} else {
descer = LOW;
}
if ((entrar) && ((tempo_atual - ultimo_entrar) > tempo_bounce)){
ultimo_entrar = millis();
} else {
entrar = LOW;
}
}
void botoes_low(){
voltar = LOW;
subir = LOW;
descer = LOW;
entrar = LOW;
}
bool indice_impar(byte indice_atual){
return (indice_atual & 1); // Verifica o bit menos significativo para paridade
}
void cursor(byte indice_atual){
if ((tempo_atual - piscado >= 500) || ((voltar||subir||descer||entrar))) {
if ((voltar||subir||descer||entrar)) {
dois_pontos_visivel = true;
} else {
dois_pontos_visivel = !dois_pontos_visivel;
}
lcd.setCursor(4, !indice_impar(indice_atual));
if (dois_pontos_visivel) {
lcd.write(byte(126));
lcd.setCursor(4, indice_impar(indice_atual));
lcd.print(F(" "));
} else {
lcd.print(F(" "));
lcd.setCursor(4, indice_impar(indice_atual));
lcd.print(F(" "));
}
piscado = tempo_atual;
}
}
void deslocar_texto(const char* texto, int linha, unsigned long intervalo_deslocamento) {
static unsigned long ultimo_deslocamento = 0;
static byte offset = 0;
static unsigned long tempo_inicio = 0;
static byte indice_anterior = -1;
static byte tamanho_texto;
if (indice_atual != indice_anterior) {
offset = 0;
lcd.setCursor(5, linha);
lcd.print(texto);
tempo_inicio = millis();
indice_anterior = indice_atual;
tamanho_texto = strlen(texto); // Calcula o tamanho do texto apenas uma vez
}
if (millis() - tempo_inicio >= 700) {
if (millis() - ultimo_deslocamento >= intervalo_deslocamento) {
ultimo_deslocamento = millis();
byte janela_visivel = 11;
// Copia apenas a parte visível do texto para o buffer
char parte_visivel[12];
strncpy(parte_visivel, texto + offset, janela_visivel);
parte_visivel[janela_visivel] = '\0'; // Adiciona o caractere nulo
lcd.setCursor(5, linha);
lcd.print(F(" "));
lcd.setCursor(5, linha);
lcd.print(parte_visivel);
offset++;
if (offset >= tamanho_texto) {
offset = 0;
}
}
}
}
// Menus
void menus(){
switch(no_menu) {
case 0: menu_principal(); break;
case 1: menu_relogio(); break;
case 2: menu_log(); break;
case 3: menu_rf(); break;
case 4: menu_pulsos(); break;
case 5: menu_pwm_mono(); break;
case 6: menu_pwm_tri(); break;
case 7: tempo_ajustado(); break;
case 8: m_log_amostragem(); break;
case 9: m_log_entrada(); break;
case 10: entrada_definida(); break;
case 11: registando(); break;
case 12: parar_registro(); break;
}
}
void menu_principal(){
no_menu = 0;
static byte indice_principal = 1;
switch(indice_principal) {
case 1: case 2:
lcd.setCursor(5, 0);
lcd.print(F("Relogio "));
lcd.setCursor(5, 1);
lcd.print(F("Data Logger"));
break;
case 3: case 4:
lcd.setCursor(5, 0);
lcd.print(F("Comunic. RF"));
lcd.setCursor(5, 1);
lcd.print(F("Con. Pulsos"));
break;
case 5: case 6:
lcd.setCursor(5, 0);
lcd.print(F("PWM Monof. "));
lcd.setCursor(5, 1);
lcd.print(F("PWM Trif. "));
break;
}
if (voltar) {
repouso_forcado = true;
} else if(subir) {
if (indice_principal > 1) indice_principal--;
} else if(descer) {
if (indice_principal < 6) indice_principal++;
} else if(entrar) {
switch(indice_principal) {
case 1:
no_menu = 1;
lcd.setCursor(3, 0);
lcd.print(F(" "));
lcd.setCursor(3, 1);
lcd.print(F(" "));
return;
case 2: no_menu = 2; return;
case 3: no_menu = 3; break;
case 4: no_menu = 4; break;
case 5: no_menu = 5; break;
case 6: no_menu = 6; break;
}
}
cursor(indice_principal);
indice_atual = indice_principal;
smile();
}
void menu_relogio(){
no_menu = 1;
DateTime now = rtc.now();
static byte selecao;
static byte hora;
static byte minuto;
static byte segundo;
static unsigned long previousMillis = 0;
const byte interval = 200;
static bool mostrar_valor = true;
static bool ajuste_relogio = false;
int aux = 0;
if (!ajuste_relogio) {
ajuste_relogio = true;
hora = now.hour();
minuto = now.minute();
segundo = now.second();
}
if (voltar) {
ajuste_relogio = false;
no_menu = 0;
selecao = 0;
} else if (subir) {
aux = 1;
} else if (descer) {
aux = -1;
} else if (entrar) {
if (selecao > 4) {
selecao = 0;
rtc.adjust(DateTime(now.year(), now.month(), now.day(), hora, minuto, segundo));
no_menu = 7;
inicio_tela = millis();
tempo_ajustado();
return;
} else {
selecao++;
}
}
if (millis() - previousMillis >= interval) {
previousMillis = millis();
mostrar_valor = !mostrar_valor;
}
switch (selecao) {
case 0: // hora
hora = hora + aux;
if (hora > 23) hora = 0; else if (hora < 0) hora = 23;
break;
case 1: // minuto
minuto = minuto + aux;
if (minuto > 59) minuto = 0; else if (minuto < 0) minuto = 59;
break;
case 2: // segundo
segundo = segundo + aux;
if (segundo > 59) segundo = 0; else if (segundo < 0) segundo = 59;
break;
case 3: // dia
rtc.adjust(DateTime(now.year(), now.month(), (now.day() + aux), now.hour(), now.minute(), now.second()));
break;
case 4: // mes
rtc.adjust(DateTime(now.year(), (now.month() + aux), now.day(), now.hour(), now.minute(), now.second()));
break;
case 5: // ano
rtc.adjust(DateTime((now.year() + aux), now.month(), now.day(), now.hour(), now.minute(), now.second()));
break;
}
lcd.setCursor(8, 0);
lcd.print(F(":"));
lcd.setCursor(11, 0);
lcd.print(F(":"));
lcd.setCursor(7, 1);
lcd.print(F("/"));
lcd.setCursor(10, 1);
lcd.print(F("/"));
char buffer[5]; // Aumentado para acomodar o ano com 4 dígitos
if (selecao == 0 && !mostrar_valor) {
lcd.setCursor(6, 0);
lcd.print(F(" "));
} else {
sprintf(buffer, "%02d", hora);
lcd.setCursor(6, 0);
lcd.print(buffer);
}
if (selecao == 1 && !mostrar_valor) {
lcd.setCursor(9, 0);
lcd.print(F(" "));
} else {
sprintf(buffer, "%02d", minuto);
lcd.setCursor(9, 0);
lcd.print(buffer);
}
if (selecao == 2 && !mostrar_valor) {
lcd.setCursor(12, 0);
lcd.print(F(" "));
} else {
sprintf(buffer, "%02d", segundo);
lcd.setCursor(12, 0);
lcd.print(buffer);
}
if (selecao == 3 && !mostrar_valor) {
lcd.setCursor(5, 1);
lcd.print(F(" "));
} else {
sprintf(buffer, "%02d", now.day());
lcd.setCursor(5, 1);
lcd.print(buffer);
}
if (selecao == 4 && !mostrar_valor) {
lcd.setCursor(8, 1);
lcd.print(F(" "));
} else {
sprintf(buffer, "%02d", now.month());
lcd.setCursor(8, 1);
lcd.print(buffer);
}
if (selecao == 5 && !mostrar_valor) {
lcd.setCursor(11, 1);
lcd.print(F(" "));
} else {
sprintf(buffer, "%04d", now.year());
lcd.setCursor(11, 1);
lcd.print(buffer);
}
smile();
}
void tempo_ajustado(){
no_menu = 7;
const unsigned int tempo_tela = 1000;
if ((millis() - inicio_tela) < tempo_tela){
lcd.setCursor(4, 0);
lcd.print(F(" Tempo "));
lcd.setCursor(4, 1);
lcd.print(F(" ajustado! "));
} else {
no_menu = 0;
return;
}
smile();
}
void m_log_entrada(){
no_menu = 9;
if (voltar) {
no_menu = 2;
return;
} else if(subir) {
cont_entrada = (cont_entrada == 2) ? 0 : cont_entrada + 1;
} else if(descer) {
cont_entrada = (cont_entrada == 0) ? 2 : cont_entrada - 1;
} else if(entrar) {
inicio_tela = millis();
entrada_analogica();
no_menu = 10;
return;
}
lcd.setCursor(5, 0);
lcd.print(F(" Registar "));
lcd.setCursor(5, 1);
lcd.print(F("entrada: A"));
char buffer[2];
sprintf(buffer, "%d", cont_entrada);
lcd.setCursor(15, 1);
lcd.print(buffer);
smile();
}
void entrada_definida(){
no_menu = 10;
const unsigned int tempo_tela = 1000;
if ((millis() - inicio_tela) < tempo_tela){
char buffer[2];
sprintf(buffer, "%d", cont_entrada);
lcd.setCursor(5, 0);
lcd.print(F("Entrada A"));
lcd.setCursor(15, 0);
lcd.print(buffer);
lcd.setCursor(5, 1);
lcd.print(F(" definida "));
} else {
no_menu = 2;
}
smile();
}
void entrada_analogica(){
switch(cont_entrada){
case 0: entrada_leitura = entrada_0; break;
case 1: entrada_leitura = entrada_1; break;
case 2: entrada_leitura = entrada_2; break;
}
}
void m_log_amostragem(){
no_menu = 8;
static byte cont = 1;
if (voltar) {
no_menu = 2;
cont = 1;
return;
} else if(subir) {
cont++;
} else if(descer) {
if (cont > 1) cont--;
} else if(entrar) {
no_menu = 7;
inicio_tela = millis();
tempo_amostragem = cont;
cont = 1;
return;
}
deslocar_texto("Intervalo em segundos:", 0, 500);
char buffer[3];
sprintf(buffer, "%02d", cont);
lcd.setCursor(8, 1);
lcd.print(buffer);
smile();
}
void registando(){
no_menu = 11;
if (voltar) {
no_menu = 12;
return;
}
lcd.setCursor(5, 0);
lcd.print(F("Registrando"));
lcd.setCursor(5, 1);
lcd.print(F("T:"));
lcd.setCursor(12, 1);
lcd.print(F("E:A"));
char buffer[4];
sprintf(buffer, "%ds", tempo_amostragem);
lcd.setCursor(7, 1);
lcd.print(buffer);
sprintf(buffer, "%d", cont_entrada);
lcd.setCursor(15, 1);
lcd.print(buffer);
smile();
}
void registro(){
Log = SD.open("Log.txt", FILE_WRITE);
if (Log) {
DateTime time = rtc.now();
Log.print(time.timestamp(DateTime::TIMESTAMP_FULL));
Log.print(F(" | A"));
Log.print(cont_entrada);
Log.print(F("= "));
Log.println(analogRead(entrada_leitura));
Log.close();
Serial.println(F("Amostra gravada"));
} else {
Serial.println(F("error opening looger.txt"));
}
}
void parar_registro(){
no_menu = 12;
if (voltar) {
no_menu = 11;
lcd.setCursor(4, 0);
lcd.print(F(" "));
lcd.setCursor(4, 1);
lcd.print(F(" "));
return;
} else if(entrar) {
no_menu = 2;
registrando_log = false;
lcd.setCursor(4, 0);
lcd.print(F(" "));
lcd.setCursor(4, 1);
lcd.print(F(" "));
return;
}
deslocar_texto("Parar registro?", 0, 500);
lcd.setCursor(6, 1);
lcd.print(F("Nao Sim"));
lcd.setCursor(5, 1);
lcd.write(byte(127));
lcd.setCursor(15, 1);
lcd.write(byte(126));
smile();
}
void menu_log(){
no_menu = 2;
static byte indice_log = 1;
if (voltar) {
no_menu = 0;
return;
} else if(subir) {
if (indice_log > 1) indice_log--;
} else if(descer) {
if (indice_log < 3) indice_log++;
} else if(entrar) {
switch(indice_log){
case 1:
lcd.setCursor(4, 0);
lcd.print(F(" "));
lcd.setCursor(4, 1);
lcd.print(F(" "));
no_menu = 8;
indice_atual = -1;
return;
case 2:
lcd.setCursor(4, 0);
lcd.print(F(" "));
lcd.setCursor(4, 1);
lcd.print(F(" "));
no_menu = 9;
return;
case 3:
lcd.setCursor(4, 0);
lcd.print(F(" "));
lcd.setCursor(4, 1);
lcd.print(F(" "));
no_menu = 11;
registrando_log = true;
return;
}
}
switch(indice_log) {
case 1: case 2:
if (indice_impar(indice_log)){
deslocar_texto("Tempo de amostragem", 0, 500);
lcd.setCursor(5, 1);
lcd.print(F("Entrada uti"));
} else {
lcd.setCursor(5, 0);
lcd.print(F("Tempo amost"));
deslocar_texto("Entrada utilizada", 1, 500);
}
break;
case 3:
deslocar_texto("Iniciar registro", 0, 500);
lcd.setCursor(5, 1);
lcd.print(F(" "));
break;
}
indice_atual = indice_log;
cursor(indice_atual);
smile();
}
void menu_rf(){
no_menu = 3;
if (voltar) no_menu = 0;
lcd.setCursor(4, 0);
lcd.print(F(" Modo em "));
lcd.setCursor(4, 1);
lcd.print(F(" producao "));
smile();
}
void menu_pulsos(){
no_menu = 4;
if (voltar) no_menu = 0;
lcd.setCursor(4, 0);
lcd.print(F(" Modo em "));
lcd.setCursor(4, 1);
lcd.print(F(" producao "));
smile();
}
void menu_pwm_mono(){
no_menu = 5;
if (voltar) no_menu = 0;
lcd.setCursor(4, 0);
lcd.print(F(" Modo em "));
lcd.setCursor(4, 1);
lcd.print(F(" producao "));
smile();
}
void menu_pwm_tri(){
no_menu = 6;
if (voltar) no_menu = 0;
lcd.setCursor(4, 0);
lcd.print(F(" Modo em "));
lcd.setCursor(4, 1);
lcd.print(F(" producao "));
smile();
}
// Loop principal
void loop(){
tempo_atual = millis();
lendo_botoes();
detectar_atividade();
if (!ocioso){
menus();
} else {
repouso();
}
static unsigned long ultima_amostra = 0;
if ((registrando_log) && ((tempo_atual - ultima_amostra) >= (tempo_amostragem * 1000))){
registro();
ultima_amostra = tempo_atual;
}
botoes_low();
}
// Função para medir a tensão de forma simples
void medirTensaoSimples() {
int valorAnalogico = analogRead(entrada_leitura);
float tensao = valorAnalogico * (5.0 / 1023.0); // Conversão para volts
}
// Função para medir a tensão com referência ajustada
void medirTensaoReferenciaAjustada() {
// Configurar a tensão de referência (ver datasheet para valores)
ADMUX |= (1 << REFS1) | (1 << REFS0); // Exemplo: AVCC com capacitor externo
int valorAnalogico = analogRead(entrada_leitura);
float tensao = valorAnalogico * (5.0 / 1023.0); // Conversão para volts
}
// Função para medir a tensão de forma diferencial (opcional)
void medirTensaoDiferencial() {
// Configurar a medição diferencial (ver datasheet para pinos e configurações)
ADMUX |= (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0); // Exemplo: A0 vs A1
ADCSRB |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Exemplo: Prescaler de 128
int valorAnalogico = analogRead(entrada_leitura);
float tensao = valorAnalogico * (5.0 / 1023.0); // Conversão para volts
}
// Função para medir a tensão com cancelamento de ruído
void medirTensaoCancelamentoRuido() {
// Habilitar ADC e iniciar conversão
ADCSRA |= (1 << ADEN) | (1 << ADSC);
// Configurar modo de redução de ruído (ver datasheet para opções)
SMCR |= (1 << SM1) | (1 << SM0); // Exemplo: Modo 1
// Aguardar conversão
while (ADCSRA & (1 << ADSC));
int valorAnalogico = ADC;
float tensao = valorAnalogico * (5.0 / 1023.0); // Conversão para volts
}