problema con relè

Salve a tutti
ho un problema con la gestione di relè,

l'hardware consiste in:

  • Arduino Uno R3 alimentata tramite caricabatterie iPhone 5V
  • Sensore di temperatura e umidita', collegati agli ingressi analogici
  • Schermo LCD 16x2 standard (tramite apposita libreria)
  • 3 Relè Songle 12V per commutare linee 220V.

I 3 relè hanno il loro alimentatore da 12V separato dall'alimentazione di Arduino, inoltre sono montati su pcb insieme ai componenti per pilotarli (quindi transistor, diodi di protezione delle bobine, resistenze varie e led di indicazione). Quindi sono collegati ad arduino semplicemente tramite una resistenza, a porte digitali.
L'alimentazione di Arduino e i relè sono quindi separate (non isolate poichè GND è comune).

il software è molto semplice:
La routine principale non fa altro che leggere i dati dei sensori (temperatura e umidita') e a seconda di questi valori letti, decide se attivare o disattivare i relè B e C, ai quali sono collegati rispettivamente le 220V di una stufa e un umidificatore. C'è poi un terzo relè A che è sempre attivo.

Il tutto funziona perfettamente per alcuni giorni (circa 3), dopo di che noto che il relè C al quale è collegato l'umidificatore non commuta più stato (di conseguenza il sensore di umidita' nota la grande differenza di umidita', ma non riesce a intervenire sul relè).

Ecco le prove che ho fatto per cercare di capire il problema:

  1. pensando che fosse un problema di relè, ho provato a invertire i relè (cioè collegare l'umidificatore al relè A o B invece che C) ma a bloccarsi è sempre quello a cui è collegato l'umidificatore (sia esso A B o C), su qualsiasi porta di arduino.
  2. pensando poi che fosse colpa del software, ho provato equivalenti routine per fare le stesse operazioni logiche (ho provato anche a aggiungere un reset ogni 6 ore, ma nonostante il codice si riavvi e quindi le variabili e gli stati delle porte si azzerino, il problema persiste).
  3. dopo il blocco, se prendo il relè e lo test su breadboard, funziona benissimo.
  4. dopo il blocco, se spengo tutto e ricarico lo sketch su Arduino, tutto torna a funzionare benissimo.

Secondo voi da cosa può dipendere?

Potrebbe anche essere un errore nel tuo sketch. Sarebbe utile tu postassi il codice.

certamente, eccolo qui:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

float temp = 0.0;  
float umiRelativa = 0.0;
const float temperatura_riferimento = 37.7;
const float umidita_riferimento = 52;
const float temperatura_tolleranza = 0.2;
const float umidita_tolleranza = 2;
const unsigned int TEMP_PIN = 8;
const unsigned int UMI_PIN = 9;


void setup() {
  pinMode(TEMP_PIN, OUTPUT);
  pinMode(UMI_PIN, OUTPUT);
  digitalWrite(TEMP_PIN, LOW);
  digitalWrite(UMI_PIN, LOW);
  lcd.begin(16, 2);
} 
  
void loop() {

    temperatura(); 
    delay(200);
    umidita();
    stampa();
    delay(800);
}


void temperatura() {
  
  int val = 0;

  for (int i=0; i<100; i++)
    val = val + analogRead(A1);   
  val = val / 100;
  temp = (5 * val /1024.0) * 100.0;
  
  if (temp < temperatura_riferimento - temperatura_tolleranza) 
    digitalWrite (TEMP_PIN, HIGH);
  else if (temp > temperatura_riferimento + temperatura_tolleranza - 0.1) 
    digitalWrite (TEMP_PIN, LOW);
}


void umidita() {
  
  float umi = 0.0;

  for (int k=0; k<100; k++)
    umi = umi + analogRead(A0);   
  umi = umi / 100;

  umiRelativa = (((umi / 1023) * 5) - 0.8) / 0.031; 
  umiRelativa = umiRelativa/(1.0546 - (0.00216 * temp));
  
  if (umiRelativa < (umidita_riferimento - umidita_tolleranza)) 
    digitalWrite (UMI_PIN, HIGH);
  else if (umiRelativa > (umidita_riferimento + umidita_tolleranza))
    digitalWrite (UMI_PIN, LOW);
}


void stampa() {
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T:");
  lcd.print(temp);
  lcd.print("-");
  lcd.print("U:");
  lcd.print(umiRelativa);
}

Qui io metterei dei numeri float, ma non credo sia questo il problema:

umiRelativa = (((umi / 1023) * 5) - 0.8) / 0.031;

Metti 1023.0 e 5.0 così viene interpretato come float (umi è float)

Sottigliezza, questo:

const unsigned int TEMP_PIN = 8;

puoi mettere unsigned char o byte, int è eccessivo.

Io non vedo errori, almeno guardando il codice senza poterlo testare dal vivo.
Eventualmente puoi collegare Arduino ad un PC con cavo USB e usare il Monitor Seriale per fare un pò di debug? Ad esempio stampando i valori delle variabili, per vedere se dopo un pò qualcosa non è come dovrebbe secondo la logica del codice.

ti ringrazio per l'aiuto,
avevo pensato di fare un log su scheda SD invece che via seriale (perche' non posso lasciare il pc connesso a arduino per 3 giorni di fila).. Però poi ho pensato di resettare arduino automaticamente ogni tot ore, proprio per vedere se il problema era legato alla logica (magari dovuto all'accumulo di qualche variabile o cose così)..
Allora ho attivato il watch dog timer ogni 6 ore (guidato da un interrupt che porta il tempo), l'arduino faceva reset correttamente ogni 6 ore, tuttavia il problema persisteva anche in questo modo.

secondo voi in questa riga faccio bene a dividere per 1024? non ricordo come sono arrivato a questa istruzione, però mi sembra strana una divisione per 1024, non dovrebbe essere 1023?
Tuttavia di sicuro non risolve il problema..

  temp = (5 * val /1024.0) * 100.0;

perche il ADC di arduino è a 10 bit quindi–> 2^10 = 1024 che dovrebbe essere più corretto, ma che tu divida per 1024 o 1023 non dovresti compiere un errore cosi grosso!!

ti ringrazio, allora forse sbaglio qui:

umiRelativa = (((umi / 1023) * 5) - 0.8) / 0.031;

dovrei mettere anche qui 1024, anche se come hai detto l'errore è molto piccolo, ma comunque in linea teorica è pur sempre errato giusto?

ma in realtà puoi usare quello che vuoi 1024 son il "numero di gradini massi possibili" ma i valori restituito son 1024-1 (se ricordo bene) io più che concentrarmi se usare l'uno o latro mi preoccuperei di usare sempre lo stesso valore :wink:

Ma i valori stampati sul LCD sono corretti?
Ad esempio se stampa U: 65 dovrebbe azionare il relè dell'umidificatore. Giusto?

Hai la possibilità di far funzionare il programma collegato alla USB e stampare i valori su seriale?

Che tipo di sensori usi? Hai un link al datasheet?