Problema su Arduino UNO, lcd e interferenze elettromagnetiche

Ciao a tutti,
Ho un problema che mi affligge da qualche settimana ed al quale non riesco a porre rimedio.
Sto realizzando un semplice progettino per la gestione di una grow box.
L'hardware in campo:
Arduino UNO
RTC DS1307
MCP23017 port expander
DHT22 sensore temp/umiditá ambientale e DS18B20 sensore temp acqua
Scheda con 8 relé con comando optoisolato 5VDC
LCD 16x2 HD44780 parallelo

Lo sketch mi permette, usando la libreria TimeAlarm di impostare i timer relativi all'accensione di:
1 lampada CFL da 150W 230v~
2 ventole 12VDC
1 pompa acqua sommersa 230V~
1 pompa aria 230V~
E di visualizzare le temperature e la % di umiditá in ambiente.

Arduino pilota via i2c il port expander connesso direttamente alla scheda rele.

tutto bene senza carichi connessi, ma in presenza di 230V~ quando i relè aprono il mio display scrive caratteri a caso e nella peggiore delle situazioni anche l'arduino si blocca. (Tutto questo anche solo con un relé connesso al carico, nello specifico una pompa acqua da acquario sommersa 1W!)

Ho provato a installare degli snubber sulle uscite senza esito positivo e ho pensato di pilotare con i miei relé su scheda dei relé finder 12VDC su zoccolo allontanandoli dal box principale e connettendo le bobine alla mia scheda relé utilizzando del cavo twistato.
È migliorato leggermente, l arduino non si pianta più ma il display continua a "impazzire".
Ho alimentato tutto da batteria, nessun esito.
Ho separato le alimentazioni di arduino e scheda rele, mantenendo massa comune, nessun esito.
Ho separato le alimentazioni, compresa la massa con un optoisolatore esterno, nessun esito.
Ho fisicamente scollegato la scheda relé dalla logica arduino, mi basta accendere una ventola 230V usando il contatto NC del finder remoto per avere lo stesso disturbo.
Oggi ho replicato l'impianto a banco.. Ds1307, mcp23017 e arduino uno, mi basta avvicinare alla breadboard la scheda relé con carico connesso al 230V, collegare la spina e il display impazzisce, per giunta il pc emette anche il tono di usb disconnesso.

Inizio a dar di matto :slight_smile: ho remotizzato il controllo della scheda relé usando un cavo twistato e la schermatura posta da un capo a terra e niente!

Nb: sull'impianto non posso sfruttare la messa a terra in quanto nessun dispositivo ha terra collegabile.

Grazie anticipatamente, enzo

ho lo stesso cavolo di problema ma con arduino mega e lcd 40 x 4
tutti parlano di condensatore 0.22mf 400v ma non riesco a capire dove collocarlo booo
:sob:

E' evidente che il disturbo è generato all'apertura dei contatto del relè (extra tensioni in apertura di un carico induttivo).

Lo snubber RC, se non è ben calcolato, serve a poco.

Prova invece con un varistore da 400V in parallelo al contatto del relè.

scusa ma non sono molto tecnico il mio relè interrompe solo una fase 220
cosa intendi per parallelo cosi?
grazie anticipatamente :confused:

telecontrollo-01.jpg

Avevo provato in precedenza con il varistore, ma prima di utilizzare i rele' su scheda esclusivamente da appoggio per i finder, domani altro test grazie cyberhs.
mi chiedo quali contromisure adotti chi progetta le classiche macchine da distributore bibite, caffé etc che monta proprio quel tipo di display...

FERROBATT:
scusa ma non sono molto tecnico il mio relè interrompe solo una fase 220
cosa intendi per parallelo cosi?
grazie anticipatamente :confused:

intende così
http://www.elettronicaonline.biz/rele-come-si-usa/

Eccomi qui dopo l'ennesima prova, varistore inserito e nessun cambiamento.
Ho un video dimostrativo :cry:

In questo sketch vengono richiamati 2 timer, uno per pompa h2o e uno per ventole, corrispondono difatti le due icone in alto. La frequenza è di 5 secondi di accensione ogni 10.
Senza carico tutto bene, basta collegare la spina per ottenere una "D" in riga 1,16 e allo sgancio del rele' il disturbo totale. Il motore utilizzato è un motorino da neanche 50W di un aspiratore.
L'hardware usato è lo stesso in uso nel progetto e montato a banco il problema si ripresenta.
Non ci sono i sensori temperatura collegati ed ho utilizzato una sola uscita rele'.

Tristezza infinita..

allego anche il codice

byte simboloTemperatura[8] =                   //icon for termometer
{
    B00100,
    B01010,
    B01010,
    B01110,
    B01110,
    B11111,
    B11111,
    B01110
};
byte simboloUmidita[8] =                       //icon for water droplet
{
    B00100,
    B00100,
    B01010,
    B01010,
    B10001,
    B10001,
    B10001,
    B01110,
};
byte simboloFan[8] = { //icona ventola
    B00000,
    B11001,
    B01011,
    B00100,
    B11010,
    B10011,
    B00000,
    B00000
};
byte simboloH2o[8] = { //icona water
    B00000,
    B01000,
    B10101,
    B00010,
    B01000,
    B10101,
    B00010,
    B00000
};
byte simboloLuce[8] = { //icona sun
    B00000,
    B10101,
    B01110,
    B11111,
    B01110,
    B10101,
    B00000,
    B00000
};


#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include "DHT.h"
#include <DS1307RTC.h>
#include "Adafruit_MCP23017.h"
#include <LiquidCrystal.h>
#include <Time.h>
#include <TimeAlarms.h>

#define DHTPIN 7     
#define DHTTYPE DHT22   
#define ONE_WIRE_BUS 6
DHT dht(DHTPIN, DHTTYPE);
Adafruit_MCP23017 mcp;


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire); //28D066A0050000CB
DeviceAddress tH2o = { 0x28, 0xD0, 0x66, 0xA0, 0x05, 0x00, 0x00, 0xCB };

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int fan = 0;
const int light = 1;
const int h2o = 2;
const int air = 3;
const int maintenance = 10; 

int fanSeconds = 0; //variabile utilizzata per la misurazione dei minuti trascorsi nel timer ventola
int fanMinute = 0;
int fanJobSec = 0; //variabile per il conteggio dei secondi di lavoro trascorsi nella funzione fan()
int h2oSeconds = 0; //variabile utilizzata per la misurazione dei minuti trascorsi nel timer ventola
int h2oMinute = 0;
int h2oJobSec = 0; //variabile per il conteggio dei secondi di lavoro trascorsi nella funzione pump()
byte lightState; //variabile per riportare lo stato della luce nel void loop()
byte pumpState = 0; //variabile per riportare lo stato della pompa nel void loop()
byte fanState = 0; //variabile per riportare lo stato della ventola nel void loop()
boolean maintMode = LOW;

void setup() {
  sensors.begin();
  sensors.setResolution(tH2o, 9);
  time_t t = now();
  setTime(t);
  setSyncProvider(RTC.get);  
  Wire.begin();
  lcd.begin(16,2);
  dht.begin();
  mcp.begin();
  
  
  /* PROGRAMMAZIONE TIMER ********************************************/
  
  
  Alarm.alarmRepeat(0,0,0,syncTime);          //acquisizione ora da RTC !!! non modificare
  Alarm.alarmRepeat(10,30,0,startLight);      //accensione luci
  Alarm.alarmRepeat (10,35,0,stopLight);      //spegnimento luci
  Alarm.timerRepeat(10,startFan);             //accende ventola, frequenza espressa in secondi 3600sec=1h, durata nella funzione startFan()
  Alarm.timerRepeat(10,startPump);            //accende ventola, frequenza espressa in secondi 3600sec=1h, durata nella funzione startFan()

  
  
  /* TERMINE PROGRAMMAZIONE TIMER ************************************/
  
  
  pinMode(maintenance,INPUT_PULLUP);
  mcp.pinMode(fan, OUTPUT);
  mcp.pinMode(light, OUTPUT);
  mcp.pinMode(h2o, OUTPUT);
  mcp.pinMode(air, OUTPUT);
  mcp.digitalWrite(fan,LOW);
  mcp.digitalWrite(h2o,LOW);
  mcp.digitalWrite(air,LOW);
  
  lcd.createChar(1,simboloTemperatura);
  lcd.createChar(2,simboloUmidita);
  lcd.createChar(3,simboloFan);
  lcd.createChar(4,simboloH2o);
  lcd.createChar(5,simboloLuce);
  
  lcd.setCursor(0,0);
  lcd.print(" Growing System ");
  delay(2000);
  lcd.clear();
  
  EEPROM.write(1,0); //
  lightState = EEPROM.read(1);
    if (lightState == 1) {
      mcp.digitalWrite(light,HIGH);
      lcd.setCursor(9,0);
      lcd.write(5);
  }
      else if (lightState == 0) mcp.digitalWrite(light,LOW);
}

 

void loop() { 
  
  Alarm.delay(200);
  time_t t = now();
  Alarm.delay(200);
  sensors.requestTemperatures();
  Alarm.delay(200);
  float h = dht.readHumidity();
  Alarm.delay(200);
  float c = dht.readTemperature();
  Alarm.delay(200);
  float cH2o = sensors.getTempC(tH2o);
  Alarm.delay(200);
  
   
  lcd.setCursor(0,0);
  if (day(t)<10) lcd.print("0");
  lcd.print(day(t), DEC);
  lcd.print("/");
  if (month(t)<10) lcd.print("0");
  lcd.print(month(t), DEC);
  lcd.setCursor(11,0);
  if (hour(t)<10) lcd.print("0");
  lcd.print(hour(t), DEC);
  lcd.print(":");
  if (minute(t)<10) lcd.print("0");
  lcd.print(minute(t), DEC);
  
  lcd.setCursor(0,1);
  lcd.print(c,1);
  lcd.write(1); 
  lcd.setCursor(6,1);
  lcd.print(h,1); 
  lcd.write(2);
  lcd.setCursor(13,1);
  lcd.print(cH2o,0);
  lcd.write(4);
                                                                       /* ventola,se timer attivo flag=1 accensione  */
  if (fanState == 1) {
    mcp.digitalWrite(fan,HIGH);
    Alarm.delay(100);
    lcd.setCursor(7,0);
    lcd.write(3);
    fanJobSec = 5; //tempo di lavoro in secondi 
    fanSeconds = (second(t)+fanJobSec%60);
    fanMinute = (minute(t)+(fanJobSec/60));
    if (fanSeconds > 60){
      fanSeconds = fanSeconds - 60;
      fanMinute ++;
    }
    if (fanMinute > 60) {
      fanMinute = fanMinute - 60;
    }
    fanState = 2;
  }                                                                     /* ventola, controllo tempi */
  if ((fanState == 2)&&(fanMinute == minute(t)&&(second(t)>=fanSeconds))){
    mcp.digitalWrite(fan,LOW);
    Alarm.delay(100);
    lcd.setCursor(7,0);
    lcd.print(" "); 
    fanSeconds = 0;
    fanState = 0; 
  }     
                                                                      /* pompa h2o, se timer attivo flag=1 accensione */
  if (pumpState == 1) {
    mcp.digitalWrite(h2o,HIGH);
    Alarm.delay(100);
    lcd.setCursor(8,0);
    lcd.write(4);
    h2oJobSec = 5; //tempo di lavoro in secondi 
    h2oSeconds = (second(t)+h2oJobSec%60);
    h2oMinute = (minute(t)+(h2oJobSec/60));
    if (h2oSeconds > 60){
      h2oSeconds = h2oSeconds - 60;
      h2oMinute ++;
    }
    if (h2oMinute > 60) {
      h2oMinute = h2oMinute - 60;
    }
    pumpState = 2;    
  }                                                                    /* pompa h2o, controllo tempi */
  if ((pumpState == 2)&&(h2oMinute == minute(t)&&(second(t)>=h2oSeconds))){     
    mcp.digitalWrite(h2o,LOW);
    Alarm.delay(100);
    lcd.setCursor(8,0);
    lcd.print(" "); 
    h2oSeconds = 0;
    pumpState = 0; 
  }   
  
 
  if(digitalRead(maintenance)==LOW) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("  maintenance");
    lcd.setCursor(0,1);
    lcd.print("  mode");
    Alarm.delay(100);
    mcp.digitalWrite(h2o,LOW);
    mcp.digitalWrite(fan,LOW);
    mcp.digitalWrite(light,LOW);
    mcp.digitalWrite(air,HIGH);
    maintMode = HIGH;
  }
  
  while(maintMode==HIGH){
    lcd.setCursor(15,1);
    lcd.print("!");
    Alarm.delay(500);
    lcd.setCursor(15,1);
    lcd.print(" ");
    Alarm.delay(500);
    if(digitalRead(maintenance)==HIGH){
          maintMode=LOW;
          mcp.digitalWrite(air,LOW);
          Alarm.delay(100);
          lcd.clear();
          Alarm.delay(100);
          lightState = EEPROM.read(1);
          if (lightState == 1) {
            mcp.digitalWrite(light,HIGH);
            lcd.setCursor(9,0);
          lcd.write(5);
          }
    }
  }
   
}

void syncTime(){
  setSyncProvider(RTC.get);
}
void startLight(){
  mcp.digitalWrite(light,HIGH);
  lcd.setCursor(9,0);
  lcd.write(5);
  lightState = 1;
  EEPROM.write(1,lightState);
}
void stopLight(){
  mcp.digitalWrite(light,LOW);
   lcd.setCursor(9,0);
  lcd.print(" ");
  lightState = 0;
  EEPROM.write(1,lightState);
}

 void startFan (){
  fanState = 1;
}

void startPump (){
  pumpState = 1;
}

Ciao!

inserito condensatore in parallelo al carico e varistore in parallelo al contatto.. :astonished:


motore vicino al display e non succede nulla!
Ogni tanto scrive geroglifici se muovo il motore ma e' gia un passo avanti!

Ciao!
Mi interessa molto la cosa!
Che tipo di varistore?
Solo condensatore o condensatore resistenza? Che valori?
Scusa lo scrosciare di domande ma vorrei risolvere pure io una situazione simile!
Grazie!!!

i lcd sono molto sensibili alla qualità del contatto, cerca di fare dei bei contatti eliminando la breadboard

Caspita problema molto simile.... Arduino uno, display 4 righe 20 caratteri senza nessun relè ma solo sensore temperatura.
Sketch piuttosto semplice che visualizza la temperatura.
Alimentato via usb tramite alimentatore con uscita usb : collegato per ore al lavoro in ufficio e funziona alla perfezione, lo porto a casa e lo attacco ad una spina, funziona per un paio di minuti quindi cominciano ad apparire caratteri privi di senso e quindi il display (o Arduino ?) va in crash facendo sparire ogni visualizzazione.
Idee?
Reset tramite pulsantino e via allo stesso problema.
PS: in casa ho in servizio un UPS che però non alimenta la linea in oggetto.

Ciao Stefa24, quella è una replica a banco dell'impiantino già installato, debuggo nelle condizioni peggiori :slight_smile:
Per quanto riguarda i valori ho utilizzato un varistore da 400V in parallelo al contatto e una rete RC in parallelo al carico con C da 100nF e res da 47ohm, quello in prova è un motorino da 100W
Ciao!

non ho letto tutto, ma il disturbo lo fa anche se sui contatti NON ce la 230vac (insomma a vuoto)?

Martinix:
non ho letto tutto, ma il disturbo lo fa anche se sui contatti NON ce la 230vac (insomma a vuoto)?

nel mio caso no

Franchelli:
Caspita problema molto simile.... Arduino uno, display 4 righe 20 caratteri senza nessun relè ma solo sensore temperatura.
Sketch piuttosto semplice che visualizza la temperatura.
Alimentato via usb tramite alimentatore con uscita usb : collegato per ore al lavoro in ufficio e funziona alla perfezione, lo porto a casa e lo attacco ad una spina, funziona per un paio di minuti quindi cominciano ad apparire caratteri privi di senso e quindi il display (o Arduino ?) va in crash facendo sparire ogni visualizzazione.
Idee?
Reset tramite pulsantino e via allo stesso problema.
PS: in casa ho in servizio un UPS che però non alimenta la linea in oggetto.

Se penso che accendendo la stazione saldante che ho affianco al pc si scollega l'USB di arduino mi viene facile pensare che nella presa interessata ci sia un passaggio di forza che infastidisce il tuo sistema.. Avevo problemi simili con un caricabatterie usb cinese, provato con quello dell'iPad (che non so quanto possa essere meglio) ma ho risolto

Evolve:
nel mio caso no

allora potrebbe essere un "disturbo" provocato dall'immissione di armoniche sulla line 230vac (dovuta apponto all'apertura e chiusura relè) queste girano allegramente per casa e magari rientrano nall'alimentatore di arduino, e chi è piu sensibile, paga lo scotto!

Dovresti provare con dei filtri per la 230vac oppure tentare di filtrare i +5vcc del dispay ma anche di arduino in generale!(magari con una rete LC )
o tuitte e tue assieme :wink:

oppure far scattare il relè SOLO quando la tensione passa per lo zero (cosi dovrebbe ridurre il caos)

Buonasera,
anche io ho un problema di interferenze con un arduino UNO.
Ho collegato la scheda per comandare un vecchio deumidificatore: controllo di compressore, ventilatore, sensore umidità, temperatura dell'evaporatore e schermo LCD. Il target di umidità viene gestito con una variabile comandata in salita e discesa con due pulsanti verso massa (con circuito fisico antirimbalzo) collegati agli interrupt 0 e 1 (pin 2 e 3). Compressore (300 W) e ventilatore sono comandati da due rele 12 V DC dotati di diodo antiparallelo alla bobina e filtro snubber parallelo al carico (varistore+condensatore+resistenza). Ogni volta che commuta il compressore la variabile target umidità cambia di valore come se venisse chiamato l'interrupt. Una cosa strana è che mi influenza solo l'interrupt 0 (pin 2) e non l'interrupt 1 (pin 3). Il ventilatore (assrbimento minore) sembra non creare nessun problema.
C'è qualche soluzione?
Ho staccato il più possibile la parte a 220V con i rele da tutto il resto, ma senza soluzione (a parte eliminare qualche interfferenza sull LCD (problema minore))..

Grazie per qualsiasi consiglio!

@gnat
Il tuo problema come si evidenzia?
con un reset del micro?
distrurbi sui caratteri del display?
o solo la lettura analogica umidità sballata?

ciao

La scheda non si resetta, a volte letture sbagliate del sensore DHT (non è un problema, in caso di errore faccio aspettare la lettura), a volte disturdi sul LCD (non è un problema).
Quello che non fa funzionare il sistema è che si attiva la routine chiamata dall'ext interrupt 0 che mi fa variare il target di umidità (ho due pulsanti che se premuti mi chiamano sul FALLING gli interrupt 0 e 1 per aumentare o diminuire il target di umidità).
La cosa strana è che il disturbo avviene solo sull'interrupt 0 e MAI sull'interrupt 1.

Dovresti allegare lo schema e lo sketch.