Guide · 17 min di lettura

Arduino si resetta da solo o si blocca: cause e soluzioni

Arduino si resetta da solo o si blocca? Corrente di servo e relè, cali di tensione, GND comune, condensatore da 470 µF, RAM piena e watchdog, passo dopo passo.

Se il tuo Arduino si resetta da solo o si blocca dopo aver funzionato per un po', la scheda non è quasi mai guasta. Nella maggior parte dei casi la causa è l'alimentazione: quando un servo inizia a muoversi, un motore parte o un relè si eccita, la corrente improvvisa fa crollare per un attimo la linea a 5 V e la protezione contro la sottotensione del processore (brown-out) riavvia la scheda. Negli altri casi i colpevoli sono i disturbi elettrici di relè e motori, i cavi lunghi, la RAM piena, un watchdog dimenticato o una porta USB del computer che non fornisce abbastanza corrente.

In questa guida imparerai prima a capire se la scheda si riavvia davvero o se si blocca soltanto. Poi spiegheremo come funziona ogni causa con valori reali di corrente e tensione e ti mostreremo le soluzioni con il codice: alimentazione separata e GND comune, condensatori da 100–470 µF, diodi di ricircolo, buffer fissi al posto di String e il watchdog. Troverai anche uno sketch di diagnosi che misura la tensione di alimentazione e la RAM libera dell'Arduino stesso, una tabella passo passo dal sintomo alla soluzione ed esempi che leggono il motivo del reset su ESP32 e Raspberry Pi Pico.

Scheda Arduino Uno R3
Arduino Uno R3: i 5 V dell'USB passano attraverso un fusibile autoripristinante da 500 mA. Quando la scheda si resetta, il programma riparte da setup(); il pulsante RESET e il pin RESET fanno la stessa cosa.

Reset o blocco? Riconosci prima il sintomo

Un Arduino che si resetta esegue il programma dall'inizio, come se avessi scollegato e ricollegato il cavo USB: setup() viene eseguito di nuovo, il servo torna all'angolo iniziale, l'LCD mostra di nuovo il testo di avvio e il messaggio di avvio ricompare nel Monitor seriale. Un Arduino bloccato, invece, non risponde più a nulla; i LED restano nell'ultimo stato, l'uscita seriale si interrompe e la scheda rimane così finché non premi il pulsante di reset. Dato che cause e soluzioni sono diverse, comincia col capire quale dei due casi hai. Il modo più semplice è aggiungere in setup() una riga Serial.println("AVVIO") e lasciare aperto il Monitor seriale.

SintomoResetBlocco
setup() viene eseguito di nuovo?Sì, il messaggio di avvio ricompareNo
Uscita serialeSi interrompe e riparte con il messaggio di avvioSi interrompe e non ritorna
Uscite e LEDSi spengono un attimo e tornano allo stato inizialeRestano fermi nell'ultimo stato
Causa più frequenteCalo di tensione, disturbi, watchdogCiclo infinito, bus I2C bloccato, RAM corrotta
Cosa controllare primaAlimentazione, GND e cablaggioCodice, uso della memoria e cavi dei sensori

Perché Arduino si resetta da solo? Le sorgenti di reset

Solo poche sorgenti possono riavviare il processore ATmega328P di Arduino Uno e Nano, e ognuna ha il suo innesco. Quando la tensione di alimentazione scende sotto una certa soglia interviene il rilevatore di brown-out (BOD); su Uno e Nano i fuse di configurazione fissano questa soglia a 2,7 V. Anche tutto ciò che porta il pin RESET a LOW riavvia la scheda: il pulsante di reset, il segnale DTR del computer o i disturbi captati da un cavo lungo collegato a quel pin. C'è poi un caso che sembra un reset ma non lo è: a causa della memoria corrotta il programma salta all'indirizzo 0 e il codice riparte da capo, ma poiché le periferiche hardware non vengono azzerate, la scheda comincia a comportarsi in modo strano.

Sorgente di resetCosa la provoca?Sintomo tipico
Accensione (POR)Collegare il cavo, l'alimentazione che sparisce del tuttoAvvio normale
Reset esterno (pin RESET)Pulsante di reset, apertura del Monitor seriale (DTR), disturbi sul pin RESETRiparte da zero quando si apre la porta o si tocca un cavo
Brown-out (BOD, 2,7 V)Picco di corrente di servo, motore, relè o striscia LED, batteria scaricaReset proprio quando il carico si muove
Watchdogwdt_reset() non è stato chiamato in tempoReset a intervalli regolari (ad es. ogni 2 secondi esatti)
Crash del softwareUscita dai limiti di un array, RAM esaurita, puntatore erratoReset o blocco casuale dopo minuti od ore

Corrente di servo, motori e relè: come un calo di tensione provoca il reset

Un servo SG90 assorbe 100–250 mA mentre si muove, ma all'avvio e quando il braccio è sotto sforzo la corrente sale oltre 0,5 A. La porta USB 2.0 di un computer fornisce al massimo 500 mA, e il fusibile sulla linea USB di Arduino Uno lavora allo stesso limite. Quando il servo, i 50 mA della scheda e qualche modulo superano questo limite, la porta o il fusibile limitano la corrente, la linea a 5 V crolla per un istante e, se la tensione scende sotto 2,7 V, il BOD riavvia la scheda. Il caso più subdolo è quando la tensione resta tra 2,7 V e circa 3,8 V: secondo il datasheet dell'ATmega328P, servono circa 3,8 V per funzionare in sicurezza a 16 MHz. In questa zona grigia il BOD non interviene, ma il processore lavora oltre il suo limite di velocità; la scheda può quindi bloccarsi invece di resettarsi, fornire valori assurdi, oppure display e sensori I2C possono bloccarsi internamente.

CaricoCorrente normaleCorrente di piccoAlimentabile dal pin 5V di Uno?
Micro servo SG90100–250 mA0,5 A e oltre (avvio, sforzo)Solo un servo e con carico leggero
Servo MG996R0,5–0,9 AFino a 2,5 ANo, serve un alimentatore separato da 5–6 V
Motore DC con riduttore TT70–250 mA~1 A (avvio, stallo)No, driver motore e alimentazione separata
Modulo relè 5 V (un canale)70–90 mABreve picco quando la bobina si eccita1–2 canali sì, da 4 in su con alimentazione separata
LED WS2812B (ciascuno)~20 mA (un colore al massimo)60 mA (bianco pieno)No; 30 LED in bianco pieno chiedono 1,8 A

Contano anche i cavi. I cavetti jumper sottili usati sulla breadboard sono di solito da 26–28 AWG, e un filo di rame da 28 AWG ha una resistenza di circa 0,21 Ω al metro. Se alimenti il servo con due cavetti da 20 cm (0,4 m tra andata e ritorno) passando per una breadboard, i cavi aggiungono circa 0,085 Ω e quattro contatti della breadboard circa 0,2 Ω in totale. Per la legge di Ohm (V = I × R), un picco di 1 A del servo perde circa 0,3 V su questi 0,29 Ω. Un cavo USB sottile e lungo, il fusibile e i componenti di protezione della scheda aggiungono circa un altro mezzo ohm; durante lo stesso picco la linea a 5 V di Arduino scende sotto 4,5 V, e se la porta del computer comincia a limitare la corrente, il calo è molto più profondo. Puoi calcolare la caduta nel tuo circuito con il calcolatore della legge di Ohm.

Dal pin 5V di Arduino Uno alimenta al massimo un solo servo SG90, e con carico leggero. Non collegare mai servo grandi come l'MG996R, motori DC o strisce LED al pin 5V o 3.3V di Arduino: la scheda si resetterà e, alla lunga, il fusibile USB, il regolatore e persino la porta USB del computer possono danneggiarsi.

Soluzione 1: alimentazione separata e GND comune

  1. Scegli un'alimentazione separata per servo e motori: per i servo, un alimentatore da 5–6 V che fornisca almeno 1 A per servo (2–3 A per un MG996R), un pacco da 4 pile AA NiMH o un modulo step-down LM2596 regolato a 5–6 V.
  2. Collega il positivo dell'alimentazione solo ai fili rossi dei servo o all'ingresso di potenza del driver motore; non portare questa linea al pin 5V di Arduino.
  3. Collega il negativo (GND) dell'alimentazione sia al carico sia al pin GND di Arduino. Senza questa GND comune la tensione del pin di segnale non ha riferimento; il servo trema o non si muove affatto.
  4. Unisci le GND in un solo punto vicino all'alimentazione (massa a stella). La corrente del motore non deve tornare passando per Arduino e le sue piste di massa; altrimenti la GND di Arduino oscilla a ogni picco del motore.
  5. Alimenta Arduino dal suo ingresso: USB, jack DC (7–12 V) o 5 V stabilizzati. Così il processore non ne risente anche se l'alimentazione dei servo crolla.
  6. Infine misura tra i pin 5V e GND di Arduino mentre il servo si muove, oppure esegui lo sketch di diagnosi qui sotto; la tensione non deve scendere sotto 4,75 V.
Modulo step-down LM2596
Modulo step-down LM2596: con il suo trimmer abbassa una tensione più alta, come quella di un alimentatore da 12 V o di un pacco Li-ion 2S, a 5–6 V; è il modo più pratico per creare una linea di alimentazione dei servo indipendente da Arduino. Regola l'uscita con il multimetro prima di collegare il carico.
Spieghiamo perché la GND comune è indispensabile e come funziona la massa a stella in Cos'è il GND?, e come scegliere pile e alimentatori nella guida per alimentare Arduino a batteria. La regola è semplice: i cavi di segnale partono da Arduino, quelli di alimentazione dalla sorgente, e le GND si uniscono.

Soluzione 2: condensatore (100–470 µF) e diodo

Un condensatore elettrolitico funziona come un piccolo serbatoio di energia accanto al carico: quando il servo chiede una corrente improvvisa, la fornisce lui finché cavi e alimentatore non recuperano. Quanto aiuta lo dice la formula ΔV = I × Δt / C. Un condensatore da 470 µF lascia scendere la tensione di soli 0,21 V durante un picco di 1 A che dura 100 µs; se lo stesso picco dura 1 ms, il calo è di 2,1 V. In altre parole, il condensatore assorbe i picchi brevi e il rumore delle spazzole dei motori, ma non sostituisce un alimentatore insufficiente. Metti 470–1000 µF sulla linea dei servo e 100 µF tra 5V e GND di Arduino, e aggiungi accanto a ciascuno un condensatore ceramico da 100 nF con la sigla 104 contro i disturbi ad alta frequenza. Per leggere le sigle usa lo strumento codice dei condensatori, per sommare condensatori in parallelo il calcolatore di reti di condensatori; le differenze tra i tipi sono spiegate in Cos'è un condensatore?.

Dove?ValorePerché?
Linea di alimentazione del servo, vicino al servo470–1000 µF / 10–16 V elettrolitico + 100 nFSmorza il picco di avvio
Tra i due terminali di un motore DC100 nF ceramicoFiltra i disturbi delle scintille delle spazzole
Tra 5V e GND di Arduino100 µF elettrolitico + 100 nFProtegge la linea del processore dai cali brevi
Ingresso di una striscia WS2812B1000 µF / 10 VAssorbe la corrente di accensione e i picchi nei cambi di colore
Pin di alimentazione di sensori e moduli100 nF ceramicoFiltra i disturbi portati dai cavi lunghi
Condensatori elettrolitici di vari valori
Condensatori elettrolitici: un valore come 470 µF / 16 V è ideale per una linea servo a 5 V. La striscia sul corpo indica il terminale negativo (−); la tensione nominale deve essere almeno il doppio di quella della linea.

Bobine dei relè, motori e solenoidi sono induttanze. Quando la corrente che le attraversa viene interrotta di colpo, la bobina si oppone al cambiamento e genera ai suoi capi un breve picco di tensione di decine o persino centinaia di volt, ben oltre la tensione di alimentazione. Questo picco si propaga sulla linea e resetta Arduino, e può anche distruggere il transistor di comando o il pin. La soluzione è un diodo di ricircolo (flyback) collegato in parallelo alla bobina e in senso inverso: il catodo di un 1N4007, il lato con la fascetta, va al positivo e l'altro capo al lato che va verso il transistor. I moduli relè pronti hanno già questo diodo; se usi un relè nudo, un solenoide o un motore comandato da un transistor o da un MOSFET, devi aggiungerlo tu. Per i motori con controllo di velocità in PWM, il diodo Schottky 1N5819, più veloce, dà risultati migliori. Trovi i dettagli in Cos'è un diodo? e in usare un MOSFET con Arduino.

Diodo raddrizzatore 1N4007
Diodo 1N4007: la fascetta grigia sul corpo indica il catodo (−). Collegato al contrario in parallelo a una bobina, cortocircuita e spegne il picco di tensione che nasce quando la corrente viene interrotta.

Disturbi, contatti dei relè e cavi lunghi

Se la scheda si resetta proprio quando un relè si diseccita, il problema sono i disturbi e non l'alimentazione. Quando un relè spegne una pompa dell'acqua, una ventola, una lampada fluorescente o un contattore, tra i contatti si forma un piccolo arco che irradia disturbi elettromagnetici a banda larga. Questi disturbi si accoppiano ai cavi dei sensori vicini, alla linea RESET e alle linee I2C, riavviando il processore o bloccando un modulo. Per evitarlo usa un modulo relè con fotoaccoppiatore, togli il ponticello JD-VCC e alimenta le bobine dei relè con una sorgente a 5 V separata; così la corrente delle bobine e i disturbi restano lontani dalla linea di Arduino. Con carichi induttivi collegati alla rete, uno snubber RC (100 Ω + 100 nF, classe X2) o un varistore sui contatti o sul carico attenua molto l'arco. Trovi i collegamenti in Cos'è un modulo relè? e il principio dell'isolamento in Cos'è un fotoaccoppiatore?.

  • I2C corto: l'I2C è nato per brevi distanze su un circuito stampato. Tieni i cavi SDA e SCL sotto i 50 cm; su tratte più lunghe scendi con le resistenze di pull-up da 4,7 kΩ a 2,2 kΩ e lascia la velocità a 100 kHz.
  • Cavi intrecciati: intreccia ogni cavo di segnale con un cavo di GND; le coppie intrecciate di un cavo di rete sono ideali.
  • Separa potenza e segnale: non far correre i cavi dei sensori in parallelo a quelli di motori, relè o rete elettrica; se devono incrociarsi, fallo ad angolo retto.
  • Lascia libero il pin RESET: un cavo lungo sul pin RESET si comporta come un'antenna e resetta la scheda quando lo tocchi o quando un motore vicino è in funzione. Se ti serve un pulsante di reset esterno, usa un cavo corto.
  • Ferriti e contenitore: anelli di ferrite sui cavi dei motori e un contenitore metallico riducono i disturbi ad alta frequenza.
  • Imposta un timeout: se i disturbi bloccano il bus I2C, la libreria Wire per impostazione predefinita aspetta all'infinito e la scheda si blocca. Il codice qui sotto evita il blocco con un timeout.
C++ (Arduino IDE)
1#include <Wire.h>
2
3const uint8_t ADDR = 0x27;   // örnek: I2C LCD adresi / example: I2C LCD address
4
5void setup() {
6  Serial.begin(9600);
7  Wire.begin();
8  Wire.setWireTimeout(25000, true);   // 25 ms; takılırsa I2C birimini sıfırla / reset the I2C unit on timeout
9}
10
11void loop() {
12  Wire.beginTransmission(ADDR);
13  byte err = Wire.endTransmission();  // 0 = cihaz cevap verdi / 0 = device answered
14
15  if (Wire.getWireTimeoutFlag()) {    // hat kilitlendi ama program donmadı / bus hung, sketch did not freeze
16    Serial.println(F("I2C zaman asimi / I2C timeout"));
17    Wire.clearWireTimeoutFlag();
18  } else if (err != 0) {
19    Serial.print(F("I2C hatasi / I2C error: "));
20    Serial.println(err);              // 2 = cihaz yok, 5 = zaman aşımı / 2 = no device, 5 = timeout
21  }
22  delay(1000);
23}

RAM esaurita e uso di String

Arduino Uno ha solo 2 KB di SRAM, e questo piccolo spazio è condiviso da variabili globali, memoria dinamica (heap) e stack usato dalle chiamate di funzione. Se al termine della compilazione vedi l'avviso Low memory available, stability problems may occur., molto probabilmente la scheda andrà in crash dopo un po'. La causa più subdola è la classe String: ogni concatenazione alloca un nuovo pezzo nello heap, il vecchio viene liberato e con il tempo la memoria si riempie di buchi. Un giorno lo stack si scontra con lo heap e il programma si resetta o si blocca in un momento casuale. Poiché il problema compare di solito dopo minuti od ore, è facile distinguerlo da quelli di alimentazione. Lascia i testi costanti nella flash con la macro F(), usa array di char di dimensione fissa e snprintf() al posto di String e non dichiarare grandi array locali dentro le funzioni. Il codice qui sotto stampa la RAM libera ogni secondo; se il valore continua a scendere, c'è una perdita di memoria. Tutto l'argomento è in Arduino: memoria insufficiente.

C++ (Arduino IDE)
1extern int __heap_start, *__brkval;
2
3// Heap ile stack arasındaki boş RAM / free RAM between heap and stack
4int freeRam() {
5  int v;
6  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
7}
8
9char line[32];             // sabit tampon, bir kez ayrılır / fixed buffer, allocated once
10unsigned long counter = 0;
11
12void setup() {
13  Serial.begin(9600);
14}
15
16void loop() {
17  counter++;
18  // Kaçın / avoid: String s = "Sayac: " + String(counter) + " sn";
19  snprintf(line, sizeof(line), "Sayac: %lu sn", counter);  // heap kullanmaz / no heap use
20  Serial.println(line);
21
22  Serial.print(F("Bos RAM / free RAM: "));  // F(): metin flaşta kalır / text stays in flash
23  Serial.println(freeRam());                // sürekli azalıyorsa sızıntı var / steady drop = leak
24  delay(1000);
25}

Watchdog: la cintura di sicurezza contro i blocchi

Il watchdog è un contatore interno al processore che funziona in modo indipendente con un proprio oscillatore a 128 kHz. Il programma deve ricaricarlo regolarmente con wdt_reset(); se non lo fa entro il tempo impostato (tra 15 ms e 8 secondi), il watchdog resetta la scheda. Così un bus I2C bloccato, una funzione intrappolata in un ciclo infinito o una lettura del sensore rovinata dai disturbi non possono bloccare la scheda per sempre; si riprende in pochi secondi. Ricorda che il watchdog è una cintura di sicurezza, non una riparazione: non risolve problemi di alimentazione o di memoria, permette solo a un progetto installato sul campo di ripartire da solo. Scegli un tempo nettamente più lungo dell'operazione più lunga del tuo codice; con un delay(3000) nel codice, un watchdog da 2 secondi resetterà la scheda in continuazione.

C++ (Arduino IDE)
1#include <avr/wdt.h>
2
3const int LED_PIN = 13;
4
5void setup() {
6  MCUSR = 0;          // reset bayraklarını temizle / clear reset flags
7  wdt_disable();      // açılışta watchdog kapalı / watchdog off during startup
8  Serial.begin(9600);
9  pinMode(LED_PIN, OUTPUT);
10  Serial.println(F("Basladi / started"));
11  delay(500);
12  wdt_enable(WDTO_2S);  // 2 sn içinde beslenmezse reset / reset if not fed within 2 s
13}
14
15void loop() {
16  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
17  delay(250);
18
19  // Seri Monitör'den 'x' gönder: takılmayı taklit eder / send 'x' to simulate a hang
20  if (Serial.available() && Serial.read() == 'x') {
21    Serial.println(F("Sonsuz donguye girildi / stuck in a loop"));
22    while (true) {}     // wdt_reset() yok: 2 sn sonra reset / no wdt_reset(): reset after 2 s
23  }
24
25  wdt_reset();          // her turda besle / feed it every loop
26}
Sui cloni di Nano con il vecchio bootloader il watchdog è pericoloso. Questo bootloader non spegne il timer dopo un reset del watchdog; il timer continua a girare con il periodo più breve (circa 16 ms) e il bootloader non riesce a finire il suo lavoro in quel tempo. Il risultato è un ciclo infinito di reset in cui il tuo codice non parte mai; la scheda si sblocca solo scollegando e ricollegando il cavo USB, e il ciclo ricomincia alla prima attivazione del watchdog. Se per la tua scheda devi scegliere ATmega328P (Old Bootloader) in Strumenti > Processore, scrivi il bootloader Optiboot prima di usare il watchdog; spieghiamo come in errore di caricamento su Arduino. Il bootloader Optiboot di Arduino Uno non ha questo problema.

Sketch di diagnosi: Arduino misura da solo la sua tensione e la sua RAM

Un multimetro è troppo lento per vedere cali di tensione di pochi millisecondi. Al suo posto puoi usare Arduino stesso come un semplice strumento di misura: il codice qui sotto misura con l'ADC il riferimento interno da 1,1 V del chip e ne ricava la tensione di alimentazione circa 9000 volte al secondo, e stampa il valore più basso di ogni secondo. Inoltre a ogni avvio incrementa un contatore nella EEPROM, così anche se apri il Monitor seriale più tardi vedi quante volte la scheda si è riavviata. Come carico di prova muove il servo su D9 tra 0 e 180 gradi ogni 2 secondi; se hai già un tuo progetto, puoi aggiungere la parte di misura al suo codice. Apri il Monitor seriale a 115200 baud.

C++ (Arduino IDE)
1// Reset teşhis kodu (Uno, Nano) / reset diagnostic sketch (Uno, Nano)
2#include <EEPROM.h>
3#include <Servo.h>
4
5Servo servo;
6extern int __heap_start, *__brkval;
7
8int freeRam() {
9  int v;
10  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
11}
12
13// Besleme gerilimini dahili 1,1 V referansla ölç / measure supply voltage against the internal 1.1 V reference
14long readVcc() {
15  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
16  ADCSRA |= _BV(ADSC);                  // ölçümü başlat / start a conversion
17  while (bit_is_set(ADCSRA, ADSC)) {}   // bitmesini bekle / wait until it is done
18  return 1125300L / ADC;                // 1100 mV × 1023 / okuma → mV / reading → mV
19}
20
21long minVcc = 9999;
22unsigned long lastPrint = 0, lastMove = 0;
23bool sideA = false;
24
25void setup() {
26  Serial.begin(115200);
27  uint16_t boots;
28  EEPROM.get(0, boots);                 // açılış sayacı / boot counter
29  if (boots == 0xFFFF) boots = 0;       // boş EEPROM / blank EEPROM
30  EEPROM.put(0, ++boots);
31  Serial.print(F("BASLADI / STARTED  acilis no / boot #"));
32  Serial.println(boots);
33
34  servo.attach(9);                      // test yükü: servo D9'da / test load: servo on D9
35  readVcc();                            // ilk ölçümü at / discard the first reading
36  delay(5);
37}
38
39void loop() {
40  long v = readVcc();                   // saniyede ~9000 ölçüm / ~9000 samples per second
41  if (v < minVcc) minVcc = v;
42
43  if (millis() - lastMove >= 2000) {    // 2 sn'de bir servoyu oynat / move the servo every 2 s
44    lastMove = millis();
45    sideA = !sideA;
46    servo.write(sideA ? 180 : 0);
47  }
48
49  if (millis() - lastPrint >= 1000) {
50    lastPrint = millis();
51    Serial.print(F("sn/s: "));
52    Serial.print(millis() / 1000);
53    Serial.print(F("  min Vcc (mV): "));
54    Serial.print(minVcc);
55    Serial.print(F("  bos RAM / free RAM: "));
56    Serial.println(freeRam());
57    minVcc = 9999;                      // her saniye sıfırla / reset every second
58  }
59}

Leggi i risultati così: su un Arduino Uno sano alimentato da USB, il valore minimo resta tra 4,6 e 5,1 V. Se scende sotto 4,5 V a ogni movimento del servo e i reset coincidono con quei momenti, il problema è l'alimentazione. Se il numero di avvio continua a salire mentre la tensione resta stabile, cerca la causa nei disturbi o nel software; se intanto la RAM libera continua a diminuire, c'è una perdita di memoria. Il riferimento interno da 1,1 V può variare di circa il 10 % da chip a chip, quindi confronta una volta la misura con un multimetro: se il multimetro indica 4,95 V e il codice 5,10 V, cambia la costante 1125300 in 1125300 × 4,95 / 5,10 ≈ 1092200. Finita la diagnosi, togli il contatore EEPROM dal codice; le celle della EEPROM reggono circa 100.000 scritture.

Tabella di diagnosi passo passo: sintomo, causa, soluzione

Leggi la tabella dall'alto in basso; le prime righe sono le cause più frequenti. Cambia una sola cosa alla volta ed esegui di nuovo lo sketch di diagnosi. Se cambi tre cose insieme non saprai quale ha risolto il problema, e lo stesso guasto si ripresenterà nel prossimo progetto.

SintomoCausa probabileCome verificarloSoluzione
Reset quando si muove un servo o un motoreIl picco di corrente fa crollare la linea a 5 VLa tensione minima nello sketch di diagnosi scende sotto 4,5 VAlimentazione 5–6 V separata, GND comune, 470–1000 µF
Reset quando il relè si diseccita, non quando si eccitaArco sui contatti e picco della bobina (disturbi)Il problema sparisce togliendo il carico del relèAlimentazione separata con JD-VCC, snubber o varistore, diodo di ricircolo
Riparte da zero quando si apre il Monitor serialeAuto-reset tramite DTR (comportamento normale)Il messaggio di avvio compare a ogni apertura della portaNon è un guasto; se serve, 10 µF tra RESET e GND
Reset solo sul computer, con l'alimentatore tutto beneLa porta USB o l'hub non forniscono abbastanza correnteSi risolve con un'altra porta e un cavo corto e spessoPorta posteriore o hub alimentato, carichi con alimentazione separata
Con la batteria da 9 V si resetta durante i movimentiResistenza interna alta, la tensione crollaVin scende sotto 7 V durante il movimento6 pile AA o pacco 2S 18650
Reset o blocco dopo minuti od oreRAM esaurita, frammentazione da StringLa RAM libera cala a poco a pocoF(), array di char, snprintf, array locali piccoli
Reset a intervalli perfettamente regolariIl watchdog non viene ricaricato in tempoL'intervallo coincide con il tempo del watchdogAggiungi wdt_reset() o allunga il tempo, evita delay() lunghi
Su un Nano il codice non parte più dopo un reset del watchdogBug del watchdog del vecchio bootloaderLa scheda si programma solo con Old BootloaderScrivi il bootloader Optiboot
Blocchi casuali con un cavo del sensore lungoIl bus I2C si blocca per i disturbiIl flag di timeout di Wire è attivoCavi corti e intrecciati, pull-up da 2,2 kΩ, setWireTimeout, watchdog
Reset avvicinando la mano o toccando la schedaCavo lungo sul pin RESET, elettricità staticaSi risolve togliendo il cavoLinea RESET corta, circuito in un contenitore
Il regolatore scalda molto e poi la scheda si resettaCorrente alta con 12 V sul jack, protezione termicaIl regolatore scotta al tattoAlimentatore da 7–9 V o modulo step-down a 5 V
La scheda non si accende o la porta sparisceCortocircuito, è scattato il fusibile USBSenza i moduli la scheda si accendeTrova il cortocircuito e controlla se la scheda è danneggiata

La porta USB non dà abbastanza corrente e il reset del Monitor seriale

Una porta USB 2.0 fornisce 500 mA e una USB 3.0 900 mA; ma poiché il fusibile USB di Arduino Uno limita a 500 mA, una porta USB 3.0 non ti dà corrente in più. Un hub USB non alimentato divide la corrente di una sola porta tra tutti i dispositivi, le porte frontali del case perdono tensione per i sottili cavi interni e i portatili a batteria possono alimentare debolmente le porte in modalità risparmio energetico. Collega la scheda direttamente a una porta posteriore con un cavo corto e di buona qualità. Esiste anche un reset che non è un guasto: Uno e Nano si resettano tramite il segnale DTR quando il Monitor seriale o un programma Python apre la porta, ed è proprio questa funzione a rendere possibile il caricamento dello sketch. Se comunichi da Python, aspetta 2 secondi dopo aver aperto la porta (comunicazione seriale tra Arduino e Python). Se vuoi disattivare del tutto il reset, metti un condensatore da 10 µF tra RESET e GND e toglilo quando carichi lo sketch. I dettagli sulla porta seriale sono in Monitor seriale di Arduino.

ESP32 si resetta da solo: leggere il motivo del reset

L'ESP32 è ancora più sensibile agli stessi problemi, perché funziona a 3,3 V e assorbe circa 240 mA durante la trasmissione Wi-Fi, di più nei picchi brevi; Espressif consiglia un'alimentazione in grado di fornire almeno 500 mA. La buona notizia è che l'ESP32 ti dice da solo perché si è riavviato. Il messaggio Brownout detector was triggered nel Monitor seriale indica un calo di tensione, mentre le righe rst:0xf (RTCWDT_BROWN_OUT_RESET) o Guru Meditation Error all'avvio mostrano il motivo del reset. Il codice qui sotto legge la stessa informazione con esp_reset_reason() e la trasforma in un testo leggibile. Sull'ESP32 il pulsante EN spegne e riaccende completamente il chip, quindi anche un reset con questo pulsante risulta come un'accensione. Tutti i messaggi e le relative soluzioni sono in ESP32: errori brownout e Guru Meditation.

C++ (Arduino IDE)
1#include <esp_system.h>
2
3// Reset sebebini yazıya çevir / turn the reset reason into text
4const char* reasonText(esp_reset_reason_t r) {
5  switch (r) {
6    case ESP_RST_POWERON:   return "Guc acilisi ya da EN tusu / power-on or EN button";
7    case ESP_RST_SW:        return "Yazilimla (ESP.restart) / software restart";
8    case ESP_RST_PANIC:     return "Cokme (Guru Meditation) / panic";
9    case ESP_RST_INT_WDT:   return "Kesme watchdog'u / interrupt watchdog";
10    case ESP_RST_TASK_WDT:  return "Gorev watchdog'u / task watchdog";
11    case ESP_RST_WDT:       return "Diger watchdog / other watchdog";
12    case ESP_RST_DEEPSLEEP: return "Derin uykudan uyanma / deep sleep wake-up";
13    case ESP_RST_BROWNOUT:  return "Gerilim dusmesi (brownout) / brownout";
14    default:                return "Bilinmeyen / unknown";
15  }
16}
17
18void setup() {
19  Serial.begin(115200);
20  delay(500);
21  esp_reset_reason_t r = esp_reset_reason();
22  Serial.print("Reset nedeni / reset reason: ");
23  Serial.println(reasonText(r));
24}
25
26void loop() {
27  Serial.print("Calisma suresi / uptime (s): ");
28  Serial.println(millis() / 1000);
29  delay(5000);
30}

Raspberry Pi Pico: motivo del reset e watchdog (MicroPython)

Grazie al suo regolatore buck-boost, il Raspberry Pi Pico funziona con qualsiasi tensione tra 1,8 e 5,5 V sul pin VSYS, quindi sopporta i cali di tensione meglio di un Arduino. Tuttavia, se colleghi un servo al pin VBUS, che porta i 5 V dell'USB, la corrente viene prelevata direttamente dalla porta del computer e, se la porta crolla, si spegne anche il Pico; inoltre non dovresti prelevare più di 300 mA in totale dal pin 3V3. Il pin di reset del Pico, RUN, è tenuto alto da una resistenza interna al chip di circa 50 kΩ; collegarci un cavo lungo apre la porta ai disturbi, proprio come il pin RESET di Arduino. In MicroPython, machine.reset_cause() sul Pico restituisce solo due valori: PWRON_RESET per l'accensione o il pin RUN e WDT_RESET per il watchdog o machine.reset(). Il watchdog si può impostare al massimo a 8388 ms e, una volta avviato, non si può più fermare; continua a resettare la scheda anche se fermi il programma in Thonny. Per questo conviene mettere un'attesa di 3 secondi all'inizio del codice.

MicroPython
1import machine, time
2from machine import Pin
3
4time.sleep(3)   # Thonny durdurabilsin diye bekle / wait so Thonny can stop the script
5
6neden = machine.reset_cause()
7if neden == machine.WDT_RESET:
8    print("Watchdog ya da machine.reset() / watchdog or machine.reset()")
9else:
10    print("Guc acilisi ya da RUN pini / power-on or RUN pin")
11
12led = Pin("LED", Pin.OUT)          # Pico ve Pico W dahili LED / onboard LED
13wdt = machine.WDT(timeout=5000)    # 5 sn; RP2040'ta en fazla 8388 ms / max 8388 ms on RP2040
14
15sayac = 0
16while True:
17    led.toggle()
18    sayac += 1
19    print("Calisiyor / running", sayac)
20    wdt.feed()                     # her turda besle / feed it every loop
21    time.sleep(1)

L'alimentazione giusta per ogni progetto

  • Auto robot: alimenta i motori con un pacco 2S 18650 tramite un L298N o un L9110S e metti un condensatore da 100 nF sui terminali di ogni motore; il montaggio è in costruire un'auto robot con Arduino.
  • Braccio robotico con servo: per quattro servo o più usa un alimentatore da 5–6 V che fornisca almeno 3–5 A e aggiungi 1000 µF sulla linea dei servo; per la scelta vedi servo MG996R e braccio robotico con Arduino.
  • Irrigazione con pompa e relè: alimenta la pompa a parte, isola il relè con JD-VCC e tieni i cavi lunghi dei sensori lontani dal cavo della pompa (sensore di umidità del terreno).
  • Strisce LED e NeoPixel: calcola circa 2 A ogni 30 LED, metti 1000 µF all'ingresso della striscia e una resistenza da 300–500 Ω sulla linea dati (WS2812B NeoPixel).
  • Comando di motori DC: non dimenticare il diodo di ricircolo su ogni motore comandato con un transistor o un MOSFET; per le schede driver già pronte vedi controllo di motori DC con L298N.
  • Stazione di sensori all'aperto: attiva il watchdog, imposta un timeout I2C e prendi l'alimentazione da una sorgente efficiente come lo step-down LM2596.

Un Arduino che si resetta da solo è frustrante, ma c'è quasi sempre una causa misurabile e risolvibile: prima riconosci il sintomo, poi misura tensione e RAM con lo sketch di diagnosi, separa l'alimentazione, unisci le GND, aggiungi condensatore e diodo e, se serve, metti in sicurezza il progetto con il watchdog. Una volta sistemato tutto, i tuoi progetti con servo, motori e relè funzioneranno per giorni senza problemi. Nell'app BlueGrays trovi il controllo dei servomotori, un'auto Bluetooth con L298N, un robot che evita gli ostacoli, il comando di una lampadina a 230 V e una stazione di irrigazione intelligente, con schemi che mostrano i collegamenti di alimentazione corretti e codice passo passo.

Domande frequenti

Perché il mio Arduino si resetta da solo?

La causa più frequente è la corrente improvvisa di un servo, di un motore o di un relè, che fa crollare per un attimo la linea a 5 V; la protezione contro la sottotensione a 2,7 V del processore riavvia così la scheda. Anche i disturbi dei contatti dei relè, la RAM esaurita, un watchdog non ricaricato e una porta USB che non dà abbastanza corrente provocano reset. Alimentare servo e motori a parte e unire le GND risolve la maggior parte dei casi.

Perché Arduino si resetta quando il servo si muove?

Anche un piccolo servo SG90 assorbe più di 0,5 A all'avvio e, insieme agli altri carichi della scheda, supera il limite della porta USB e del fusibile da 500 mA di Arduino Uno. Quando la tensione crolla, la scheda si resetta. Alimenta il servo con una sorgente separata da 5–6 V, collega la sua GND a quella di Arduino e aggiungi un condensatore da 470–1000 µF sulla linea del servo.

Perché Arduino si resetta quando scatta il relè?

La bobina del relè assorbe un picco di corrente quando si eccita, e quando si diseccita bobina e contatti generano disturbi. Soprattutto l'arco che si forma spegnendo carichi induttivi come pompe, ventole o lampade fluorescenti può resettare Arduino. Su un modulo con fotoaccoppiatore togli il ponticello JD-VCC e alimenta i relè a parte, aggiungi uno snubber o un varistore sul carico e tieni i cavi dei sensori lontani da quelli del carico.

Perché Arduino si blocca dopo un po'?

I blocchi che compaiono dopo minuti od ore dipendono quasi sempre dalla RAM che si riempie e dalle concatenazioni di String che frammentano la memoria. Anche un bus I2C bloccato dai disturbi o un codice che aspetta in un ciclo infinito bloccano la scheda. Misura la RAM libera, usa array di char al posto di String, imposta un timeout con Wire.setWireTimeout() e attiva il watchdog come sicurezza.

Quale condensatore mettere in un circuito con Arduino?

Sulla linea di alimentazione di servo e motori vanno bene 470–1000 µF, tra 5V e GND di Arduino un elettrolitico da 100 µF. Aggiungere accanto a ciascuno un ceramico da 100 nF (104) filtra anche i disturbi ad alta frequenza. La tensione nominale dell'elettrolitico deve essere almeno il doppio di quella della linea, e il terminale negativo, quello con la striscia, va a GND.

Perché Arduino si resetta quando apro il Monitor seriale?

Uno e Nano si resettano tramite il segnale DTR quando si apre la porta seriale; non è un guasto ma l'auto-reset che permette di caricare lo sketch. Se comunichi da un programma come Python, aspetta 2 secondi dopo aver aperto la porta. Per disattivare il reset, metti un condensatore da 10 µF tra RESET e GND e toglilo prima di caricare lo sketch.

Vedi tutti i progetti
Utilizzo del servomotore
#35Principiante
Premium

Utilizzo del servomotore

Il braccio di un piccolo servomotore ruota a turno in tre posizioni: tutto all'inizio, esattamente a metà e tutto alla fine, aspettando due secondi a ogni fermata. L'Arduino dice al motore a quale ang

4.7(48)
67
Lampadina 220V con pulsante (Push)
#19Avanzato
Premium

Lampadina 220V con pulsante (Push)

Finché tieni premuto il pulsante, una vera lampadina da 220 volt resta accesa, e si spegne appena lo lasci. Il piccolo segnale dell'Arduino non può accendere la lampadina direttamente, quindi in mezzo

4.4(30)
38
Auto controllata via Bluetooth con L298N
#80Avanzato
Premium

Auto controllata via Bluetooth con L298N

Trasforma il telefono in un telecomando e guida la tua auto robot. L'Arduino riceve tramite un modulo Bluetooth i comandi di un'app di controllo remoto sul telefono e fa girare le ruote con un driver

5.0(38)
65
Robot che evita gli ostacoli
#81Avanzato
Premium

Robot che evita gli ostacoli

Che ne dite di costruire un veicolo intelligente che trova la propria strada? L'Obstacle Avoiding Robot scruta costantemente l'ambiente circostante grazie al sensore a ultrasuoni posto davanti a lui.

5.0(38)
49
Stazione di irrigazione intelligente
#83Avanzato
Premium

Stazione di irrigazione intelligente

Un giardiniere che annaffia le tue piante da solo, così non si seccano mentre sei in vacanza. Un sensore di umidità misura quanto è bagnata la terra; quando diventa secca, l'Arduino accende la pompa d

5.0(42)
57
Coreografia di servo in cerchio - Animazioni con 32 servomotori
#102Avanzato
Premium

Coreografia di servo in cerchio - Animazioni con 32 servomotori

Un progetto di animazione visiva che utilizza 32 servomotori disposti in cerchio su un Arduino Mega. I servo sono gestiti in un unico array e collegati ai pin 22-53 del Mega per visualizzare quattro diverse sequenze di movimento: una vibrazione caotica in cui tutti i servo si muovono ad angoli casuali, uno sweep sincrono in cui si muovono tutti allo stesso tempo, un'onda che ruota dolcemente intorno a un cerchio e infine un ago di bussola che oscilla a destra e a sinistra. L'effetto onda vortico

4.5(40)
62
Servomotore ESP32 (controllo tramite potenziometro)
#118Intermedio
Premium

Servomotore ESP32 (controllo tramite potenziometro)

In questo progetto controlliamo un servomotore SG90 tramite un potenziometro. Regoliamo l'angolo del servomotore mappando il valore analogico letto dal potenziometro su un intervallo compreso tra 0 e 180 gradi. La libreria ESP32Servo genera segnali per servomotori sui GPIO adatti dell'ESP32 che possono funzionare come uscite; in questo progetto si utilizza GPIO 18. Si tratta di un metodo di controllo fondamentale per bracci robotici, gimbal per telecamere e meccanismi di porte automatiche.

4.3(29)
42