//==================== FÁBIO ELETRONICA ======================
// V2.50 12/11/2025
// Controle para fonte de bancada dupla individual
//========================== Bibliotecas ================================
#include <Bounce2.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
//======Display==========
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//======================= Bitmaps ========================================
const unsigned char epd_bitmap_AAUSB[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xdf, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xdf, 0xff, 0xff,
0xff, 0xff, 0xee, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xee,
0x70, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x0f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xee, 0x70, 0x00, 0x00,
0x00, 0x00, 0x7f, 0x0f, 0xdf, 0x9f, 0x30, 0x30, 0x1f, 0xee, 0x77, 0xff, 0xf8, 0x00, 0x00, 0x7f,
0x0f, 0xdf, 0x9f, 0x20, 0x10, 0x0f, 0xee, 0x77, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0x0f, 0xdf, 0x9f,
0x27, 0x93, 0xcf, 0xee, 0x77, 0xff, 0xfb, 0xff, 0xe0, 0x7f, 0xff, 0xdf, 0x9f, 0x27, 0xf3, 0xcf,
0xee, 0x77, 0xff, 0xfb, 0xff, 0xe0, 0x7f, 0xff, 0xdf, 0x9f, 0x20, 0x30, 0x1f, 0xee, 0x77, 0xff,
0xfb, 0xff, 0xe0, 0x7f, 0xff, 0xdf, 0x9f, 0x30, 0x10, 0x1f, 0xee, 0x77, 0xff, 0xfb, 0xff, 0xe0,
0x7f, 0xff, 0xdf, 0x9f, 0x3f, 0x90, 0x0f, 0xee, 0x77, 0xff, 0xfb, 0xff, 0xe0, 0x7f, 0xff, 0xdf,
0x9f, 0x3f, 0x93, 0xcf, 0xee, 0x77, 0xff, 0xfb, 0xff, 0xe0, 0x7f, 0x0f, 0xdf, 0x9f, 0x27, 0x93,
0xcf, 0xee, 0x77, 0xff, 0xfb, 0xff, 0xe0, 0x7f, 0x0f, 0xdf, 0x80, 0x20, 0x10, 0x0f, 0xee, 0x77,
0xff, 0xf8, 0x00, 0x00, 0x7f, 0x0f, 0xdf, 0xc0, 0x70, 0x30, 0x1f, 0xee, 0x77, 0xff, 0xf8, 0x00,
0x00, 0x7f, 0x0f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xee, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xdf, 0xff, 0xff, 0xff, 0xff, 0xee, 0x70, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xdf, 0xff, 0xff,
0xff, 0xff, 0xee, 0x60, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_onF1[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3e,
0x78, 0x03, 0x3c, 0x06, 0x7e, 0xfd, 0x83, 0x7e, 0x0e, 0x60, 0xcd, 0x83, 0x66, 0x1e, 0x60, 0x0d,
0x83, 0x06, 0x06, 0x7c, 0x3d, 0x9f, 0x1e, 0x06, 0x3e, 0x7d, 0xbf, 0x3e, 0x06, 0x06, 0xcd, 0xb3,
0x66, 0x06, 0x06, 0xcd, 0xb3, 0x66, 0x06, 0x7e, 0xfd, 0xbf, 0x7e, 0x06, 0x7c, 0x7d, 0x9f, 0x3e,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x07, 0x01, 0xc0,
0x07, 0xff, 0x8f, 0x83, 0xe0, 0x07, 0xff, 0x8f, 0xc3, 0xe0, 0x0f, 0xff, 0xcf, 0xc3, 0xe0, 0x0f,
0xff, 0xcf, 0xe3, 0xe0, 0x0f, 0x87, 0xcf, 0xf3, 0xe0, 0x0f, 0x87, 0xcf, 0xf3, 0xe0, 0x0f, 0x87,
0xcf, 0xfb, 0xe0, 0x0f, 0x87, 0xcf, 0xff, 0xe0, 0x0f, 0x87, 0xcf, 0xff, 0xe0, 0x0f, 0x87, 0xcf,
0xff, 0xe0, 0x0f, 0x87, 0xcf, 0xff, 0xe0, 0x0f, 0x87, 0xcf, 0xbf, 0xe0, 0x0f, 0x87, 0xcf, 0x9f,
0xe0, 0x0f, 0x87, 0xcf, 0x9f, 0xe0, 0x0f, 0xff, 0xcf, 0x8f, 0xe0, 0x0f, 0xff, 0xcf, 0x87, 0xe0,
0x07, 0xff, 0x8f, 0x87, 0xe0, 0x07, 0xff, 0x8f, 0x83, 0xe0, 0x01, 0xfe, 0x07, 0x01, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_onF2[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00,
0x00, 0x00, 0x3e, 0x78, 0x03, 0x3c, 0x0f, 0x80, 0x7e, 0xfd, 0x83, 0x7e, 0x1f, 0xc0, 0x60, 0xcd,
0x83, 0x66, 0x19, 0xc0, 0x60, 0x0d, 0x83, 0x06, 0x01, 0xc0, 0x7c, 0x3d, 0x9f, 0x1e, 0x03, 0x80,
0x3e, 0x7d, 0xbf, 0x3e, 0x07, 0x00, 0x06, 0xcd, 0xb3, 0x66, 0x0e, 0x00, 0x06, 0xcd, 0xb3, 0x66,
0x1c, 0x00, 0x7e, 0xfd, 0xbf, 0x7e, 0x1f, 0xc0, 0x7c, 0x7d, 0x9f, 0x3e, 0x1f, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc1, 0xc0, 0x70, 0x00,
0x01, 0xff, 0xe3, 0xe0, 0xf8, 0x00, 0x01, 0xff, 0xe3, 0xf0, 0xf8, 0x00, 0x03, 0xff, 0xf3, 0xf0,
0xf8, 0x00, 0x03, 0xff, 0xf3, 0xf8, 0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xfc, 0xf8, 0x00, 0x03, 0xe1,
0xf3, 0xfc, 0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xfe, 0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xff, 0xf8, 0x00,
0x03, 0xe1, 0xf3, 0xff, 0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xff, 0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xff,
0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xef, 0xf8, 0x00, 0x03, 0xe1, 0xf3, 0xe7, 0xf8, 0x00, 0x03, 0xe1,
0xf3, 0xe7, 0xf8, 0x00, 0x03, 0xff, 0xf3, 0xe3, 0xf8, 0x00, 0x03, 0xff, 0xf3, 0xe1, 0xf8, 0x00,
0x01, 0xff, 0xe3, 0xe1, 0xf8, 0x00, 0x01, 0xff, 0xe3, 0xe0, 0xf8, 0x00, 0x00, 0x7f, 0x81, 0xc0,
0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_offoff[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x0f, 0xff, 0x07, 0xff, 0x80, 0x3f, 0xfe,
0x1f, 0xff, 0x8f, 0xff, 0xc0, 0x3f, 0xfe, 0x1f, 0xff, 0x8f, 0xff, 0xc0, 0x7f, 0xff, 0x1f, 0xff,
0x0f, 0xff, 0x80, 0x7f, 0xff, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x7c, 0x1f, 0x1f, 0x00, 0x0f, 0x80,
0x00, 0x7c, 0x1f, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x7c, 0x1f, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x7c,
0x1f, 0x1f, 0xff, 0x0f, 0xff, 0x80, 0x7c, 0x1f, 0x1f, 0xff, 0x8f, 0xff, 0xc0, 0x7c, 0x1f, 0x1f,
0xff, 0x8f, 0xff, 0xc0, 0x7c, 0x1f, 0x1f, 0xff, 0x0f, 0xff, 0x80, 0x7c, 0x1f, 0x1f, 0x00, 0x0f,
0x80, 0x00, 0x7c, 0x1f, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x7c, 0x1f, 0x1f, 0x00, 0x0f, 0x80, 0x00,
0x7f, 0xff, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x7f, 0xff, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x3f, 0xfe,
0x1f, 0x00, 0x0f, 0x80, 0x00, 0x3f, 0xfe, 0x1f, 0x00, 0x0f, 0x80, 0x00, 0x0f, 0xf8, 0x0e, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_onon[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x30, 0x07, 0xc7, 0xc0, 0x7c, 0x70, 0x07, 0xcf, 0xe0, 0x60,
0xf0, 0x06, 0x0c, 0xe0, 0x60, 0x30, 0x06, 0x00, 0xe0, 0x7c, 0x30, 0x07, 0xc1, 0xc0, 0x7c, 0x31,
0xc7, 0xc3, 0x80, 0x60, 0x31, 0x06, 0x07, 0x00, 0x60, 0x31, 0x86, 0x0e, 0x00, 0x60, 0x31, 0x06,
0x0f, 0xe0, 0x60, 0x31, 0xc6, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x1c, 0x07, 0x00,
0x1f, 0xfe, 0x3e, 0x0f, 0x80, 0x1f, 0xfe, 0x3f, 0x0f, 0x80, 0x3f, 0xff, 0x3f, 0x0f, 0x80, 0x3f,
0xff, 0x3f, 0x8f, 0x80, 0x3e, 0x1f, 0x3f, 0xcf, 0x80, 0x3e, 0x1f, 0x3f, 0xcf, 0x80, 0x3e, 0x1f,
0x3f, 0xef, 0x80, 0x3e, 0x1f, 0x3f, 0xff, 0x80, 0x3e, 0x1f, 0x3f, 0xff, 0x80, 0x3e, 0x1f, 0x3f,
0xff, 0x80, 0x3e, 0x1f, 0x3f, 0xff, 0x80, 0x3e, 0x1f, 0x3e, 0xff, 0x80, 0x3e, 0x1f, 0x3e, 0x7f,
0x80, 0x3e, 0x1f, 0x3e, 0x7f, 0x80, 0x3f, 0xff, 0x3e, 0x3f, 0x80, 0x3f, 0xff, 0x3e, 0x1f, 0x80,
0x1f, 0xfe, 0x3e, 0x1f, 0x80, 0x1f, 0xfe, 0x3e, 0x0f, 0x80, 0x07, 0xf8, 0x1c, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_fbtec[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x83, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0x83, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x83,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x83, 0xff,
0xff, 0x80, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x83, 0xff, 0xff,
0x80, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x80,
0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x03, 0xf0, 0x3f, 0x80, 0x00,
0x01, 0xfc, 0x00, 0x0f, 0xf8, 0x00, 0x7f, 0xc0, 0x7e, 0x00, 0x03, 0xf0, 0x3f, 0x80, 0x00, 0x01,
0xfc, 0x00, 0x1f, 0xfc, 0x01, 0xff, 0xf0, 0x7e, 0x00, 0x03, 0xf0, 0x7f, 0x80, 0x00, 0x01, 0xfc,
0x00, 0x3f, 0xfe, 0x03, 0xff, 0xf8, 0x7f, 0xff, 0x03, 0xff, 0xff, 0x00, 0x00, 0x01, 0xfc, 0x00,
0x7f, 0xff, 0x07, 0xff, 0xfc, 0x7f, 0xff, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x01, 0xfc, 0x00, 0xfe,
0x3f, 0x8f, 0xff, 0xfc, 0x7f, 0xff, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x01, 0xfc, 0x00, 0xfc, 0x1f,
0x8f, 0xf0, 0xfc, 0x7f, 0xff, 0x03, 0xff, 0xfe, 0x07, 0xfc, 0x01, 0xfc, 0x01, 0xfc, 0x1f, 0x8f,
0xe0, 0x7c, 0x7f, 0xff, 0x03, 0xf0, 0x7f, 0x07, 0xfc, 0x01, 0xfc, 0x01, 0xff, 0xff, 0x8f, 0xe0,
0x00, 0x7e, 0x00, 0x03, 0xf0, 0x3f, 0x87, 0xfc, 0x01, 0xfc, 0x01, 0xff, 0xff, 0x8f, 0xe0, 0x00,
0x7e, 0x00, 0x03, 0xf0, 0x3f, 0x87, 0xfc, 0x01, 0xfc, 0x01, 0xff, 0xff, 0x8f, 0xe0, 0x00, 0x7e,
0x00, 0x03, 0xf0, 0x3f, 0x87, 0xfc, 0x01, 0xfc, 0x01, 0xfc, 0x00, 0x0f, 0xe0, 0x7c, 0x7e, 0x00,
0x03, 0xf0, 0x7f, 0x80, 0x00, 0x01, 0xfc, 0x00, 0xfc, 0x00, 0x0f, 0xf0, 0xfc, 0x7e, 0x00, 0x03,
0xff, 0xff, 0x80, 0x00, 0x01, 0xfc, 0x00, 0xfe, 0x1f, 0x0f, 0xff, 0xfc, 0x7e, 0x00, 0x03, 0xff,
0xff, 0x80, 0x00, 0x01, 0xfc, 0x00, 0x7f, 0xff, 0x07, 0xff, 0xfc, 0x7e, 0x00, 0x03, 0xff, 0xff,
0x00, 0x00, 0x01, 0xfc, 0x00, 0x3f, 0xfe, 0x03, 0xff, 0xf8, 0x7e, 0x00, 0x03, 0xff, 0xfe, 0x00,
0x00, 0x01, 0xfc, 0x00, 0x1f, 0xfc, 0x01, 0xff, 0xf0, 0x7e, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00,
0x01, 0xfc, 0x00, 0x0f, 0xf8, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void drawBitmap(const unsigned char *bitmap, uint8_t w, uint8_t h) {
display.drawBitmap(0, 3, bitmap, w, h, 1); // Valor 0 Inverte as cores
display.display();
}
// ========================= Modulo RTC ==========================
RTC_DS3231 rtc;
//------------------------------------------------------------------
const char *version = "V2.50"; // Muda o nome da versão
unsigned long TempoStby = 900000; //Tempo para entrar em Stby
//------------ Variaveis Relogio -----------------------------------------
unsigned long lastUpdate = 0;
unsigned long currentMillisH = 0;
const long intervalHora = 300;
// Variáveis para detectar o clique triplo
int clickCount = 0;
int x = 1;// Evita que o ajute do relogio seja chamado quando estiver ligado
int y = 0;// Evita ligar a fonte enquanto o ajuste esta sendo feito
int h = 0;// Evita travamento durante o ajuste pelo botao power
unsigned long lastClickTime = 0;
bool lastButtonState = HIGH;
const long debounceTime = 50;
bool RelogioAdj = false;
//------------------------------------------------------------------------
//=== Pinos de Entrada e Saída ============================
const uint8_t BUTTON_PIN = 4; // BT Modo
const uint8_t LIGAF1_PIN = 3; // BT Liga F1
const uint8_t LIGAF2_PIN = 2; // BT Liga F2
const uint8_t RF_PINS[] = { 5, 6 };
const uint8_t RL_PINS[] = { 7, 8, 9, 10 };
const uint8_t LED_PIN = 12; // LED
const uint8_t BUZZER_PIN = 11; // Buzzer
const uint8_t PFC1_PIN = A1; // Liga PFC1
const uint8_t PFC2_PIN = A0; // Liga PFC2
const uint8_t buttonPower = 13; // Botão Power
const uint8_t pinA3 = A3; // Saída Rele USB
// Estados dos Botões e Relés=================================
bool buttonPowerPressed = false; // Estado do botão
bool longPressExecuted = false;
bool a3State = true;
bool standbyBeepDone = false;
// ======================= Variáveis de Tempo =====================
unsigned long TempoMaximoEmStby;
unsigned long standbyBeepStartTime = 0;
unsigned long buttonPowerPressTime = 0; // Tempo botão pressionado
unsigned long pressStartTime = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long previousMillisF1 = 0; // Variável de tempo para F1
unsigned long previousMillisF2 = 0; // Variável de tempo para F2
unsigned long previousMillisDisplay = 0;
unsigned long resetTimer = 0;
const long intervalDisplay = 500;
const long interval = 1000; // Delay LED
const long interval2 = 1000; // Delay do relé PFC
unsigned long standbyStartTime = 0; // Standby
// ================== Leitura Analógica Pino A6 ===================
const int numReadings = 3; // Número de leituras para calcular a média
int readings[numReadings]; // Array para armazenar as leituras
int readIndex = 0; // Índice da leitura atual
int total = 0; // Soma das leituras
float average = 0; // Média das leituras
float leituraPin; // Armazena a leitura
//=========================== Estado do Sistema ==================
int state = 0;
int resett = 0;
int executarCodigo = 0;
int executarCodigo2 = 0;
bool botaoF1 = false;
bool botaoF2 = false;
bool pfc1State = false; // Estado do PFC1
bool pfc2State = false; // Estado do PFC2
bool isStandby = false;
bool buttonPressed = false;
static unsigned long desligandoStartTime = 0;
static bool mostrandoDesligando = false;
static bool desligandoExibido = false;
// ====================== Debouncers =========================
Bounce debouncerButton = Bounce();
Bounce debouncerF1 = Bounce();
Bounce debouncerF2 = Bounce();
//================= SETUP =============
void setup() {
relogio();
inicializarDisplay();
inicializarPinos();
inicializarDebouncers();
SelfTest();
} //=========== LOOP ===================
void loop() {
reset();
poweroff();
handleButtonPress();
updateOutputs();
handleFonteButtons();
InHora();
}
//================== CLOCK ==============
void relogio() {
rtc.begin(); // Inicia o módulo RTC
DateTime now = rtc.now();
}
//========================================================================
void inicializarDisplay() {
DDRB |= (1 << DDB4); // LED_PIN como saída
PORTB |= (1 << PORTB4); // Liga o Led Stby
DDRB &= ~(1 << DDB5); // Pino 13 como entrada
PORTB |= (1 << PORTB5); // Ativa o pull-up interno do pino 13
delay(100); // Atraso para o pino 13 Bootload
// Se resett for diferente de 1, espera até que o botão no pino 13 seja pressionado
if (resett != 1) {
while (PINB & (1 << PINB5)) {
}
}
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Endereço I2C do display
for (;;)
;
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
int imagem_largura = 119;
int imagem_altura = 25;
int x = (SCREEN_WIDTH - imagem_largura) / 2;
int y = (SCREEN_HEIGHT - imagem_altura) / 2;
//y -= 10; //Move para cima
//y += 15; //Move para baixo
display.drawBitmap(x, y, epd_bitmap_fbtec, imagem_largura, imagem_altura, WHITE);// Logo Inicial
display.setTextSize(1);
display.setCursor(15, 55);
display.println(F("FABIO ELETRONICA"));
display.display();
delay(1000);
}
//========================================================================
void inicializarPinos() {
// Configuração dos pinos como entrada
DDRD &= ~(1 << DDD2); // LIGAF2_PIN
DDRD &= ~(1 << DDD3); // LIGAF1_PIN
DDRD &= ~(1 << DDD4); // BUTTON_PIN
pinMode(A6, INPUT); // Pino leitura Analógica fontes
// Habilitar pull-up interno para os pinos de entrada
PORTD |= (1 << PORTD2) | (1 << PORTD3) | (1 << PORTD4);
// Configuração dos pinos como saída
DDRD |= (1 << DDD5) | (1 << DDD6) | (1 << DDD7); // RF1_PIN, RF2_PIN, RL1_PIN
DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3); // RL2_PIN, RL3_PIN, RL4_PIN, BUZZER_PIN
//DDRB |= (1 << DDB4); // LED_PIN (D12)
DDRC |= (1 << DDC0); // PFC2_PIN (A0)
DDRC |= (1 << DDC1); // PFC1_PIN (A1)
DDRC |= (1 << DDC2); // Rele USB (A2)
DDRC |= (1 << DDC3); // Rele Pow (A3)
// Inicializar pinos de saída com nível baixo
PORTD &= ~((1 << PORTD5) | (1 << PORTD6) | (1 << PORTD7));
PORTB &= ~((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2) | (1 << PORTB3) | (1 << PORTB4));
PORTC &= ~((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3));
}
//=========================================================================
void inicializarDebouncers() {
debouncerButton.attach(BUTTON_PIN);
debouncerButton.interval(20);
debouncerF1.attach(LIGAF1_PIN);
debouncerF1.interval(15);
debouncerF2.attach(LIGAF2_PIN);
debouncerF2.interval(15);
}
// =================== Teste De Reles ==================================
void SelfTest() { /*
const int relePins[] = {5, 6, 7, 8, 9, 10};
const int totalReles = sizeof(relePins) / sizeof(relePins[0]);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 0);
display.print("Self-Test");
display.display();
for (int i = 0; i < totalReles; i++) {
digitalWrite(relePins[i], HIGH);
delay(200);
digitalWrite(relePins[i], LOW);
delay(200);
tone(BUZZER_PIN, 2700, 50);
delay(200);
// Atualiza a barra de progresso
int barWidth = (SCREEN_WIDTH * (i + 1)) / totalReles;
display.fillRect(0, 40, barWidth, 15, SSD1306_WHITE);
display.display();
}
delay(500);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(37, 0);
display.println(version);
display.setCursor(32, 25);
display.println(F("Teste"));
display.setCursor(18, 44);
display.println(F("Completo"));
display.display();
//Toque inicial
tone(BUZZER_PIN, 1000, 100);
delay(100);
tone(BUZZER_PIN, 1300, 100);
delay(100);
tone(BUZZER_PIN, 1600, 100);
delay(100);
tone(BUZZER_PIN, 1900, 200);
state = 0;
delay(1000); */
}
//====================================================================================================
//================================= COMECO DO CODIGO ================================================
void reset() {
if (digitalRead(LIGAF1_PIN) == LOW) { // Botão pressionado
if (!buttonPressed) {
resetTimer = millis();
buttonPressed = true;
}
// Se o botão ficar pressionado por 5 segundos (5000ms)
if (millis() - resetTimer >= 4000) {
DesligaPin();
resett = 1;
display.clearDisplay();
display.setTextSize(2);
display.setCursor(35, 28);
display.print("Reset");
display.display();
delay(100);
asm volatile ("jmp 0"); // Salta para o endereço 0 da memória (reset)
}
} else {
buttonPressed = false;
}
}
void DesligaPin(){// Desliga todos os pinos
PORTD &= ~((1 << PORTD5) | (1 << PORTD6) | (1 << PORTD7)); // Desliga LIGAF1_PIN, LIGAF2_PIN, RL1_PIN
PORTB &= ~((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2) | (1 << PORTB3) | (1 << PORTB4)); // Desliga RL2_PIN, RL3_PIN, RL4_PIN, BUZZER, LED1
PORTC &= ~((1 << PORTC0) | (1 << PORTC1) | (1 << PORTC2) | (1 << PORTC3)); // Desliga PFC1, PFC2, USB, Geral
}
//====================== Botao Power ======================================
void ligarSistema() {
a3State = true;
state = 0;
x = 1;
executarCodigo = 0;
executarCodigo2 = 0;
tone(BUZZER_PIN, 2700, 50);
desligandoExibido = false;
botaoF1 = false;
botaoF2 = false;
previousMillisF1 = millis();
previousMillisF2 = millis();
pfc1State = false;
pfc2State = false;
}
void desligarSistema() {
a3State = false;
DesligaPin();
executarCodigo = 1;
executarCodigo2 = 1;
isStandby = false;
standbyStartTime = 0;
tone(BUZZER_PIN, 3000, 50);
}
void poweroff() {//=======================================
unsigned long currentMillis = millis();
if (y == 0) {
if (!(PINB & (1 << PINB5))) {
if (!buttonPowerPressed) {
buttonPowerPressed = true;
buttonPowerPressTime = currentMillis;
} else if (currentMillis - buttonPowerPressTime >= 800) {
if (!a3State) {
ligarSistema();
} else {
desligarSistema();
}
buttonPowerPressed = false;
}
} else {
if (buttonPowerPressed && (currentMillis - buttonPowerPressTime < 800)) {
isStandby = false;
standbyStartTime = 0;
standbyBeepStartTime = 0;
standbyBeepDone = false;
executarCodigo2 = 0;
}
buttonPowerPressed = false;
}
if (!a3State && !RelogioAdj) {
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (!desligandoExibido) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(4, 28);
display.print("Desligando");
display.display();
desligandoStartTime = currentMillis;
mostrandoDesligando = true;
desligandoExibido = true;
} else if (mostrandoDesligando && currentMillis - desligandoStartTime >= 1000) {
mostrandoDesligando = false;
}
if (!mostrandoDesligando) {
DateTime now = rtc.now();
display.clearDisplay();
display.setTextSize(3);
display.setCursor(20, 17);
char buffer[6];
snprintf(buffer, sizeof(buffer), "%02d %02d", now.hour(), now.minute());
display.print(buffer);
display.setCursor(58, 17);
if ((currentMillis / interval) % 2 == 0)
display.println(F(":"));
char dataFormatada[11];
sprintf(dataFormatada, "%02d/%02d/%04d", now.day(), now.month(), now.year());
display.setTextSize(2);
display.setCursor(6, 50);
display.print(dataFormatada);
// Opcional: temperatura
/*
float temperature = rtc.getTemperature();
display.setTextSize(1);
display.setCursor(46, 0);
display.print(temperature);
display.print("c");
*/
x = 0;
display.display();
}
}
}
}
}
//=================================================================
//========================= Botao MODO ============================
void handleButtonPress() {
//------------------- Leitura do pino A6 -------------------------
total = total - readings[readIndex];
readings[readIndex] = analogRead(A6);
total = total + readings[readIndex];
readIndex = (readIndex + 1) % numReadings;
average = total / numReadings;
leituraPin = average * (5.0 / 1023.0); // Converte para volts
if (executarCodigo == 1 || leituraPin > 0.10) {
PORTB |= (1 << PORTB4); // Aciona o LED
return; // Sai da função
} else {
PORTB &= ~(1 << PORTB4); // Desliga o LED
}
//===============================================================
currentMillis = millis(); // Obtém o tempo atual
debouncerButton.update();
if (debouncerButton.read() == LOW) {
if (pressStartTime == 0) {
pressStartTime = currentMillis; // Armazena o tempo de início da pressão
} else if (currentMillis - pressStartTime >= 1000 && !longPressExecuted) {
// Se o botão foi pressionado por mais de 1 segundo
//executarLongPress();
}
} else {
if (pressStartTime != 0 && !longPressExecuted) {
// Se o botão foi pressionado por menos de 1 segundo e solto
executarShortPress();
}
pressStartTime = 0; // Reseta o tempo de início
longPressExecuted = false; // Reseta a marcação de longo período
}
}
//-----------------Anter era o USB -----------------------
void executarLongPress() {
if (executarCodigo2 == 0) { //Evita que o buzer toque em STBY
tone(BUZZER_PIN, 1250, 50);
}
}
//------------------------Modos da Saida--------------------------
void executarShortPress() {
if ((PORTC & (1 << PORTC2)) || isStandby) { //Garante que o estado volte para 0
state = 0;
} else {
state = (state + 1) % 6;
}
standbyStartTime = 0; //Reseta o tempo de stby
if (executarCodigo2 == 0) { //Evita que o buzer toque em STBY
tone(BUZZER_PIN, 1200, 50);
}
}
//-----------------------------------------------------------------
void updateOutputs() {
if (executarCodigo == 1) {
return; // Sai da função se executarCodigo for 1
}
// Controle dos relés
PORTD = (state == 1 || state == 2 || state == 3) ? (PORTD | (1 << PORTD7)) : (PORTD & ~(1 << PORTD7)); // Liga só RL1
PORTB = (state == 2) ? (PORTB | (1 << PORTB0)) : (PORTB & ~(1 << PORTB0)); // Liga RL1 e RL2
PORTB = (state == 3) ? (PORTB | (1 << PORTB1)) : (PORTB & ~(1 << PORTB1)); // Liga RL1, RL3 e RL4
PORTB = (state == 4 || state == 3) ? (PORTB | (1 << PORTB2)) : (PORTB & ~(1 << PORTB2)); // Liga só RL4
PORTC = (state == 5) ? (PORTC | (1 << PORTC2)) : (PORTC & ~(1 << PORTC2)); // Liga USB somente no estado 5
//-------------------------- STBY-----------------------------------
if (!(PINB & (1 << PINB4))) {
if (standbyStartTime == 0) {
standbyStartTime = millis();
TempoMaximoEmStby = 600000;//Tempo para desligar em stby, 10m
} else if (millis() - standbyStartTime >= TempoStby) { // Tempo para Standby 10 Minutos
isStandby = true;
}
} else {
standbyStartTime = 0;
isStandby = false;
}
display.clearDisplay();
if (isStandby) {
state = 0;
display.clearDisplay(); // Limpa sempre
display.setTextSize(2);
display.setCursor(18, 20);
// Pisca o texto "Stand-by"
if ((millis() / interval) % 2 == 0) {
display.println(F("Stand-by"));
}
// Beep duplo ao entrar em Standby
if (!standbyBeepDone) {
unsigned long tempoAtual = millis();
if (standbyBeepStartTime == 0) {
standbyBeepStartTime = tempoAtual;
tone(BUZZER_PIN, 2500, 50); // Primeiro bip
} else if (tempoAtual - standbyBeepStartTime >= 150 && tempoAtual - standbyBeepStartTime < 300) {
tone(BUZZER_PIN, 2500, 50); // Segundo bip após 300ms
} else if (tempoAtual - standbyBeepStartTime >= 300) {
standbyBeepDone = true; // Finaliza sequência
}
}
// Desliga apos um tempo em stby
if (millis() - standbyStartTime >= TempoStby + TempoMaximoEmStby) {
desligarSistema(); //
}
// Ações de Standby
DesligaPin();
executarCodigo2 = 1;
botaoF1 = false;
botaoF2 = false;
previousMillisF1 = millis();
previousMillisF2 = millis();
pfc1State = false;
pfc2State = false;
display.display(); // Atualiza o display
return; // Evita que o restante do display seja desenhado
}
//-------------------------------------------------------------------
else {
display.setTextSize(1); // Tamanho do texto
display.drawLine(0, 18, SCREEN_WIDTH, 18, SSD1306_WHITE); // Linha
display.setTextSize(2);
switch (state) {
case 1:
display.setCursor(8, 0);
display.println(F("GND Comum"));
break;
case 2:
display.setCursor(15, 0);
display.println(F("Em Serie"));
break;
case 3:
display.setCursor(14, 0);
display.println(F("Paralelo"));
break;
case 4:
display.setCursor(30, 0);
display.println(F("Diodo"));
break;
case 5:
display.setTextSize(1);
display.setCursor(4, 5);
display.print(F("Out 1:"));
display.print((PINC & (1 << PINC1)) ? F("ON") : F("OFF"));
display.setCursor(72, 5);
display.print(F("Out 2:"));
display.print((PINC & (1 << PINC0)) ? F("ON") : F("OFF"));
break;
default:
display.setCursor(26, 0);
display.println(F("Normal"));
display.setCursor(3, 55);
break;
}
//---------------------------Bitmaps-------------------------------------
// Prioridade: se state == 5, mostra apenas USB
bool out1State = (PINC & (1 << PINC1));
bool out2State = (PINC & (1 << PINC0));
bool out3State = (PINC & (1 << PINC2));
if (state == 5) {
int imagem_largura = 100;
int imagem_altura = 31;
int x = (SCREEN_WIDTH - imagem_largura) / 2;
int y = (SCREEN_HEIGHT - imagem_altura) / 2;
y += 15;
display.drawBitmap(x, y, epd_bitmap_AAUSB, imagem_largura, imagem_altura, WHITE);
} else {
if (out1State && out2State) {
int imagem_largura = 36;
int imagem_altura = 36;
int x = (SCREEN_WIDTH - imagem_largura) / 2;
int y = (SCREEN_HEIGHT - imagem_altura) / 2;
y += 15;
display.drawBitmap(x, y, epd_bitmap_onon, imagem_largura, imagem_altura, WHITE);
} else if (!out1State && !out2State) {
int imagem_largura = 51;
int imagem_altura = 22;
int x = (SCREEN_WIDTH - imagem_largura) / 2;
int y = (SCREEN_HEIGHT - imagem_altura) / 2;
y += 15;
display.drawBitmap(x, y, epd_bitmap_offoff, imagem_largura, imagem_altura, WHITE);
} else if (out1State) {
int imagem_largura = 40;
int imagem_altura = 36;
int x = (SCREEN_WIDTH - imagem_largura) / 2;
int y = (SCREEN_HEIGHT - imagem_altura) / 2;
y += 15;
display.drawBitmap(x, y, epd_bitmap_onF1, imagem_largura, imagem_altura, WHITE);
} else if (out2State) {
int imagem_largura = 43;
int imagem_altura = 36;
int x = (SCREEN_WIDTH - imagem_largura) / 2;
int y = (SCREEN_HEIGHT - imagem_altura) / 2;
y += 15;
display.drawBitmap(x, y, epd_bitmap_onF2, imagem_largura, imagem_altura, WHITE);
}
}
display.display();
}
}
//====================================================================================
//================== Liga Desliga Fontes ==============================================
void handleFonteButtons() {
if (executarCodigo == 1 || executarCodigo2 == 1) {
return; // Sai da função se executarCodigo for 1
}
debouncerF1.update();
debouncerF2.update();
unsigned long currentMillis = millis(); // Tempo atual
auto handleButton = [&](bool &buttonState, unsigned long &previousMillis, uint8_t portD, uint8_t portC, bool &pfcState) {
if (buttonState) {
if (currentMillis - previousMillis >= interval2 && !pfcState) {
PORTC |= (1 << portC); // Liga PFC_PIN
pfcState = true; // Indica que o PFC está ligado
}
} else {
if (currentMillis - previousMillis >= interval2 && !pfcState) {
PORTD &= ~(1 << portD); // Desliga F
} else if (currentMillis - previousMillis < interval2 && !pfcState) {
PORTC &= ~(1 << portC); // Desliga PFC_PIN
}
}
};
// Verifica se o botão F1 foi pressionado e solto
if (debouncerF1.fell()) {
botaoF1 = !botaoF1;
previousMillisF1 = currentMillis; // Armazena o tempo atual
tone(BUZZER_PIN, 2000, 50); // Toca o buzzer
if (botaoF1) {
PORTD |= (1 << PORTD5); // Liga F1 imediatamente
PORTC |= (1 << PORTC3); // Liga Geral
// Se o state for 1,2 ou 3, liga as duas fontes
if (state == 1 || state == 2|| state == 3) {
botaoF2 = true;
previousMillisF2 = currentMillis;
tone(BUZZER_PIN, 2000, 50);
PORTD |= (1 << PORTD6); // Liga F2 imediatamente
}
} else {
pfc1State = false; // Indica que o PFC1 deve ser desligado
previousMillisF1 = currentMillis; // Reinicia o tempo para o próximo intervalo
}
}
// Verifica se o botão F2 foi pressionado e solto
if (debouncerF2.fell()) {
botaoF2 = !botaoF2;
previousMillisF2 = currentMillis; // Armazena o tempo atual
tone(BUZZER_PIN, 2000, 50); // Toca o buzzer
if (botaoF2) {
PORTD |= (1 << PORTD6); // Liga F2 imediatamente
PORTC |= (1 << PORTC3); // Liga Geral
} else {
pfc2State = false; // Indica que o PFC2 deve ser desligado
previousMillisF2 = currentMillis; // Reinicia o tempo para o próximo intervalo
}
}
// Atualiza o estado dos botões F1 e F2
handleButton(botaoF1, previousMillisF1, PORTD5, PORTC1, pfc1State);
handleButton(botaoF2, previousMillisF2, PORTD6, PORTC0, pfc2State);
}
//========================= Ajuste do Relogio =====================================
void InHora() {
if (x == 0) { //Evita ajuste com a fonte ligada
if (h ==0){
bool currentButtonState = digitalRead(buttonPower);
if (lastButtonState == LOW && currentButtonState == HIGH && (millis() - lastClickTime > debounceTime)) {
if (millis() - lastClickTime < 2000) {
clickCount++;
} else {
clickCount = 0;
}
lastClickTime = millis();
}
lastButtonState = currentButtonState;
}
if (clickCount >= 4) {
RelogioAdj = true;
y = 1;//Trava o Botao para nao ligar
h = 1;//trava o botao power
AdjHora();//Cahama o ajuste do relogio
}
}
}
//=====================================================
void AdjHora() {
// Variáveis estáticas mantêm seus valores entre as chamadas da função
static int etapaDeAjuste = 0; // 0:hora, 1:min, 2:dia, 3:mes, 4:ano
static bool ajusteIniciado = false;
static int hora, minuto, dia, mes, ano;
// Timers para debounce dos botões
static unsigned long lastBtSobe = 0;
static unsigned long lastBtDesce = 0;
static unsigned long lastBtModo = 0;
DateTime now = rtc.now();
// Bloco de inicialização: Executa apenas na primeira vez que a função é chamada
if (!ajusteIniciado) {
hora = now.hour();
minuto = now.minute();
dia = now.day();
mes = now.month();
ano = now.year();
etapaDeAjuste = 0; // Garante que o ajuste comece sempre pela hora
ajusteIniciado = true;
}
// BOTÃO DE MODO (BUTTON_PIN): Avança para a próxima etapa de ajuste
if (digitalRead(BUTTON_PIN) == LOW && millis() - lastBtModo > 200) {
lastBtModo = millis();
etapaDeAjuste++; // Avança para a próxima etapa
// Se passou da última etapa (ano), salva tudo e sai do modo de ajuste
if (etapaDeAjuste > 4) {
// Salva os novos valores no RTC
rtc.adjust(DateTime(ano, mes, dia, hora, minuto, now.second()));
// PREPARA PARA SAIR DO MODO DE AJUSTE
ajusteIniciado = false; // Reseta para a próxima vez que o ajuste for chamado
// *** PONTO CRÍTICO: Reseta as variáveis que te mantêm no modo de ajuste ***
clickCount = 0; // Isso fará a condição em InHora() se tornar falsa!
RelogioAdj = false;
y = 0;
h = 0;//Destrava o botao
display.clearDisplay();
display.display();
return; // Sai da função para finalizar o ajuste
}
}
// BOTÃO DE AUMENTAR (LIGAF1_PIN): Incrementa o valor da etapa atual
if (digitalRead(LIGAF2_PIN) == LOW && millis() - lastBtSobe > 200) {
lastBtSobe = millis();
switch (etapaDeAjuste) {
case 0: hora = (hora + 1) % 24; break;
case 1: minuto = (minuto + 1) % 60; break;
case 2: dia = (dia % 31) + 1; break;
case 3: mes = (mes % 12) + 1; break;
case 4: ano++; break;
}
}
// BOTÃO DE DIMINUIR (LIGAF2_PIN): Decrementa o valor da etapa atual
if (digitalRead(LIGAF1_PIN) == LOW && millis() - lastBtDesce > 300) {
lastBtDesce = millis();
switch (etapaDeAjuste) {
case 0: hora = (hora - 1 + 24) % 24; break;
case 1: minuto = (minuto - 1 + 60) % 60; break;
case 2: dia = (dia - 1 < 1) ? 31 : dia - 1; break;
case 3: mes = (mes - 1 < 1) ? 12 : mes - 1; break;
case 4: ano = (ano - 1 < 2020) ? 2099 : ano - 1; break;
}
}
// ATUALIZAÇÃO DO DISPLAY: Mostra os valores e pisca o campo ativo
if (millis() - lastUpdate > 100) {
lastUpdate = millis();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(22, 2);display.print("Ajuste Relogio");
display.setTextSize(2);
display.setCursor(30, 20);
if (hora < 10) display.print("0");
display.print(hora);
display.print(":");
if (minuto < 10) display.print("0");
display.print(minuto);
display.setCursor(5, 43);
if (dia < 10) display.print("0");
display.print(dia);
display.print("/");
if (mes < 10) display.print("0");
display.print(mes);
display.print("/");
display.print(ano);
bool pisca = (millis() / 400) % 2; // Pisca a cada 400ms
if (pisca) {
switch (etapaDeAjuste) { //A L C
//L A
case 0: display.setCursor(31, 30); display.print("--");break;//Hora
case 1: display.setCursor(66, 30); display.print("--");break;//Minuto
case 2: display.setCursor(6, 53); display.print("--");break;//Dia
case 3: display.setCursor(42, 53); display.print("--");break;//Mes
case 4: display.setCursor(77, 53); display.print("----");break;//Ano
}
}
display.display();
}
}
/*-----------ERROS CORRIGIDOS E MELHORIAS IMPLEMENTADAS-----------------
-V1.93 Correção de erros.
Corrigido erro quando desligava pelo botao power e ligava teria que dar 2 cliques para ligar as Fontes.
-V1.94 Melhorias de uso no dia-a-dia.
Agora depedendo do MODO da Fonte ele pode ligar uma ou as duas poupando tempo.
-V1.95 Adicionado o reset via codigo ao segurar o botao f1 por 5seg.
-V1.99 Melhorias no desempenho.
Reduzido tamanho da memoria usada por bitmaps.
Usava 28.188 bytes (91%) Maximo 30720 bytes. Agora usa 24.270 bytes (78%) -13%.
Variaveis globais 544 bytes (26%) Maximum 2048 bytes.
Antes os bitmaps usavam 8.192 bytes. Agora otimizado para 1.340 bytes. Reduzido -1.852 bytes.
Correcao de erro na exibição da data.
Otimizaçao de funcoes repetidas e nao usada.
--Nova Versao V2.00 Implementado o ajuste de horas atraves dos botoes.
-V2.01 Mudanca no teste de reles, adicionado mais reles e troca da barra deixando.
menos demorado.
Correcao de erro de clique duplo ao retornar do stby.
-V2.02 Correcao do ajuste do relogio, agora ele nao pode ser ajustado qundo a fonte estiver ligada entre outros bugs
-V2.03 Correcao dos erros e adicionado ajuste da data, antes era so o relogio.
-V2.45 Mudancas na logica dos Modos da fonte, Antes teria que precionar por 1s para entrar no modo USB isso perdia tempo
agora alogica esta implementada junto dos outros modos da fonte, apos o "Diodo" e mais pratico.
Adicionado aviso sonoro para qundo entra em stby.
-V2.50 Criada funcoes separadas para ligado e desligado e adicionado condicao para quando entra em
stby depois de 10m desliga o sistema.
*/