Info isolamento relèa 5v 30a yyg-2

Buongiorno a tutti, sto riscontrando qualche problemino con questo relè ( https://www.amazon.it/gp/product/B07TWH7FWW/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1 ) che ho mantenuto nel progettino anche se è eccessivo, prima comandava una cella di peltier da 12v 24a ed era dimensionato, ora comanda un compressore ed è di molto sovradimensionato ma l'ho mantenuto lo stesso...
Comunque il problema è il seguente: praticamente ho un sensore di temperatura (ds18B20) che legge una temperatura, sopra una data temperatura avvia il relè che mi raffredda il liquido fino ad un delta che imposto. Con la cella di peltier non avevo problemi di lettura, con il compressore ogni tanto mi da delle letture sballate.
Esempio: temperatura impostata a 4 gradi, il relè stacca a 3,5 e riattacca sopra ai 4,5.
Ogni tanto capita che quando riattacca, alla successiva lettura esca un valore casuale (la lettura è data da un media di letture) inferiore ai 3,5 e stacca, alla successiva legge la giusta temperatura e il compressore va fino a che non deve staccare sotto i 3,5.
é una cosa abbastanza casuale....

Ora il il relè lo alimento direttamente da arduino, vorrei alimentarlo separatamente, la mia domanda è la seguente: semplicemente attacco la 5v di un alimentatore esterno e metto in comune i gnd o devo fare qualche altra cosa?

Di seguito il codice per rendervi conto di cosa deve fare:


```cpp
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int t0=4;
float temperature;
int counter=0;
float media[30];
float result=0;
int soglia=0;
int a=0;
String riga1= "ver 1.1";
String temp;
float delta=0.5;

void setup() {
  Serial.begin(9600);
  //Serial.print("t0=");
  //Serial.println(t0);
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  Serial.println("inizio");
  pinMode(2, OUTPUT); //relè
  pinMode(3, OUTPUT); //led rosso
  pinMode(4, OUTPUT); //led verde
  digitalWrite(2, LOW); //relè spento
  digitalWrite(3, HIGH); //led rosso accesso power
  digitalWrite(4, LOW);  //led verde spento no freddo
  sensors.begin();
  EEPROM.put(a,t0);
  Serial.print("t0=");
  Serial.println(t0);
  lcd.setCursor(0,0);
  lcd.print(riga1);
  lcd.setCursor(0,1);
  lcd.print("t0=");
  lcd.setCursor(4,1);
  //temp=t0;
  lcd.print(t0);
 
}

void loop() {
  tasti();
  raffreddamento();
}
void tasti (){
  int plus= digitalRead(6);
    if (plus==HIGH) {
      t0=t0+1;
      EEPROM.write(a, t0);
      lcd.setCursor(4,1);
      lcd.print("  ");
      lcd.setCursor(4,1);
      lcd.print(t0);
      delay(500);
    }
  int minus=digitalRead(7);
    if (minus==HIGH) {
      t0=t0-1;
      EEPROM.write(a, t0);
      lcd.setCursor(4,1);
      lcd.print("  ");
      lcd.setCursor(4,1);
      lcd.print(t0);  
      delay(500);
    }
}

void printTemperature(String label, float value) {
  if (value != DEVICE_DISCONNECTED_C) {
    Serial.println(label + ": " + String(value) + "°C");
  } else {
    Serial.println("Impossibile rilevare la temperatura");
  }
}
float raffreddamento() {  
  //Serial.println("entrato in raffreddamento");
  sensors.requestTemperatures();
  temperature = sensors.getTempCByIndex(0);
  printTemperature("Temperature", temperature);
  Serial.print("temperature= ");
  Serial.println(temperature);
  if (counter<30) {
      media[counter]=temperature;
      counter++;
  }
  else {
    counter=0;
    calcolaMedia(media);
    
  }
  delay(1000);
}
void calcolaMedia(float array[]) {
  float somma=0;
  for (int i=0; i<30; i++) {
    somma=somma + array[i];
  }
  result=somma/30;
  Serial.println("media temperatura = ");
  Serial.println(result);
  Serial.print("°C");
  lcd.setCursor(8,1);
  lcd.print("t1=");
  lcd.setCursor(11,1);
  lcd.print("    ");
  lcd.setCursor(11,1);
  lcd.print(result);
  attiva(result);
}
int attiva(float value){
    if (value >= (t0+delta)) {
      //Serial.println("entrato ciclo true, soglia= ");
      soglia=1;
      //Serial.println(soglia);
    }
     if (value <= (t0-delta)) {
        soglia=0;
        //Serial.print("entrato ciclo false, soglia= ");
        //Serial.println(soglia);
      }
      peltier();
}
void peltier() {
  
  //Serial.print("valore sogliaControllo ");
  //Serial.println(soglia);
  if (soglia==1) {
    digitalWrite(4,HIGH); //accensione led verde
    digitalWrite(2,HIGH); //accensione peltier
    //Serial.println("attivazione peltier");
  }
  else {
    digitalWrite(4,LOW); //spegnimento led verde
    digitalWrite(2,LOW);  //peltier spenta
    //Serial.println("disattivazione peltier");
  }
}


  

Ecco, fatto così NON serve a nulla ... NON ci devono essere cose in comune, nemmeno i GND e questo lo ottieni con i moduli relè opto isolati che hanno i pin separati per l'alimentazione relè.

Ad esempio, con i classici modulini a 2 relè opto isolati hai:

e, come vedi hai le due cose totalmente separate. Ovviamente il tutto poi lavora a logica inversa ... pin Arduino HIGH - relè non eccitato, pin Arduino LOW - relè eccitato.

Guglielmo

Perfetto;) Grazie mille
Allora cambio relè e risolvo il problema;)

Nella funzione del termostato, quando c'è la transizione da soglia = 0 -> soglia = 1 salva il temo di millis() in una variabile globale, che userai per ritardate l'acquisizione dei campioni di circa 2 o 3 secondi.
In questo modo le letture errate non saranno nell'array dei campioni.
Stessa operazione quando c'è la transizione 1 -> 0 della variabilei soglia.

Ciao.

Oddio non ci avevo pensato....cosi ci metto una pezza sicuramente! Poi cambio il relè e risolvo alla radice;) Grazie mille!

Forse, speriamo, ma magari invece la radice è qualcos'altro (scintillazione dei contatti, disturbi EM irradiati dai collegamenti del compressore) e cambiare relé/alimentazione non fa nessuna differenza.

Grazie per l'integrazione, sicuramente modificando il codice come mi ha suggerito @Maurotec ho risolto il problema, ora non ho più letture fasulle. Per ora lo lascio così, poi quando mi andrà di arrampicarmi e lavorare un attimo scomodo (è tutto sopra un mobile alto) proverò a cambiare anche il relè per vedere se cambia qualcosa. Cmq l'importante è che via software una pezza ce l'ho messa;)

Buongiorno Guglielmo, mi servirebbe una mano o un link...
praticamente ho sostituito il relè con uno che avevo in casa (optoisolato dalla descrizione), ti incollo una foto qui sotto. Non ho trovato naturalmente il jumper che dicevi te in foto e naturalmente se lo attacco all'alimentazione esterna il relè si accende e non mi fa il cambio di stato (luce verde accesa, luce rossa deboluccia, quando avviene il cambio di stato non fa nulla). Il software è stato modificato in logica inversa...Appena ci attacco il gnd di arduino insieme comincia a funzionare tutto....ipotizzo di avere il relè sbagliato....puoi linkarmi su amazon un relè giusto da acquistare?

La correzione software ha funzionato fino ad un certo punto, mi sono accorto che dopo un pò casualmente mi da ancora letture sbagliate quindi voglio isolare completamente questo cavolo di relè....


In realtà avrei un'altra domanda ancora perchè mi sono accorto di un comportamento strano....
Praticamente se attacco la spina parte il tutto e mi fa la prima lettura, in caso sia maggiore di 4,50 parte il compressore e mi porta la temperatura alla soglia corretta (ho impostato a differenza del codice sopra due soglie, superiore e inferiore per gestire l'evaporatore freddo che continua a raffreddare anche a compressore spento, per il resto il codice è uguale).
Dalla seconda accensione del compressore (quindi il ciclo è che l'acqua arriva per esempio a 3,50, si riscalda fino a superare i 4,50) i dati delle letture cominciano a sballare. Praticamente a compressore spento mi fa la lettura giusta, appena si accende anche se ha il delay sulla lettura (sono arrivato ad impostare anche 30 secondi) legge male e mi stacca il compressore. Se stacco la spina e riattacco (quindi resetto) si comporta bene fino alla fine del primo ciclo (temperatura alta-> accensione compressore->arrivo a temperatura->spenta compressore).

Perchè mi fa sta cosa? Cioè è come se i disturbi li sentisse alla seconda accensione del compressore (anche se i controlli sulla temperatura li fa sempre, anche durante la prima accensione)....

Forse in realtà è un problema software di cui non mi accorgo?
Rimetto qui il codice, non tenete conto del delay dei 30 secondi che è orribile ma per fare le prove mi è più veloce che capire come impostare millis()


```cpp
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int t0=4;
float temperature;
int counter=0;
float media[30];
float result=0;
int soglia=0;
int a=0;
String riga1= "ver 1.3";
String temp;
float deltaSup=0.5;
float deltaInf=0.1;
//float controllo=0.50;

void setup() {
  Serial.begin(9600);
  //Serial.print("t0=");
  //Serial.println(t0);
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  Serial.println("inizio");
  pinMode(2, OUTPUT); //relè
  pinMode(3, OUTPUT); //led rosso
  pinMode(4, OUTPUT); //led verde
  digitalWrite(2, HIGH); //relè spento
  digitalWrite(3, HIGH); //led rosso accesso power
  digitalWrite(4, LOW);  //led verde spento no freddo
  sensors.begin();
  EEPROM.put(a,t0);
  Serial.print("t0=");
  Serial.println(t0);
  lcd.setCursor(0,0);
  lcd.print(riga1);
  lcd.setCursor(0,1);
  lcd.print("t0=");
  lcd.setCursor(4,1);
  //temp=t0;
  lcd.print(t0);
 
}

void loop() {
  tasti();
  raffreddamento();
}
void tasti (){
  int plus= digitalRead(6);
    if (plus==HIGH) {
      t0=t0+1;
      EEPROM.write(a, t0);
      lcd.setCursor(4,1);
      lcd.print("  ");
      lcd.setCursor(4,1);
      lcd.print(t0);
      delay(500);
    }
  int minus=digitalRead(7);
    if (minus==HIGH) {
      t0=t0-1;
      EEPROM.write(a, t0);
      lcd.setCursor(4,1);
      lcd.print("  ");
      lcd.setCursor(4,1);
      lcd.print(t0);  
      delay(500);
    }
}

void printTemperature(String label, float value) {
  if (value != DEVICE_DISCONNECTED_C) {
    Serial.println(label + ": " + String(value) + "°C");
  } else {
    Serial.println("Impossibile rilevare la temperatura");
  }
}
float raffreddamento() {  
  //Serial.println("entrato in raffreddamento");
  sensors.requestTemperatures();
  temperature = sensors.getTempCByIndex(0);
  printTemperature("Temperature", temperature);
  Serial.print("temperature= ");
  Serial.println(temperature);
  if (counter<30) {
      media[counter]=temperature;
      counter++;
  }
  else {
    counter=0;
    calcolaMedia(media);
    
  }
  delay(1000);
}
void calcolaMedia(float array[]) {
  float somma=0;
  for (int i=0; i<30; i++) {
    somma=somma + array[i];
  }
  result=somma/30;
  Serial.println("media temperatura = ");
  Serial.println(result);
  Serial.print("°C");
  lcd.setCursor(8,1);
  lcd.print("t1=");
  lcd.setCursor(11,1);
  lcd.print("    ");
  lcd.setCursor(11,1);
  lcd.print(result);
  attiva(result);
}
int attiva(float value){
    if (value >= (t0+deltaSup)) {
      //Serial.println("entrato ciclo true, soglia= ");
      soglia=1;
      //Serial.println(soglia);
    }
     if (value <= (t0-deltaInf)) {
        soglia=0;
        //Serial.print("entrato ciclo false, soglia= ");
        //Serial.println(soglia);
      }
      peltier();
}
void peltier() {
  
  //Serial.print("valore sogliaControllo ");
  //Serial.println(soglia);
  if (soglia==1) {
    digitalWrite(4,HIGH); //accensione led verde
    digitalWrite(2,LOW); //accensione peltier
    //Serial.println("attivazione peltier");
    delay(30000);
  }
  else {
    digitalWrite(4,LOW); //spegnimento led verde
    digitalWrite(2,HIGH);  //peltier spenta
    delay(30000);
    //Serial.println("disattivazione peltier");
  }
}


  

Non è optoisolato. Alimentazione relé, e circuito di comando, non si possono separare. C'è un optoisolatore, ma non ha funzione di separazione galvanica. Però si può comandare sia in logica positiva che negativa tramite impostazione del jumper.

Come è collegato il sensore di temperatura? Quanto sono lunghi i cavi?

Ciao, Ale.

... ne hanno un'infinità ... QUESTO è solo uno dei tanti, ma ... considera prima quello che ti ha detto Claudio_FF e la correttezza di tutto il codice.

Guglielmo

Il sensore di temperatura ha i cavi di lunghezza stock con la resistenza inserita nel modo corretto, ripeto prima ha sempre funzionato, ha portato un sacco di disturbi il compressore che devo risolvere in qualche maniera

Nel caso fosse questo il problema come me ne accorgo? Io intanto il relè giusto l'ho acquistato e domani lo cambio...nel caso dovessi avere ulteriori problemi su cosa posso concentrarmi? Tiene presente che sul relè è montato uno snubber

Ti ringrazio, allora ho acquistato quello giusto. Il codice per le mie conoscenze è corretto, ma ripeto per le mie conoscenze...dovreste darci un occhio voi per vedere se qualche cosa non va e io non mi rendo conto;)

Disturbi che però sembrano interessare più il sensore di temperatura che non l'arduino stesso, per cui non è detto che cambiando relè risolvi.

Ciao, Ale.

si in effetti Arduino non sembra interessato, anche perchè lo schermo non presenta caratteri strani...ricontrollo le saldature della sonda di temperatura...magari ho saldato male e si è mosso qualcosa....

Prova anche ad abbassare il valore della resistenza di pullup, specie se il collegamento è lungo, dai un'occhiata a questa tabella:

Pull up resistor

An indicative table for pull up resistors, (E12 series), to get started.

Note: thicker wires require smaller resistors (typically 1 step in E12 series)

Length 5.0 Volt 3.3 Volt Notes
10cm (4") 10K0 6K8 might work without
20cm (8") 8K2 4K7
50cm (20") 4K7 3K3
100cm (3'4") 3K3 2K2
200cm (6'8") 2K2 1K0
500cm (16'8") 1K0 *
longer * *
  • = no info, smaller?

Poi, se vuoi veramente capire se dipende dal sensore, se ne hai una altro collegalo al suo posto (altrimenti usa direttamente lo stesso), cambia le soglie di temperatura con altre intorno ai 30 gradi, così puoi attivare la soglia anche tenendolo in mano, lascia tutto il resto collegato (relè, compressore, etc) e vedi come si comporta.

Ciao, Ale.

Il collegamento è corto, in realtà seguendo la tabella potrei mettere una resistenza da 8k2 invece che da 4k7...sicuramente stasera stacco questa sonda e ne metto una nuova risaldando da capo....vediamo che cosa esce... La prova "fuori dall'acqua" posso farla anche non cambiando le soglie, sicuro lo provo;)