ottimizzazione calcolo matematico

Ciao ragazzi,

di seguito il calcolo che effettuo per calcolalarmi la temperatura percepita in funzione del vento e della temperatura reale. c'è un modo per rendere più snello il tutto?

non sono riuscito a farla funzionare se non andando a dividere pezzo pezzo tutti i passaggi, l'intenzione è quella di ottimizzare codice e guadagnare un pò di memoria flash che è al 94%....

grazie

double Tpercepita1;                    
float Tpercepita2;                           
float Tpercepita3;                     
float Tpercepita4;                          
float Tpercepita5;                   
float Tpercepita6;                    
float Tpercepita7;                       
double Tpercepita8;  


// 0,045*(5,2735*sqrt(W)+10,45-0,2778*W)*(T-33)+33;


    // W = velocità vento
    //T = temperatura
    Tpercepita1 = sqrt(WindSpeed);
    Tpercepita2 = 5.2735 * Tpercepita1;
    Tpercepita3 = 0.2778 * WindSpeed;
    Tpercepita4 = Tpercepita2 + 10.45 - Tpercepita3;
    Tpercepita5 = bme280.getTemperature() - 33;
    Tpercepita6 = 0.045 * Tpercepita4;
    Tpercepita7 = Tpercepita6 * Tpercepita5;
    Tpercepita8 = Tpercepita7 + 33;
  }
}

Se non devi aggiungere altre parti di programma non hai problemi, anzi puoi arrivare anche al 100% senza aver problemi.
Nel programma hai stringhe di testo fisse (Es. messaggi su display) a cui non hai applicato la funzione F()?
Hai messaggi di debug su seriale?

ciao

simosere:
non sono riuscito a farla funzionare se non andando a dividere pezzo pezzo tutti i passaggi

in che senso non funzionava?

Magari hai sbagliato ad impostare l’equazione…
ovvio che se dividi, dichiari una variabile per ogni pezzo… guardando al volo con due variabili fai tutto, al posto di dichiararne 8… :slight_smile:

MD

simosere:
di seguito il calcolo che effettuo per calcolalarmi la temperatura percepita in funzione del vento e della temperatura reale. c'è un modo per rendere più snello il tutto?

Non avendo il resto del codice non è facile darti altri consigli di ottimizzazione, però scusa, ma anche io mi chiedo: ti servono veramente 8 variabili per fare quella cosa? Il calcolo "spezzato" ti serve solo per essere certo delle conversioni e cast eventualmente impliciti, ma per curiosità, che differenza di valore hai tra la tua Tpercepita8 e questa sotto? Assumo che getTemperature() e WindSpeed siano float:

double Tpercepita0 = 0.045 * (5.2735 * sqrt(WindSpeed) + 10.45 - 0.2778 * WindSpeed)*(bme280.getTemperature() - 33) + 33;

Falle calcolare entrambe e vediamo, secondo me invece di 8 variabili ne puoi usare una perché da qualche prova che ho fatto a me quella dà lo stesso valore della sequenza di 8.
Poi per il resto del programma dovresti farcelo vedere.

Ciao ragazzi e grazie delle risposte.... come detto a suo tempo provai ma senza esito positivo...

appena posso provo il tuo codice docdoc, grazie... intento allego il codice che uso.... ehehehe credo che da ottimizzare troverete molto... :stuck_out_tongue:

questa in allegato è la versione finale di un sistema di automazione tende che funziona con pioggia/vento e temperatura reale e percepita e ha un controllo spartano da remoto...

nel prossimo futuro quello che vorrei fare è:

  • ammesso che riesca a risparmiare spazio, implementare lo stesso controllo che faccio sul sensore pioggia anche per il sensore temperatura

  • rivedere completamente la gestione da remoto, costruendomi proprio una pagina html.(ma qui avoglia a capire e studiare... :slight_smile: )

E' giusto dire e ricordare che un contributo enorme a questo codice è stato dato da Patrick,Brunello, Ete e Guglielmo e spero di non dimenticare nessuno.

ciao e grazie

Cominciamo con un'idea per semplificare un po le funzioni: tutte le svolgi e le avvolgi possono essere unite in una sola funzione con parametri di ingresso: il pin su cui agire e se avvolgere o meno. Non dovrebbe essere difficile farlo, e per la modifica nel resto del codice sacro cerca e sostituisci di un comune programma di scrittura testo.

Inoltre con una seconda passata rendi const un paio di variabili che ti sei dimenricato. Sempre parlando di variabili credo che, se ti son sufficienti 2 cifre decimali puoi trasformare i float in int, moltiplicando per 100 il loro valore. Chiaramente giocherai di casting in sede di rappresentazione grafica.

Le prime righe della setup() fanno cose apparentemente uguali alla verificawifi(). Sicuro che servano entrambe e che non basti richiamare la seconda nella prima?

Poi si entra nel loop, in un paradiso di String, certo che non si possa sfoltire o eliminare in favore di stringhe classiche?

E probabilmente, come da te stesso detto, potrei continuare.

Se non sei a collo anche con la SRAM puoi eliminare tutte le funzioni F()

Silente:
Poi si entra nel loop, in un paradiso di String, certo che non si possa sfoltire o eliminare in favore di stringhe classiche?

Concordo totalmente con Silente, ma soprattutto per questo punto, le String vanno evitate come la peste. Tra l'altro non sono conteggiate nello spazio calcolato durante la compilazione, quindi doppio pericolo.
Comunque visto che il programma è abbastanza lungo, la conversione potrebbe richiederti un certo tempo per cui ti consiglio di farlo se dovessi avere problemi nella gestione della RAM, oppure man mano che dovessi mettere mano al codice per ulteriori evoluzioni.

ragazzi grazie dei consigli, ma non sono cosi chiari per il mio livello di programmazione...

come primo passaggio vorrei capire cosa significa:

certo che non si possa sfoltire o eliminare in favore di stringhe classiche?

che vuol dire stringhe classiche? potete farmi un'esempio con la differenza con una stringa mia attuale e una cambiata con la strnga classica? non sto capendo...

a livello di ram sono al 50%

maubarzi:
Se non sei a collo anche con la SRAM puoi eliminare tutte le funzioni F()

a quali ti riferisci? a quelle del seriale immagino...

Le prime righe della setup() fanno cose apparentemente uguali alla verificawifi(). Sicuro che servano entrambe e che non basti richiamare la seconda nella prima?

grande non ci avevo pensato... solo cosi passo dal 94% al 91.... :slight_smile:

simosere:
a quali ti riferisci? a quelle del seriale immagino...

Tutte, non ti servono, spostano su flash da sram a te serve l'opposto eventualmente.
Poi ne hai un sacco per un singolo carattere definito come stringa.

simosere:
che vuol dire stringhe classiche? potete farmi un'esempio con la differenza con una stringa mia attuale e una cambiata con la strnga classica? non sto capendo...

Stringa classica=array di char. Prova a googlare sotto questo nome e vedi se é più chiaro

Silente:
Stringa classica=array di char. Prova a googlare sotto questo nome e vedi se é più chiaro

sto provando a capirci qualcosa.... vediamo se ci sono:

esempio:

String Webpagina = "Pioggia:" + String(misurazione) + "\r\n";

diventa:

char stringa[9]="Pioggia:";

char stringa[12]= misurazione;


printf("Pioggia:" + (misurazione));

Non propio, la prima parte di "Pioggia:" va anche bene hai dimensionato correttamente l'array lasciando lo spazio per il terminatore.
La seconda parte invece non va bene, o meglio non è possibile dirlo con assoluta certezza ma al 99% non può andare bene.
Misurazione credo sia di tipo float, int o double quindi non puoi assegnare direttamente un "qualcosa" per trasformarlo in array di char, ci sono svariate funzioni, ad esempio la itoa converte un intero in un array.
Visto che tu vuoi stampare il risultato però ti consiglio di guardare la snprintf che ti permette di formattare vari tipi di dato per "convertirli" in array di char

ok grazie per l'info.

devo mettermi a fare delle prove. devo dire che a primo occhio mi risulta un pelino complicato...

ma per stampare il risultato cosa intendi? io lo vorrei vedere da remoto...

allora ragazzi,

ho fatto una prima ottimizzazione del codice e devo dirvi già grazie per parecchi consigli:

  • la formula ottimizzata di sukko pera funziona… e quindi sono passato da 8 variabili a 1 sola.

  • ho tolto F() a tutti gli lcd.print , questo si è reso possibile solo togliendo le prime righe della setup() e richiamando verificawifi() e ho tolto tutti i serial print in essa contenuta

sono passato in questo modo da:

Lo sketch usa 28918 byte (94%) dello spazio disponibile per i programmi. Il massimo è 30720 byte.
Le variabili globali usano 1068 byte (52%) di memoria dinamica, lasciando altri 980 byte liberi per le variabili locali. Il massimo è 2048 byte.

a:

Lo sketch usa 27516 byte (89%) dello spazio disponibile per i programmi. Il massimo è 30720 byte.
Le variabili globali usano 1074 byte (52%) di memoria dinamica, lasciando altri 974 byte liberi per le variabili locali. Il massimo è 2048 byte.

ora vorrei concentrarmi sulle stringhe… e sto valutando quanto giàà detto, ma non sto capendo molto dai link consigliati da fabpolli… continerò a studiare e vedere come fare…

nel frattempo ho smanettato un pò con la libreria WiFiEsp example: WebServer, e vi chiedo… mettendo tutto il cocice che ho in questo momento ed escludando le stringhe… ho fatto una prova grossolana, il risultato che ottengo è questo:

Lo sketch usa 29100 byte (94%) dello spazio disponibile per i programmi. Il massimo è 30720 byte.
Le variabili globali usano 1594 byte (77%) di memoria dinamica, lasciando altri 454 byte liberi per le variabili locali. Il massimo è 2048 byte.
Poca memoria disponibile, potrebbero presentarsi problemi di stabilità

andando un pò ad ottimizzare i vari serial print e magari cercando di abbassare il consimo di ram, sfavorendo la memoria flash pensate sia cmq meglio rispetto ad avere tutte qulle stinghe?

allego il codice attuale ottimizzato e la prova con la libreria wifi non provata e non verificata.

prova_con_libreria_Wifisesp_web_server.ino (53.8 KB)

230219_codice_ongoing_ottimizzato.ino (56.5 KB)

simosere:
andando un pò ad ottimizzare i vari serial print e magari cercando di abbassare il consimo di ram, sfavorendo la memoria flash pensate sia cmq meglio rispetto ad avere tutte qulle stinghe?

allego il codice attuale ottimizzato e la prova con la libreria wifi non provata e non verificata.

Guarda che l’unica cosa a cui devi prestare attenzione è la memoria dinamica la flash puoi occuparla anche al 100% senza nessun genere di problema, fermo restando la necessità di eliminare le String

fabpolli:
Guarda che l'unica cosa a cui devi prestare attenzione è la memoria dinamica la flash puoi occuparla anche al 100% senza nessun genere di problema, fermo restando la necessità di eliminare le String

ok grazie mille per il chiarimento! :slight_smile: