LCD I2C con PCF8574

Ciao a tutti......ho ancora il problema dei caratteri strani sull LCD pilotato dal PCF 8574

Il mio progetto include un Arduino 2009 + PCF8574 + RTC DS1307 + n.2 DHT11 e n.1 DHT22 + SR 74HC595 attraverso la quale comando una scheda con 8 Relay

Il problema è che dopo un tempo indefinito, sul LCD compaiono una serie di caratteri strani, mentre 'sotto' il resto continua a funzionare.

Ho provato a smontare tutto e assicurarmi che le connessioni siano correte e ho notato che se non collego la scheda a 8 relay e i tre DHT questo problema non si verifica.

Sapete darmi una spiegazione.

GRAZIE !!!!

Potresti postare le foto del progetto e lo sketch?
Detto così è un po' difficile aiutarti.

Domani il forum è chiuso dalle 9 alle 21. :roll_eyes:

#include "Wire.h"
#include <SD.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>

#define DS1307_ADDRESS 0x68
#define DHTPIN3 A0
#define DHTPIN2 A2
#define DHTPIN1 A1
#define DHTTYPE1 DHT11   // DHT 11
#define DHTTYPE2 DHT22   // DHT 22  (AM2302)

DHT dht1(DHTPIN1, DHTTYPE1);
DHT dht2(DHTPIN2, DHTTYPE1);
DHT dht3(DHTPIN3, DHTTYPE2);

LiquidCrystal_I2C lcd(0x24,20,4);  // set the LCD address to 0x24 for a 16 chars and 2 line display

File myFile;

int latchPin =9;
int dataPin = 10;
int clockPin = 8;
int x =0;

//ShiftReg. 76543210
byte b1 = 0b11111111 ; 
byte b2 = 0b00000000 ; 

void setup(){
  Wire.begin();
  //Serial.begin(9600);
  //setDateTime(); //MUST CONFIGURE IN FUNCTION
  lcd.init();
  lcd.backlight();
  pinMode(latchPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  lcd.setCursor(0,0);
  lcd.print(F(" **TempMon v1.02**"));
  lcd.setCursor(0,1);
  lcd.print(F(" Starting System...."));
  if (!SD.begin(4)) {
    lcd.setCursor(0,1);
    lcd.print(F(" SD Shield ERROR !!!"));
    return;
  } else {
  lcd.setCursor(0,1);
  lcd.print(F("    SD Shield ON    ")); }
  
   dht1.begin();
   dht2.begin();
   dht3.begin();
   delay(1000);
   lcd.clear();
}

void loop(){
  
  // lcd.init();
  lcd.setCursor(0,0);
  lcd.print(F(" **TempMon System**"));
  lcd.setCursor(2,2);
  String dtime ="";
  dtime += printDate();
  lcd.print(dtime);

  delay(1000);

   int h1 = dht1.readHumidity();
   int t1 = dht1.readTemperature();
   int h2 = dht2.readHumidity();
   int t2 = dht2.readTemperature();
   int h3 = dht3.readHumidity();
   int t3 = dht3.readTemperature();
   int Tmedia, Hmedia;
   
   if (t1 < 1 || !isnan(t1)){ Tmedia = (t2+t3)/2;}
   else if (t2 < 1 || !isnan(t2)) {Tmedia = (t1+t3)/2;}
   else if (t3  <1 || !isnan(t3)) {Tmedia = (t2+t1)/2;}
    else  {Tmedia = (t1+t2+t3)/3;}
    
   if (h1 < 1 || !isnan(h1)){ Hmedia = (h2+h3)/2;}
   else if (h2 < 1 || !isnan(h2)) { Hmedia = (h1+h3)/2;}
   else if (h3 < 1 || !isnan(h3)) {Hmedia = (h2+h1)/2;}
    else { Hmedia = (h1+h2+h3)/3;}
    
   int tsec=printSec();
   int tmin=printMin();
   
   lcd.setCursor(0,0);
   lcd.print(F(" *Tm: "));
   lcd.print(Tmedia);
   lcd.print(F("C  "));
   lcd.print(F("*Hm: "));
   lcd.print(Hmedia);
   lcd.print(F("% "));
   lcd.setCursor(0,1);
   lcd.print(F("  T1: "));
   lcd.print(t1);
   lcd.print(F("C   "));
   lcd.print(F("H1: "));
   lcd.print(h1);
   lcd.print(F("% "));
   lcd.setCursor(0,2);
   lcd.print(F("  T2: "));
   lcd.print(t2);
   lcd.print(F("C   "));
   lcd.print(F("H2: "));
   lcd.print(h2);
   lcd.print(F("% "));
   lcd.setCursor(0,3);
   lcd.print(F("  T3: "));
   lcd.print(t3);
   lcd.print(F("C   "));
   lcd.print(F("H3: "));
   lcd.print(h3);
   lcd.print(F("% "));
   
   dtime += "-";
   dtime += Tmedia;
   dtime += "-";
   dtime += t1;
   dtime += "-";
   dtime += t2;
   dtime += "-";
   dtime += t3;
   dtime += "-";
   dtime += Hmedia;
   dtime += "-";
   dtime += h1;
   dtime += "-";
   dtime += h2;
   dtime += "-";
   dtime += h3;
   
   delay(3000);
   lcd.clear();
        
   if (Tmedia < 22) 
        { bitClear(b1,5); 
          lcd.setCursor(0,0);
          lcd.print(F("Temperatura....BASSA"));
          dtime += "-Temp. BASSA";
        } else {
          bitSet(b1,5); }
   if (Tmedia > 32) 
        { bitClear(b1,0); 
          bitClear(b1,1);
          bitClear(b1,2);
          bitClear(b1,3);
          lcd.setCursor(0,0);
          lcd.print(F("Temperatura.....ALTA"));
          dtime += "-Temp. ALTA";
        } else {
          bitSet(b1,0);
          bitSet(b1,1);
          bitSet(b1,2);
          bitSet(b1,3);}
          
   if (Hmedia < 75) 
        { bitClear(b1,6);
          bitClear(b1,4);  
          lcd.setCursor(0,1);
          lcd.print(F("Umidita........BASSA"));
          dtime += "-Umid. BASSA";
        } else {
          bitSet(b1,6);
          bitSet(b1,4); }       
   if (Hmedia > 95) 
        { bitClear(b1,2); //top fan
          bitClear(b1,0); //front 2
          bitClear(b1,1); //front
          lcd.setCursor(0,1);
          lcd.print(F("Umidita.........ALTA"));
          dtime += "-Umid. ALTA";
        } else {
          bitSet(b1,2); 
          bitSet(b1,1);
          bitSet(b1,1);}
    
    
    if (tmin < 8) 
      { bitClear(b1,3); 
        bitClear(b1,2);
        lcd.setCursor(0,2);
        lcd.print(F("Ricambio Aria.....ON"));
        dtime += "-Ric. ARIA";}
        
    
    digitalWrite(latchPin,LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, b1);
    shiftOut(dataPin, clockPin, LSBFIRST, b2);
    digitalWrite(latchPin, HIGH);     
    delay(2000);
   
 if (tsec < 5) {
   File dataFile = SD.open("log.txt", FILE_WRITE);
    
    if (dataFile) {
      dataFile.println(dtime);
      dataFile.close();
    } else {
      lcd.println(F("ERROR open log.txt"));
      delay(1000);
    }
  }
  
  lcd.clear();
}



//************ INIZIO codice DS1307 *****************
void setDateTime(){

  byte second =      16; //0-59
  byte minute =      22; //0-59
  byte hour =        23; //0-23
  byte weekDay =     4; //1-7
  byte monthDay =    23; //1-31
  byte month =       5; //1-12
  byte year  =       13; //0-99

  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(0); //stop Oscillator

  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekDay));
  Wire.write(decToBcd(monthDay));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));

  Wire.write(0); //start 

  Wire.endTransmission();

}

byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

String printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());
  String dataora = "";

  //print format date ES.  3/1/11 23:59:59
  dataora +=monthDay;
  dataora +="/";  
  dataora +=month;
  dataora +="/";
  dataora +=year;
  dataora +=" ";
  dataora +=hour;
  dataora +=":";
  dataora +=minute;
  dataora +=":";
  dataora +=second;
  
  return dataora;
  
}

int printSec(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);
  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  return second;
  
}

int printMin(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);
  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  return minute;
  
}
//************ FINE codice DS1307 *****************

https://docs.google.com/file/d/0ByoKd_e1bIw5UTJOTUpKRFR1ZEE/edit?usp=sharing

Spero sia sufficiente............considerando che sono un princiante :smiley:

Lato Hardware mancano i condensatori da 100nF vicino alle alimentazioni degli integrati e a cavallo del 7805.
Vedi schema 16 (set 6) --> http://www.pighixxx.com/abc-arduino-basic-connections/

Poi controlla lato Software il quantitativo di memoria durante il runtime --> http://www.leonardomiliani.com/2012/come-sapere-loccupazione-di-ram-del-proprio-sketch/

Grazie paolo.............il documento è moooooolto interessante ma purtroppo non si legge niente dalle immagini sono troppo poco definite...... credi quindi che la mancanza di questo condensatore possa creare questo problema ????

Ho trovato questo schema, puo andare :

oppure

http://forum.arduino.cc/index.php?topic=174281.msg1368490#msg1368490

io invece ho usato questo:

tronicman:
ma purtroppo non si legge niente dalle immagini sono troppo poco definite......

Se clicchi sulla scritta Set6 ecc ecc puoi scaricare il PDF da stampare in formato A3. :astonished:

Grazie provo subito........credi che questo possa risolvere il problema ?

Hai verificato anche la situazione della memoria durante il funzionamento?
Potresti stamparla in una zona dell'LCD.

inserisci due resistenze di PullUp, da 2,2k, sulla linea I2C ( SDA e SCL )

ciao,
L'induttanza delle bobine dei relè in fase di apertura crea delle sovratensioni che fanno sbarellare il display.
Hai messo il diodo in parallelo alla bobina del relè?
Guarda qua: http://www.nanoreef.it/immagini/faidate/termostato/2.jpg
Se così non risolvi, hai 3 vie d'uscita da provare:

  1. Disaccoppi le bobine dei relè con degli accoppiatori ottici, ma il disturbo potrebbe rientrarti dalla massa che è in comune, ma se hai un fotoaccoppiatore in casa puoi provare
  2. Metti in parallelo alla bobina del relè dei varistori del voltaggio di controllo della bobina stessa http://www.circuitielettronici.it/varistori.htm
  3. Sostituisci i relè a bobina con dei relè a stato solito, molto meglio se controlli carichi a 220 Volt

Marco

marcolino7:
ciao,
L'induttanza delle bobine dei relè in fase di apertura crea delle sovratensioni che fanno sbarellare il display.
Hai messo il diodo in parallelo alla bobina del relè?
Guarda qua: http://www.nanoreef.it/immagini/faidate/termostato/2.jpg
Se così non risolvi, hai 3 vie d'uscita da provare:

  1. Disaccoppi le bobine dei relè con degli accoppiatori ottici, ma il disturbo potrebbe rientrarti dalla massa che è in comune, ma se hai un fotoaccoppiatore in casa puoi provare
  2. Metti in parallelo alla bobina del relè dei varistori del voltaggio di controllo della bobina stessa http://www.circuitielettronici.it/varistori.htm
  3. Sostituisci i relè a bobina con dei relè a stato solito, molto meglio se controlli carichi a 220 Volt

Marco

Grazie a tutti e scusate la lunga assenza ma per motivi di lavoro non ho potuto postare prima......allora..... le resitenza di pullup c'erano di già e non risolvono il problema, ho provato a sostiuire l'alimentazione con con il circuito consigliato su ArduinoBasicConnections ma ancora niente, LCD continua a sbarellare, credo che davvero sia dovuto alle induttanze delle bobine.

Ora la mia conoscenza dell' elettronica non mi permette di capire come poter aggiungere dei varistori tra il mio arduino e la shield a 8 relay ().....in questo caso mi dovreste aiutare con uno schemettino anche grossolano.....una sorta di pappa pronta :frowning:

Grazie davvero a tutti

Prima del Varistore, hai messo il diodo?
Ti ho allegato un esempio.

M.

questa è la mia shield

vedo i diodi ma niente altro di cui abbiamo parlato sopra

Si i diodi ci sono.
A quanti volt è alimentata questa scheda? Dove prendi l'alimentazione?

M.

la scheda è alimentata a 5v e l'alimentazione la prendo dal circuito suggerito in Arduino Basic connections, che mi regola la corrente che proviena da un alimentatore da 12v 10A

Cioè l'alimentazione della scheda a relè, è in comune con quella di Arduino?
Oppure per arduino usi il suo alimentatore integrato?

M.

si è in comune con quella di arduino......ovvero......i 12v li collego al Vin di Arduino e tutti gli altri dispositivi sono alimentati dal circuito che ho costruito io seguendo ABC.......ovviamente stesso GND per tutti

Ok,
quindi con i 12 Volt ci alimenti la scheda Arduino, poi con gli stessi 12 volt, alimenti la scheda a Relè tramite il circuito regolatore che hai pubblicato.
L'alimentazione del LCD con il PCF8574, la prendi da Arduino, oppure dal tuo circuito con cui alimenti i relé?
Magari se riesci a pubblicare uno schema a blocchi con tutti i componenti e le alimentazioni come sono collegate.

M.

L alimentazione del display la prendo dal circuitino.....cmq questo è lo schema.....ora ho eliminato lo shift register ed ho modificato il circuito di alimentazione con quello di ABC

https://docs.google.com/file/d/0ByoKd_e1bIw5UTJOTUpKRFR1ZEE/edit?usp=sharing

Dovresti provare a mettere un Varistore da 5 Volt in parallelo ai morsetti di alimentazione della scheda relè.
Tieni presente però che io non ho completamente risolto, ma ho ridotto di molto il problema, però io comando delle elettrovalvole a 220 Volt.

M.