Campionamento con Termocoppie e Contagiri

Ciao a tutti! Sto avendo problemi a far funzionare il codice del mio progetto. Problemi sicuramente legati alla mia ignoranza in fatto di programmazione.
Inizio dal principio e vi spiego la situazione. Ho un tornio un po' datato e ho la necessità di campionare delle temperature e la velocità di rotazione del mandrino. L'intervallo di velocità del mandrino è tra i 100rpm e i 1000rpm. Inoltre, sto sfruttando una scheda MEGA2560.
La questione temperatura l'ho risolta acquistando quattro termocoppie di tipo K con relativo circuito integrato (MAX6675), ne ho scritto il codice che campiona ogni 2 secondi e poi sfrutto un programma esterno (CoolTerm) per il salvataggio dei dati su file .txt (che poi vado ad aprire in excel).
I problemi nascono nel momento in cui voglio andare a misurare il tempo che ci impiega il mandrino a compiere una rotazione. Per fare tale misurazione ho acquistato un sensore ad effetto hall (KY-003).
Ho sfruttato uno sketch trovato su questo forum per far campionare il sensore. Tale sketch sfrutta la funzione interrupt, la quale mi sta dando parecchie rogne.

di seguito il codice:

#include <max6675.h>

int ktcSO1 = 6; //Termocoppia #3
int ktcSO2 = 7; //Termocoppia #2
int ktcSO3 = 8; //Termocoppia #1
int ktcSO4 = 5; //Termocoppia #4
int ktcCS = 9; 
int ktcCLK = 10; 

unsigned long time;
unsigned long Tempo_Attuale; 
unsigned long Tempo_Precedente;
unsigned long Tempo_Evento;  
 
MAX6675 ktc1(ktcCLK, ktcCS, ktcSO1);
MAX6675 ktc2(ktcCLK, ktcCS, ktcSO2);
MAX6675 ktc3(ktcCLK, ktcCS, ktcSO3);
MAX6675 ktc4(ktcCLK, ktcCS, ktcSO4);

void setup() {
  attachInterrupt(0,Evento,RISING); //mettere su pin digitale 2
  Serial.begin(9600);
  Serial.print("Tempo"); 
  Serial.print(" ");  //questo spazio mi serve per facilitare il passaggio da txt a excel
  Serial.print("Termo#1");
  Serial.print(" "); 
  Serial.print("Termo#2");
  Serial.print(" ");
  Serial.print("Termo#3");
  Serial.print(" "); 
  Serial.print("Termo#4");
  Serial.print(" ");
  Serial.println("Millisecondi/Giro");
}

void loop() {
    time = millis();
    Tempo_Attuale = millis();
    
    Serial.print(time/1000);
    Serial.print(" ");
    Serial.print(ktc3.readCelsius());
    Serial.print(" ");
    Serial.print(ktc2.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc1.readCelsius());
    Serial.print(" "); 
    Serial.println(ktc4.readCelsius());
    
    delay(2000);
 }
 
  void Evento(){ 
    Tempo_Evento = Tempo_Attuale - Tempo_Precedente;
    Serial.println(Tempo_Evento);                            
    Tempo_Precedente = Tempo_Attuale;
}

Giustamente, quando viene "attivato" il void Evento(), questo mi va a bloccare momentaneamente il loop per stampare sul seriale il valore Tempo_Evento. Però questa cosa non mi va bene, perché mi va a "sporcare" l'acquisizione dei dati di temperatura. Vi faccio un'esempio:

12 25.50 26.25 26.25 27.25
14 25.50 26.00 26.25 27.25
4272
17 25.75 25.75 2136
25.75 27.25
0
0
19 25.50 26.00 26.00 27.00
2137

In rosso ho segnato il tempo trascorso dall'avvio, in verde la temperatura delle quattro termocoppie e in nero i valori relativi al tempo al giro (il fatto che siano molto differenti tra di loro è semplicemente perchè al momento sto provando il sensore "manualmente", facendoci passare vicino un magnete).
In primo luogo ho problemi legati all'interruzione del mio loop, come al tempo 17. in secondo luogo, ho problemi legati all'acquisizione del tempo del giro al di sotto dei 2000 ms, infatti mi restituisce un valore pari a 0.

Arrivato a questo punto ho provato una seconda strada, ovvero utilizzare un costrutto IF-ELSE:

#include <max6675.h>

int ktcSO1 = 6; //Termocoppia #3
int ktcSO2 = 7; //Termocoppia #2
int ktcSO3 = 8; //Termocoppia #1
int ktcSO4 = 5; //Termocoppia #4
int ktcCS = 9; 
int ktcCLK = 10; 

unsigned long time;
unsigned long Tempo_Attuale; 
unsigned long Tempo_Precedente;

int hall = 2; //pin sensore effetto hall
int val; //numeric variable

 
MAX6675 ktc1(ktcCLK, ktcCS, ktcSO1);
MAX6675 ktc2(ktcCLK, ktcCS, ktcSO2);
MAX6675 ktc3(ktcCLK, ktcCS, ktcSO3);
MAX6675 ktc4(ktcCLK, ktcCS, ktcSO4);

void setup() {
  Serial.begin(9600);
  pinMode(hall, INPUT); //settaggio sensore effetto hall
  Serial.print("Tempo");
  Serial.print(" ");
  Serial.print("Termo#1");
  Serial.print(" ");
  Serial.print("Termo#2");
  Serial.print(" ");
  Serial.print("Termo#3");
  Serial.print(" ");
  Serial.print("Termo#4");
  Serial.print(" ");
  Serial.println("Millisecondi/Giro");
}

void loop() {
  val = digitalRead(hall);
  time = millis(); 
  Tempo_Attuale = millis();   
  if (val == HIGH){
    Serial.print(time/1000);
    Serial.print(" "); 
    Serial.print(ktc3.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc2.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc1.readCelsius());
    Serial.print(" ");
    Serial.print(ktc4.readCelsius());
    Serial.print(" ");
    Serial.println("none");
  }
  else{
    Serial.print(time/1000);
    Serial.print(" "); 
    Serial.print(ktc3.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc2.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc1.readCelsius());
    Serial.print(" ");
    Serial.print(ktc4.readCelsius());
    Serial.print(" ");
    Serial.println(Tempo_Attuale-Tempo_Precedente);
    Tempo_Precedente = Tempo_Attuale;
  }
  //delay(2000); 
 }

Pure in questo caso mi sono ritrovato ad avere problemi: se mantengo il delay(2000), quello che ottengo è la perdita del'acquisizione del segnale del contagiri. Se invece tolgo il delay, il sistema delle termocoppie non è più in grado campionare le temperature, segnandomi sempre la temperatura ambiente.

Ipotizzando che il primo codice che ho scritto sia quello più corretto, vorrei sapere se è possibile modificare o riscrivere il codice in maniera tale che la funzione che calcola il tempo al giro, non vada ad interrompere quella del campionamento delle temperature.

Un'altra possibile idea che mi era venuta prevedeva di salvare i valori del tempo per giro in un array per poi stamparli a schermo una volta finito il mio ciclo di campionamento. Però avrei la necessità di far girare il tornio per 45minuti a 1000Giri al minuto, e dubito fortemente si possano tenere in memoria 45000 valori.

Chiedo scusa per la lunghezza del post, ma ho cercato di spiegare tutto quanto per dare un quadro completo della situazione. O perlomeno è quello che ho cercato di fare. Ovviamente qualsiasi consiglio anche per quello che sto considerando corretto nel codice è ben accetto.

Ringrazio anticipatamente chiunque si prenderà la briga di leggere.

E' stato detto e ripetuto tantissime volte su questo forum ... :slight_smile:
... le ISR debbono essere le più brevi possibili e NON DEVONO ASSOLUTAMNETE né usare la porta seriale né l'istruzione delay().

Quindi, tanto per cominciare, nella ISR salva i valori che ti servono, alza una "flag" e nel loop() se tale flag è alzata stampi quello che vuoi e la resetti, ma NON usare la seriale nella ISR.

Dopo di che ... guarda il tuo secondo blocco di codice ... è pieno di "porcherie (BBcode)" dati dalla formattazione (colori) che ti sei portato dietro ... cortesemente correggi, grazie :wink:

Guglielmo

Grazie per la risposta!

Non riesco a capire cosa intendi con:

gpb01:
alza una "flag"

mentre per quanto riguarda le porcherie del secondo codice, ipotizzo ti riferisca ai due colori rosso e verde. Li ho usati solo durante la scrittura di questo post semplicemente per evidenziare i vari contenuti. Nel codice non ci sono.

Prima di tutto TUTTE le variabili usate in una ISR devono essere dichiarete "volatile", poi, ne dichiari una che chiami miaFlag e la metti a valore "false".

Quando entri nella ISR, fai il minimo di cose indispensabili e, prima di uscire, metti miaFlag a "true".

Nel loop(), che gira sempre, controlli il valore di miaFlag ... se lo trovi "true" vuol dire che la ISR è partita e ci sono cose che puoi stampare, rimetti la miaFlag a "false" (così al prossimo interrupt te ne accorgi) e stampi quello che devi stampare. E' il modo "corretto" di gestire le cose in una ISR ... farla la più breve possibile e fare fuori tutto quello che può essere fatto fuori. La seriale poi NON va proprio usata per un problema di "interrupts" che, anche essa, usa.

Per i colori, ora va bene, visto che hai tolto i tag CODE :wink:

Guglielmo

una cosa del tipo:

volatile bool giroFatto=false  // da mettere all'inizio del programma

void Evento(){
    Tempo_Attuale=millis()  // o micros()
    giroFatto= true
}

poi nel loop

void loop() {
    if (giroFatto) {
       Tempo_Evento = Tempo_Attuale - Tempo_Precedente;
       Serial.println(Tempo_Evento);                            
       Tempo_Precedente = Tempo_Attuale;
       giroFatto = false
   }
}

Grazie mille ad entrambi, gentilissimi.
Ho modificato il codice seguendo i vostri consigli. Il risultato è il seguente:

#include <max6675.h>

int ktcSO1 = 6; //Termocoppia #3
int ktcSO2 = 7; //Termocoppia #2
int ktcSO3 = 8; //Termocoppia #1
int ktcSO4 = 5; //Termocoppia #4
int ktcCS = 9; 
int ktcCLK = 10; 

unsigned long time;
volatile int Tempo_Attuale; 
volatile int Tempo_Precedente;
volatile int Tempo_Evento;  
volatile bool giro = false;

MAX6675 ktc1(ktcCLK, ktcCS, ktcSO1);
MAX6675 ktc2(ktcCLK, ktcCS, ktcSO2);
MAX6675 ktc3(ktcCLK, ktcCS, ktcSO3);
MAX6675 ktc4(ktcCLK, ktcCS, ktcSO4);

void setup() {
  attachInterrupt(0,Evento,RISING); //mettere su pin digitale 2
  Serial.begin(9600);
  Serial.print("Tempo");
  Serial.print(" ");
  Serial.print("Termo#1");
  Serial.print(" "); 
  Serial.print("Termo#2");
  Serial.print(" ");
  Serial.print("Termo#3");
  Serial.print(" "); 
  Serial.print("Termo#4");
  Serial.print(" ");
  Serial.println("Millisecondi/Giro");
}

void loop() {
    time = millis();
    Tempo_Attuale = millis();
    
    Serial.print(time/1000);
    Serial.print(" ");
    Serial.print(ktc3.readCelsius());
    Serial.print(" ");
    Serial.print(ktc2.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc1.readCelsius());
    Serial.print(" "); 
    Serial.print(ktc4.readCelsius());
    Serial.print(" "); 
    if (giro) {
       Tempo_Evento = Tempo_Attuale - Tempo_Precedente;
       Serial.println(Tempo_Evento);                            
       Tempo_Precedente = Tempo_Attuale;
       giro = false;
    }
    else{
      Serial.println(" "); 
    }
    delay(2000);
 }
 
 
  void Evento(){ 
    Tempo_Attuale = millis();
    giro = true;
}

L'unico problema che sto riscontrando è che il valore del giro è ancora soggetto al delay. Quindi se ho frequente di rotazione al di sotto dei 2000ms non vengono stampate. Per la precisione, il valore minimo che mi segna il Tempo_Attuale è di 2136ms. Se il tornio girasse a 1000rpm, significherebbe che dovrei campionare a (1000/60)^-1= 0.06sec= 60ms. Ma un delay(60) non è compatibile con le mie termocoppie

usa un'altra variabile sempre con millis() per impostare i tempi della stampa nel loop. I delay() devono sparire!!!!

Ho modificato secondo i vostri consigli e ora funziona tutto perfettamente. grazie mille a tutti!

Come non detto. Il codice si compila correttamente ma da un po' di problemi.
Il codice modificato è il seguente:

#include <max6675.h>

int ktcSO1 = 6; //Termocoppia #3
int ktcSO2 = 7; //Termocoppia #2
int ktcSO3 = 8; //Termocoppia #1
int ktcSO4 = 5; //Termocoppia #4
int ktcCS = 9; 
int ktcCLK = 10; 

unsigned long time;
unsigned long Tprecedente = 0; 
unsigned long intervallo = 2000; 
volatile long Tempo_Attuale; 
volatile long Tempo_Precedente;
volatile long Tempo_Evento;  
volatile bool giro = false;

MAX6675 ktc1(ktcCLK, ktcCS, ktcSO1);
MAX6675 ktc2(ktcCLK, ktcCS, ktcSO2);
MAX6675 ktc3(ktcCLK, ktcCS, ktcSO3);
MAX6675 ktc4(ktcCLK, ktcCS, ktcSO4);

void setup() {
  attachInterrupt(0,Evento,RISING); //mettere su pin digitale 2
  Serial.begin(9600);
  Serial.print("Millisecondi/Giro");                   
  Serial.print(" ");                                   
  Serial.print("Tempo");
  Serial.print(" ");
  Serial.print("Termo#1");
  Serial.print(" "); 
  Serial.print("Termo#2");
  Serial.print(" ");
  Serial.print("Termo#3");
  Serial.print(" "); 
  Serial.println("Termo#4");
}

void loop() {
    time = millis();
    Tempo_Attuale = millis();
    unsigned long Tcorrente = millis();                
    
    if (giro) {
       Tempo_Evento = Tempo_Attuale - Tempo_Precedente;
       Serial.println(Tempo_Evento);                                       
       Tempo_Precedente = Tempo_Attuale;
       giro = false;
    }
    if(Tcorrente - Tprecedente > intervallo) {         //nuova parte
      Tprecedente = Tcorrente;
      Serial.print("/");
      Serial.print(" ");
      Serial.print(time/1000);
      Serial.print(" ");
      Serial.print(ktc3.readCelsius());
      Serial.print(" ");
      Serial.print(ktc2.readCelsius());
      Serial.print(" "); 
      Serial.print(ktc1.readCelsius());
      Serial.print(" "); 
      Serial.println(ktc4.readCelsius());
      }
    
 }
  
  void Evento(){ 
    Tempo_Attuale = millis();
    giro = true;
}

Il problema principale è che nel momento in cui faccio partire il tutto, i valori delle temperature oscillano in maniera strana.
In realtà, i valori della termocoppia ktc1 si comportano in maniera apparentemente corretta, mentre quelli delle altre 3 termocoppie no. A fronte di ciò, posso dire che la prima termocoppia è stata acquistata dal seguente link, mentre le altre tre sono state acquistate da questo link.
Quello che ho notato è che, quando collego sia termocoppie che sensore hall per i giri, i dati che mi vengono stampati risultano sballati. Di seguito un esempio:

/ 60 43.50 43.25 30.75 42.50
604
585
596
596
/ 62 42.50 107.25 8.50 59.75
595
595
595
/ 64 43.50 51.50 30.50 43.00
596
595
595
/ 66 44.00 42.00 30.50 43.50
655
536
595
595
/ 68 43.75 40.00 30.75 12.00
596
595
595
/ 70 44.25 45.25 30.25 42.50
596
595
595
/ 72 44.50 43.25 30.75 43.50
705
485
595
595

In giallo ci sono il numero di giri, in verde il tempo di campionatura delle termocoppie e in nero ho lasciato le termocoppie. Il primo valore di temperatura si riferisce alla termocoppia del primo link, la quale non da problemi.
Però, nel momento in cui vado a scollegare il sensore hall lasciando collegate le termocoppie, i valori di temperatura si ristabilizzano tutti quanti. (ad eccezione di alcune oscillazioni della seconda termocoppia che a volte varia di +o- 10gradi)

/ 140 44.00 49.50 30.75 46.25
/ 142 44.25 45.00 31.75 47.25
/ 144 43.75 48.75 32.25 47.25
/ 146 44.75 59.25 33.00 47.00
/ 148 44.25 49.25 31.75 47.50
/ 150 44.25 49.50 32.00 47.50
/ 152 44.75 51.00 33.00 48.25
/ 154 44.00 49.25 32.00 47.75
/ 156 44.25 49.50 31.50 47.25
/ 158 44.50 40.00 32.25 49.00
/ 160 44.50 49.50 32.25 47.00

Voi sapreste darmi qualche indicazione? Non ho la benchè minima idea sul dove andare a sbattere la testa. Ho provato ad invertire anche le varie termocoppie, scambiare i circuiti integrati max6675, ma niente, l'integrato della termocoppia del primo link va sempre bene, gli altri tre no.

Ps: i circuiti integrati delle termocoppie sono quelli linkati precedentemente, mentre le termocoppie vere e proprie sono queste

nel caso potesse risultare utile, vi allego anche un grafico dell'andamento delle temperature. le oscillazioni risultano essere accoppiate all'attivazione del sensore hall

Temperature.pdf (47.3 KB)

allora:

non ho verificato se ci sono dei limiti di tempo tra una lettura e l'altra per le varie sonde, però se staccando il sensore hall funziona tutta.... mi sa che c'è qualche interferenza

quello che volevo invece farti notare è questo:
se
tempo_totale = millis()
lo metti nel loop
ogni volta che passi da li lo cambi, invece tu vuoi misutare il tempo tra 2 impulsi (1 giro) del motorino
quindi va eliminato. al limite va messo come ultima istruzione del setup.

allo stesso modo Tcorrente non ti serve, usa direttamente millis() nei calcoli

time = millis() che ti serve? visto che lo leggi anche questo ad ogni giro di loop
e se sono passati i 2 secondi lo stampi sulla seriale, quindi il suo valore può variare da circa 0 a 1 millisecondi
inoltre vedi che si colora in arancio (vuol dire che è una parola utilizzata da qualche funzione) quindi sarebbe meglio chiamarla tempo

infine le variabili di tipo volatile se le usi per memorizzare i millis() vanno dichiarate unsigned quindi
volatile unsigned long nomeVariabile

te l'ho solo ripulito un po...

#include <max6675.h>

int ktcSO1 = 6; //Termocoppia #3
int ktcSO2 = 7; //Termocoppia #2
int ktcSO3 = 8; //Termocoppia #1
int ktcSO4 = 5; //Termocoppia #4
int ktcCS = 9;
int ktcCLK = 10;

//unsigned long time;

unsigned long Tprecedente = 0;
unsigned long intervallo = 2000;

unsigned long Tempo_Precedente;
volatile unsigned long Tempo_Attuale ;
volatile bool giro = false;

MAX6675 ktc1(ktcCLK, ktcCS, ktcSO1);
MAX6675 ktc2(ktcCLK, ktcCS, ktcSO2);
MAX6675 ktc3(ktcCLK, ktcCS, ktcSO3);
MAX6675 ktc4(ktcCLK, ktcCS, ktcSO4);

void setup() {
   attachInterrupt(0, Evento, RISING); //mettere su pin digitale 2
   Serial.begin(9600);
   Serial.print("Millisecondi/Giro");
   Serial.print(" ");
   Serial.print("Tempo");
   Serial.print(" ");
   Serial.print("Termo#1");
   Serial.print(" ");
   Serial.print("Termo#2");
   Serial.print(" ");
   Serial.print("Termo#3");
   Serial.print(" ");
   Serial.println("Termo#4");
   Tempo_Attuale = millis();
}

void loop() {
   //  time = millis();
   if (giro) {
      //Tempo_Evento = Tempo_Attuale - Tempo_Precedente;
      Serial.println(Tempo_Attuale - Tempo_precedente);
      Tempo_Precedente = Tempo_Attuale;
      giro = false;
   }
   if (millis() - Tprecedente > intervallo) {        //nuova parte
      Serial.print("/");
      Serial.print(" ");
      //   Serial.print(time / 1000);
      Serial.print(" ");
      Serial.print(ktc3.readCelsius());
      Serial.print(" ");
      Serial.print(ktc2.readCelsius());
      Serial.print(" ");
      Serial.print(ktc1.readCelsius());
      Serial.print(" ");
      Serial.println(ktc4.readCelsius());
      Tprecedente = millis();
   }
}

void Evento() {
   Tempo_Attuale = millis();
   giro = true;
}

Per prima cosa grazie per la pulizia al codice. Anche a me sembrava ci fossero troppe cose, ma visto che mi funzionava ho optato per non togliere niente.
In secondo luogo, secondo voi queste interferenze da cosa potrebbero essere causate? La cosa strana è che mi da problemi solo con 3 termocoppie e non con tutte e 4. Per quanto riguarda le componenti dovrebbero essere uguali per tutte le termocoppie, o sbaglio?
I cavi delle termocoppie che sto usando sono di 2metri, ho ipotizzato fossero troppo lunghi, ma comunque non mi spiego come mai rimane sempre una sola termocoppia che funzioni e le altre no.
Per quanto riguarda la disposizione, i 4 circuiti integrati delle termocoppie sono stati messi uno di fianco all'altro sulla breadboard. è possibile che interferiscano l'una con l'altra? In questo momento non sono a casa, appena riesco carico anche una foto di come le ho collegate

sicuramente i componenti possono essere "simili" per tutte le schedine ma sicuramente non uguali :smiley:

hai notato che la max6675 da come tensione di funzionamento 3-5V Gamma di temperatura: -20 ? ~ 85 ?.

mentre la Haljia solo 3V Gamma di temperatura Tipo K 0 - 600℃

ma l'intervallo -20/+80 °C si riferisce alla temperatura a cui deve stare la giunzione fredda. mentre il range di intervallo che può essere misurato in un caso è 0/600 e nell'altro è 0/1024 e direi che, per le misurazioni che devo fare, questi due intervalli comprono largamente i valori di mio interesse.
per la tensione di funzionamento, sinceramente mi sono accorto solo ora, anche perchè ho sempre fatto riferimento ai datasheet trovati in rete che mi davano una tensione tra i 3.3 e 5V.
io adesso sto alimentando tutto con una tensione di 5V, però devo dire che la Haljia è l'unica che non mi da problemi

un momento però!

MAX6675 ktc1(ktcCLK, ktcCS, ktcSO1);
MAX6675 ktc2(ktcCLK, ktcCS, ktcSO2);
MAX6675 ktc3(ktcCLK, ktcCS, ktcSO3);
MAX6675 ktc4(ktcCLK, ktcCS, ktcSO4);

tu stai usando 1 solo pin CS per tutte le sonde e cambi invece il MISO

prova a cambiare così

MAX6675 ktc1(ktcCLK, ktcSO1, ktcCS);
MAX6675 ktc2(ktcCLK, ktcSO2, ktcCS);
MAX6675 ktc3(ktcCLK, ktcSO3, ktcCS);
MAX6675 ktc4(ktcCLK, ktcSO4, ktcCS);

magari poi cambia il mone a KtcCS in ktcMISO

scusa ma non riesco a seguire il tuo ragionamento.
cambiare il CS in MISO cosa dovrebbe comportare?
e poi, quale dovrebbe essere il risultato di invertire ktcCS con ktcSO#?

io mi sono affidato a questo sito per collegare e far funzionare le termocoppie. ho semplicemente ipotizzato che l'unica cosa che doveva cambiare nei vari circuiti max6675 era il collegamento di output (SO) mentre il CS e il CLK li tenevo uguali

int ktcSO1 = 6; //Termocoppia #3
int ktcSO2 = 7; //Termocoppia #2
int ktcSO3 = 8; //Termocoppia #1
int ktcSO4 = 5; //Termocoppia #4
int ktcCS = 9; 
int ktcCLK = 10; 


MAX6675 ktc1(ktcCLK, ktcCS01, ktcCS);
MAX6675 ktc2(ktcCLK, ktcCS02, ktcCS);
MAX6675 ktc3(ktcCLK, ktcCS03, ktcCS);
MAX6675 ktc4(ktcCLK, ktcCS04, ktcCS);

Patrick_M non ha tutti i torti, il collegamento corretto è questo.
Si lavora sul CS, non sul MISO

KatzFrey:
scusa ma non riesco a seguire il tuo ragionamento.
cambiare il CS in MISO cosa dovrebbe comportare?
e poi, quale dovrebbe essere il risultato di invertire ktcCS con ktcSO#?

io mi sono affidato a questo sito per collegare e far funzionare le termocoppie. ho semplicemente ipotizzato che l'unica cosa che doveva cambiare nei vari circuiti max6675 era il collegamento di output (SO) mentre il CS e il CLK li tenevo uguali

il cambio del nome della variabile non comporta nulla.... è solo per coerenza nel senso che siccome vanno scambiati i collegamenti avrai nuovamente il nome corretto.

la tua ipotesi non è corretta infatti il protecollo SPI prevede che si possano collegare più oggetti sulle stesse linee di clock e dati (CLK e SO) mentre la selezione dell'oggetto che invia la comunicazione è data alzando e abbassando il pin CS (chip Select) così come li hai collegati tu iniziano a trasmettere tutti assieme
collegali secondo lo schema che ti ha postato brunello e poi verifica se hai ancora i problemi che lamentavi all'inizio :wink:

Perfetto, appena riesco provo come mi avete consigliato e vi faccio sapere.
Anche se però ho ancora un dubbio: ma se il collegamento che ho fatto io è sbagliato, come mai se ho solo le termocoppie collegate mi funziona e mi segna le temperatura corrette, mentre se ci collego anche il contagiri no?
diciamo che è più una mia curiosità personale questa domanda

per ora vi ringrazio

Purtroppo, anche modificando il codice come mi avete suggerito, non è cambiato nulla. Quello che ho ottenuto ora è che l'andamento, anche in assenza di contagiri, ha delle oscillazioni che prima non aveva. Metto in allegato un grafico per render meglio l'idea. La curva in blu si riferisce alla termocoppia che non mi ha mai dato problemi.

A questo punto, ragionando tra me e me, ho ipotizzato potesse esserci un problema nel come avevo fatto il circuito, magari qualche collegamento sbagliato ecc.. per cui quello che ho fatto è stato riscrivere la prima parte del codice in modo tale da rendere indipendenti sia il CLK che l'SO delle varie termocoppie. Il problema è che così facendo non ho risolto assolutamente nulla. ottengo ancora gli stessi risultati di prima

Andamento termocoppia#1.pdf (55.7 KB)