cosa c'è di sbagliato in questo codice!?!

potrebbe "aggiungere" alla (sua) libreria un/alcuni metodo/i con va_arg ... sai che bei rompicapo!? :smiley:

Oppure la cosa si può fare usando funzioni della libreria, quindi senza toccarla
Si crea una funzione che accetta in ingresso i puntatori alle variabili da stampare, e lei le stampa una ad una.
Nella loop() appare una sola riga, ma non credo sia conveniente dal lato spazio e complicazioni di codice.
Inoltre il numero di variabili possibili é fisso, e ci deve essere un esclusione dei puntatori a 0, presenti in caso di richieste eccessive.
Per fare si fa, per essere conveniente non lo é

Non c'è bisogno di scomodare i puntatori in questo caso :slight_smile:
Se proprio vuoi fare tutto con una sola riga di codice, ti potresti creare tu una funzione stampa() che riceve i dati che vuoi stampare, e al suo interno chiamerai tante volte il metodo print con le varie variabili.
Una funzione di questo tipo non da nessun beneficio, sennò usare nel restante codice una sola riga per stampare più variabili.

La soluzione più semplice è usare sprintf() per inserire in un array di 16 elementi i dati, con la possibilità di formattarli a piacere, e poi inviarlo al display con una singola lcd.print().

Nel mio contatore geiger per visualizzare ore, minuti e secondi ho usato String:

// oref, minutif e secondif sono ore minuti e secondi formattati in stringhe a 2 caratteri
//  mettendo uno spazio prima se il valore è di una sola cifra, cioè minore o uguale a 9.
ore=int(S/3600);
if(ore>9) oref=String(ore); else oref=" "+String(ore);

minuti=int((S%3600)/60);
if(minuti>9) minutif=String(minuti); else minutif=" "+String(minuti);

secondi=(S%3600)%60; 
if(secondi>9) secondif=String(secondi); else secondif=" "+String(secondi);

if      (S<60)         lcd.print("   "+secondif+"s");
else if (S<3600) lcd.print(minutif+"m"+secondif+"s");
else                 lcd.print(oref+"h"+minutif+"m");

Allo stesso modo, per visualizzare più valori con un solo lcd.print (giustamente, perché impiega del tempo e rallenta il ciclo: è bene, quindi, scrivere solo se c'è qualche variazione oppure una volta ogni secondo o anche più secondi), puoi scrivere:
lcd.print(String(valore1)+String(valore2)+String(valore3)+String(valore4));

Datman:
...
lcd.print(String(valore1)+String(valore2)+String(valore3)+String(valore4));

Per carità, lascia stare la classe String !!!

Guglielmo

E' tanto bistrattata, ma funziona...

Certo che funziona, ci mancherebbe pure, ma dimentichi che ...

... NON sei su un PC dove c'è un sistema operativo ed un "garbage collector", sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria, porta quasi sempre ... a grossi problemi e sicuri mal di testa !!! :smiling_imp:

Quello che occorre fare è imparare ad usare bene le stringhe classiche del C e le funzioni che trovi nella libreria standard (... che, oltretutto, è automaticamente inclusa dal IDE) AVR libc ed, in particolare, quanto è in <string.h> :wink:

Guglielmo

Sì, ho letto poco fa il problema della frammentazione. Si potrebbe fare:
char a[6]="Pippo";
char b[9]="Topolino";
e poi fare lcd.print con a e b concatenate?

Il problema è che Arduino è stato inventato per persone che non ne sanno nulla e tutte le guide sono fatte per quelle persone! Non c'è una guida che insegni a usare il microcontrollore in maniera efficiente senza dover fare un corso pluriennale di C, anche perché si finirebbe per non usare più digitalRead, digitalWrite, analogRead, String e altro che sono presunti "punti di forza" di Arduino! :slight_smile:

Datman:
...
e poi fare lcd.print con a e b concatenate?

La soluzione più elegante l'ha data Astro alcuni post fa ... usare la sprintf() che è estremamente comoda e potente :slight_smile:

Guglielmo

Datman:
Il problema è che Arduino è stato inventato per persone che non ne sanno nulla e tutte le guide sono fatte per quelle persone!

... che è poi la sua più grande "debolezza" e "limitazione", perché, a parte tutte le baggianate che si leggono in giro, se uno vuole fare poco più di un "blink", tocca lasciar stare il copia/incolla stile "scimmia" e mettersi seriamente a "studiare" :wink:

Guglielmo

Ho letto e riletto sprintf() ma, senza aver fatto un corso di C, mi sembra scritto in giapponese! :slight_smile:

Ahahahahahahah ...
... si, può sembrare complicata, ma non lo è, devi solo imparare alcuni identificatori e la loro sintassi.

Particamente, in una stringa scrivi quello che vuoi comporre, esempio immaginando che vuoi ...

testo_1, variabile_1, testo_2, variabile_2, testo_3, variabile_3

... dove, ad esempio, variabile_1,2,3 sono tre interi e che testo_1 sia "Valore variabile 1: ", testo_2 sia " , della variabile 2:" e testo_3 sia " , della variabile 3:"

... allora la stringa che dovrai comporre dovrà indicare tutto ciò:

"Valore variabile 1: %i , della variabile 2: %i , della variabile 3: %i"

Come vedi il testo rimane uguale e dove deve essere messo il valore metti il simbolo di % ed il tipo della variabile. I vari tipi e le loro varie forme, sono spiegate in un qualsiasi buon reference di C (es. QUI), comunque, %i indica che li deve andare una variabile intera.

La sprintf() diventerà, nel nostro esempio:

sprintf( stringaDiDestinazione, "Valore variabile 1: %i , della variabile 2: %i , della variabile 3: %i", variabile_1, variabile_2, variabile_3 );

... che riempirà stringaDiDestinazione con la stringa voluta :slight_smile:

Spero sia chiaro ... ::slight_smile:

Guglielmo

Mi sembra di sì. Appena posso lo studio con comodo.
Grazie! :slight_smile:

Datman:
Mi sembra di sì. Appena posso lo studio con comodo.
Grazie! :slight_smile:

Non solo, usa la formattazione della come printf del C quindi puoi fare riferimento a quella istruzione con tanti esempi in rete, esempio cose come metter in automatico gli zeri, esempio data e ora,
snprintf(buf,100,"%02/%02/%04",giorno,mese,anno);
ottieni 01/01/2017 anche se passi 1 gennaio 2017 invece di ottenere un brutto 1/1/2017

P.S. io preferisco snprintf a cui devi passare la dimensione stringa/buffer per essere sicuri di non andare oltre
P.S. ulteriore: limitazione, la sprintf sugli avr non funziona %f per i double/float.

nid69ita:
P.S. ulteriore: limitazione, la sprintf sugli avr non funziona %f per i double/float.

Beh .. per quello c'è una bella funzioncina che trasforma il float in stringa ( ftoa() ) così lo puoi passare direttamente. L'ho trovata in giro, ma aveva qualche errore, l'ho sistemata e ... allego l'esempio e la funzione al post :smiley:

E' piuttosto veloce dato che il lavoro vero lo fa con i long e i char :wink:

Guglielmo

ftoa_example.zip (674 Bytes)

Ecco trovato un argomento da trattare nei "famosi tutorial" che un moderatore italiano a caso voleva scrivere.

nid69ita:
P.S. io preferisco snprintf a cui devi passare la dimensione stringa/buffer per essere sicuri di non andare oltre

Ottimo consiglio!

nid69ita:
P.S. ulteriore: limitazione, la sprintf sugli avr non funziona %f per i double/float.

Corretto, ma se non ricordo male, c'era una #define da scommentare che abilitava ciò, a costo di parecchia flash.

Ho letto e riletto sprintf() ma, senza aver fatto un corso di C, mi sembra scritto in giapponese!

In realtà guardando gli esempi è molto semplice capire il suo utilizzo, ho visto del tuo codice e non fai cose banali...

Off Topic
La filosofia di arduino di rendere le cose semplici, fornendo esempi di codice, una vastità di librerie anche sviluppate da terzi, a mio avviso porta anche a "sfruttare intensamente" il microcontrollore.
L'alternativa è programmare direttamente il microcontrollore in C, ma se si cerca in rete non esistono progetti complessi realizzati programmando direttamente un microcontrollore. Anche molti professionisti che lavorano con i microcontrollori, non sarebbero in grado di creare codice molto complesso come alcune librerie, è per questo che è difficile trovare, ad esempio, un server web realizzato con un picmicro...

torn24:
... ma se si cerca in rete non esistono progetti complessi realizzati programmando direttamente un microcontrollore. Anche molti professionisti che lavorano con i microcontrollori, non sarebbero in grado di creare codice molto complesso come alcune librerie, è per questo che è difficile trovare, ad esempio, un server web realizzato con un picmicro...

Ma questa dove l'hai letta ? ? ? :o :o :o

Non confondiamo i programmini "amatoriali" che si vedono su questo (o su altri simili) forum, con il lavoro "professionale".

Chi ci lavora seriamente programma essenzialmente in 'C' (... ed in assembler) e i produttori seri ti mettono a disposizione tutte le librerie ed i sorgenti che ti occorrono ottimizzati ! Prova solo a cercare la "Peripheral Library" (plib) di Microchip o, per i PIC32, "Microchip Harmony" e ti renederai conto delle decine di migliaia di righe di codice 'C' che vengono messe a disposizione.

Non trovi i progetti in rete per un semplice motivo ... perché un professionista, che quindi lo fa per "professione" (ovvero ci porta lo stipendio a casa), viene pagato per scrivere il codice ed il codice NON viene distribuito in rete ma è di proprietà del committente che lo conserva gelosamente (... spesso ben protetto da copyright) !

Per quanto concerne poi realizzare un "web server" con un piccolo 8bit ... è un gioco carino, un bell'esercizio, ma, seriamente, non serve a molto. Se ti serve un vero "web server" vai su tutt'altra cosa, se ti serve uno scambio di dati su ethernet idem.

Guglielmo