Arduino in crash

Da quando ho messo su il mio progettino per la realizzazione di una incubatrice automatica, sto avendo una serie di problemi con arduino, se lavora per poco (10-20min) nessun problema, ma se lo lascio acceso per qualche ora inizia a dare problemi. Considerando che dovrà stare acceso anche per mesi interi (che non so quanto gli faccia bene) chiedo aiuto a voi. Nel progetto sono presenti:
2 sonde dht22 ( controllo umidità, sono le prime a bloccarsi e a segnare 0 sul display)
2 sonde ds18b20 ( che non stanno dando problemi per ora)
3 relè su moduli separati
1 display 20x4

Dopo qualche ora sul display si iniziano a vedere caratteri strani: frecce, virgole, punti e chi ne ha più ne metta. A questo punto diventano illeggibili i dati di arduino ( temperature e umidità) e arduino si blocca.
Molto spesso prima di questo problema perdo le informazioni dalle sonde di umidità che segnano 0% e che ovviamente mi fanno accedere la macchina dell’umiltà che la fa arrivare alle stelle.
Tutto il materiale è montato in una scatola 30x20x10, le sonde sono fuori ovviamente.
Grazie in anticipo a chi mi aiuterà!!

Il comportamento sembra dovuto ad eccessivo riscaldamento della scatola che contiene Arduino & compagnia (probabilmente anche l'alimentatore).

A che tensione alimenti Arduino?

Fa' questa prova: all'apparire dei sintomi apri la scatola e tocca il chip dell'Arduino. Se ti scotti è quello.

Se all'apparire dei sintomi apri la scatola e raffreddi il tutto, torna a funzionare? E se resetti Arduino senza diminuire il calore?

Caio,
P.

Probabilmente dipende dai relè. Prova ad allontanare le schede relè o a toglierli del tutto.

Arduino lo alimento a 9v 1A max, dopo il crash se tolgo e rimetto l'alimentazione riprende a funzionare, quindi non credo che sia il calore, comunque prove a toccare il chip di arduino. Provo anche a scollegare i relè e vedo che succede.

... il problema è sicuramente con i relè ... se ne è parlato decine e decine di volte qui sul forum e sono state date anche le soluzioni. Fai una ricerca.

Guglielmo

L'OP segnala che il fenomeno si manifesta "dopo qualche ora". In generale i problemi con i relè si manifestano improvvisamente all'attacco/stacco del relè stesso.

Sarebbe interessante anche vedere il codice che usa. Potrebbe saturarsi la memoria dinamica.

banks01 posta il codice.

Ciao,
P.

pgiagno:
L’OP segnala che il fenomeno si manifesta “dopo qualche ora”. In generale i problemi con i relè si manifestano improvvisamente all’attacco/stacco del relè stesso.

… diciamo che NON c’è una “regola” per queste cose … può capitare come può non capitare e, quando capita, si blocca tutto :smiley: Magari attiva alcuni relè in momenti diversi, vai a sapere …

Concordo comunque che un’occhiata al codice può essere proficua, anche per scoprire se usa ed abusa della classe “String”, altro noto problema dicusso centiania di volte sempre qui sul forum :wink:

>banks01: …mi raccomando, in conformità al regolamento, punto 7, il codice va racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone </> … primo a sinistra.

Guglielmo

Se ci fai caso vedrai che Arduino NON si blocca (prova a far lampeggiare un led, contemporaneamente al programma e comunque puoi usare il watch dog, ma vedrai che raramente arduino si blocca).
Certo è che non riesci a leggere niente sul display (è diventato una bestia nera questo problema) e probabilmente anche le sonde ti danno letture errate. Per resettare il display non ci sono altre soluzioni che spegnerlo e riaccenderlo, dato che la routine di reset funziona solo all'accensione.
Una mia soluzione è stata di alimentare il display con un pin di Arduino, in modo da resettarlo (spegnendolo e riaccendendolo) al bisogno.

La causa, come ti hanno detto, risiede nel contatto del relay che accende i riscaldatori (solitamente lampade normali oppure infrarosse). Qui puoi filtrare il contatto con un filtro RC e già dovrebbe migliorare di molto.
Altra cosa che puoi fare è usare un display I2C, se non lo hai già fatto, e tenere i collegamenti moooolto corti.
Poi la scheda relè (che presumo sia optoisolata) va il più lontano possibile dal display.
Le sonde collegale a fili schermati, con la calza collegata al negativo SOLO dal lato arduino.

Vedrai che risolvi.

pgiagno:
L'OP segnala che il fenomeno si manifesta "dopo qualche ora".

Chiaro.
All'accensione hai bassa temperatura.
Quando arriva in temperatura è li che i relè cominciano ad accendersi e spegnersi.

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_1 10
#define ONE_WIRE_BUS_2 5
OneWire sonda1(ONE_WIRE_BUS_1);
OneWire sonda2(ONE_WIRE_BUS_2);
DallasTemperature sensore1(&sonda1);
DallasTemperature sensore2(&sonda2);


#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


#include "DHT.h"
DHT dht(2, DHT22);
DHT dht1(3, DHT22);

const int relayPin = 4;
const int relayPin1 = 8;
const int relayPin2 = 9;

int pulsantePin = 7;
int val = 0;

volatile bool max1 = true;
volatile bool min1 = true;



void setup(void) {
  
  Serial.begin(9600);

  lcd.begin(20, 4);
  dht.begin();
  dht1.begin();

  pinMode(relayPin, OUTPUT);
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);

  sensore1.begin();
  sensore2.begin();

  pinMode(pulsantePin, INPUT);




}

void loop(void) {

  val = digitalRead(pulsantePin);

  if (max1 && (val == HIGH) ) {

    lcd.clear();
    max1 = false;
    min1 = true;
    dht.begin();
    dht1.begin();
    sensore1.begin();
    sensore2.begin();
  }

  if (val == HIGH) {

    int h = dht.readHumidity();
    int h1 = dht1.readHumidity();

    float t1 = sensore1.getTempCByIndex(0);
    float t2 = sensore2.getTempCByIndex(0);

    sensore1.requestTemperatures();
    sensore2.requestTemperatures();
    lcd.setCursor(0, 0);
    lcd.print("Arduino: ON");
    lcd.setCursor(11, 0);
    lcd.print(" ");
    lcd.setCursor(0, 1);
    lcd.print("Schiusa: T=");
    lcd.print(t1);
    lcd.setCursor(9, 2);
    lcd.print("U=");
    lcd.print(h1);
    lcd.print("%");
    lcd.setCursor(0, 3);
    lcd.print("Config:");
    lcd.setCursor(7, 3);
    lcd.print("T=");
    lcd.print(t2);
    lcd.setCursor(15, 3);
    lcd.print("U=");
    lcd.print(h);
    lcd.print("%");

    if ( t1 < 37.7 && h1 < 60)  {

      digitalWrite(relayPin1, HIGH); // VENTOLA 220V RELE SU POTEZIOMENRTO MANULAE//
      digitalWrite(relayPin, LOW); //VENTOLA 12V RELE SU TRASFORMATORE//
      digitalWrite(relayPin2, HIGH); // MACCHINA DEL VAPORE ESTERNA //
      delay(10000);
    }

    if ( t1 > 37.7 && t1 < 37.9 && h1 < 60)  {

      digitalWrite(relayPin1, LOW);
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayPin2, HIGH);
      delay(10000);


    }

    if (t1 > 37.9 && h1 < 60)  {

      digitalWrite(relayPin1, LOW);
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayPin2, HIGH);
      delay(10000);
    }

    if (t1 < 37.7 && h1 > 60 && h1 < 65 )  {

      digitalWrite(relayPin1, HIGH);
      digitalWrite(relayPin, LOW);
      digitalWrite(relayPin2, LOW);
      delay(10000);
    }
    if (t1 > 37.7 && t1 < 37.9 && h1 > 60 && h1 < 65 )  {

      digitalWrite(relayPin1, LOW);
      digitalWrite(relayPin, LOW);
      digitalWrite(relayPin2, LOW);

    }
    if (t1 > 37.9 && h1 > 60 && h1 < 65 )  {

      digitalWrite(relayPin1, LOW);
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayPin2, LOW);
      delay(10000);

    }
    if (t1 < 37.7 && h1 > 65 )  {

      digitalWrite(relayPin1, HIGH);
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayPin2, LOW);
      delay(5000);
    }
    if (t1 > 37.7 && t1 < 37.9 && h1 > 65 )  {

      digitalWrite(relayPin1, LOW);
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayPin2, LOW);
      delay(10000);

    }

    if (t1 > 37.9 && h1 > 65 )  {

      digitalWrite(relayPin1, LOW);
      digitalWrite(relayPin, HIGH);
      digitalWrite(relayPin2, LOW);
      delay(10000);

    }
    

  }


  else {
    
    int h = dht.readHumidity();
    int h1 = dht1.readHumidity();

    float t1 = sensore1.getTempCByIndex(0);
    float t2 = sensore2.getTempCByIndex(0);

    sensore1.requestTemperatures();
    sensore2.requestTemperatures();
    
    Serial.print("temp");
    Serial.print(t1);
    Serial.print("umi");
    Serial.print(h1);
    
    lcd.setCursor(0, 0);
    lcd.print("Arduino: OFF Info:");
    lcd.setCursor(0, 1);
    lcd.print("   Version: 1.0.0");
    lcd.setCursor(0, 2);
    lcd.print("                    ");
    lcd.setCursor(0, 3);
    lcd.print("Creator: A. Milella");
    
    digitalWrite(relayPin, LOW); // VENTOLE 12V AVANTI //
    digitalWrite(relayPin1, LOW); // VENTOLA 220V RETRO //
    digitalWrite(relayPin2, LOW); // MACCHINA VAPORE //

    max1 = true;
    min1 = false;

  }

}

Ragazzi questo è il codice, che ne pensate?
Quindi quello che potrei fare per risolvere il problema sarebbe spostare i relè in qualche altra parte per evitare interferenze con arduino e il display, opporre porre un interruttore sul vcc del display, per riavviarlo in caso di necessita. Credo comunque che arduino continui a funzionare anche se non visualizzo il display, il problema più grosso a questo punto sono le sonde dht22, perché perdendo le informazioni mi sballano la configurazione. Qualcuno ha da consigliare delle sonde per umidità abbastanza serie? ( precisione richiesta dalla macchina da 1 a 2%)

... non mi sembra di vedere l'uso della classe "String" ne di allocazioni dinamiche di memoria, per cui ... resta il solito problema dei relè. Che scheda relè stai usando esattamente? Metti un link ...

Guglielmo

gpb01
Uso dei relè a modulo singolo, per la precisione sono 3, questo è il link https://www.google.com/amp/s/www.az-delivery.de/a/s/products/2-relais-modul questi sono simili, io li ho comprati da amazon, in allegato la foto

Quelli che hai linkato di Amazon NON mi sembrano neanche optoaccoppiati, mentre quelli del link sono decisamente meglio e, se si vogliono evitare guai, il corretto utilizzo è con DUE alimentazioni (quindi due alimentatori) del tutto separate, come in questo schema ...

... in tale modo funzionano a logica inversa (pin HIGH - >relè diseccitato, pin LOW -> relè eccitato), ma hanno il grande vantaggio di essere completamente separati come alimentazione.

Guglielmo

Ma nel mio caso, ovvero ne ho tre di quel tipo li, come posso fare?
Comunque questa è la descrizione del prodotto :
Questo relé contiene un optoaccoppiatore separato, e grazie alla sua facilità di utilizzo è il kit perfetto per i vostri primi passi nel mondo dell'elettronica e della prototipazione.

Il modulo relè KY-019 da 5V vi consente di controllare una carica di corrente continua DC o corrente alternata AC proveniente da un microntrollore Arduino o Raspberry. Dal punto di vista del controllo, agisce quindi come un interruttore controllabile.
Il modulo consente di gestire un ampio range di tensioni operative, quindi vi da la massima flessibilità di integrazione in vari tipi di progetti e dispositivi. È quindi il relé perfetto quando la vostra esigenza è quella di commutare tra delle tensioni più alte verso un'uscita a 5 V.

banks01:
Ma nel mio caso, ovvero ne ho tre di quel tipo li, come posso fare?

Quale tipo li? Quelli di Amazon? … se è così, mi spiace ma quelli NON prevedono alimentazioni separate e l’unica è provare i suggerimenti dati nei post precedenti.

Guglielmo

P.S.: Nella foto di quello di Amazon io vedo solo un transistor, ma non riesco a vedere l’optoaccoppiatore … magari è nascosto da un’altra parte … ::slight_smile:

Di intendevo quelli... Grazie mille per la disponibilità

P.S.: Nella foto di quello di Amazon io vedo solo un transistor, ma non riesco a vedere l'optoaccoppiatore ... magari è nascosto da un'altra parte ... ::)

No, non c'è proprio
hanno toppato la descrizione

Ma per forza i relè devi usare?
Cosa piloti esattamente?