Monitor seriale Arduino: baud rate, invio dati e Serial Plotter
Come usare il monitor seriale di Arduino: Serial.begin e baud rate, caratteri strani, fine riga, parseInt, Plotter seriale ed esempi per ESP32 e Pico.
Il monitor seriale di Arduino (Serial Monitor) è la finestra dell'Arduino IDE che permette alla tua scheda e al tuo computer di scambiarsi testo attraverso il cavo USB. Qui leggi l'uscita di ogni riga Serial.println() del tuo sketch e da qui invii comandi alla scheda. È il modo più rapido per vedere quale valore sta misurando un sensore in questo momento, fino a quale riga è arrivato il tuo programma o se un pulsante viene davvero premuto, e per questo è lo strumento di debug numero uno su Arduino. Per usarlo ti bastano Serial.begin(9600) nel codice, la porta giusta selezionata nel selettore della scheda e la stessa velocità nel monitor e nel codice.
In questa guida inizierai aprendo il monitor seriale e poi vedrai che cosa significa davvero il baud rate, come stampare numeri in decimale, esadecimale e binario con print e println, come impostare il numero di decimali e come costruire righe ordinate con snprintf. Con sketch di esempio che compilano davvero, vediamo tutte le cause dei caratteri strani, l'effetto dell'impostazione di fine riga sul tuo codice, l'invio di numeri e comandi di testo dal computer alla scheda (Serial.read, parseInt, readStringUntil), i grafici in tempo reale con il Plotter seriale e tecniche di debug che ti semplificheranno la vita. Le ultime sezioni mostrano come cambia l'uscita seriale su ESP32 e Raspberry Pi Pico (con Arduino e con MicroPython) e come risolvere problemi frequenti come un monitor vuoto.

Che cos'è il monitor seriale di Arduino e come funziona?
L'ATmega328P, il cervello di Arduino Uno, comunica con l'esterno tramite un'unità di comunicazione seriale chiamata UART: invia i dati bit per bit su una linea (TX) e li riceve su un'altra (RX). I computer moderni non hanno più questo tipo di porta seriale, quindi un secondo chip sulla scheda (un ATmega16U2 sull'Uno originale, di solito un CH340 sui cloni) converte il segnale in USB. Il computer vede la scheda come una porta seriale virtuale: per esempio COM3 su Windows, /dev/ttyACM0 o /dev/ttyUSB0 su Linux e un nome che inizia con /dev/cu.usbmodem o /dev/cu.usbserial su macOS. Il monitor seriale apre questa porta, mostra come testo i byte in arrivo e invia alla scheda ciò che scrivi, sulla stessa strada. Di default Arduino usa il formato 8N1: per ogni byte un bit di start, 8 bit di dati, nessun bit di parità e un bit di stop. Un solo carattere occupa quindi 10 bit sulla linea; useremo questo numero nei calcoli di velocità.
| Caratteristica | Arduino Uno | ESP32 DevKit | Raspberry Pi Pico |
|---|---|---|---|
| Collegamento USB | Chip ponte ATmega16U2 o CH340 | Chip ponte CP2102 o CH340 | USB integrato del RP2040 (USB CDC) |
| Pin di Serial | D0 (RX), D1 (TX) | GPIO 3 (RX), GPIO 1 (TX) | Nessun pin, direttamente via USB |
| Porte seriali hardware aggiuntive | Nessuna (via software con SoftwareSerial) | Serial1 e Serial2 (Serial2 spesso su GPIO 16 RX, GPIO 17 TX) | Serial1 (GP0 TX, GP1 RX), Serial2 (GP8 TX, GP9 RX) |
| Velocità tipica | 9600 baud | 115200 baud | Indifferente, funziona alla velocità USB |
| Si resetta all'apertura del monitor | Sì (linea DTR) | Dipende dalla scheda e dal programma | No |
| Serial.printf() | Non disponibile, usa snprintf | Disponibile | Disponibile |

Come aprire e usare il monitor seriale
- Aggiungi la riga Serial.begin(9600); nella parte setup() del tuo sketch e caricalo sulla scheda. Senza questa riga la scheda non scrive nulla sulla porta seriale.
- Scegli la porta a cui è collegata la scheda nel selettore della barra in alto o nel menu Strumenti > Porta. Se non è selezionata nessuna porta, il monitor seriale mostra l'avviso Non collegato. Scegli una scheda e la porta di comunicazione per una connessione automatica. (nell'interfaccia inglese: Not connected. Select a board and a port to connect automatically.)
- Clicca sull'icona della lente in alto a destra, usa il menu Strumenti > Monitor seriale o premi Ctrl+Maiusc+M (Cmd+Shift+M su macOS). Nell'IDE 2 il monitor si apre nel pannello in basso, accanto alla sezione Output.
- Nel menu della velocità, a destra del pannello, scegli lo stesso baud rate del codice; in questo esempio 9600. Se la velocità è diversa, compaiono caratteri strani.
- Per inviare dati alla scheda, scrivi nella casella del messaggio in cima al pannello e premi Invio. Nel menu accanto scegli il fine riga; più avanti spieghiamo perché questa impostazione è importante.
- Con i pulsanti in alto a destra puoi sospendere lo scorrimento automatico (utile per rileggere le righe precedenti), attivare il timestamp che aggiunge l'ora del computer all'inizio di ogni riga e cancellare l'output.
Nel vecchio Arduino IDE 1.8 il monitor seriale si apre in una finestra separata; i comandi fanno lo stesso lavoro, solo in posizioni diverse: le caselle di scorrimento automatico e timestamp sono in basso a sinistra, i menu di fine riga e velocità in basso a destra. Puoi anche osservare la porta seriale senza l'IDE: PuTTY o CoolTerm su Windows, il comando screen /dev/ttyUSB0 115200 su Linux e macOS e arduino-cli monitor -p COM3 -c baudrate=115200 su qualsiasi sistema fanno la stessa cosa. Ricorda una cosa: una porta seriale può essere aperta da un solo programma alla volta. Finché uno script Python o PuTTY tiene occupata la porta, non puoi caricare codice dall'IDE; l'installazione dell'IDE e il resto dell'interfaccia sono spiegati nella guida come installare Arduino IDE.
Serial.begin() e baud rate: 9600 o 115200?
Serial.begin(velocità) avvia la porta seriale alla velocità indicata e si chiama quasi sempre una sola volta dentro setup(). La velocità si esprime in baud, cioè in bit al secondo sulla linea. Poiché ogni carattere occupa 10 bit, 9600 baud significano al massimo 960 caratteri al secondo; inviare un singolo carattere richiede circa 1,04 millisecondi. Una riga di 30 caratteri occupa 31 ms a questa velocità, quindi appena vuoi stampare centinaia di letture al secondo ti scontri con questo limite. A 115200 baud la stessa riga richiede solo 2,6 ms. Il valore nello sketch e quello nel monitor seriale devono coincidere, perché non c'è un segnale di clock comune e il ricevitore legge i bit basandosi solo sui tempi.
| Baud rate | Caratteri al secondo | Durata di un carattere | Dove si usa? |
|---|---|---|---|
| 9600 | 960 | 1,04 ms | Esempi Arduino; valore predefinito di moduli come HC-05 e GPS NEO-6M |
| 57600 | 5760 | 174 µs | Velocità di caricamento dei Nano con il vecchio bootloader, alcuni moduli |
| 74880 | 7488 | 134 µs | Messaggi di avvio (boot) dell'ESP8266 |
| 115200 | 11520 | 87 µs | ESP32, Pico e debug veloce; velocità di caricamento del nuovo bootloader dell'Uno |
| 250000 | 25000 | 40 µs | Registrazione dati veloce; generata senza errore dal clock a 16 MHz dell'Uno |
| 1000000 | 100000 | 10 µs | Trasferimento dati molto veloce; richiede un cavo corto |
Il clock a 16 MHz dell'Uno non riesce a generare ogni velocità con esattezza: 115200 baud funzionano in realtà con uno scarto di circa il 2 %, a 117647 baud. Questo scarto non crea problemi nel monitor seriale, ma può causare errori quando comunichi con un altro microcontrollore su un cavo lungo; in questi casi 57600 o 250000 baud, generati senza errore, sono più sicuri. Se stai iniziando, usa 9600 con Uno e Nano e 115200 con ESP32 e Pico. Se colleghi due schede con fili TX-RX, la velocità deve essere uguale da entrambe le parti, le GND devono essere in comune e una linea TX a 5 V va abbassata con un partitore di tensione prima di arrivare a un ingresso RX a 3,3 V (ESP32, Pico). Trovi i dettagli nell'articolo comunicazione seriale UART.
Serial.print() e Serial.println(): stampare e formattare
Serial.print() scrive il valore che gli passi e lascia il cursore sulla stessa riga; Serial.println() aggiunge in più i caratteri di fine riga (\r\n), così l'uscita successiva comincia su una riga nuova. Per mostrare più valori su una riga, scrivi le prime parti con print e l'ultima con println. Queste funzioni accettano quasi ogni tipo, come int, long, float, char, testo e String, e il secondo parametro facoltativo stabilisce il formato. Per gli interi puoi scegliere DEC, HEX, BIN e OCT, mentre per i numeri decimali il secondo parametro è il numero di cifre decimali. I decimali vengono stampati di default con 2 cifre e arrotondati. Nel codice qui sotto abbiamo scritto l'uscita di ogni riga come commento:
1// Biçimlendirme örnekleri: çıktılar yorumlarda / Formatting examples: output in the comments
2void setup() {
3 Serial.begin(9600);
4 int sayi = 78;
5 float pi = 3.14159;
6
7 Serial.println(sayi); // 78
8 Serial.println(sayi, HEX); // 4E
9 Serial.println(sayi, BIN); // 1001110
10 Serial.println(sayi, OCT); // 116
11 Serial.println(pi); // 3.14 (varsayılan 2 basamak / 2 decimals by default)
12 Serial.println(pi, 4); // 3.1416
13 Serial.write(65); // A (ham bayt / raw byte)
14 Serial.println(); // yalnız satır sonu / line break only
15
16 Serial.print("Sicaklik:\t"); // \t = sekme / \t = tab
17 Serial.print(23.46, 1); // 23.5
18 Serial.println(" C"); // Sicaklik: 23.5 C
19
20 char satir[32];
21 int saat = 9, dakika = 5;
22 snprintf(satir, sizeof(satir), "Saat %02d:%02d", saat, dakika);
23 Serial.println(satir); // Saat 09:05
24
25 char metin[10];
26 dtostrf(pi, 6, 2, metin); // Uno'da %f yerine / instead of %f on the Uno
27 Serial.println(metin); // " 3.14"
28}
29
30void loop() {
31}| Codice | Cosa mostra il monitor seriale | Nota |
|---|---|---|
| Serial.print(78); | 78 | Il decimale (DEC) è il predefinito |
| Serial.print(78, HEX); | 4E | Esadecimale; per indirizzi, colori e valori di byte |
| Serial.print(78, BIN); | 1001110 | Binario; gli zeri iniziali non vengono stampati |
| Serial.print(3.14159); | 3.14 | Per i decimali, 2 cifre di default |
| Serial.print(3.14159, 4); | 3.1416 | 4 cifre decimali, arrotondato |
| Serial.write(65); | A | Invia il carattere ASCII numero 65, non il numero |
| Serial.print('A'); | A | Il tipo char viene stampato come carattere |
| Serial.print(5e9); | ovf | Sull'Uno i decimali oltre circa 4,29 miliardi non si possono stampare |
Invece di stampare le righe lunghe pezzo per pezzo, puoi preparare un unico testo con snprintf(): %d è un intero, %02d un intero a due cifre con zero iniziale, %s un testo e %lu un unsigned long come millis(). Per risparmiare memoria, la libreria C dell'Uno non supporta %f; se provi a stampare un decimale, al suo posto vedrai un ?. Converti quindi prima i decimali in testo con dtostrf(numero, larghezza, decimali, buffer). Su ESP32 e Pico puoi usare direttamente Serial.printf(). L'Uno ha solo 2 KB di RAM; scrivere i testi fissi con la macro F(), come in Serial.println(F("Ciao")), li tiene nella memoria flash invece che nella RAM ed evita problemi di memoria insufficiente nei progetti grandi.
Caratteri strani nel monitor seriale: cause e soluzione
Se vedi ⸮⸮⸮, � o mucchi di lettere e simboli casuali, i dati arrivano al computer ma vengono decodificati male. Poiché la comunicazione seriale non ha un segnale di clock comune, il ricevitore calcola il centro di ogni bit in base alla propria velocità, a partire dal momento in cui vede il bit di start. Se la velocità è sbagliata o il clock della scheda non è quello previsto, i bit vengono letti nel momento sbagliato e ogni byte diventa un altro carattere. Quasi sempre la causa è una sola impostazione; la tabella qui sotto ordina i casi più frequenti per sintomo. Per le schede con diverse opzioni di clock, come la Pro Mini, dai un'occhiata anche all'articolo Arduino Pro Mini.
| Sintomo | Causa | Soluzione |
|---|---|---|
| Caratteri strani dall'inizio alla fine | La velocità del monitor seriale è diversa da quella di Serial.begin() | Scegli nel menu a destra la velocità del codice |
| Solo una riga è illeggibile all'avvio, il resto va bene | L'ESP8266 a 74880 o l'ESP32 a 115200 baud stampa il proprio messaggio di avvio | È normale; per leggerlo imposta il monitor su quella velocità |
| L'uscita della Pro Mini è sempre illeggibile | È stato scelto 5 V / 16 MHz per una scheda da 3,3 V / 8 MHz e la velocità reale si dimezza | Scegli il clock reale della scheda nel menu Strumenti > Processore |
| Caratteri casuali si mescolano al testo normale | Un modulo collegato a D0/D1 parla anch'esso sulla linea | Collega il modulo ad altri pin con SoftwareSerial |
| Simboli strani al posto dei numeri | Serial.write(numero) invia il numero come byte grezzo | Usa Serial.print() per stampare il numero come testo |
| I dati tra due schede arrivano corrotti | GND non in comune, cavo lungo o velocità diverse | Collega le GND, accorcia il cavo, abbassa la velocità |
| La stessa riga illeggibile si ripete e la scheda si riavvia | L'alimentazione non basta e la scheda continua a resettarsi | Controlla alimentatore e cavo, alimenta il carico a parte |
Impostazione di fine riga: No Line Ending, New Line, Carriage Return, Both NL & CR
Quando scrivi nella casella del messaggio e premi Invio, il monitor seriale non invia solo i caratteri digitati, ma anche uno o due caratteri invisibili in base al fine riga scelto. Se il tuo codice non se li aspetta, per esempio perché tratta ogni byte in arrivo come un comando, anche '\n' (valore 10) e '\r' (13) vengono letti come comandi. Al contrario, se il codice aspetta un fine riga e l'impostazione è No Line Ending, la riga non finisce mai; readStringUntil() aspetta fino allo scadere del timeout. La tabella mostra i byte inviati alla scheda quando scrivi 42 e premi Invio:
| Significato | Nome nell'IDE | Carattere aggiunto | Byte inviati per 42 |
|---|---|---|---|
| Non viene aggiunto nulla | Nessun fine riga / No Line Ending | Nessuno | 52, 50 |
| A capo (LF) | A capo / New Line | \n (LF, 10) | 52, 50, 10 |
| Ritorno carrello (CR) | Ritorno carrello (CR) / Carriage Return | \r (CR, 13) | 52, 50, 13 |
| Entrambi (CR + LF) | Entrambi NL & CR / Both NL & CR | \r\n (13, 10) | 52, 50, 13, 10 |
Una regola pratica: per il codice che legge riga per riga scegli New Line e applica trim() al testo letto; così il codice funziona qualunque impostazione scelga l'utente. Per comandi di un solo carattere come 1, 0 o a, No Line Ending è la scelta più pulita. L'IDE ricorda la tua scelta, quindi ricontrollala quando passi a un altro progetto.
Inviare dati dal computer ad Arduino: Serial.read(), parseInt(), readStringUntil()
I byte che invii dal monitor seriale si mettono in coda nel buffer di ricezione della scheda (64 byte sull'Uno). Serial.available() ti dice quanti byte vi stanno aspettando, Serial.read() prende il byte successivo e lo toglie dal buffer, restituendo -1 se non ci sono dati, e Serial.peek() guarda il byte successivo senza toglierlo. Ricorda che tutto ciò che arriva dalla tastiera è fatto di caratteri ASCII: se scrivi 7, la scheda non riceve il numero 7 ma 55, il codice del carattere '7'. Trovi un esempio di semplici comandi a un tasto nell'articolo comandi Arduino; qui trattiamo numeri a più cifre e comandi fatti di parole. Se il buffer si riempie, i nuovi byte in arrivo vanno persi; gestire i tempi con millis() invece di aspettare a lungo con delay() dentro loop() rende quindi più sicura anche la lettura seriale.
Serial.parseInt() estrae il primo numero intero dai caratteri in arrivo: salta lettere e spazi iniziali, unisce le cifre e si ferma al primo carattere che non è una cifra; capisce anche il segno meno. Così il testo "128" diventa il numero 128. Per i decimali, Serial.parseFloat() fa lo stesso lavoro. Queste funzioni hanno un'abitudine che devi conoscere: se non arriva nessun numero, aspettano di default 1000 ms e poi restituiscono 0. Il classico errore nasce così: con l'impostazione New Line invii 42, parseInt legge 42 ma il '\n' resta nel buffer. Al giro successivo loop() vede available() maggiore di 0 e richiama parseInt, che aspetta un secondo e restituisce 0. Risultato: dopo ogni numero arriva anche uno 0, e non capisci perché il LED si spegne un secondo dopo ogni numero. Il codice qui sotto risolve il problema alla radice scartando il carattere successivo se non è una cifra, e accorcia l'attesa con setTimeout().
1// Seri Port Ekranı'ndan sayı al: LED parlaklığı 0-255
2// Read a number from the Serial Monitor: LED brightness 0-255
3const int LED_PIN = 9; // ~9 PWM pini + 220 ohm direnç / ~9 PWM pin + 220 ohm resistor
4
5void setup() {
6 pinMode(LED_PIN, OUTPUT);
7 Serial.begin(9600);
8 Serial.setTimeout(100); // parseInt en fazla 100 ms bekler / parseInt waits at most 100 ms
9 Serial.println(F("0-255 arasi bir sayi yaz / Type a number from 0 to 255"));
10}
11
12void loop() {
13 if (Serial.available() > 0) {
14 char c = Serial.peek(); // sıradakine bak, silme / look at the next byte, keep it
15 if (isDigit(c) || c == '-') {
16 int deger = Serial.parseInt(); // "128" -> 128
17 deger = constrain(deger, 0, 255); // aralığın dışına çıkma / stay within range
18 analogWrite(LED_PIN, deger);
19 Serial.print(F("Parlaklik / Brightness: "));
20 Serial.println(deger);
21 } else {
22 Serial.read(); // '\r', '\n' ve harfleri at / drop '\r', '\n' and letters
23 }
24 }
25}Per i comandi fatti di parole, la cosa più comoda è leggere l'intera riga come String. Serial.readStringUntil('\n') legge finché arriva un '\n', scarta il carattere di fine riga e restituisce il resto. Se l'impostazione è Both NL & CR, alla fine del testo resta un '\r', il tuo comando "on" diventa "on\r" e il confronto fallisce. Per questo conviene applicare subito trim() alla riga letta: elimina gli spazi iniziali e finali e i caratteri '\r' e '\n'. toLowerCase() rende uguali ON, On e on. L'esempio qui sotto capisce i comandi on, off, blink 250 e status; usa il monitor seriale a 115200 baud con New Line. Poiché fa lampeggiare il LED con millis() invece di delay(), risponde subito a un nuovo comando in qualsiasi momento.
1// Metin komutları: on, off, blink 250, status
2// Text commands: on, off, blink 250, status
3const int LED_PIN = LED_BUILTIN; // Uno'da pin 13 / pin 13 on the Uno
4bool ledAcik = false; // LED'in şu anki durumu / current LED state
5bool yanipSon = false; // yanıp sönme modu / blink mode
6unsigned long aralik = 500; // yanıp sönme aralığı (ms) / blink interval (ms)
7unsigned long sonDegisim = 0; // LED'in son değiştiği an / last time the LED changed
8
9void ledYaz(bool acik) {
10 ledAcik = acik;
11 digitalWrite(LED_PIN, acik ? HIGH : LOW);
12}
13
14void komutuIsle(String komut) {
15 if (komut == "on") {
16 yanipSon = false;
17 ledYaz(true);
18 Serial.println(F("LED: on"));
19 } else if (komut == "off") {
20 yanipSon = false;
21 ledYaz(false);
22 Serial.println(F("LED: off"));
23 } else if (komut.startsWith("blink")) {
24 long ms = komut.substring(5).toInt(); // "blink 250" -> 250
25 aralik = (ms >= 50) ? ms : 500; // çok küçükse 500 ms / fall back to 500 ms
26 yanipSon = true;
27 Serial.print(F("Blink (ms): "));
28 Serial.println(aralik);
29 } else if (komut == "status") {
30 Serial.print(F("LED: "));
31 Serial.print(ledAcik ? F("on") : F("off"));
32 Serial.print(F(", blink: "));
33 Serial.println(yanipSon ? F("yes") : F("no"));
34 } else {
35 Serial.print(F("Bilinmeyen komut / Unknown command: "));
36 Serial.println(komut);
37 }
38}
39
40void setup() {
41 pinMode(LED_PIN, OUTPUT);
42 Serial.begin(115200);
43 Serial.setTimeout(100); // satır sonu gelmezse 100 ms sonra bırak / give up after 100 ms without a line ending
44 Serial.println(F("Komutlar / Commands: on, off, blink 250, status"));
45}
46
47void loop() {
48 if (Serial.available() > 0) {
49 String komut = Serial.readStringUntil('\n'); // Enter'a kadar oku / read up to Enter
50 komut.trim(); // '\r' ve boşlukları sil / strip '\r' and spaces
51 komut.toLowerCase(); // ON ile on aynı olsun / treat ON like on
52 if (komut.length() > 0) {
53 komutuIsle(komut);
54 }
55 }
56
57 if (yanipSon && millis() - sonDegisim >= aralik) { // delay() olmadan yanıp sön / blink without delay()
58 sonDegisim = millis();
59 ledYaz(!ledAcik);
60 }
61}| Funzione | Cosa restituisce | Quanto aspetta? | Uso ideale |
|---|---|---|---|
| Serial.read() | Un byte (int), -1 se non ci sono dati | Non aspetta | Comandi di un carattere, un tuo parser |
| Serial.peek() | Il byte successivo, senza toglierlo dal buffer | Non aspetta | Guardare cosa arriva prima di decidere |
| Serial.parseInt() | Un intero long, 0 allo scadere del timeout | Il tempo di setTimeout (1000 ms di default) | Inserimento di numeri: angolo, velocità, luminosità |
| Serial.parseFloat() | Un float, 0 allo scadere del timeout | Il tempo di setTimeout | Valori di regolazione decimali, per esempio 2.5 |
| Serial.readStringUntil(c) | Il testo fino al carattere c (String) | Finché arriva c o scade il tempo | Comandi con parole e parametri |
| Serial.readBytesUntil(c, buffer, n) | Numero di byte letti; scrive il testo in un array di char | Finché arriva c, si leggono n byte o scade il tempo | Lettura senza String che risparmia RAM |
Grafici in tempo reale con il Plotter seriale
Il Plotter seriale (Serial Plotter) trasforma i numeri in arrivo dalla porta seriale in un grafico a linee in tempo reale; si apre con l'icona a forma d'onda in alto a destra nell'IDE o dal menu Strumenti > Plotter seriale. Il formato è semplicissimo: separa i valori di una riga con virgole, spazi o tabulazioni e chiudi la riga con println. Ogni riga diventa un passo temporale del grafico e ogni valore della riga una curva di colore diverso. Se metti un nome davanti ai valori nel formato etichetta:valore, le curve prendono quel nome e puoi nasconderle o mostrarle una per una con le caselle sopra il grafico; senza etichette le curve si chiamano value 1, value 2 e così via. Anche qui il menu della velocità deve corrispondere al codice. Il codice qui sotto disegna sullo stesso grafico la lettura grezza di A0 e la sua versione smussata:
1// Seri Çizici: ham değer ve yumuşatılmış değer / Serial Plotter: raw and smoothed value
2const int SENSOR_PIN = A0; // potansiyometre ya da LDR bölücü çıkışı / potentiometer or LDR divider output
3float yumusak = 0; // üstel ortalama / exponential moving average
4
5void setup() {
6 Serial.begin(115200);
7}
8
9void loop() {
10 int ham = analogRead(SENSOR_PIN); // 0-1023
11 yumusak = yumusak * 0.9 + ham * 0.1; // yeni ölçümün payı %10 / the new reading weighs 10%
12
13 Serial.print("Min:0,Max:1023,"); // dikey ekseni sabitler / keeps the y-axis fixed
14 Serial.print("Ham:");
15 Serial.print(ham);
16 Serial.print(",Yumusak:");
17 Serial.println(yumusak); // satırı bitir: bir ölçüm / end the line: one sample
18 delay(20); // saniyede yaklaşık 50 satır / about 50 lines per second
19}- Fissa la scala: il Plotter seriale riadatta continuamente l'asse verticale ai valori in arrivo, quindi piccole oscillazioni sembrano enormi. Aggiungere a ogni riga due valori costanti come Min:0,Max:1023, blocca l'asse.
- Niente spazi nelle etichette: poiché spazi e virgole valgono come separatori, "Temp Sala:24" viene diviso in due parti; usa nomi con il trattino basso come Temp_Sala.
- Nella riga solo etichette e numeri: unità e descrizioni come "Temp 24 C" rovinano il grafico; stampa le descrizioni per il monitor seriale in un codice separato.
- Regola il ritmo di invio: delay(20) significa circa 50 righe al secondo. Se invii troppo in fretta il grafico scorre via in un attimo, se invii troppo lentamente la linea sembra una scala.
- Guarda il filtro con i tuoi occhi: disegnare il valore grezzo e la media sullo stesso grafico mostra subito quanto un filtro riduce il rumore; trovi i metodi nell'articolo filtrare i dati dei sensori.
- Per registrare usa un altro strumento: il Plotter seriale non salva i dati su file. Per misure lunghe stampa i valori come righe CSV e importali in Excel oppure leggili con Python.
Tecniche di debug con il monitor seriale
Arduino Uno non ha un debugger che esegua il codice passo passo; questo lavoro lo fa il monitor seriale. Ma le righe print sparse a caso nel codice diventano presto un mucchio di testo illeggibile. Queste abitudini ti aiuteranno a trovare gli errori molto più in fretta:
- Stampa prima un messaggio da setup(): se vedi la riga "Started" una volta a ogni avvio, la scheda funziona. Se la riga si ripete di continuo, la scheda si resetta in continuazione e il problema è più nell'alimentazione che nel codice; vedi la guida Arduino si riavvia da solo.
- Stampa i valori con il loro nome: invece di scrivere solo 512, scrivi temp=24.5 umid=40; così non dovrai chiederti dopo a che cosa corrisponde ogni numero.
- Segna dove sei arrivato: se il programma si blocca da qualche parte, metti brevi marcatori come A, B, C prima dei passi importanti. L'ultimo marcatore che compare sullo schermo indica dove il programma si è fermato.
- Stampa quando cambia, non a ogni giro: loop() gira migliaia di volte al secondo. Stampare a ogni giro inonda lo schermo e rallenta il programma; stampa un valore solo quando cambia o una volta al secondo con millis().
- Misura il tempo: per vedere quanto dura un'operazione, salva il valore di micros() prima e dopo e stampa la differenza. Così scovi una lettura lenta di un sensore o un ciclo lungo.
- Non stampare dentro gli interrupt: l'uscita seriale richiede tempo; usare Serial.print in una funzione di interrupt la allunga inutilmente e può farti perdere altri eventi. Nell'interrupt imposta solo una variabile flag e fai la stampa in loop(); dettagli nell'articolo interrupt su Arduino.
- Metti le righe di debug dietro un solo interruttore: con le macro qui sotto puoi togliere del tutto dal codice ogni uscita di debug impostando DEBUG a 0; nel progetto finito risparmi memoria flash e tempo.
1// Hata ayıklama makroları: tek satırla aç ya da kapat
2// Debug macros: switch all debug output on or off with one line
3#define DEBUG 1 // 0 yaparsan debug satırları koddan çıkar / set to 0 to strip debug lines
4
5#if DEBUG
6 #define DBG(x) Serial.print(x)
7 #define DBGLN(x) Serial.println(x)
8#else
9 #define DBG(x)
10 #define DBGLN(x)
11#endif
12
13const int SENSOR_PIN = A0;
14const int ESIK = 800; // uyarı eşiği / warning threshold
15bool esikUstunde = false; // son durum / last state
16unsigned long sonRapor = 0;
17unsigned long turSayisi = 0; // saniyedeki loop() turu / loop() passes per second
18
19void setup() {
20 Serial.begin(115200);
21 DBGLN(F("Basladi / Started"));
22}
23
24void loop() {
25 turSayisi++;
26 int deger = analogRead(SENSOR_PIN);
27
28 bool simdi = deger > ESIK;
29 if (simdi != esikUstunde) { // yalnız değişince yaz / print only on change
30 esikUstunde = simdi;
31 DBG(F("[esik / threshold] "));
32 DBG(simdi ? F("ustunde / above") : F("altinda / below"));
33 DBG(F(", deger / value = "));
34 DBGLN(deger);
35 }
36
37 if (millis() - sonRapor >= 1000) { // saniyede bir özet / one summary per second
38 sonRapor = millis();
39 DBG(F("t = "));
40 DBG(sonRapor);
41 DBG(F(" ms, tur/s / loops/s = "));
42 DBGLN(turSayisi);
43 turSayisi = 0;
44 }
45}Ricorda che l'uscita seriale ha un costo. Sull'Uno anche il buffer di trasmissione è di 64 byte; quando è pieno, Serial.print() aspetta che si liberi spazio e loop() rallenta. Puoi misurarlo da solo con il contatore di giri del codice qui sopra: se aggiungi una riga di 25 caratteri stampata a ogni giro, a 9600 baud il programma scende a circa quaranta giri al secondo, mentre stampare solo quando cambia ne conserva migliaia. Se vuoi vedere con certezza che cosa ha stampato la scheda subito prima di bloccarsi o resettarsi, chiama Serial.flush() dopo la riga critica; aspetta che tutto il contenuto del buffer sia stato inviato. Nei programmi più complessi, passare a una struttura a macchina a stati e stampare una sola riga solo quando lo stato cambia rende molto più facile seguire le tracce di un errore.
Uscita seriale su ESP32
Sulle schede ESP32 DevKit, Serial è la UART0 sui pin GPIO 1 (TX) e GPIO 3 (RX), collegata all'USB tramite il chip CP2102 o CH340 della scheda. La velocità abituale è 115200 baud, perché anche la ROM interna del chip stampa all'avvio righe come rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) a questa velocità; se lasci il monitor a 115200, potrai leggere anche queste righe. Il core Arduino per ESP32 offre Serial.printf() e supporta la stampa dei decimali con %f. Le porte seriali aggiuntive Serial1 e Serial2 si possono assegnare ai pin che preferisci; quando colleghi un modulo è comune usare Serial2 su GPIO 16 e 17. Sulle schede con USB integrato come ESP32-S3 ed ESP32-C3, se il monitor seriale resta vuoto, imposta Strumenti > USB CDC On Boot su Enabled. Per vedere gli avvisi del core stesso, scegli Error, Warn, Info, Debug o Verbose nel menu Strumenti > Core Debug Level; nel tuo codice puoi stampare messaggi di log con file e numero di riga usando le macro log_e, log_w e log_i.
1// ESP32: Serial (USB), Serial2 (GPIO16/17), printf ve log
2// ESP32: Serial (USB), Serial2 (GPIO16/17), printf and logging
3const int POT_PIN = 34; // ADC1, yalnız giriş pini / ADC1, input-only pin
4unsigned long sonYazdirma = 0;
5
6void setup() {
7 Serial.begin(115200); // açılış mesajlarıyla aynı hız / same rate as the boot messages
8 delay(500);
9 Serial2.begin(9600, SERIAL_8N1, 16, 17); // RX = GPIO16, TX = GPIO17
10
11 Serial.printf("Model: %s, CPU: %lu MHz\n", ESP.getChipModel(), (unsigned long)ESP.getCpuFreqMHz());
12 Serial.printf("Bos RAM / Free heap: %lu bayt / bytes\n", (unsigned long)ESP.getFreeHeap());
13 log_i("Core Debug Level en az Info ise gorunur / shown when Core Debug Level is Info or higher");
14}
15
16void loop() {
17 while (Serial2.available() > 0) { // Serial2'den geleni USB'ye aktar / forward Serial2 data to USB
18 Serial.write(Serial2.read());
19 }
20
21 if (millis() - sonYazdirma >= 1000) { // delay() yok, tampon taşmaz / no delay(), no buffer overflow
22 sonYazdirma = millis();
23 float volt = analogReadMilliVolts(POT_PIN) / 1000.0; // kalibre gerilim / calibrated voltage
24 Serial.printf("t=%lu ms, GPIO34=%.2f V\n", millis(), volt); // ESP32'de %f çalışır / %f works on ESP32
25 }
26}Con problemi di connessione Wi-Fi, reset inattesi ed errori Guru Meditation, il monitor seriale è il primo posto da guardare: qui compaiono il tipo di errore, la causa del reset e le righe del backtrace. Spieghiamo come interpretare questi messaggi nelle guide ESP32 brownout e Guru Meditation e ESP32 non si connette al Wi-Fi. Se usi l'ESP32 per la prima volta, parti dall'articolo Che cos'è l'ESP32?.
Uscita seriale su Raspberry Pi Pico: Arduino e MicroPython
Il Raspberry Pi Pico non ha un chip ponte USB-seriale; l'RP2040 gestisce da solo l'USB e si presenta al computer direttamente come porta seriale (USB CDC). Nel core Arduino-Pico di Earle Philhower, Serial è questa porta USB e, poiché i dati viaggiano alla velocità dell'USB, il valore di velocità in Serial.begin() viene ignorato. Questo ha due conseguenze: non importa più quale velocità scegli nel monitor, ma la scheda non si resetta come un Uno quando apri il monitor seriale. I primi messaggi stampati in setup() sono già stati inviati e persi quando apri il monitor; quindi aspetta un attimo che il computer apra la porta, come nell'esempio qui sotto. Lo stesso vale per le schede con ATmega32U4 come Leonardo, Micro e Pro Micro. La vera UART del Pico, sui pin GP0 e GP1, si usa con il nome Serial1.
1// Raspberry Pi Pico (Arduino-Pico çekirdeği): USB seri port
2// Raspberry Pi Pico (Arduino-Pico core): USB serial port
3void setup() {
4 Serial.begin(115200); // USB'de hız değeri önemsiz / the baud value is ignored over USB
5 unsigned long baslangic = millis();
6 while (!Serial && millis() - baslangic < 3000) {
7 delay(10); // port açılana kadar en çok 3 sn bekle / wait up to 3 s for the port
8 }
9 Serial1.begin(9600); // UART0: GP0 = TX, GP1 = RX
10 Serial.println("Pico hazir / Pico ready");
11}
12
13void loop() {
14 Serial.print("Sicaklik / Temperature (C): ");
15 Serial.println(analogReadTemp(), 1); // dahili sensör, yaklaşık / internal sensor, approximate
16 Serial1.println(millis()); // aynı anda UART0'a da yaz / also write to UART0
17 delay(1000);
18}In MicroPython è tutto ancora più semplice: tutto ciò che stampi con print() arriva al computer via USB e compare nella Shell di Thonny; non c'è nessun baud rate da impostare. Se apri il menu View > Plotter di Thonny, i numeri delle righe diventano un grafico in tempo reale, come nel Plotter seriale. Per ricevere dati dal computer puoi usare input(), ma input() blocca il programma finché non arriva una riga. Per ascoltare i comandi continuando a misurare, controlla con select.poll() se ci sono dati in attesa su stdin, come nell'esempio qui sotto; basta scrivere on oppure off nella Shell e premere Invio. Il Pico e l'installazione di MicroPython sono spiegati nell'articolo Che cos'è il Raspberry Pi Pico?.
1# Pico MicroPython: print() ile yazdır, programı durdurmadan komut al
2# Pico MicroPython: print with print(), read commands without blocking
3import sys
4import select
5import time
6from machine import ADC, Pin
7
8led = Pin(25, Pin.OUT) # Pico'da dahili LED; Pico W'de Pin("LED") / onboard LED; Pin("LED") on Pico W
9sensor = ADC(4) # dahili sıcaklık sensörü / internal temperature sensor
10poll = select.poll()
11poll.register(sys.stdin, select.POLLIN)
12
13while True:
14 volt = sensor.read_u16() * 3.3 / 65535
15 sicaklik = 27 - (volt - 0.706) / 0.001721
16 print("Sicaklik:{:.1f}".format(sicaklik)) # Thonny Plotter da çizer / Thonny's Plotter can graph it
17 if poll.poll(0): # bekleyen veri var mı? / is input waiting?
18 komut = sys.stdin.readline().strip() # satırı al, boşlukları sil / read the line, strip spaces
19 if komut == "on":
20 led.value(1)
21 elif komut == "off":
22 led.value(0)
23 print("Komut / Command:", komut)
24 time.sleep(1)Monitor seriale vuoto, porta occupata: errori comuni e soluzioni
| Sintomo | Causa | Soluzione |
|---|---|---|
| Lo schermo è completamente vuoto | Manca Serial.begin() oppure è selezionata la porta sbagliata | Aggiungi Serial.begin() in setup() e scegli la porta giusta nel selettore della scheda |
| Non collegato. Scegli una scheda e la porta di comunicazione per una connessione automatica. (Not connected.) | Nessuna porta selezionata nell'IDE o scheda scollegata | Collega la scheda e selezionala nel menu Strumenti > Porta |
| Serial port busy oppure Access is denied | La porta è aperta in un'altra finestra dell'IDE, in PuTTY o in uno script Python | Chiudi il programma che occupa la porta; una porta si apre in un solo programma alla volta |
| Mancano le prime righe su Leonardo o Pico | Una scheda con USB integrato non si resetta all'apertura del monitor | Aspetta un attimo in setup() con while (!Serial) |
| Su ESP32-S3/C3 non compare nulla | USB CDC On Boot è disattivato e l'uscita va ai pin UART | Strumenti > USB CDC On Boot: Enabled |
| Dopo ogni numero arriva anche uno 0 | parseInt va in timeout sul carattere di fine riga | Salta i caratteri che non sono cifre o scegli No Line Ending |
| I confronti dei comandi non coincidono mai | Alla fine del testo è rimasto un '\r' | Applica trim() dopo la lettura |
| La porta non compare mai nell'elenco | Cavo solo di ricarica o driver CH340/CP210x mancante | Usa un cavo dati e installa il driver |
Idee di progetto con la comunicazione seriale
- LED e relè comandati dal computer: amplia il parser di comandi di questo articolo per controllare un relè o un motore con i comandi on, off e blink.
- Registratore di dati dei sensori: stampa temperatura e umidità come righe CSV separate da virgole e trasformale in tabella e grafico sul computer; il DHT11 è un buon sensore per iniziare.
- Grafico della luce in tempo reale: osserva il valore di una fotoresistenza LDR o di un potenziometro nel Plotter seriale e guarda l'effetto del filtro sullo stesso grafico.
- Pannello desktop con Python: leggi i dati inviati da Arduino con un programma Python e crea un'interfaccia con pulsanti; dettagli nell'articolo comunicazione seriale tra Arduino e Python.
- Banco prova per moduli: anche i moduli GPS, Bluetooth e GSM usano una porta seriale; inoltra i dati grezzi del modulo al monitor seriale per verificare che funzioni (HC-05, GPS NEO-6M).
- Prove senza scheda: se non hai una scheda a portata di mano, anche Tinkercad ha un monitor seriale; puoi eseguire il codice di questo articolo in una simulazione Tinkercad.
Quando avrai preso confidenza con il monitor seriale, cercare gli errori su Arduino smetterà di essere un tirare a indovinare e diventerà una questione di misure. Come passo successivo leggi l'articolo comunicazione seriale UART per far dialogare due schede tramite TX e RX, e quello sul convertitore USB-TTL per programmare schede senza USB. Nell'app BlueGrays trovi progetti come la stampa sul monitor seriale della distanza misurata con un HC-SR04, la lettura dell'intensità luminosa con una LDR, la misura di temperatura e umidità con un DHT11 e il collegamento di due Arduino con una linea seriale, passo dopo passo con schemi elettrici e codice pronto all'uso.
Domande frequenti
Come si apre il monitor seriale di Arduino?
Dopo aver caricato il codice, clicca sull'icona della lente in alto a destra nell'Arduino IDE, usa il menu Strumenti > Monitor seriale o premi Ctrl+Maiusc+M. Nell'IDE 2 il monitor si apre nel pannello in basso. Nel selettore della scheda deve essere scelta la porta giusta e il menu della velocità a destra deve coincidere con il valore di Serial.begin() nel codice.
Perché il monitor seriale mostra caratteri strani?
La causa più comune è che il baud rate del monitor seriale è diverso dal valore di Serial.begin() nel codice; appena i due coincidono, il testo torna leggibile. Se è illeggibile solo una riga all'avvio, si tratta del messaggio di avvio dell'ESP8266 o dell'ESP32 ed è normale. Scegliere la frequenza di clock sbagliata su schede come la Pro Mini o collegare un modulo ai pin D0/D1 provoca lo stesso sintomo.
Meglio 9600 o 115200 baud con Arduino?
Funzionano entrambi; l'importante è che codice e monitor seriale usino la stessa velocità. 9600 baud trasportano circa 960 caratteri al secondo e bastano per progetti semplici con l'Uno. Se stampi molti dati o usi un ESP32 o un Pico, scegli 115200: è 12 volte più veloce e la stampa rallenta meno il programma.
Qual è la differenza tra Serial.print e Serial.println?
Serial.print() scrive il valore e lascia il cursore sulla stessa riga; Serial.println() dopo la scrittura aggiunge i caratteri di ritorno carrello e a capo (\r\n). Per mostrare più valori su una riga si usa prima print e alla fine println. La riga deve terminare con println anche perché il Plotter seriale conti ogni riga come un campione distinto.
Perché nel monitor seriale non compare niente?
Per prima cosa controlla che setup() contenga Serial.begin() e che nel selettore della scheda sia scelta la porta giusta. Sulle schede con USB integrato come Leonardo, Pico ed ESP32-S3 i primi messaggi di setup() possono essere inviati e persi prima che il monitor si apra; aggiungi una breve attesa con while (!Serial). Su ESP32-S3 e C3, inoltre, l'opzione USB CDC On Boot del menu Strumenti deve essere su Enabled.
Perché Arduino si resetta quando apro il monitor seriale?
Su Uno, Nano e Mega la linea DTR del chip USB è collegata al pin RESET tramite un condensatore; quando la porta si apre, questa linea genera un breve impulso e la scheda riparte. Questo schema serve a facilitare il caricamento e fa sì che tu non perda i messaggi di setup(). Se non lo vuoi, puoi mettere un condensatore da 10 µF tra RESET e GND, ma devi toglierlo prima di caricare il codice.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
HC-SR04 Misura della distanza (display seriale)
Il sensore HC-SR04 funziona come un pipistrello che trova la strada al buio: manda un suono che non puoi sentire, ne ascolta l'eco e misura quanto è lontano l'oggetto davanti a sé. L'Arduino scrive qu

Misurare l'intensità luminosa con LDR
Vuoi vedere quanto è luminosa la tua stanza sotto forma di numero? L'LDR, un piccolo componente sensibile alla luce, misura la luce ambiente e l'Arduino scrive il valore sullo schermo del computer ogn

Temperatura e umidità con DHT11
Quanti gradi ci sono nella tua stanza, e l'aria è umida o secca? Il sensore DHT11 misura temperatura e umidità, e l'Arduino scrive i valori su uno schermo LCD a due righe, aggiornandoli ogni paio di s

Lettura dell'intensità luminosa con il modulo LDR ESP32
Monitoraggio in tempo reale sul Serial Monitor del valore grezzo dell'ADC del modulo LDR e della percentuale relativa di luce calcolata dai valori di riferimento al buio e alla luce. Questa percentuale non è una misurazione in lux. Spiega il principio di calibrazione del modulo. È consigliabile eseguirlo prima del Progetto 10, poiché serve a determinare il valore di soglia.

Leggere i codici di un telecomando IR
Ogni tasto del telecomando della TV invia un codice segreto con una luce che non puoi vedere. Il ricevitore a infrarossi cattura quella luce e l'Arduino scrive sullo schermo del computer il codice di

Lettura del valore RFID
Il portachiavi del condominio o la tessera d'ingresso nascondono un numero di identificazione segreto, e questo progetto lo legge. Avvicina la tessera al lettore RFID e l'Arduino scrive il suo numero

Comunicazione unidirezionale tra 2 Arduino
Fai parlare due Arduino con un solo filo: premi il pulsante sull'uno e il LED dell'altro si accende, premi di nuovo e si spegne. La scheda che invia segnala la pressione con un breve messaggio, e quel

Comunicazione bidirezionale tra 2 Arduino
Due Arduino collegati con dei fili parlano tra loro: premi il pulsante di uno e si accende la luce dell'altro, premilo di nuovo e si spegne. Entrambe le schede hanno lo stesso programma, quindi ognuna
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

