#include "U8glib.h"
// Biblioteca para controlar o display OLED
#include <Wire.h>
// Biblioteca para comunicação I2C
#include "RTClib.h"
// Biblioteca para interagir com módulos de relógio em tempo real (RTC)
#include "moonPhaser.h"
// Biblioteca para o Método 3
moonPhaser moonPhase; // iniciar instância para a lua
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // cria objeto u8g para o Display
RTC_DS1307 RTC; // iniciando módulo RTC
static unsigned char lua_cheia_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xff, 0x3f, 0x00,
0x80, 0xff, 0x7f, 0x00, 0xe0, 0xff, 0xff, 0x01, 0xf0, 0xff, 0xff, 0x03,
0xf0, 0xff, 0xff, 0x03, 0xf8, 0xff, 0xff, 0x07, 0xfc, 0xff, 0xff, 0x0f,
0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0xff, 0x1f,
0xfe, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x1f,
0xfe, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x1f,
0xfe, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f,
0xfc, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0x03,
0xf0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x01, 0x80, 0xff, 0x7f, 0x00,
0x00, 0xff, 0x3f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 };
static unsigned char minguante_gibosa_bits[] = {
0x00, 0xf8, 0x0f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x80, 0xff, 0xff, 0x00,
0xe0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0x7f, 0x00,
0xf8, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x1f, 0x00,
0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00,
0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00,
0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00,
0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00,
0xfe, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0xf8, 0xff, 0x1f, 0x00,
0xf8, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0x00,
0x80, 0xff, 0xff, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xf8, 0x1f, 0x00 };
static unsigned char quarto_minguante_bits[] = {
0x00, 0xf8, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x80, 0xff, 0x01, 0x00,
0xe0, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00,
0xf8, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00,
0xff, 0x1f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
0xfe, 0x1f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00,
0xf8, 0x7f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x01, 0x00,
0x80, 0xff, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00 };
static unsigned char minguante_bits[] = {
0x00, 0xf8, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
0xe0, 0x0f, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00,
0xf8, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00,
0xf8, 0x01, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00,
0x80, 0x1f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00 };
static unsigned char lua_nova_bits[] = {
0x00, 0xf8, 0x07, 0x00, 0x00, 0x07, 0x38, 0x00, 0x80, 0x00, 0x40, 0x00,
0x60, 0x00, 0x80, 0x01, 0x10, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04,
0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x10,
0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x20,
0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20,
0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x20,
0x01, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10,
0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04,
0x08, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x02, 0x60, 0x00, 0x80, 0x01,
0x80, 0x00, 0x40, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0xf8, 0x07, 0x00 };
static unsigned char crescente_bits[] = {
0x00, 0xf8, 0x07, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x7e, 0x00,
0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xe0, 0x07,
0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x80, 0x1f,
0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x3f,
0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f,
0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f,
0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x80, 0x1f,
0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xe0, 0x07,
0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x01,
0x00, 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0xf8, 0x07, 0x00 };
static unsigned char quarto_crescente_bits[] = {
0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xe0, 0x7f, 0x00,
0x00, 0xe0, 0xff, 0x01, 0x00, 0xc0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x07,
0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x1f,
0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xfc, 0x3f,
0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfc, 0x3f,
0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xfc, 0x3f,
0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x1f,
0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x07,
0x00, 0x80, 0xff, 0x07, 0x00, 0xc0, 0xff, 0x03, 0x00, 0xe0, 0xff, 0x01,
0x00, 0xe0, 0x7f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xfc, 0x07, 0x00 };
static unsigned char crescente_gibosa_bits[] = {
0x00, 0xfc, 0x07, 0x00, 0x00, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0x7f, 0x00,
0xc0, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x03, 0x80, 0xff, 0xff, 0x07,
0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x1f,
0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfc, 0xff, 0x3f,
0x00, 0xfc, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f,
0x00, 0xf8, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f,
0x00, 0xf8, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfc, 0xff, 0x1f,
0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x07,
0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x01,
0xc0, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xfe, 0x07, 0x00 };
void setup() {
// Inicia a comunicação serial com uma taxa de transmissão de 9600 bits por segundo
Serial.begin(9600);
// Inicia o módulo RTC
RTC.begin();
// Verifica se o RTC está funcionando corretamente
if (!RTC.isrunning()) {
Serial.println("RTC não está ligado.");
}
// Inicia a comunicação com dispositivos externos usando o protocolo I2C
Wire.begin();
}
void loop() {
u8g.firstPage(); // Inicia a primeira página do Display
// Loop para desenhar a fase lunar
do {
desenharLua(); // Chama a função para desenhar a fase lunar
} while (u8g.nextPage()); // Vai para a próxima página do Display
// Reconstrói a o desenho após um pequeno intervalo
delay(50);
}
// static int fase = 0;
// void loop() {
// // Loop com todas as fases
// u8g.firstPage(); // Inicia a primeira página do Display
// // Loop para desenhar a fase lunar
// do {
// desenharLua(fase); // Chama a função para desenhar a fase lunar
// } while (u8g.nextPage()); // Vai para a próxima página do Display
// // Reconstrói o desenho após um pequeno intervalo
// fase++;
// delay(100);
// if (fase == 8) { // Se atingir 8 desenhos
// fase = 0; // Reinicia o número de desenhos para 0
// }
// }
void desenharLua(void){
// Define a fonte para o texto
u8g.setFont(u8g_font_profont15);
u8g.setFont(u8g_font_5x7);
// Desenha o título "Relógio Lunar" e uma linha separadora
u8g.drawStr(15,10, "Relógio Lunar");
u8g.drawLine(0,13,128,13);
// Calcula a taxa de iluminação lunar e a exibe
float percentLit = taxaIluminacao();
char buffer[10];
dtostrf(percentLit, 3, 0, buffer);
strcat(buffer, "%");
u8g.drawStr(100, 30, buffer);
// Determina a fase lunar atual e a desenha junto com o nome correspondente
int mp = faseLunarConway();
// int mp = faseLunarSinodico();
// int mp = faseLunarAngulo();
// int mp = fase;
switch (mp){
case 0:
u8g.drawStr(15,61, "Lua Cheia");
u8g.drawXBM(45,18,30,30,lua_cheia_bits);
break;
case 1:
u8g.drawStr(15,61, "Minguante Gibosa");
u8g.drawXBM(45,18,30,30,minguante_gibosa_bits);
break;
case 2:
u8g.drawStr(15,61, "Quarto Minguante");
u8g.drawXBM(45,18,30,30,quarto_minguante_bits);
break;
case 3:
u8g.drawStr(15,61, "Lua Minguante");
u8g.drawXBM(45,18,30,30,minguante_bits);
break;
case 4:
u8g.drawStr(15,61, "Lua Nova");
u8g.drawXBM(45,18,30,30,lua_nova_bits);
break;
case 5:
u8g.drawStr(15,61, "Lua Crescente");
u8g.drawXBM(45,18,30,30,crescente_bits);
break;
case 6:
u8g.drawStr(15,61, "Quarto Crescente");
u8g.drawXBM(45,18,30,30,quarto_crescente_bits);
break;
case 7:
u8g.drawStr(15,61, "Crescente Gibosa");
u8g.drawXBM(45,18,30,30,crescente_gibosa_bits);
break;
}
}
int taxaIluminacao() {
moonData_t moon;
DateTime now = RTC.now();
moon = moonPhase.getPhase(now.year(), now.month(), now.day(), now.hour());
float percentLit = moon.percentLit * 100;
return percentLit;
}
int faseLunarAngulo() {
moonData_t moon; // instância da biblioteca para armazenar os dados da lua
DateTime now = RTC.now();
moon = moonPhase.getPhase(now.year(), now.month(), now.day(), now.hour());
int moon_angle = moon.angle; // Obtém o ângulo da lua
// Verifica o ângulo da lua e retorna o número correspondente à fase lunar
if (moon_angle == 0 || moon_angle == 360) {
return 4; // Lua Nova
} else if (moon_angle > 0 && moon_angle < 90) {
return 5; // Crescente Crescente
} else if (moon_angle == 90) {
return 6; // Primeiro Quarto
} else if (moon_angle > 90 && moon_angle < 180) {
return 7; // Crescente Crescente
} else if (moon_angle == 180) {
return 0; // Lua Cheia
} else if (moon_angle > 180 && moon_angle < 270) {
return 1; // Gibbosa Decrescente
} else if (moon_angle == 270) {
return 2; // Último Quarto
} else if (moon_angle > 270 && moon_angle < 360) {
return 3; // Crescente Minguante
}
}
int faseLunarSinodico(){
// Função para calcular a fase lunar sinódica (0 a 7)
DateTime now = RTC.now(); // Obtendo a data atual pelo módulo RTC
double data_juliana = 0; // Data Juliana
double dias_lunares = 0; // Dias decorridos desde o início do ciclo lunar atual
int fase_lunar = 0;
// Calcula a Data Juliana com base na data atual
data_juliana = dataJuliana(now.year(), now.month(), now.day());
// Ajusta a Data Juliana para iniciar em 1º de janeiro de 1972
data_juliana = int(data_juliana - 2244116.75);
// Divide pela duração do ciclo lunar (aproximadamente 29.53 dias)
data_juliana /= 29.53;
// Calcula os dias lunares decorridos neste mês
fase_lunar = data_juliana;
data_juliana -= fase_lunar; // Deixa a parte fracionária da variável
dias_lunares = data_juliana * 29.53;
// Calcula e retorna a fase lunar (0 a 7)
fase_lunar = data_juliana * 8 + 0.5;
fase_lunar = fase_lunar & 7;
return fase_lunar;
}
double dataJuliana(int ano, int mes, int dia){
// Função para calcular a data juliana com base na data fornecida
// As variáveis a seguir são usadas nas diferentes etapas da conversão,
// para a realização de ajustes
int ajuste_mes,ajuste_ano;
double dias_ano, dias_meses, ajuste_bissexto;
double data_juliana;
// Ajuste do ano e mês para o cálculo
ajuste_ano = ano - int((12 - mes)/10);
ajuste_mes = mes + 9;
if(ajuste_mes >= 12) {
ajuste_mes = ajuste_mes - 12;
}
// conversão dos anos em dias
dias_ano = 365.25 * (ajuste_ano + 4172);
// converte a variável mm, com o ajuste dos meses, em dias (adicionando 0.5 para representar o meio dia)
dias_meses = int((30.6001 * ajuste_mes) + 0.5);
// realiza a conversão do ajuste dos anos para dias, considerando os anos bissextos
ajuste_bissexto = int((((ajuste_ano/100) + 4) * 0.75) - 38);
// cálculo da data juliana, somando o total de dias e removendo o desvio dos anos bissextos.
data_juliana = dias_ano + dias_meses + dia + 59;
data_juliana = data_juliana - ajuste_bissexto; // j é a data juliana às 12h UT (Tempo Universal)
return data_juliana;
}
int diaLunarConway(DateTime data) {
// Extrai o ano, mês e dia do objeto DateTime fornecido
int ano = data.year();
int mes = data.month();
int dia = data.day();
// Verifica se o ano está dentro do intervalo aceito
if (ano < 1900 || ano >= 2100) {
Serial.println("A data deve ser maior que 1900 e menor que 2100");
return -1; // Retorna -1 em caso de erro
}
// Define o valor do século (valores fixos, pois o método só é aplicável aos séculos XX e XXI)
double seculo = -4.0;
if (ano > 2000) {
seculo = -8.3;
}
// Etapas do método de Conway para obter o valor do ano
int digitos = ano % 100;
int valor = digitos % 19;
if (valor > 9) {
valor -= 19;
}
valor *= 11;
valor %= 30;
valor += seculo;
// Adiciona o mês e o dia ao valor obtido a partir do ano
valor += mes + dia;
// Ajusta para adicionar 2 caso o mês seja janeiro ou fevereiro
if (mes < 3) {
valor += 2;
}
// Calcula o valor final, arredondando para o número inteiro mais próximo
valor = round(valor) % 30;
// Garante que o resultado seja positivo, ajustando se necessário
return (valor < 0) ? valor + 30 : valor;
}
int faseLunarConway() {
DateTime now = RTC.now();
int lunarDay = diaLunarConway(now);
if (lunarDay <= 28) {
if (lunarDay >= 24) {
return 3; // MINGUANTE
}
if (lunarDay >= 22) {
return 2; // QUARTO MINGUANTE
}
if (lunarDay >= 17) {
return 1; // MINGUANTE GIBOSA
}
if (lunarDay >= 14) {
return 0; // LUA CHEIA
}
if (lunarDay >= 9) {
return 7; // CRESCENTE GIBOSA
}
if (lunarDay >= 7) {
return 6; // QUARTO CRESCENTE
}
if (lunarDay >= 2) {
return 5; // CRESCENTE
}
}
return 4; // LUA NOVA
}