Arduino Uno si autoresetta con Display e sonda Temperatura

Ciao a tutti,

sto affrontando una problematica a cui non riesco a venire a capo malgrado innumerevoli tentativi fatti.

Ho realizzato un piccolo sistema che accende per un tempo preimpostato una lampada a 220V (assorbimento: 400W) ed al raggiungimento della temperatura impostata accende anche delle ventoline (tipo computer) a 12V.

Fin qui tutto bene: calcola il tempo, visualizza la temperatura, accende la lampada e le ventoline alla temperatura desiderata ...ma, assolutamente random, ogni tanto si resetta interrompendone il funzionamento.

Oltretutto la sonda invia ogni tanto dei dati errati che ho dovuto eliminare perché sul display creavano casini vari.

Sono disperato!!! :sob:

Grazie mille in anticipo,
Sergio

Allego:
-codice
-schema elettrico (i simboli possono essere errati ma sono quelli che ho trovato ;-))

#include <EEPROM.h>
#include <core_build_options.h>
#include <secTimer.h>
#include <genieArduino.h>

//librerie per gestione sonda temperatura
#include <OneWire.h>
#include <DallasTemperature.h>

//Crea un'istanza della libreria Timer
secTimer myTimer;

#define lampPin        5 //pin uscita Accensione Lampada
#define ONE_WIRE_BUS   6 // pin ingresso dati sonda temperatura
#define ventolePin     7 //pin uscita Accensione ventole

 
// Definisco l'istanza di comunicazione OneWire 
// (valida non solo per il modulo di temperatura Maxim/Dallas)
OneWire oneWire(ONE_WIRE_BUS);
 
// passo da oneWire a Dallas Temperature.
DallasTemperature sensors(&oneWire);

int temperatureSet = EEPROM.read(0);; //variabile temperatura impostata
int temperatureRead; // temperatura letta

int tempoOre = EEPROM.read(1);
int tempoMin = EEPROM.read(2);
long tempo = (tempoOre * 60) + (tempoMin);  //tempo impostato        
long tempoAtt = 0;     //tempo attuale decrescente
long timer = 0;
int tempoAttOre = 0;
int tempoAttMin = 0;
int flagTempoLamp = 0;
int tempoTotLamp = 0;

int counterSondaAvaria = 0;

int tempoTotOreLamp = (EEPROM.read(4) * 100) + EEPROM.read(5); //Tempo totale di utilizzo della lampadina

int sicurezzaState; // variabile sicurezza

int flagSic = 0;

int flag = 0;       //mantiene il valore del "Buttone premuto"



void setup() {
  
  // baud rate di comunicazione porta seriale
  genieBegin (GENIE_SERIAL, 9600);  //Serial0
  
    // Start libreria sonda
  sensors.begin();

  //Tutti i segnali dai pulsanti vengono inviati alla funzione myGenieEventHandler
  genieAttachEventHandler(myGenieEventHandler);

  //Resetta il Display
  pinMode(4, OUTPUT);  
  digitalWrite(4, 1);  
  delay(1000);
  digitalWrite(4, 0);  
  
  delay (3500);
  
  pinMode(lampPin, OUTPUT);
  pinMode(ventolePin, OUTPUT);
  
  //metto il sistema in attesa
  digitalWrite(lampPin, 0);  //spengo resistenza riscaldamento
  digitalWrite(ventolePin, 0);  //spengo le ventole

  genieWriteObject(GENIE_OBJ_LED, 0x01, 0); //spengo il led RUN TEST 
  genieWriteObject(GENIE_OBJ_LED, 0x00, 0); //spengo il led fine ciclo 
  
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x05, temperatureSet);
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x04, temperatureSet);
  
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, tempoMin);
  //genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x06, tempoMin);
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x07, tempoMin); 
      
  //genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, tempoOre);
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x01, tempoOre);
  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x08, tempoOre);
  
   genieWriteObject(GENIE_OBJ_STRINGS, 0x00, 0);
   genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 0);
}


void loop() { 

genieDoEvents();        //gli eventi dal touch sono ricevuti ed incolonnati qui. 

  if (flag == 1) {
     timer = myTimer.readTimer();           
     //tempoAtt = tempo - timer/60; conteggio da tempo impostato a zero
     tempoAtt = timer/60; //conteggio da 0 a tempo impostato
     tempoAttOre = (tempoAtt / 60); //converto i secondi in ore
     tempoAttMin = (tempoAtt % 60); //converto i secondi in minuti
     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x06, tempoAttMin);
     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, tempoAttOre);
     //tempo decrementale
     //if ((tempoAttOre == 0) && (tempoAttMin == 0)) 
     //   flag = 3; 
     //tempo incrementale
     if ((tempoAttOre == tempoOre) && (tempoAttMin == tempoMin)) {
        flag = 3;     
     }
  }
   
   if (flag == 3) { //Stop
     digitalWrite(lampPin, 0);  //spengo resistenza
     genieWriteObject(GENIE_OBJ_LED, 0x01, 0); //spengo il led RUN TEST 
     genieWriteObject(GENIE_OBJ_LED, 0x00, 1); //accendo il led fine cilco
     myTimer.stopTimer();
//     tempoAtt = 0;
//     timer = 0;      
//     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x06, 0);
//     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 0);
     flag = 0;
     genieWriteObject(GENIE_OBJ_SOUND, 0x00, 0);
   }
  
  // chiamo sensors.requestTemperatures() per richiedere la temperatura
  // a tutti i sensori
  sensors.requestTemperatures();
  
  temperatureRead = sensors.getTempCByIndex(0);
    // uso "byIndex" perchè posso avere più sensori 
    // 0 è il primo, 1 il secondo ...
    
 if (temperatureRead > 1 && temperatureRead < 100) {    

  genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x03, temperatureRead);
  
      if (temperatureRead >= 76) {
       flag = 3;
      }

      if ((temperatureRead >= temperatureSet) && (temperatureRead < 76)) {
       digitalWrite(ventolePin, 1);  //Accendo ventole 
      }
      else {digitalWrite(ventolePin, 0);}  //spengo ventole
      
      counterSondaAvaria = 0;
 }
    
// Conteggio il tempo della sonda in avaria per determinare 
// se è rotta o se si tratta di una lettura anomala
 else {
   counterSondaAvaria = counterSondaAvaria + 1;
   delay(1000);
   
   if (counterSondaAvaria == 20) { 
     genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x03, 000);
     digitalWrite(ventolePin, 0);  //spengo ventole
     flag = 3;
   }
 }
  
} // *** Fine LOOP ***
   

//Ho tolto tutte le funzioni in quanto eccedevo il numero max di caratteri ...oltretutto le funzioni sono solo per impostare tempi e temperature

..ma piloti dei relè direttamente dal pin di Arduino? e senza diodo di ricirloco aulla bobina? hai hai hai!!!

Gli optocoppler hanno bisogno di una resistenza per limitare la corrente lato Pilotaggio. Sei sicuro che puoi dare direttamente 5V al SSR e non serve ache lí una resistenza.
Spero che il trasformatore disegnato sia un alimentatore Dc da 12V.
Gli optocoppler non possono pilotare direttamente le ventole; non reggono la corrnete.
ciao Uwe

UWE credo sia peggio di quel che pensi, se leggi su quelle "optocopie" ce scritto RLe1 ecc credo abbia usato il simbolo delle opto per indicare relè :frowning: (jn ogni caso è uno schema poco chiaro)

Martinix:
UWE credo sia peggio di quel che pensi, se leggi su quelle "optocopie" ce scritto RLe1 ecc credo abbia usato il simbolo delle opto per indicare relè :frowning: (jn ogni caso è uno schema poco chiaro)

Questo particolare mi é sfuggito. Ricontrollato; Comunque se é un relé reed puó essere pilotabile con i 30-40 mA di Arduino, ma non senza diodo di protezione.

@Sergiuli: Disegna un schema elettrico consone alle convenzioni elettroniche (anche a mano e fai una foto)

Ciao Uwe

Grazie !!! ...leggo sempre le vostre risposte nei vari topics e vi invidio per la competenza.

Lo schema (come avevo premesso) è giusto come collegamenti ma non come simboli; allego una foto così si vedono meglio i componenti.

dite che bisogna mettere una resistenza per comandare i relè, ma sempre? da quanto?

Potrebbe essere un motivo dell'autospegnimento?

questo è io DS dei relè:
http://www.meder.com/fileadmin/products/en_datasheets/3205100012e.pdf

sembra funzionio a 5V @10mA quindi uan corrente sopportabile da arduino, ma il diodo di protezione, veloce lodevi sempre mettere in antiparallelo alla bobinetta

e lo stesso diodo veloce, lo metterei anche sui motori ventole, perche anche loro emanaono schifezze ed anche dei filtrini, almeno che non siano bruscless che li dovrebbe provvedere la propria elettronica.

se hai la possibilità, prova ad alimentare le ventole con un altro alimentatore in modo da tenere pulita l'alimentazione di arduino e vedi se miglira o no e visto che usi un relè, non collegare le masse delle ventole con quella di arduino lasciale galvanicamente separate!

se il relè ha la bobina a che so 12vcc e tu gli dai 12Vcc di alimentazione NON occorre resitenza perchè è gai dimensionato correttamente.
Diverso il fatto se tu hai un relè a 5vCc e lo alimenti a 12Vcc li si ci devi mettere e calcolare una resistenza per limitare la corrente, ma è uan cosa che si cerca di evitare (manovra di emrgenza), se il tutto funziona a 12Vvc si usanno relè a 12Vcc e via discorrendo

Se in questo modo risolverò il problema sarà per me una gran sollievo, avevo paura di dover rivedere il tutto.

Che tipo di diodi mi consigli di utilizzare? Anche sulle ventole li devo montare in antiparellelo?

Grazie per il tempo che dedicate a tutti noi, cheers

Il picco di tensionen negativo che viene generato dai relé a causa del diodo mancante puó resettare Arduino . Sei fortunato che non Ti abbia rotto l'Arduino.
Per i relé bastano i soliti 1N4148 o i 1N4007 (che sono piu cari). Per la ventola 1N4007.
Ciao Uwe

Ho però ancora un dubbio sullo spegnimento ...ho notato che il problema si pone solo sulle shield dove utilizzo la sonda della temperatura mentre quelle che ho fatto per accendere e spegnere la lampada senza la rilevazione della temperatura funzionano correttamente ...o meglio, non molto correttamente visto che mancano i diodi ;-).

Non può essere un problema della seriale? Potrebbe un conflitto (se c'è) spegnere Arduino?