Utilizzo "intelligente" di serial.print

off topic on —
maledetta nuova interfaccia. non mi abituerò mai :face_with_symbols_over_mouth:
off topic off ----

Salve a tutti . Parliamo di Serial.print
Uso tantissimo - come credo facciano in molti - il Serial.print, per poter fare debugging e capire che succede.
Come sappiano spreca molte risorse ed una volta terminato lo sketch, in pratica i serial print non servono più.
Piuttosto che cancellarli tutti (andando incontro anche al fatto che un giorno potrebbero riservire) , io uso il metodo di commentare l’istruzione Serial.begin, in modo che non compaia nulla.

La domanda è : il metodo che adotto è giusto ed equivale alla cancellazione di tutti i serial print o in questo modo spengo-accendo e basta e le risorse vengono in ogni caso utilizzate ?.
Se sbaglio, esiste altro metodo per ottenere un risultato simile ?

Siamo in due … :+1:

Tornando alla tua domanda … NON, non è il modo giusto di procedere e non risparmi risorse …
… il modo corretto è usare il pre-processore del ‘C’:

...
#define mioDEBUG
...
...
#ifdef mioDEBUG
   Serial.begin(9600);
#endif
...
...
#ifdef mioDEBUG
   Serial.print("messaggio");
   Serial.println(variabile);
   ...
#endif
...

… in questo modo, finche c’è la #define iniziale le righe racchiuse tra il #ifdef ed il #endif sono incluse nel tuo programma, nel momento in cui comenti la #define iniziale … le righe NON sono più incluse e non vengono quindi nemmeno compilate. :wink:

Guglielmo

questo però significa che debbo mettere un if-endif per ogni serial print, giusto ?
se così fosse se metto 300 serial print (su programmi lunghi) non mi passa più ! :pensive:
dura lex, sed lex

Devi metterli per tutte quelle righe che NON vuoi ci siano poi nella versione definitiva … molto comodo anche per fare versioni diverse dello stesso programma che offrono funzionalità aggiuntive (es. a pagamento :grin:)

Guarda che basta farci l’abitudine, i miei programmi sono pieni di quegli #ifdef :wink:

Guglielmo

infatti l’utilizzo era proprio questo, con aggiunto anche quello di non far vedere ai furbetti il log del monitor seriale e di permettere a me, con un flag “nascosto” nella eeprom, di leggere o no in caso di problemi.
Farò come dici, vediamo se reggo :slight_smile: :smile:
Grazie come sempre dei preziosi consigli

I Serial.print() infatti li raggruppo tutti a fine programma, prima della chiusura del void loop()

Ciao…primo post con nuovo forum…vediamo…

io ultimamente faccio così:

#define DEBUG 0

#if DEBUG
#define SERIALE Serial
#define ATTIVA SERIALE.begin(9600);
#define STAMPA_LN(x) SERIALE.println(x);
#else
#define ATTIVA
#define STAMPA_LN(x)
#endif

void setup() {
  ATTIVA
  STAMPA_LN("ciao");

}

quindi non mi serve seminare il programma di ifdef-endif etc…

2 Likes

Azz che genialata. Mi sa che te la rubo.
Unica curiosità… perché definisci SERIALE invece di usare Serial nei 2 define successivi?

Stesso metodo di @ORSO2001.

E aggiungo anche altre informazioni al print di debug come file e riga del sorgente, nome della funzione etcetc

Ci posti un esempio? :smile:

Con MCU che supportano il printf (ESPxx, STM32, etcetc) mi sono creato questo file che includo dove serve. Immagino che si possa adattare anche senza l’uso di printf.

#ifndef __LOG_H__
#define __LOG_H__

#ifdef __cplusplus
extern "C"
{
#endif

// Windows
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)

// Linux, Mac
// #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

#define _LOG_FORMAT(letter, format)  "\n[" #letter "][%s:%u] %s():\t" format, __FILENAME__, __LINE__, __FUNCTION__

#if DEBUG_ENABLE
#define log_debug(format, ...) Serial.printf(_LOG_FORMAT(D, format), ##__VA_ARGS__)
#define log_error(format, ...) { Serial.println(); Serial.printf(_LOG_FORMAT(E, format), ##__VA_ARGS__); }
#define log_info(format, ...) Serial.printf(_LOG_FORMAT(I, format), ##__VA_ARGS__)
#define lineTrap() {Serial.printf("[%s:%u] - ", __FILENAME__, __LINE__); Serial.print(__func__); Serial.println("()");}
#else
#define log_debug(format, ...)
#define log_error(format, ...)
#define log_info(format, ...)
#define lineTrap()
#endif

#define DEBUG_F true
#if DEBUG_F
	#ifdef ESP32
		#define functionLog() { \
		Serial.printf("Heap memory %6d / %6d", heap_caps_get_free_size(0), heap_caps_get_largest_free_block(0));\
		Serial.print("\t\t\t--- "); Serial.print(millis()); Serial.print("mS > ");  Serial.print(__func__); Serial.println("()"); }
	#elif defined(ESP8266)
		#define functionLog() { \
		uint32_t free; uint16_t max; uint8_t frag; ESP.getHeapStats(&free, &max, &frag); Serial.printf("free: %5d - max: %5d <- ", free, max);\
		Serial.printf("[%s:%u]\t--- ", __FILE__, __LINE__); Serial.print(millis()); Serial.print("mS > ");  Serial.print(__func__); Serial.println("()"); }
	#endif
#else
    #define functionLog()
#endif


#ifdef __cplusplus
}
#endif

#endif

damngif

@giorgiogiorgio ahahahah :rofl:

È solo la versione “evoluta” dello schema di base già scritto da @ORSO2001
Ho preso quanto già presente nel core esp32 per Arduino e semplificato/modificato un po’ per le mie esigenze.

@giorgiogiorgio : essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO … Grazie. :slight_smile:

Guglielmo

Quindi con il tuo metodo basta commentare //ATTIVA per non far compilare tutto ciò che diversamente verrebbe stampato?

Grazie

@droidprova …no…nella prima riga dove c’è #define DEBUG …se metti “0” o false non stampa…se metti “1” o true stampa.

Grazie!

e se avessi ad esempio una funzione di nome stampa() che viene lanciata dal loop() dove raccolgo tutti i print del programma utile al debug, come potrei disattivarla col tuo sistema?

Io attualmente la commento del tutto assieme alla serial.begin() nel setup().

Forse con due righe è meglio, che ne pensate? Certo non è a livelli top ma per il mio utilizzo potrebbe andare bene:

bool flag = true;

#define DEBUG flag    // 0 non stampa, 1 stampa

#if DEBUG
#define SERIALE Serial
#define ATTIVA SERIALE.begin(9600);
#define STAMPA_LN(x) SERIALE.println(x);
#else
#define ATTIVA
#define STAMPA_LN(x)
#endif


void setup() {
  ATTIVA
}

void loop() {
#ifdef DEBUG
  stampa();
#endif
}

void stampa() {
  STAMPA_LN("ciao");
  delay(1000);
}

domanda: lo stato della variabile flag posso cambiarla a programma caricato, che so usando una comunicazione con telegram?

però compilando il codice assegnando lo stato a DEBUG con la variabile flag non funziona, se invece gli assegno direttamente il valore 0 o 1 allora funziona. Perchè?

Curiosità…
a livello di “dita che premono sulla tastiera” che vantaggio c’è a cambiare true con false rispetto a cambiare 1 con 0?