Problemi lettura della temperatura con termistore

Ciao a tutti, ho iniziato a lavorare su un progetto che ho in mente da tempo, ovvero creare una stampante 3d controllata con linuxcnc.
Dovendo gestire il tutto tramite porta parallela dotata di soli pin digitali ho deciso di usare un arduino uno per la gestione della temperatura dell'estrusore.
Quindi ho creato il circuito che si può vedere in foto, ho scritto il codice per la lettura della temperatura, ho importato la libreria pid, ho fatto un po' di tuning (molto "a caso" leggendo guide e facendo molte prove) in modo da riuscire a controllare la temperatura della resistenza, ma ho un problema.
Per qualche motivo i valori letti tramite termistore (un NTC da 100k) sembrano non essere molto stabili.
Dato che durante il processo di tuning lavoravo attorno ai 100°C le oscillazioni non erano troppo gravi, e pensavo di aver risolto introducendo una funzione di smoothing tramite media, ma in realtà all'aumentare della temperatura (e quindi al diminuire della resistenza del termistore) le temperature diventano sempre più instabili (variano anche di oltre 5 gradi) tanto che le oscillazioni risultano visibili anche dopo aver applicato lo smoothing con finestra di 30 valori.
Le oscillazioni non sono "reali" dato che persistono anche dopo aver scollegato l'alimentazione della resistenza, sono semplicemente letture imprecise.

Ho provato a collegare la massa del termistore all'altro pin gnd pensando che potesse essere l'alimentatore da 12v con massa comune a creare casino, ma non è cambiato nulla.

Quale può essere il problema?

Vi ringrazio in anticipo

ps: tenete presente che ho basi pressoché nulle di elettronica anche se mi sforzo di imparare/capire passo passo

Google Photos

Benvenuto. Essendo il tuo primo post, nel rispetto del regolamento, ti chiediamo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il su citato REGOLAMENTO... Grazie.
Qui una serie di link utili, non inerenti al tuo problema:

Ok, mi sono presentato nel topic che hai linkato :slight_smile:
Ti ringrazio per i link utili!

Probabilmente capta disturbi. Metti un condensatore elettrolitico da 10~47uF tra il pin d'ingresso analogico e massa.

Un dubbio, stai usando il termistor in un partitore resistivo ed alimentando il termistor con la stessa alimentazione del resto ? ... (google, come al solito, non mi lascia vedere le immagini)

Se si, qualsiasi oscillazione, anche minima, che ti dovessi trovare sull'alimentazione, varierebbe anche la lettura ... per avere maggiore precisione dovresti usare una sorgente di tensione stabilizzata, o meglio ancora un riferimento campione, sia per l'AREF sia per il partitore del termistor ... un banale TL431A ben filtrato e regolato per una tensione inferiore a quella di alimentazione (diciamo 4V, ma poi anche quello che vuoi tu, basta che sai qual'e' per le letture) risolve il problema, in quei casi ... :wink:

Beh... basta abilitare il riferimento interno a 1,1V. Non è molto preciso, ma è stabile.

Si, ma usare solo 1.1V limita parecchio la corrente disponibile per i circuiti ADC interni, specie perche' lui dice di avere un termistor da 100K (se fosse da 10K andrebbe molto meglio, considerando che i datasheet delle MCU Atmel consigliano un'impedenza dei circuiti connessi ai pin ADC di 10K massimi) ... pero' se non gli serve particolare velocita' di lettura, forse potrebbe andare anche quella, anche se un riferimento esterno e' di solito piu preciso e stabile ...

Innanzitutto vi ringrazio per le risposte, ho allegato la foto in modo che possiate scaricarla (non che sia molto accurata).
Non conoscevo usata possibilità di utilizzare la tensione di riferimento a 1.1v. Domani provo a vedere se la situazione migliora.
Per farlo dovrei anche mettere mano al codice per il calcolo della resistenza del termistore? Se non ricordo male nella formula è presente come parametro la tensione "di ingresso" (5v) ma quella dovrebbe rimanere la stessa o sbaglio?

Vi ringrazio di nuovo per l'aiuto.

Devi dare Aref al partitore al posto dei 5V.
L'ingresso è ad alta impedenza, puramente capacitivo, ma noi gli mettiamo addirittura 10...47uF in parallelo!
Il valore che leggi rimane lo stesso, perché la tensione fornita al partitore rimane uguale al fondo scala dell'ADC (circa 5V prima e circa 1,1V adesso)

Quindi dimmi se ho capito bene:

  • Collego il termistore ad aref invece che a vcc
  • La mia funzione per il calcolo della resistenza rimane come nel listato seguente

double calculateR(int rawAnalogData){
Vout = (rawAnalogData * Vin) / 1024.0;
return refR * (Vin/Vout - 1);
}

Ma vin in questo caso diventa 1.1 invece di 5.

è corretto?

Ho appena provato, ma la situazione non sembra essere particolarmente migliorata.
Per il condensatore ne ho solo da 10uf ma con rating di 50v, ho provato ma anche quello sembra non portare miglioramenti.

edit:Ho un dubbio. I fili che vanno dall'arduino al termistore corrono parallelamente a quelli che alimentano la resistenza (che viene alimentata con una sorta di PWM molto lento, con periodo 1 secondo), questa alternanza tra 0v e 12v nei fili adiacenti può causare qualche problema? In che modo l'aumento della temperatura dell'estrusore (e quindi la diminuzione della resistenza del termistore) può accentuare il problema? (sempre che questa sia una possibile causa).

Giusto per completare le informazioni che vi ho fornito mi trovo a 200 gradi circa con letture di resistenza che oscillano continuamente tra i 788 ohm e i 400ohm, e la temperatura continua a saltare tra i 197 gradi e i 207-208.
Inoltre le oscillazioni persistono anche ad alimentazione 12v scollegata, quindi la mia teoria precedente non è corretta.

.... letture di resistenza che oscillano continuamente tra i 788 ohm e i 400ohm, e la temperatura continua a saltare tra i 197 gradi e i 207-208....

i valori che hai con l'analogRead() quali sono ?

Oscillano tra il 1011 e il 1019.
C'è da dire che la risoluzione dell'ADC dell'uno è veramente bassa, ma resta il fatto che fino ai 130 - 140 gradi il problema non esiste (o è risolvibile con una media)

Però devo trovare il modo di risolvere, il PID impazzisce con letture che oscillano anche di 10 gradi.

Ultima cosa: Mi pare di osservare che con l'alimentatore da 12v scollegato il problema migliori leggermente (persistono le oscillazioni ma sono nell'ordine dei 2-3 gradi).

Eh, certo... Fai viaggiare il pwm accanto a un segnale con 50kohm di impedenza!!!
Hai messo il condensatore in parallelo all'ingresso analogico?

No, come dicevo poco fa ne ho solo elettrolitici da 50v 10uf, o dei ceramici con codice 104 (e mi pare di capire che siano da 0.1uf).
In ogni caso non mi spiego come il pwm possa creare questo problema solo ad alte temperature, se porto l'estrusore a 100° ho letture stabili con oscillazioni entro 1 grado. Oltretutto il problema persiste (anche se forse in misura leggermente inferiore) anche con l'alimentazione da 12v staccata.

edit: aggiungerei che dato che il problema si verifica a temperature alte a quel punto l'impedenza dovrebbe essere addirittura sotto al kohm (non avendo esperienza in campo elettronico non so se sia meglio o peggio, ma in teoria dovrebbe fluire più corrente e quindi il segnale dovrebbe essere meno soggetto a disturbi. Sbaglio?)

Dici 788 e 400 ohm: con 100k in serie: 788=8/1024; 400=4/1024. La risoluzione è bassissima. Una variazione di 1 corrisponde a diversi gradi! Per avere più risoluzione devi fare il partitore con una resistenza simile al valore che assume la NTC alla temperatura media di lavoro.
Se la NTC alle temperature di lavoro ha una resistenza fra 400 ohm e 2kohm, fai il partitore con 1kohm anziché 100k.

P.s: L'ADC ha l'impostazione standard, vero, non hai impostato l'ADC veloce? In modo veloce è meno preciso.

muz94:
...

  • Collego il termistore ad aref invece che a vcc
    ...

Ehm, non esattamente ... AREF serve a fornire al comparatore interno di Arduino un valore diverso da VCC, e questo si ottiene collegandoci una sorgente di tensione di riferimento, inferoire a VCC (e se non ricordo male bisogna anche dire alla MCU di usare il valore esterno) ...

Detta banalmente, se ad AREF non ci colleghi nulla ed usi i valori standard (o se lo colleghi a VCC che e' lo stesso), i 1023 gradini del convertitore inerno ,quando leggi un'ingresso analogico, vanno da zero a VCC ... se ci colleghi ad esempio 2,5V, anche la lettura poi sara' da zero a 2,5V ... lo stesso per qualsiasi altro valore ... lo si usa quando hai un riferimento di tensione esterno piu stabile e preciso di VCC, in modo che la lettura non venga falsata dalle fluttuazioni e dai disturbi presenti sull'alimentazione ... ed ovviamente in quei casi anche il partitore del termistor andra' collegato alla stessa fonte di tensione stabile, e non piu a VCC ... se non lo usi gia per nient'altro anche l'uscita a 3.3V potrebbe andare, non e' un riferimento precisissimo, ma sempre meglio dei 5V ...

Sì. Per usare una tensione di riferimento esterna bisogna inserire: analogReference(EXTERNAL);

Etemenanki:
Ehm, non esattamente ... AREF serve a fornire al comparatore interno di Arduino un valore diverso da VCC, e questo si ottiene collegandoci una sorgente di tensione di riferimento, inferoire a VCC (e se non ricordo male bisogna anche dire alla MCU di usare il valore esterno) ...

Detta banalmente, se ad AREF non ci colleghi nulla ed usi i valori standard (o se lo colleghi a VCC che e' lo stesso), i 1023 gradini del convertitore inerno ,quando leggi un'ingresso analogico, vanno da zero a VCC ... se ci colleghi ad esempio 2,5V, anche la lettura poi sara' da zero a 2,5V ... lo stesso per qualsiasi altro valore ... lo si usa quando hai un riferimento di tensione esterno piu stabile e preciso di VCC, in modo che la lettura non venga falsata dalle fluttuazioni e dai disturbi presenti sull'alimentazione ... ed ovviamente in quei casi anche il partitore del termistor andra' collegato alla stessa fonte di tensione stabile, e non piu a VCC ... se non lo usi gia per nient'altro anche l'uscita a 3.3V potrebbe andare, non e' un riferimento precisissimo, ma sempre meglio dei 5V ...

Mh, allora:
non vorrei dire una fesseria dato che ho ripreso in mano arduino da poco (e comunque non l'ho mai usato intensamente), ma cercando online dopo i suggerimenti degli altri utenti ho trovato questo: analogReference() - Arduino Reference, e navigando su altri siti mi è parso di capire che impostando il riferimento a "INTERNAL" dal pin AREF avrei potuto prelevare un riferimento interno a 1.1v.
Scoperto questo ho effettivamente fatto una prova: ho collegato aref al termistore ed ho letto i valori analogici utilizzando come valore di riferimento per il caolcolo 1.1 al posto di 5, ed i valori mi parevano essere corretti (ma comunque oscillanti).
Può essere un caso o no? Credo che se l'arduino non mi avesse fornito effettivamente quella tensione dal pin AREF difficilmente avrei letto valori sensati.

edit: Ho appena testato con il multimetro, con Il riferimento impostato su INTERNAL tra il pin AREF e gnd ho una tensione di 1.05V, altrimenti leggo circa 5v.

Per quanto riguarda il post di Datman:
-no, io personalmente non ho impostato l'ADC veloce
-ok, non avevo considerato la mia resistenza. Effettivamente su altri siti avevo letto l'idea di utilizzare una resistenza di valore simile a quello assunto "mediamente" dall'ntc, semplicemente ho seguito un altro sito che probabilmente discuteva l'utilizzo del termistore per la lettura di temperature ambientali (e per cui probabilmente la resistenza a 25° poteva avere senso).

Ora faccio qualche prova in tal senso.
Una domanda: questo come influisce sull'accuratezza del calcolo della temperatura? Otterrò valori meno corretti a temperatura ambiente, ma più accurati alle temperature di esercizio? (180-230°C)

Scusate il secondo post.
Ho appena sostituito la resistenza da 100k con una da 10k,e già così le letture sono migliorate drasticamente, i valori di temperatura oscillano di non più di un grado, e contando che devo ancora sistemare il PID il risultato è ottimo.

Non so veramente come ringraziarvi. Rimane la mia domanda del post precedente, ma direi che il problema del topic è risolto.

Grazie 1000, ora non resta che proseguire con il resto del progetto (solo eheh).