Autoreset, questo sconosciuto

L'autoreset è una funzione che permette di trasferire lo sketch, una volta compilato, su Arduino senza dover premere fisicamente il tasto di reset per avviare il bootloader. Dal punto di vista elettronico viene sfruttato il segnale standard della RS232 DTR (Data Terminal Ready) che normalmente si trova a 1 logico e va a 0 durante la trasmissione dei dati. DTR è connesso con il pin reset dell'ATmega tramite un condensatore da 100 nf che assieme alla resistenza di pull up da 10k crea un vero e proprio circuito RC con la relativa costante di tempo che vale 100nf * 10 k = 1ms. Rammento che la costante di tempo di un circuito RC è il tempo necessario affinché la tensione passi da 0V a 0.707 * Vmax, il tempo necessario per la carica completa del condensatore è circa 6*RC. Sa controlliamo con il DSO cosa succede al segnale DTR, in ingresso al condensatore, e cosa succede sul reset quando l'IDE inizia a programmare l'ATmega osserviamo un impulso verso 0 logico sul DTR che dura circa 120 ms e un rapido impulso verso 0 logico sul reset. Analizzando in dettaglio solo l'impulso sul reset possiamo osservare che questo rimane a 0 logico reale, tensione minore di 0.8 V, per oltre 140 us e arriva a 3.5V in poco meno di 1 ms (5V*0.707 = tensione per costante di tempo) come atteso. Le due immagini allegate sono gli screen capture del DSO, la traccia 1 (gialla) è il reset, la traccia due (azzurra) è DTR, la prima immagine è il ciclo completo del segnale DTR, circa 120 ms, la seconda immagine è il dettaglio dell'impulso di reset.

Nel post successivo ci sono tre ulteriori immagini che illustrano nel dettaglio cosa succede collegando una resistenza da 10k tra Reset e +5V, una resistenza da 330 ohm tra Reset e +5V e un condensatore da 10 uf tra Reset e +5V. Nel caso della resistenza da 10k l'effetto è solo quello di dimezzare la costante di tempo, si mette in parallelo alla 10k già presente su Arduino riducendola a 5k. Nel caso della resistenza da 330 ohm c'è una drastica riduzione della costante di tempo però reset rimane a 0 logico per poco più di 1 us e questo basta per resettare l'ATmega. Il terzo test è con il condensatore da 10 uf collegato tra reset e +5V, in pratica in parallelo alla resistenza di Pull Up, in questo caso la costante di tempo viene quasi azzerata perché il condensatore fornisce quasi istantaneamente tutta la corrente necessaria per caricare la capacità da 100 nf, bastano meno di 100 ns, impedendo il reset dell'ATmega.

|500x357

|500x357

Reset.JPG|990x707

Resdet.JPG|990x707

Le altre tre immagini:

|500x357

|500x357

|500x357

Res10k.JPG|990x707

Res330.JPG|990x707

Res10u.JPG|990x707

Azzz, me l'aspettavo che finiva così :astonished: :fearful: Grazie, sei un grande! Un solo chiarimento, il C da 10µF io l'ho messo sempre tra reset e GND, non +5V, mi chiarisci questo passaggio?

menniti: Un solo chiarimento, il C da 10µF io l'ho messo sempre tra reset e GND, non +5V, mi chiarisci questo passaggio?

Non so da dove venga fuori questa cosa del condensatore tra reset e gnd, forse da qualche post sul forum internazionale, non è molto logica da un punto di vista elettronico. Il condensatore da 10 micro si mette tra reset e +5V perché deve fornire la corrente per caricare nel minor tempo possibile il condensatore da 100 nf, di fatto bypassa la resistenza da 10k portando quasi a 0 la costante di tempo, inoltre migliora l'immunità ai disturbi del reset. Non ho provato con valori minori di 10 uf, dovrebbe bastare un condensatore da 1 uf, se trovo un attimo di tempo domani faccio pure questa prova.

Beh, tutto sto casino è nato dal fatto che funziona e che si tentava di fare una spiegazione elettronica allo schema: R 120 tra +5V e reset & C 10µF tra reset e GND (o anche il solo C sempre tra reset e GND).

Altra cosa: Nell'immagine della R 330 la traccia gialla dopo 9µS è ancora a meno di 2V, tu hai scritto che il reset rimane a 0 per poco più di 1µS, cosa non sto capendo?

Data sheet ATmega 328 pagina 318, tabella 28-3 dove ci sono le caratteristiche elettriche per il reset e la Vcc da cui risulta che Vrst (RESET Pin Threshold Voltage) è compresa tra un minimo di 0.2 VCC e un massimo di 0.9 VCC. In pratica tensioni maggiori di 0.9V non sono considerate valide per il reset, il caso limite estremo è che tensioni maggiori di 0.2V non sono valide, un valore tipico sono 0.8V e su questa base di tensione ho estrapolati i tempi come evidenziato dai cursori.

astrobeed: Data sheet ATmega 328 pagina 318, tabella 28-3 dove ci sono le caratteristiche elettriche per il reset e la Vcc da cui risulta che Vrst (RESET Pin Threshold Voltage) è compresa tra un minimo di 0.2 VCC e un massimo di 0.9 VCC. In pratica tensioni maggiori di 0.9V non sono considerate valide per il reset, il caso limite estremo è che tensioni maggiori di 0.2V non sono valide, un valore tipico sono 0.8V e su questa base di tensione ho estrapolati i tempi come evidenziato dai cursori.

OK, chiaro e limpido. Grazie di tutto XD

Ho sempre usato il condensatore messo tra RST e GND (sì, la "dritta" proviene dal forum internazionale) ed ha sempre funzionato perfettamente. Stasera ho letto questo thread ed ho voluto provare a programmare un Attiny85 usando l'Arduino UNO come programmatore ISP e mettendo il condensatore da 10 uF tra +5V e RST....

Passi:

1) prendo l'Arduino e ci carico sopra lo sketch ArduinoISP; 2) prendo una breadboard su cui avevo un Attiny "cavia" con sketch Blink che faceva lampeggiare un LED sul pin 4; 3) collego la breadboard all'Arduino in configurazione ISP e collego al PC: il LED sulla breadboard lampeggia, segno che l'Attiny sta lavorando normalmente 4) metto il C collegato col pin + alla linea +5V e col pin - tramite un filo al pin RST 5) seleziono l'Attiny ad 8 MHz ed invio lo sketch Blink modificato per il pin 4

Risultato??? Al successivo riavvio del micro il LED lampeggiava con una intensità bassissima, quasi impercettibile! Ma c'è di più: adesso esce una piccola tensione anche dal pin 2 (il pin SCK in configurazione ISP) dell'Attiny.... rilevabile collegando un LED con resistenza. Me ne sono accorto perché mi aveva acceso debolmente il led "L" di Arduino, collegato al pin 13.

Io non me ne intendo di elettronica ma non è che con quel condensatore è "saltato" qualcosa? Cioè che sia ad un certo punto passata più corrente e l'Attiny si sia "fulminato"? Uhm... anche il 2° Attiny, programmato con il condensatore tra RST e GND, si comporta alla stessa maniera... che cosa buffa... cos'è, un'epidemia?

Niente da fare... ho ricontrollato e ricontrollato più e più volte. Ho riflashato tutto, dagli Attiny agli Atmega. Gli Attiny sono andati, partiti, persi.... non so cosa sia successo. Il condensatore non c'entra niente perché ho provato con un Atmega328 e questo funziona bene... Eppure divento matto! Capisco il primo Attiny, magari posso aver fatto io inavvertitamente contatto io con qualcosa, ma il secondo era sì sulla stessa breadboard ma era completamente scollegato! Montato e programmato è saltato anche quello. L'unica cosa che mi può venire in mente è che ho messo il 2° Attiny nello STESSO identico punto della breadboard dove ho programmato il primo. Magari è saltata una pista ed ha bruciato anche il secondo?

@Leo ma il tiny risponde ancora correttamente? cioè riesci a leggere signature e fuse? hai provato a far blinkare il led su un pin diverso ?

leo72: Niente da fare... ho ricontrollato e ricontrollato più e più volte. Ho riflashato tutto, dagli Attiny agli Atmega. Gli Attiny sono andati, partiti, persi.... non so cosa sia successo. Il condensatore non c'entra niente perché ho provato con un Atmega328 e questo funziona bene... Eppure divento matto! Capisco il primo Attiny, magari posso aver fatto io inavvertitamente contatto io con qualcosa, ma il secondo era sì sulla stessa breadboard ma era completamente scollegato! Montato e programmato è saltato anche quello. L'unica cosa che mi può venire in mente è che ho messo il 2° Attiny nello STESSO identico punto della breadboard dove ho programmato il primo. Magari è saltata una pista ed ha bruciato anche il secondo?

Ma se anche salta una pista (e ci vorrebbe un corto selvaggio con un'alimentazione notevolissima) al più non riesci a collegare correttamente il pin, al massimo potresti brickarlo, certamente non bruciarlo. Se pensi siano brickati non buttarli, mi raccomando... ;)

EDIT: comunque sia il condensatore lo hai collegato sul reset di Arduino quindi, al di là della prova col 328, non poteva certo essere lui la causa del problema.

menniti: EDIT: comunque sia il condensatore lo hai collegato sul reset di Arduino quindi, al di là della prova col 328, non poteva certo essere lui la causa del problema.

Esatto, il condensatore non ha alcun punto di contatto col micro che viene programmato, è solo sul pin di reset dell'ATmega sul quale c'è lo sketch isp.

@Brain: curiosamente sì, riesco a flasharlo sia dall'IDE sia con l'USBtinyISP. In entrambi i casi è visto correttamente e programmato.

@menniti: nessun "corto selvaggio", alimentavo la breadboard con i 5V presi dall'Arduino e son sicuro di non aver invertito i ponticelli (+ sul - e viceversa) perché uso sempre cavetti colorati (rosso per il + e verde per il -) quindi facilmente identificabili

@astro: chiaro.

Cmq qualcosa è successo. Esattamente prima della programmazione il LED sul pin dell'Attiny lampeggiava con un'intensità normale. Appena ho programmato il micro, il LED credevo fosse spento, da quanto era fioco. Ho dovuto parare la luce con la mano per vedere che lampeggiava. Inoltre mi sono accorto che qualcosa non andava perché ho notato che, appena terminata la programmazione ISP, il led "L" sull'Arduino era fiocamente illuminato perché riceveva tensione dall'Attiny mediante il cavettino sul pin 13. Collegando infatti un LED direttamente al 7° pinedino dell'Attiny (pin 2) mi sono accorto che usciva tensione, misurata in 4,8V con un tester.

Resta il mistero che da ieri sera ho i 2 Attiny "andati".

Una considerazione sulle correnti in gioco, osservando attentamente la misura con il condensatore da 10 uf si vede chiaramente che il segnale DTR non va subito a 0 logico, come avviene in tutti gli altri casi, ma ci va in un certo tempo seguendo la curva di carica del condensatore da 100 nf. La cosa è abbastanza logica perché la corrente che può scorrere nel circuito è limitata dalla somma dell'impedenza d'uscita del FTDI o 8u2, non dichiarate sul data sheet, e dalla ESR del condensatore che normalmente per un elettrolitico da 10 uf, non low esr, è una decina di ohm. E' possibile stimare con buona precisione la reale corrente che scorre partendo dalla costante di tempo della variazione su DTR, circa 8 us per arrivare al valore di tensione dovuto a RC, con un semplice calcolo ci troviamo la resistenza serie equivalente e da questa la corrente di picco.

R = 8 us / 100 nf = 80 ohm. Ip = 5V / 80 ohm = 62 mA.

Anche se è un valore di picco che dura meno di un us è superiore alla massima corrente ammessa su un GPIO del 8u2 o del FTDI, nel primo caso sono 40 mA nel secondo caso sono 24 mA. Da notare che le misure sono state fatte sia su una UNO che su una 2009, sono totalmente identiche salvo l'ultima con il condensatore da 10 uf dove sulla 2009 il tempo di discesa verso lo 0 logico di DTR è maggiore, non mi ricordo di quanto e non ho salvato la misura, il che limita la corrente che passa sul FTDI a molto meno di 62 mA, sicuramente a causa del fatto che l'impedenza d'uscita è maggiore rispetto al 8u2. Da tenere presente che il valore di corrente massimo sui GPIO riportato sui datasheet è riferito ad un flusso continuo e non ad una serie di impulsi, toccherebbe parlare di valore rms della corrente che ci porta ad un valore continuo equivalente quasi nullo nel nostro caso. In tutti i casi sarebbe bene non superare lo stesso i valori massimi riportati dai data sheet, per ottenere il risultato basta inserire una resistenza di piccolo valore, 100 ohm dovrebbero bastare, in serie al condensatore per ridurre la corrente di picco a circa 20 mA sia con l'8u2 che con l'FTDI. Cerco di verificare strumentalmente la cosa in giornata, sopratutto gli effetti sull'impulso di reset vero e proprio che dovrebbe rimanere ampiamente entro i margini di sicurezza, durata minore di 100 ns, per non resettare l'ATmega.

in pratica la R va tra +5V e il positivo del C? Allora evidentemente si è trattato di un'errata interpretazione dei collegamenti, in precedenza, visto che anche lì c'erano una R da 120 e un C da 10µF in serie rispetto al +5, solo che il negativo del C invece che sul Reset era collegato a massa, mentre sul reset andava il punto di giunzione R-C. Un dubbio: col "vecchio" sistema era possibile fare ripetuti upload sul chip stand alone ma non era ovviamente possibile aggiornare l'eventuale sketch (magari per fare una prova "locale") su Arduino, è sempre la stessa cosa, o abbiamo qualche miglioria in tal senso?

menniti: in pratica la R va tra +5V e il positivo del C? Allora evidentemente si è trattato di un'errata interpretazione dei collegamenti, in precedenza, visto che anche lì c'erano una R da 120 e un C da 10µF in serie rispetto al +5, solo che il negativo del C invece che sul Reset era collegato a massa, mentre sul reset andava il punto di giunzione R-C.

Con la r in serie al condensatore tra +5V e il condensatore chiuso verso GND non limiti in nessun modo la corrente che scorre attraverso il condensatore da 100nf, l'energia la prende dal condensatore da 10 uf e non attraverso la resistenza, questa serve solo garantire una ricarica veloce del condensatore, che comunque attraverso la 10k avviene lo stesso in meno di un secondo (partendo dalla scarica completa) quindi assolutamente inutile abbassare questo valore. In pratica potrebbe bastare la sola resistenza da 120 ohm tra +5V e reset, è in parallelo alla pull up da 10k del reset, ma a differenza del condensatore da 10 uf, che ha una limitata quantità di energia, questa può far scorrere indefinitamente fino a 42 mA, cosa che in caso di errori/distrazioni può creare non pochi problemi.

Un dubbio: col "vecchio" sistema era possibile fare ripetuti upload sul chip stand alone ma non era ovviamente possibile aggiornare l'eventuale sketch (magari per fare una prova "locale") su Arduino, è sempre la stessa cosa, o abbiamo qualche miglioria in tal senso?

Non cambia nulla perché se tieni bloccato l'autoreset di Arduino non puoi caricare un nuovo sketch a meno che non premi fisicamente il tasto di reset.

Grazie, posso approfittare sull'argomento "reset"? Sto facendo un po' di prove con l'HVFuse, per la programazione del chip mediante l'applicazione di una tensione di 12V al pin reset del chip, per circa un secondo, il tempo di programmare i fusibili. Sto sperimentando dei circuitini che mi permettono di "eliminare" due smd (così faccio un pcb realizzabile senza problemi): un booster che tira fuori 12V a partire dai 5 di Arduino ed un circuito npn-pnp per switchare la tensione di 12V al reset usando un impulso HIGH proveniente da un pin di Arduino. Mi manca un elemento fondamenlate: la corrente richiesta dal pin reset a 12V affinché si possano programmare i fusibili. Questo dato mi serve sia per capire se il booster che sto provando va bene (dovrebbe erogare circa 20mA) che per calcolarmi la R di limitazione dei 12V verso il reset del chip. Puoi darmi qualche indicazione o al limite qualche schema alternativo? Ripeto l'esigenza è fare un pcb semplice da montare (non per me che sarei attrezzato...) e risparmiare qualche cent.

menniti: che per calcolarmi la R di limitazione dei 12V verso il reset del chip.

Il data sheet non riporta la corrente massima richiesta dal reset quando gli si collegano i 12 Volt, però se la memoria non mi inganna non servono più di pochi uA, quindi una bella resistenza in serie da 1k giusto per limitare la massima corrente che può fluire su quella linea. Al limite basta fare una semplice verifica strumentale, metti in serie al reset la r da 1k, fornisci il 12V e controlla con l'oscilloscopio (DSO) come varia la tensione ai capi della resistenza che in questo caso diventa uno shunt per la misura della corrente.

Bene, la prova la faccio per curiosità, ma se sono pochi µA sono a posto, il booster va benissimo, resta lo schema per l'ampli di tensione, da quanto ho capito devo per forza usare un npn che pilota un pnp, altrimenti il solo npn (in uscita dal micro ho un impulso HIGH per il pilotaggio) non conduce nella configurazione a collettore comune. La conferma me la dà proprio la configurazione del chip smd che devo eliminare, fatta in questo modo, anche se speravo di "cavarmela" col solo npn.

Dal punto di vista elettronico viene sfruttato il segnale standard della RS232 DTR (Data Terminal Ready) che normalmente si trova a 1 logico e va a 0 durante la trasmissione dei dati.

Ok, ho seguito tutte le discussioni e voglio fare alcune considerazioni dal lato software: perchè è necessario resettare arduino board sempre è comunque? In effetti il DTR messo alto fà parte della prodedura di riconoscimento fatta da avrdude quando comunica con la board. Comunicare con la board significa in sostanza comunicare con il software installato nel micro, software che è il conosciutissimo bootloader.

Avrdude invia dei dati in seriale e si aspetta una determinata risposta, quando questa non è corretta avrdude visualizza il messagio stk500 not in sync (o simile).

Quindi la procedura di reset serve per dialogare con il bootloader, perchè questo entra in azione solo dopo il reset.

Dalla lettura dei post capisco che quando una board arduino viene usata come programmatore ICSP, questo auto reset su questa board non è gradito. Quindi se ho capito bene, lato software basterebbe mettere nella configurazione dell'ide un flag, es autoreset.disable = true.

Quanto detto mi fa pensare al fatto che il programma ICSP da mettere su arduino non prevede l'uso di un bootloader, cioè non ha necessità di "switchare" tra bootloader e user code, ma dall'altro lato leggo che per la uno board il nuovo bootloader risolve il problema.

La cosa mi interessa lato software per il programma che sto sviluppando (arvdudequi). Al momento sono fermo per vari motivi (uno attendo di fare aquisti, micro ecc). Alla fine la domanda è: La cosa è risolvibile lato software evitando di abilitare il DTR, quando si sta usando la board con il programma ICISP? Ci sarebbe da vedere se questo segnale deve comunque essere cambiato perchè previsto dal protocollo implementato dal programma ICISP, se fosse così non c'è verso di aggire lato software, se non modificando il bootloader come sembra sia stato fatto per l'optiboot, anche se la cosa non mi convince.

Non ho le idee molto chiare in merito, posso chiarirmele leggendo il codice, ma se c'è qualcuno che le ha già più chiare delle mie (idee) lo ascolterei con piacere.

Ciao.