Aquest grup va fer un visualitzador que permet diverses opcions, com mostrar missatges que s'escriuen en una pàgina web, el temps que farà o un versicle que canvia cada dia.
El programa del microcontrolador és el següent:
#include <SPI.h> // Carreguem la biblioteca SPI #include <WiFiNINA.h> // Carreguem la biblioteca WiFiNINA #include <WiFiUdp.h> // Farem servir UDP per llegir l'hora d'internet #include <Adafruit_NeoPixel.h> #include "ssd1306.h" #define ARDUINOJSON_DECODE_UNICODE 1 #include <ArduinoJson.h> // Carreguem la biblioteca json #define LED 1 // pota on hem connectat el LED #define LEDP 6 // pota on hem connectat el LED #define pol 7 #define pol_dw 5 #define pol_ok 4 #define N_Do0 33 #define N_ReB0 35 #define N_Re0 37 #define N_MiB0 39 #define N_Mi0 41 #define N_Fa0 44 #define N_SolB0 46 #define N_Sol0 49 #define N_LaB0 52 #define N_La0 55 #define N_SiB0 58 #define N_Si0 62 #define N_Do1 65 #define N_ReB1 69 #define N_Re1 73 #define N_MiB1 78 #define N_Mi1 82 #define N_Fa1 87 #define N_SolB1 93 #define N_Sol1 98 #define N_LaB1 104 #define N_La1 110 #define N_SiB1 117 #define N_Si1 123 #define N_Do2 131 #define N_ReB2 139 #define N_Re2 147 #define N_MiB2 156 #define N_Mi2 165 #define N_Fa2 175 #define N_SolB2 185 #define N_Sol2 196 #define N_LaB2 208 #define N_La2 220 #define N_SiB2 233 #define N_Si2 247 #define N_Do3 262 #define N_ReB3 277 #define N_Re3 294 #define N_MiB3 311 #define N_Mi3 330 #define N_Fa3 349 #define N_SolB3 370 #define N_Sol3 392 #define N_LaB3 415 #define N_La3 440 #define N_SiB3 466 #define N_Si3 494 #define N_Do4 523 #define N_ReB4 554 #define N_Re4 587 #define N_MiB4 622 #define N_Mi4 659 #define N_Fa4 698 #define N_SolB4 740 #define N_Sol4 784 #define N_LaB4 831 #define N_La4 880 #define N_SiB4 932 #define N_Si4 988 #define N_Do5 1047 #define N_ReB5 1109 #define N_Re5 1175 #define N_MiB5 1245 #define N_Mi5 1319 #define N_Fa5 1397 #define N_SolB5 1480 #define N_Sol5 1568 #define N_LaB5 1661 #define N_La5 1760 #define N_SiB5 1865 #define N_Si5 1976 #define N_Do6 2093 #define N_ReB6 2217 #define N_Re6 2349 #define N_MiB6 2489 #define N_Mi6 2637 #define N_Fa6 2794 #define N_SolB6 2960 #define N_Sol6 3136 #define N_LaB6 3322 #define N_La6 3520 #define N_SiB6 3729 #define N_Si6 3951 #define N_Do7 4186
extern uint16_t hiScore;
const char idXarxa[] = "MOVISTAR-WIFI6"; // Nom del punt d'accés
const char contrasenya[] = "BSdDAGXxAA"; // Contrasenya de connexió
const char* SERVIDOR_VERSICLE = "discoverybiblestudy.org";
const char* PAGINA_VERSICLE = "/daily/api/";
const char* SERVIDOR_CLIMA = "api.open-meteo.com";
const char* PAGINA_CLIMA ="/v1/forecast?latitude=41.45&longitude=2.25&daily=weather_code,temperature_2m_max,wind_speed_10m_max&forecast_days=4&timezone=Europe%2FMadrid";
const char* server4 = SERVIDOR_VERSICLE;
const char* pagin = PAGINA_VERSICLE;
unsigned long darreraConnexio = 0;
const unsigned long periodeConnexio = 10000UL;
String line = "";
byte valorLED = 0;
byte R = 0;
byte G = 0;
byte B = 0;
char TEXT1[50] = "";
char TEXT2[50] = "";
char TEXT3[50] = "";
String versiculo1 = "";
String ref = "";
int indexClima = 0;
String climaDia[4];
float climaTemp[4];
String climaCelTxt[4];
float climaVent[4];
int opcioWeb = 1;
SAppMenu menu;
const char *elements[] = {
"VERSICLE",
"CLIMA",
"RECORDATORI 1",
"RECORDATORI 2",
"RECORDATORI 3"
};
int n = 0;
bool enviar = false;
int status = WL_IDLE_STATUS;
WiFiServer server(80); // Creem un objecte de comunicació amb el port 80
// El port 80 és el de defecte per a http
WiFiSSLClient clientJSON;
unsigned int localPortHora = 2390;
IPAddress timeServer(129, 6, 15, 28);
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[NTP_PACKET_SIZE];
WiFiUDP Udp;
int hora, minuts, segons;
const unsigned long DESFASAMENT_HORA = 7200UL;
const unsigned long periodeHoraNTP = 60000UL;
const unsigned long periodeReintentHora = 5000UL;
unsigned long darreraPeticioHora = 0;
unsigned long tempsBaseHora = 0;
unsigned long millisBaseHora = 0;
bool horaDisponible = false;
bool menuPrincipal = true;
int segonMostrat = -1;
bool op=false;
bool ntpyes = false;
bool jsonyes = false;
bool faseu = false;
bool climaDisponible = false;
Adafruit_NeoPixel cadena = Adafruit_NeoPixel(1, LED, NEO_GRB + NEO_KHZ800);
String Dades(String peti, String param){
String valor = "";
String sepa;
int pos;
if (peti.indexOf("?") != -1) {
peti = peti.substring(peti.indexOf("?")+1);
if (peti.indexOf(param) != -1) {
peti = peti.substring(peti.indexOf(param)+param.length());
sepa = peti.substring(0, 1);
peti = peti.substring(1);
pos = peti.indexOf("&");
if (pos == -1) {
pos = peti.indexOf(" ");
}
if ((pos != 0) && (sepa == "=")){
valor = peti.substring(0, pos);
}
}
}
return valor;
}
int posicioCentrada(String text) {
int ampladaText = text.length() * 6;
int x = (128 - ampladaText) / 2;
if (x < 0) {
x = 0;
}
return x;}
String netejaTextWeb(String txt) {
String senseTags = "";
bool dinsEtiqueta = false;
for (int i = 0; i < txt.length(); i++) {
char c = txt[i];
if (c == '<') {
dinsEtiqueta = true;
} else if (c == '>') {
dinsEtiqueta = false;
} else if (!dinsEtiqueta) {
senseTags += c;
}
}
txt = senseTags;
txt.replace(""", "\"");
txt.replace("'", "'");
txt.replace("&", "&");
txt.replace("<", "<");
txt.replace(">", ">");
txt.replace(" ", " ");
txt.replace("–", "-");
txt.replace("—", "-");
txt.replace("…", "...");
txt.replace("¡", "!");
txt.replace("¿", "?");
String resultat = "";
for (int i = 0; i < txt.length(); i++) {
if (txt[i] == '&' && i + 2 < txt.length() && txt[i + 1] == '#') {
int j = i + 2;
bool esNumero = false;
int valor = 0;
while (j < txt.length() && isDigit(txt[j])) {
esNumero = true;
valor = valor * 10 + (txt[j] - '0');
j++;
}
if (esNumero && j < txt.length() && txt[j] == ';') {
if (valor >= 32 && valor <= 126) {
resultat += char(valor);
} else {
resultat += "?";
}
i = j;
} else {
resultat += txt[i];
}
} else {
resultat += txt[i];
}
}
txt = resultat;
txt.replace("\r", " ");
txt.replace("\n", " ");
txt.replace("\t", " ");
while (txt.indexOf(" ") != -1) {
txt.replace(" ", " ");
}
txt.trim();
return txt;
}
void printCentrat(int y, String text) {
int x = posicioCentrada(text);
ssd1306_printFixed(x, y, text.c_str(), STYLE_NORMAL);
}
void printMissatgeCentrat(String text) {
int maxCaracters = 21;
int y = 24;
if (text.length() <= maxCaracters) {
printCentrat(32, text);
} else {
while (text.length() > 0 && y <= 56) {
String tros = text.substring(0, maxCaracters);
int espai = tros.lastIndexOf(' ');
if (text.length() > maxCaracters && espai > 0) {
tros = text.substring(0, espai);
text = text.substring(espai + 1);
} else {
text = text.substring(tros.length());
}
tros.trim();
printCentrat(y, tros);
y += 8;
}
}
}
String agafaLinia(String text, int &posicio) {
const int maxCaracters = 21;
while ((posicio < text.length()) && (text.charAt(posicio) == ' ')) {
posicio++;
}
if (posicio >= text.length()) {
return "";
}
int finalLinia = posicio + maxCaracters;
String linia;
if (finalLinia >= text.length()) {
linia = text.substring(posicio);
posicio = text.length();
} else {
String tros = text.substring(posicio, finalLinia + 1);
int espai = tros.lastIndexOf(' ');
if (espai > 0) {
linia = text.substring(posicio, posicio + espai);
posicio = posicio + espai + 1;
} else {
linia = text.substring(posicio, finalLinia);
posicio = finalLinia;
}
}
linia.trim();
return linia;}
int mostraPaginaVersicle(String text, int posicioInicial) {
int posicio = posicioInicial;
int y = 16;
ssd1306_clearScreen();
ssd1306_printFixed(0, 0, ref.c_str(), STYLE_NORMAL);
for (int i = 0; i < 5; i++) {
String linia = agafaLinia(text, posicio);
ssd1306_printFixed(0, y, linia.c_str(), STYLE_NORMAL);
y += 8;
}
return posicio;}
void esperaBotoDret() {
while (digitalRead(pol_dw)) {
actualitzaHoraInternet();
delay(50);
}
while (!digitalRead(pol_dw)) {
delay(50);
}
}
void mostraVersiclePaginat() {
int posicioPagina = 0;
int properaPosicio = mostraPaginaVersicle(versiculo1, posicioPagina);
while (!digitalRead(pol_ok)) {
delay(50);
}
while (digitalRead(pol_dw)) {
actualitzaHoraInternet();
if (!digitalRead(pol_ok)) {
while (!digitalRead(pol_ok)) {
delay(50);
}
if (properaPosicio < versiculo1.length()) {
posicioPagina = properaPosicio;
} else {
posicioPagina = 0;
}
properaPosicio = mostraPaginaVersicle(versiculo1, posicioPagina);
}
delay(50);
}
while (!digitalRead(pol_dw)) {
delay(50);
}
}
void calculHora(unsigned long Segs) {
Segs = Segs % 86400UL;
hora = Segs / 3600;
Segs = Segs % 3600;
minuts = Segs / 60;
segons = Segs % 60;}
String dosDigitsString(int valor) {
if (valor < 10) {
return "0" + String(valor);
}
return String(valor);
}
String textHora() {
if (!horaDisponible) {
return "--.--";
}
unsigned long tempsActual = tempsBaseHora + ((millis() - millisBaseHora) / 1000UL);
calculHora(tempsActual);
return dosDigitsString(hora) + "." + dosDigitsString(minuts) ;
}
void demanaHoraInternet() {
for (int k = 0; k < NTP_PACKET_SIZE; k++) {
packetBuffer[k] = 0;
}
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Serial.println("Enviant petició NTP...");
Udp.beginPacket(timeServer, 123);
if (Udp.parsePacket() | ntpyes==true) {
Serial.println("Resposta NTP OK");
jsonyes = false;
} else if (ntpyes == false){
Serial.println("No hi ha resposta NTP");}
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
darreraPeticioHora = millis();
}
void llegeixRespostaHora() {
if (Udp.parsePacket()) {
if (ntpyes == false){
Serial.println("?? Resposta NTP rebuda");
ntpyes = true;
}
Udp.read(packetBuffer, NTP_PACKET_SIZE);
unsigned long Word1 = packetBuffer[40];
unsigned long Word2 = packetBuffer[41];
unsigned long Word3 = packetBuffer[42];
unsigned long Word4 = packetBuffer[43];
unsigned long Temps1900 = Word1 << 24;
Temps1900 |= Word2 << 16;
Temps1900 |= Word3 << 8;
Temps1900 |= Word4;
tempsBaseHora = Temps1900 + DESFASAMENT_HORA;
millisBaseHora = millis();
horaDisponible = true;
}
}
void actualitzaHoraInternet() {
llegeixRespostaHora();
if (!horaDisponible) {
if (millis() - darreraPeticioHora > periodeReintentHora) {
demanaHoraInternet();
}
} else if (millis() - darreraPeticioHora > periodeHoraNTP) {
demanaHoraInternet();
}
}
void dibuixaHoraMenu() {
if (!menuPrincipal) {
return;
}
String text = textHora();
int x = 128 - text.length() * 6;
ssd1306_printFixed(x, 56, " ", STYLE_NORMAL);
ssd1306_printFixed(x, 56, text.c_str(), STYLE_NORMAL);
}
void mostrarMenuPrincipal() {
menuPrincipal = true;
ssd1306_showMenu(&menu);
dibuixaHoraMenu();
}
void actualitzaRellotgeMenu() {
actualitzaHoraInternet();
if (!menuPrincipal) {
return;
}
if (!horaDisponible) {
if (segonMostrat != -2) {
segonMostrat = -2;
dibuixaHoraMenu();
}
return;
}
unsigned long tempsActual = tempsBaseHora + ((millis() - millisBaseHora) / 1000UL);
int segonActual = tempsActual % 60;
if (segonActual != segonMostrat) {
segonMostrat = segonActual;
dibuixaHoraMenu();
}
}
String tradueixCel(int codi) {
if (codi == 0) return "Sol";
if (codi == 1) return "Poc nuvol";
if (codi == 2) return "Mig nuvol";
if (codi == 3) return "Nuvol";
if (codi == 45 || codi == 48) return "Boira";
if (codi == 51 || codi == 53 || codi == 55) return "Plugim";
if (codi == 61 || codi == 63 || codi == 65) return "Pluja";
if (codi == 66 || codi == 67) return "Pluja gelada";
if (codi == 71 || codi == 73 || codi == 75) return "Neu";
if (codi == 77) return "Neu granulada";
if (codi == 80 || codi == 81 || codi == 82) return "Ruixats";
if (codi == 95) return "Tempesta";
if (codi == 96 || codi == 99) return "Tempesta forta";
return "Desconegut";
}
void mostraDiaClima(int i) {
ssd1306_clearScreen();
if (i < 0 || i >= 4) return;
String linia1 = "Dia: " + climaDia[i];
String linia2 = "Temp: " + String(climaTemp[i], 1) + " deg. C";
String linia3 = "Clima: " + climaCelTxt[i];
String linia4 = "Vent: " + String(climaVent[i], 1) + " km/h";
printCentrat(8, linia1);
printCentrat(24, linia2);
printCentrat(40, linia3);
printCentrat(56, linia4);
}
void mostraClimaPaginat() {
indexClima = 0;
ssd1306_clearScreen();
mostraDiaClima(indexClima);
while (!digitalRead(pol_dw)) {
delay(50);
}
bool sortir = false;
while (!sortir) {
actualitzaHoraInternet();
if (!digitalRead(pol_ok)) {
while (!digitalRead(pol_ok)) delay(50);
indexClima++;
if (indexClima >= 4) indexClima = 0;
ssd1306_clearScreen();
mostraDiaClima(indexClima);
}
if (!digitalRead(pol_dw)) {
while (!digitalRead(pol_dw)) delay(50);
sortir = true;
}
delay(50);
}
while (!digitalRead(pol_dw)) delay(50);
}
void setup() {
ssd1306_128x64_i2c_init();
ssd1306_fillScreen(0);
ssd1306_setFixedFont(ssd1306xled_font6x8);
pinMode(pol_dw, INPUT_PULLUP); // El polsador és una entrada
pinMode(pol_ok, INPUT_PULLUP); // El polsador és una entrada
pinMode(pol, INPUT_PULLUP); // El polsador és una entrada
ssd1306_createMenu(&menu, elements, sizeof(elements)/sizeof(elements[0]));
mostrarMenuPrincipal();
Serial.begin(9600); // Monitor sèrie
pinMode(LEDP, OUTPUT); // La pota del LED és sortida
analogWrite(LEDP, 0); // Comencem amb el LED apagat
TEXT1[0] = '\0';
TEXT2[0] = '\0';
TEXT3[0] = '\0';
cadena.begin(); // Inicialitza els NeoPixels
R = 0;
G = 0;
B = 0;
cadena.clear();
cadena.setPixelColor(0, R, G, B);
cadena.show();
delay(200);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
delay(1000); // Petita pausa per assegurar la transmissió
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("No s'ha trobat el dispositiu Wi-Fi");
while (true); // Bloquegem el programa
}
String versio = WiFi.firmwareVersion();
if (versio < "1.0.0") {
Serial.println("Convindria actualitzar el firmware");
}
while (status != WL_CONNECTED) {
Serial.print("Connectant a la xarxa ");
Serial.println(idXarxa);
status = WiFi.begin(idXarxa, contrasenya);
delay(10000); // Ho tornarem a intentar passats 10 s
}
server.begin(); // Posem en marxa el servidor
Serial.print("Connectat a ");
Serial.println(WiFi.SSID());
Serial.print("Estat de la connexió: ");
Serial.println(WiFi.status());
Serial.print("Adreça IP del dispositiu: ");
Serial.println(WiFi.localIP());
Serial.print("Intensitat del senyal: ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
Serial.println();
Serial.print("Ja pots fer la teva connexió al dispositiu ");
Serial.println(WiFi.localIP());
Udp.begin(localPortHora);
Serial.println("DEBUG 9: UDP iniciat");
demanaHoraInternet();
mostrarMenuPrincipal();
}
void loop() { // Programa que es repeteix indefinidament
actualitzaRellotgeMenu();
if (n==0) n = 1;
if (millis() < 50) {
cadena.setPixelColor(0, 0,0,0);
cadena.show();
}
if (n==0) {
delay(200);
ssd1306_clearScreen();
mostrarMenuPrincipal();
}
if (status != WiFi.status()) { // Mirem si ha canviat l'estat de la connexió
status = WiFi.status();
if (status == WL_AP_CONNECTED) {
Serial.println("Dispositiu connectat al punt d'accés");
} else {
Serial.println("El dispositiu s'ha desconnectat del punt d'accés");
}
}
if (!digitalRead(pol)) {
while (!digitalRead(pol)) delay(50);
if (opcioWeb == 1) {
menuPrincipal = false;
waitForStart();
gameLoop(hiScore);
delay(200);
ssd1306_clearScreen();
mostrarMenuPrincipal();
} else if (opcioWeb == 2) {
tone(3, N_La2, 450);
delay(450);
tone(3, N_Si2, 150);
delay(150);
tone(3, N_Do3, 900);
delay(900);
tone(3, N_Re3, 300);
delay(300);
tone(3, N_Si2, 300);
delay(300);
tone(3, N_Do3, 300);
delay(300);
tone(3, N_La2, 1200);
delay(1200);
tone(3, N_Do3, 450);
delay(450);
tone(3, N_Re3, 150);
delay(150);
tone(3, N_Mi3, 900);
delay(900);
tone(3, N_Mi3, 300);
delay(300);
tone(3, N_Sol3, 300);
delay(300);
tone(3, N_Mi3, 300);
delay(300);
tone(3, N_Re3, 600);
delay(600);
tone(3, N_Do3, 600);
delay(600);
}
else if (opcioWeb == 3) {
delay(600);
tone(3, N_Do4, 300);
delay(300);
tone(3, N_LaB4, 300);
delay(300);
tone(3, N_LaB4, 300);
delay(300);
tone(3, N_Sol4, 1500);
delay(1500);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 1800);
delay(1800);
tone(3, N_Re4, 600);
delay(600);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Sol4, 1200);
delay(1200);
tone(3, N_Re4, 600);
delay(600);
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_MiB4, 300);
delay(300);
tone(3, N_Do4, 1200);
delay(1200);
tone(3, N_Do4, 300);
delay(300);
tone(3, N_LaB4, 300);
delay(300);
tone(3, N_LaB4, 300);
delay(300);
tone(3, N_Sol4, 1500);
delay(1500);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 1800);
delay(1800);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Re4, 300);
delay(300);
tone(3, N_Sol4, 1200);
delay(1200);
tone(3, N_Re4, 600);
delay(600);
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_MiB4, 300);
delay(300);
tone(3, N_Do4, 1200);
delay(1200);
tone(3, N_Do4, 300);
delay(300);
tone(3, N_Do5, 300);
delay(300);
tone(3, N_Do5, 300);
delay(300);
tone(3, N_SiB4, 1500);
delay(1500);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_SiB4, 300);
delay(300);
tone(3, N_SiB4, 1800);
delay(1800);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_MiB5, 1200);
delay(1200);
tone(3, N_Re5, 1200);
delay(1200);
tone(3, N_Do5, 1200);
delay(1200);
tone(3, N_Do4, 300);
delay(300);
tone(3, N_Do5, 300);
delay(300);
tone(3, N_Do5, 300);
delay(300);
tone(3, N_SiB4, 1500);
delay(1500);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_SiB4, 300);
delay(300);
tone(3, N_SiB4, 1800);
delay(1800);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_Sol4, 300);
delay(300);
tone(3, N_MiB5, 1200);
delay(1200);
tone(3, N_Re5, 1200);
delay(1200);
tone(3, N_Do5, 2700);
delay(300);
}
}
if (!digitalRead(pol_dw)){
ssd1306_menuDown(&menu);
mostrarMenuPrincipal();
while (!digitalRead(pol_dw)){
;
}
}
if (!digitalRead(pol_ok)){
menuPrincipal = false;
ssd1306_clearScreen();
printMissatgeCentrat("\n\n");
if(ssd1306_menuSelection(&menu) == 2){
if (TEXT1[0] == '\0') {
printMissatgeCentrat("Recordatori Buit");
cadena.setPixelColor(0, 125, 0, 0);
cadena.show();
tone(3, N_Do3, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 300);
delay(300);
tone(3, N_MiB3, 600);
delay(600);
tone(3, N_Sol2, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 600);
delay(600);
} else {
printMissatgeCentrat(TEXT1);
cadena.setPixelColor(0, 0, 125, 0);
cadena.show();
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_La3, 150);
delay(150);
tone(3, N_Fa3, 150);
delay(150);
tone(3, N_Sol3, 150);
delay(150);
tone(3, N_Re4, 150);
delay(150);
tone(3, N_Do4, 600);
delay(600);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
esperaBotoDret();
}
}
if (ssd1306_menuSelection(&menu) == 3){
if (TEXT2[0] == '\0') {
printMissatgeCentrat("Recordatori Buit");
cadena.setPixelColor(0, 125, 0, 0);
cadena.show();
tone(3, N_Do3, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 300);
delay(300);
tone(3, N_MiB3, 600);
delay(600);
tone(3, N_Sol2, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 600);
delay(600);
} else {
printMissatgeCentrat(TEXT2);
cadena.setPixelColor(0, 0, 125, 0);
cadena.show();
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_La3, 150);
delay(150);
tone(3, N_Fa3, 150);
delay(150);
tone(3, N_Sol3, 150);
delay(150);
tone(3, N_Re4, 150);
delay(150);
tone(3, N_Do4, 600);
delay(600);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
esperaBotoDret();
}
}
if (ssd1306_menuSelection(&menu) == 4){
if (TEXT3[0] == '\0') {
printMissatgeCentrat("Recordatori Buit");
cadena.setPixelColor(0, 125, 0, 0);
cadena.show();
tone(3, N_Do3, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 300);
delay(300);
tone(3, N_MiB3, 600);
delay(600);
tone(3, N_Sol2, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 600);
delay(600);
} else {
printMissatgeCentrat(TEXT3);
cadena.setPixelColor(0, 0, 125, 0);
cadena.show();
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_La3, 150);
delay(150);
tone(3, N_Fa3, 150);
delay(150);
tone(3, N_Sol3, 150);
delay(150);
tone(3, N_Re4, 150);
delay(150);
tone(3, N_Do4, 600);
delay(600);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
esperaBotoDret();
}
}
if (ssd1306_menuSelection(&menu) == 0){
if (versiculo1.length() == 0) {
printMissatgeCentrat("Cap Versicle Rebut");
cadena.setPixelColor(0, 125, 0, 0);
cadena.show();
tone(3, N_Do3, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 300);
delay(300);
tone(3, N_MiB3, 600);
delay(600);
tone(3, N_Sol2, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 600);
delay(600);
} else {
printMissatgeCentrat("Obrint Versicle");
cadena.setPixelColor(0, 0, 125, 0);
cadena.show();
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_La3, 150);
delay(150);
tone(3, N_Fa3, 150);
delay(150);
tone(3, N_Sol3, 150);
delay(150);
tone(3, N_Re4, 150);
delay(150);
tone(3, N_Do4, 600);
delay(600);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
mostraVersiclePaginat();
}
}
if (ssd1306_menuSelection(&menu) == 1){
if (!climaDisponible) {
printMissatgeCentrat("Registre Climatic No Rebut");
cadena.setPixelColor(0, 125, 0, 0);
cadena.show();
tone(3, N_Do3, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 300);
delay(300);
tone(3, N_MiB3, 600);
delay(600);
tone(3, N_Sol2, 300);
delay(300);
tone(3, N_SiB2, 300);
delay(300);
tone(3, N_Do3, 600);
delay(600);
} else {
printMissatgeCentrat("Obrint Registre Climatic");
cadena.setPixelColor(0, 0, 125, 0);
cadena.show();
tone(3, N_SiB3, 300);
delay(300);
tone(3, N_La3, 150);
delay(150);
tone(3, N_Fa3, 150);
delay(150);
tone(3, N_Sol3, 150);
delay(150);
tone(3, N_Re4, 150);
delay(150);
tone(3, N_Do4, 600);
delay(600);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
mostraClimaPaginat();
}
}
while (!digitalRead(pol_ok)){
;
}
delay(1000);
cadena.setPixelColor(0, 0, 0, 0);
cadena.show();
ssd1306_clearScreen( );
mostrarMenuPrincipal();
}
delay(500);
WiFiClient client = server.available(); // Mirem si hi ha clients
if (client) { // Si hi ha un client...
Serial.println("Nou client");
String peticio = ""; // Aquí guardarem una línia de la petició del client
while (client.connected()) { // Mentre el client estigui connectat
if (client.available()) { // Si hi ha dades disponibles
char c = client.read(); // Llegim un byte
Serial.write(c);
if (c == '\n') { // Mirem si és un salt de línia
if (peticio.length() == 0) {
enviar = true; // Llestos per enviar la resposta
break; // Sortim del while
} else { // Si hem rebut un salt de línia
if (peticio.indexOf("GET") != -1) { // Si no ho troba torna -1
if (Dades(peticio, "R") != "") { // Hi havia el paràmetre R?
R = Dades(peticio, "R").toInt();
}
if (Dades(peticio, "G") != "") { // Hi havia el paràmetre G?
G = Dades(peticio, "G").toInt();
}
if (Dades(peticio, "B") != "") { // Hi havia el paràmetre B?
B = Dades(peticio, "B").toInt();
}
cadena.setPixelColor(0, R, G, B);
cadena.show();
}
if (peticio.indexOf("GET") != -1) { // Si no ho troba torna -1
if (Dades(peticio, "LED") != "") { // Hi havia el paràmetre?
valorLED = Dades(peticio, "LED").toInt();
}
analogWrite(LEDP, valorLED); // Enviem el valor al LED
}
if (peticio.indexOf("GET") != -1) { // Si no ho troba torna -1
if (Dades(peticio, "MISSATGE1") != "") { // Hi havia el paràmetre?
if (Dades(peticio, "MISSATGE1") == "Cap" || Dades(peticio, "MISSATGE1") == "cap") {
strcpy(TEXT1, "");
} else strcpy(TEXT1, Dades(peticio, "MISSATGE1").c_str());
}
for (int i = 0; TEXT1[i] != '\0'; i++) {
if (TEXT1[i] == '+') TEXT1[i] = ' ';
}
}
if (peticio.indexOf("GET") != -1) { // Si no ho troba torna -1
if (Dades(peticio, "MISSATGE2") != "") { // Hi havia el paràmetre?
if (Dades(peticio, "MISSATGE2") == "Cap" || Dades(peticio, "MISSATGE2") == "cap") {
strcpy(TEXT2, "");
} else strcpy(TEXT2, Dades(peticio, "MISSATGE2").c_str());
}
for (int i = 0; TEXT2[i] != '\0'; i++) {
if (TEXT2[i] == '+') TEXT2[i] = ' ';
}
}
if (peticio.indexOf("GET") != -1) { // Si no ho troba torna -1
if (Dades(peticio, "MISSATGE3") != "") { // Hi havia el paràmetre?
if (Dades(peticio, "MISSATGE3") == "Cap" || Dades(peticio, "MISSATGE3") == "cap") {
strcpy(TEXT3, "");
} else strcpy(TEXT3, Dades(peticio, "MISSATGE3").c_str());
}
for (int i = 0; TEXT3[i] != '\0'; i++) {
if (TEXT3[i] == '+') TEXT3[i] = ' ';
}
}
if (peticio.indexOf("GET") != -1) { // Si no ho troba torna -1
if (Dades(peticio, "OPCIO") != "") {
opcioWeb = Dades(peticio, "OPCIO").toInt();
}
}
peticio = ""; // Comencem línia amb una línia buida
}
} else if (c != '\r') { // Si el caràcter no és un retorn
peticio += c; // Afegim el caràcter rebut
}
}
}
if (enviar) {
// Resposta al client
client.println("HTTP/1.1 200 OK");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<meta charset='UTF-8'>");
client.println("<html>");
client.print("<h1>El LED està a (");
client.print(R);
client.print(", ");
client.print(G);
client.print(", ");
client.print(B);
client.println(")</h1>");
client.println("<form action='/' method='get'>");
client.println("<p>R: <span id='valorR'>");
client.print(R);
client.println("</span></p>");
client.print("<input type='range' id='sliderR' name='R' min='0' max='255' value='");
client.print(R);
client.println("' oninput='actualitzaRGB()'>");
client.println("<p>G: <span id='valorG'>");
client.print(G);
client.println("</span></p>");
client.print("<input type='range' id='sliderG' name='G' min='0' max='255' value='");
client.print(G);
client.println("' oninput='actualitzaRGB()'>");
client.println("<p>B: <span id='valorB'>");
client.print(B);
client.println("</span></p>");
client.print("<input type='range' id='sliderB' name='B' min='0' max='255' value='");
client.print(B);
client.println("' oninput='actualitzaRGB()'>");
client.println("<p>Previsualització:</p>");
client.println("<div id='preview' style='width:120px;height:120px;border:1px solid black;'></div>");
client.println("<br>");
client.println("<input type='submit' value='Enviar RGB'>");
client.println("</form>");
client.print("<h1>El LED està a ");
client.print(valorLED);
client.println("</h1>");
client.println("<form action='/' method='get'>");
client.println("<p></p>");
client.println("<p></p>");
client.println("<input type='text' name='LED'>");
client.println("<p></p>");
client.println("<p></p>");
client.print("<h1>VERSICLE: ");
client.print("<p>");
if (versiculo1.length() == 0) {
client.print("Cap versicle rebut");
} else {
client.print(versiculo1);
}
client.print("<h1>CLIMA D'AVUI: ");
client.print("<p>");
if (!climaDisponible) {
client.print("Cap clima rebut");
} else {
client.print(climaDia[0]);
client.print(" - ");
client.print(climaTemp[0]);
client.print("°C - ");
client.print(climaCelTxt[0]);
client.print(" - Vent ");
client.print(climaVent[0]);
client.print(" km/h");
}
client.print("<h1>RECORDATORI 1: ");
if(TEXT1[0] == '\0') {
client.print("Cap");
} else {
client.print(TEXT1);
}
client.println("</h1>");
client.println("<form action='/' method='get'>");
client.println("<p></p>");
client.println("<p></p>");
client.println("<input type='text' name='MISSATGE1' maxlength='50'>");
client.print("<h1>RECORDATORI 2: ");
if(TEXT2[0] == '\0') {
client.print("Cap");
} else {
client.print(TEXT2);
}
client.println("</h1>");
client.println("<form action='/' method='get'>");
client.println("<p></p>");
client.println("<p></p>");
client.println("<input type='text' name='MISSATGE2' maxlength='50'>");
client.print("<h1>RECORDATORI 3: ");
if(TEXT3[0] == '\0') {
client.print("Cap");
} else {
client.print(TEXT3);
}
client.println("</h1>");
client.println("<form action='/' method='get'>");
client.println("<p></p>");
client.println("<p></p>");
client.println("<input type='text' name='MISSATGE3' maxlength='50'>");
client.println("</p>");
client.print("<h1>OPCIÓ D'ACCIÓ: ");
if(opcioWeb == 2){
client.print("Segadors");
}
else if(opcioWeb == 3){
client.print("TITANIUM");
} else {
client.print("Cap");
}
client.println("</h1>");
client.println("<form action='/' method='get'>");
client.println("<p>Escull una opció:</p>");
client.println("<select name='OPCIO'>");
client.print("<option value='1'");
client.print("<option value='2'");
if(opcioWeb == 2) client.print(" selected");
client.println(">Segadors</option>");
client.print("<option value='3'");
if(opcioWeb == 3) client.print(" selected");
client.println(">TITANIUM</option>");
client.println("</select>");
client.println("<input type='submit'>");
client.println("</form>");
client.println("<script>");
client.println("function actualitzaRGB(){");
client.println("let r=document.getElementById('sliderR').value;");
client.println("let g=document.getElementById('sliderG').value;");
client.println("let b=document.getElementById('sliderB').value;");
client.println("document.getElementById('valorR').innerHTML=r;");
client.println("document.getElementById('valorG').innerHTML=g;");
client.println("document.getElementById('valorB').innerHTML=b;");
client.println("document.getElementById('preview').style.backgroundColor='rgb('+r+','+g+','+b+')';");
client.println("}");
client.println("actualitzaRGB();");
client.println("</script>");
client.println("</html>");
delay(1);
enviar = false;
}
client.stop(); // Tanquem la connexió
Serial.println("Fi de la connexió amb el client");
}
if (millis() - darreraConnexio > periodeConnexio) {
if (jsonyes==false) {
Serial.println("Fent petició JSON...");
}
clientJSON.stop();
if (faseu == false) {
server4 = SERVIDOR_VERSICLE;
pagin = PAGINA_VERSICLE;
} else {
server4 = SERVIDOR_CLIMA;
pagin = PAGINA_CLIMA;
}
if (clientJSON.connect(server4, 443)) {
if (jsonyes == false) {
Serial.println("S'ha fet la connexió al servidor");
jsonyes = true;
}
clientJSON.print("GET ");
clientJSON.print(pagin);
clientJSON.println(" HTTP/1.1");
clientJSON.print("Host: ");
clientJSON.println(server4);
clientJSON.println("Connection: close");
clientJSON.println();
darreraConnexio = millis();
} else {
Serial.println("Ha fallat la connexió");
}
}
while (clientJSON.available()) {
line = clientJSON.readStringUntil('\r');
if (line.indexOf('{')>=0) {
if (op==false){
Serial.println("Tractem les dades");
op=true;
}
DynamicJsonDocument json_doc(8000);
DeserializationError json_error = deserializeJson(json_doc, line);
if (json_error) {
if (jsonyes == false) {
Serial.println("JSON No Rebut");
}
} else if (jsonyes == false) {
Serial.println("JSON Rebut");
jsonyes = true;
} else {
if (faseu==false){
String versiculo = json_doc["text"];
String refe = json_doc["ref"];
ref = netejaTextWeb(refe);
versiculo1 = netejaTextWeb(versiculo);
faseu=true;
server4 = SERVIDOR_CLIMA;
pagin = PAGINA_CLIMA;
climaDisponible = true;
} else {
for (int i = 0; i < 4; i++) {
String dia = json_doc["daily"]["time"][i] | "";
float temperatura = json_doc["daily"]["temperature_2m_max"][i] | 0.0;
int codiCel = json_doc["daily"]["weather_code"][i] | -1;
float velocitatVent = json_doc["daily"]["wind_speed_10m_max"][i] | 0.0;
if (dia.length() >= 10) {
dia = dia.substring(5);
}
climaDia[i] = dia;
climaTemp[i] = temperatura;
climaCelTxt[i] = tradueixCel(codiCel);
climaVent[i] = velocitatVent;
}
faseu = false;
server4 = SERVIDOR_VERSICLE;
pagin = PAGINA_VERSICLE;
}
}
}
}
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.