Go Down

Topic: Lettura Temperatura con Sensore TM36  (Read 936 times) previous topic - next topic

LOLLO65

Capisco ke da te è tarduccio , qui dove sono io negli USA sono le 5pm.
ok grazie in ogni caso.

A domani. Buona notte :smiley-sleep:


Standardoil

#16
Sep 10, 2020, 11:11 pm Last Edit: Sep 10, 2020, 11:12 pm by Standardoil
ah, scusa, prima di nanna


il mio nick?

il mio papà mi ha chiamato Nelson......

e i miei compagni di scuola hanno "equivocato" con un noto membro di una famiglia di petrolieri

in particolare quando all'ITIS ci hanno fatto vedere una serie di filmati di fisica sponsorizzati dalla casa petrolifera in questione

e il soprannome mi è piaciuto e mi è rimasto
Non presurrò più la buona fede di chi:
NON indenta o USA la classe string o NON esegue le ricerche
Troppe volte e' stato segnalato che è sbagliato, quindi se si comportano così NON sono in buona fede

Non bado a studenti, che copino altrove

LOLLO65

Ho avuto l'impressione che lavorassi per una qualche compagnia petrolifera o di indagini petrolifere dato l'inconsueto nick name che solitamente è usato da persone che lavorano nel settore.
Settore per il quasle ho lavorato, ora invece effettuo indagini geologia marina finalizzate all'installazione di generatori elettrici eolici. 
Tra qualche ora è in arrivo un uragano, il mare si sta inc......do e noi stiamo rientrando in porto ma si balla che non ti dico.
Infatti Gli US dopo qualche decenni rispetto all'europa sta investendo molto sul settore energetico green "diciamolo".
Infatti la Stardardoil è una compagnia Americana https://www.britannica.com/topic/Standard-Oil, il cui magnate era il famoso John D. Rockefeller. Nel link la storia di ST.oil.

finisco di sistemare lo sketch e poi lo riposto, vediamo se ho aggiustato tutto come si deve.

LOLLO65

Allora spero di aver fatto abbastanza ordine:
1) aggiunta una variabile sensroPIN,
2) corretto nr acquisizioni a 99 per ottenere le 100 acquisizioni.
3)eliminata variabile float temp,
4) reimpostati valori formula conversione °C

Code: [Select]

//lettura temperatura con sensore TMP36

int sensorPIN = A0;
int val_Adc = 0;     // sensore TMp36 applicato al analog pin A0
float temp =0;         

byte seven_seg_digits[10][7] =                                                           
  { //seg. a,b,c,d,e,f,g          nr
         { 1,1,1,1,1,1,0 },  // = 0 
         { 0,1,1,0,0,0,0 },  // = 1
         { 1,1,0,1,1,0,1 },  // = 2
         { 1,1,1,1,0,0,1 },  // = 3
         { 0,1,1,0,0,1,1 },  // = 4
         { 1,0,1,1,0,1,1 },  // = 5
         { 1,0,1,1,1,1,1 },  // = 6
         { 1,1,1,0,0,0,0 },  // = 7
         { 1,1,1,1,1,1,1 },  // = 8
         { 1,1,1,1,0,1,1 },  // = 9
   };
 
    void setup()
{
 /* Serial.begin(9600);          //  setup serial
  pinMode(0, OUTPUT);  //unita a primo led
  pinMode(1, OUTPUT);  //unita b
  pinMode(2, OUTPUT);  //unita c
  pinMode(3, OUTPUT);  //unita d
  pinMode(4, OUTPUT);  //unita e
  pinMode(5, OUTPUT);  //unita f
  pinMode(6, OUTPUT);  //unita g
  pinMode(7, OUTPUT);  //decine A 2ndo led
  pinMode(8, OUTPUT);  //decine B
  pinMode(9, OUTPUT);  //decine C
  pinMode(10, OUTPUT); //decine D
  pinMode(11, OUTPUT); //decine E
  pinMode(12, OUTPUT); //decine F
  pinMode(13, OUTPUT); //decine G
 */ 
  DDRD=0b11111111;
  DDRB=0b00111111;

}

void loop()
{
 delay(300);
 //init variabile
 sensorPin = analogRead(A0);
 //eseguo un ciclo
 for(byte Ciclo = 0; Ciclo<99; Ciclo++) // 0-99 =100 acquisizioni
 
  //acquisisco il valore sensorPin e lo sommo alla variabile val_Adc
  val_Adc += analogRead(sensorPin);

 //eseguo la media dei 100 valori letti
val_Adc /= 100;  //controllare il reference /=
// calcolo la temperatura in °C
 temp = ((val_Adc * 0.0048828125) - 0.5) / 0.01; //  (valore da usare senza applicato il Vref 0.0048828125
// Serial.println("temperature in C =");
 //Serial.println(temp); // debug value

  int pin=0 ; // per il primo 7-seg pins 0,1,2,3,4,5,6 collegati ai pin led posiz. a,b,c,d,e,f,g
  int pin1=7; // per 2ndo 7-seg pins 7,8,9,10,11,12,13 collegati ai pin led A,B,C,D,E,F,G


  int tempH;//high number
  tempH=int(temp/10);
 
  int tempL; //low number
  tempL=int(temp-tempH*10);

  for(int j=0;j<7;j++)
  {
    digitalWrite(pin,seven_seg_digits[tempL][j]);
  pin++;}
  for(int i=0;i<7;i++)
  {
   digitalWrite(pin1,seven_seg_digits[tempH][i]);
 pin1++;}
  delay(500);
 
}



LOLLO65

Avevo dimenticato di aggiustare sensorPIN, fatto anche questo.  :smiley-confuse:

maubarzi

Ho come l'impressione che tu non abbia un IDE davanti su cui testare il codice, è corretto?
Stai scrivendo tutto "a secco", vero?
Giusto per capirsi, così evitiamo incomprensioni e sappiamo che più che di codice funzionante si tratta di pseudocodice concettuale da rivedere nei dettagli una volta disponibile un IDE e un Arduino.

Detto questo, la mia domanda è:
Perchè continui a fare una lettura fuori ciclo?
Io per maggior chiarezza farei un reset fuori ciclo e poi le 100 letture tutte nel ciclo, così non rischi più di incasinarti con la media da 100 o 101, della serie: boh, vediamo se ho fatto altre letture sparse...
Tenere il codice semplice e lineare aiuta a mantenerne il controllo nel tempo.

Nel codice, poi, la lettura fuori ciclo l'hai fatta mettendo le variabili un po' a caso e scritte un po' a caso (da cui la premessa di cui sopra)

A parte il case sui nomi, che salterà all'occhio in fase di compilazioni, per cui al momento chissene...
La lettura fuori ciclo la fai scrivendo su sensorPin (che all'anagrafe sarebbe invece sensorPIN) invece che su val_Adc.

Poi, mi sa, che non hai colto il suggerimento sulle cifre significative.
Il concetto non era tanto sulla quantità di cifre, ma sul fatto che moltiplichi e dividi per numeri molto più piccoli di 1, quindi ti porti dietro tanti zeri.
Il suggerimento era di moltiplicare sia dividendo che divisore per lo stesso multiplo di 10 ottenendo valori più gestibili per le variabili utilizzate.
Ad es. se la variabile riesce a gestire 8 cifre significative, al dilà dell'esponente, e tu parti da 0,000... te ne sei già giocate 4 perdendo quelle oltre l'ottava.
Era questo il concetto che si voleva esprimere.

Ultimissimo suggerimento, per aiutare chi cerca di aiutarti, quando lo posti il codice, elimina tutti i pezzi di codice commentati perchè non servono alla discussione e creano solo confusione, tienili pure nel tuo sketch per il tuo debug, ma se qui li elimini non rischi incomprensioni.

Per il resto: in bocca al lupo per l'uragano, spero nulla di catastrofico.

Maurizio
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

LOLLO65

Esatto per il momento non ho un IDE su cui testare il tutto, perche sono imbarcato su una nave oceanografica per idagini geologiche finalizzate alla costruzione di impianti Eolici, per cui mi limito a verificare il funzionamento del solo sketch, è quello che posso fare, Poi quando tornero a casa affronterò il problema con assemblaggio IDE.
Per ora ragiono sui tuoi suggerimenti.
Per l'uragano niente problemi siamo rientrati in porto. 

Grazie in ogni caso. aggiungo karma

zoomx

Domanda: perché un sensore analogico TMP36?

LOLLO65

Perche mi serve di capire come arduino funziona dato che sono ancora alle prime esperienze.
Poi dalle caratteristiche sembra migliore del LM35,
poi perche volevo utilizzarlo sulla mia moto, che ha l'indicatore della temperatura a lancetta e a me piace vedere l'effettivo nr in °C di temperatura.
L'indicatore a lancetta è alimentato ovviamente in tensione e pensavo di applicarla ad arduino togliendo il sensore, apportando le necessarie modifiche per rispettare il valori di tensione da applicare ad arduino.
Il TMP36 così come LM35 possono essere facilmete messi a contatto con il motore della moto o inseriti in un tools che viene inserito sul circuito di raffreddamento della MOTO.
Potrei anche utilizzare direttamente un sensore digitale utilizzando altri schemi elettrici e sketch.
Per ora faccio un pò di esperienza con questo.

Se hai qualche suggerimento su altri sensori sono ben accetti.
Grazie della Domanda.

Saluti Lorenzo

zoomx

I sensori analogici con uscita in tensione hanno il problema che possono prendere disturbi lungo il fili che lo collegano all'Arduino.
Se vuoi mantenere l'analogico dovresti usare quelli con uscita in corrente, cosa che però complica l'acquisizione perché devi aggiungere un circuito adattatore.
Il digitale dovrebbe risolvere. Se usi i DS18B20 ne puoi usare parecchi collegati tutti con solo 3 fili, sono indirizzabili. Il lato negativo è che sono un po' lenti, hanno bisogno di circa 700 millisecondi per effettuare una misura (alla massima precisione altrimenti il tempo scende) anche se puoi comandare la misura per tutti e dopo 700 millisecondi leggerli tutti alla massima velocità.
Se però vuoi misurare la temperatura sul motore devi tenere conto che se il sensore va oltre i 100 gradi il cavetto magari no.
Oltre i 150 ci sono praticamente solo gli analogici, termocoppie, Pt100 e NTC, per le prime 2 esistono delle schedine con il convertitore apposta per utilizzarli con Arduino.
Quindi il sensore va scelto in funzione dell'uso, dipende dall'intervallo di temperature, dalla precisione e accuratezza richiesta, dalla frequenza di acquisizione, dal tempo di equilibrio, dalle dimensioni e così via. Anche dal costo.

LOLLO65

Ciao ZoomX,
Ti ringrazio dei suggerimenti sui Sensori,
L'ideale sarebbe utilizzare una termocoppia appliucata ad un Amp operazionale opportunatamente calibrato.
Avrei anche lo schema elettrico dell'operazionale oppure usare lo schedino convertitore predisposto per Arduino, Vedrò come si comporta il circuito e poi studirò gli step successivi.
 

Ora rispondo alla domanda di Maubarzi(Perchè continui a fare una lettura fuori ciclo?),
L'IDE su cui testo gli sketch è 1.8.12 lo avevo frainteso con la disponibilità di una board arduino che non ho, 
In effetti il caos dello skect deriva da il copia ed incolla di alcuni sketch.
Mi sono messo quindi a riflettere su dove era l'errore e ripensando anche a come acquisivo le misure e ho riscritto lo sketch confrontandolo con altri esempi e ho notato le differenze.
Ora sono giunto a questo sketch mi funziona bene ma quando arrivo a misurare 95 mi indica 94 sul 7seg, a 97 indica 96.97 sul virtual monitor e 96sul 7seg, quando misuro 99 sul sensore mi indica 98 sul 7seg,
Tutto questo avviene sempre sul simulatore. 

Segue solo la prima parte dello sketch fino al coalcolo temperatura.
Code: [Select]

int misure[20];
int somma;
int media;
                     
 
void setup()
{
//DDRD=0b11111111;
//DDRB=0b00111111;
Serial.begin(9600);
}
 
void loop(){ 
 analogRead(A0); 
 int i;
  for (i=0;i<20;i++){
    misure[i]=analogRead(A0);
    Serial.println(misure[i]);
 
 }
  somma=0;
  for (int i=0;i<20;i++) {
  somma=somma+misure[i];
 // media=somma/20;
 
  }
 media=somma/20;
  Serial.print("la media e' ");
 Serial.println(media);
 
 
 float voltage = media * 5.0;
 voltage /= 1024.0;

 
 float temperatureC = (voltage - 0.5) * 100 ; 
                                               


 
Spero sia corretto questa volta.

Quello che noto sul serial monitor è che le letture avvengono rapidamente e ogni xtempo dato dal delay viene stampata la temperatura.
Cè un modo per fare le letture 1 al secondo? Sicuramente mi direte di si usalndo il millis.  :(  ::)

Grazie ancora,
PS ogni gg continuo a darvi Karma.



 

maubarzi

#26
Sep 15, 2020, 09:14 am Last Edit: Sep 15, 2020, 09:19 am by maubarzi
Le letture analogiche, hanno si 1024 valori, ma vanno da 0 a 1023, quindi il tuo fondoscala è 1023 e non 1024.
Poi

Code: [Select]

 float voltage = media * 5.0;
 voltage /= 1024.0;


lo puoi fare usando la funzione map() che fa proprio questo tipo di conversioni.

Poi, mi sa che hai problemi di arrotondamento sulle varie variabili.

Un consiglio che mi sentirei di darti è di evitare i float e di usare operazioni su interi, messe nell'opportuno ordine e stando attenti agli overflow.
Come fare con i decimali? Moltiplichi tutto per un multiplo di 10 tale da rendere interi i decimali che ti servono.
Ad es. i 100°C verrebbero rappresentati con 10000.
In questo modo si evitano arrotondamenti strani dei float e piloti tu il risultato che vuoi ottenere.
Non sempre gli arrotondamenti fatti sono quelli consueti, a volte si va solo per troncamento.

Da 10000 per ottenere i gradi basta dividere per 100 (che sugli interi produce già una divisione intera) e per i decimali basta che usi l'operatore % che ti restituisce il resto della divisione intera.

Per la temporizzazione, si, il consiglio e il modo giusto per farle è di usare millis().
E' una brutta bestia? Ti ci sei già imbattuto con scarsi risultati? Alla fine è solo una questione di adattarsi al modo di ragionare dei micro, fatto questo passo ti diventa tutto più naturale. All'inizio può essere antiintuitivo, ma solo perchè non siamo abituati a pensare formalmente a come parallelizziamo le varie operazioni che facciamo tutti i giorni, ma se ci pensi bene, l'approccio umano è molto più vicino all'uso di millis che di delay.

Se vuoi tenere sotto controllo il codice, potresti fare una funzione che fa una singola lettura completa e poi nel loop richiamarla con la logica di utilizzo di millis.

Code: [Select]

#define INTERVAL 1000

void setup() {
  unsigned long prev = millis();
}

void loop() {
  unsigned long curr = millis();
  if (curr - prev >= INTERVAL) { // Scritto così si evita il problema di overflow.
    letturaCompleta();
    prev = curr; // Fatto così cadenza in modo esatto anche se ci sono ritardi nell'esecuzione. Se fai prev = millis(), invece, la cadenza sarà INTERVAL + delta
  }
}


Con questo approccio, ogni compito è isolato in una singola funzione che diventa più leggibile perchè fa meno cose.
Come noti il loop è semplicissimo e si capisce subito cosa fa.
Ogni funzione che vuoi schedulare la puoi richiamare in questo modo con la sua variabile prevXXX dedicata e il suo INTERVALXXX relativo.
Ne metti 2+ in fila e hai un esempio di multi tasking elementare.  ;D

Se ti permangono problemi con decimali o differenze varie, il consiglio è di mettere dei Serial.print nei vari valori per capire da dove derivano e poi agisci di conseguenza cambiando strategia sugli arrotondamenti.

Grazie ancora,
PS ogni gg continuo a darvi Karma.
Dalli quando sono veramente meritati, altrimenti il meccanismo non diventa più meritocratico e perde di significato, oltre a stimolare a tirarla in lungo per guadagnarne di più  :P  :D

Maurizio
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

LOLLO65

Ciao Maubarzi e grazie dei suggerimenti, quanta carne al fuoco, almeno per me,  molto interessanti e mi ci dedicherò.
Comincio a comprendere meglio il millis con gli esempi che hai fatto. andro anche a leggermi tutto sulla funzione map().
Grazie

Ve ne avevo promessi mille di K.
Consentimi, però, di dartene ancora uno credo ke te lo meriti.






 

LOLLO65

Si nel millis mi ci sono già imbattuto e poi sono riuscito ad attenere cio che volevof acendo lampeggiare 3 led raggiunto un determinato valore.

Stavo provando ad inserirlo nello sketch ed cio ottenevo era solo la lettura di analogRead, x la somma e media ottenevo dati errati.

Ciao grazie ancora   

zoomx

Per le termocoppie ci sono degli integrati apposta che poi tu interroghi, Maxim se non sbaglio, li fa anche per le Pt100. Li quello che costa poi è il singolo sensore se lo vuoi di qualità.

I valori vanno da 0 a 1023 e le tensioni vanno da 0 a 4.99 non 5V. O meglio fino alla tensione di riferimento meno la tensione di riferimento diviso 1024 (c'è scritto nel datasheet). Se usi la USB già la tensione di riferimento può essere 4.97 volt o anche meno, ecco perché preferisco i sensori digitali. I chip tipo il Maxim poi ci pensano più o meno loro.


Go Up