Arduino Mega e problemi con LCD

Ciao a tutti.
Ho un arduino MEGA e un display lcd 2004A con l'interfaccia I2C basata su PCF8574. Sto connettendo SDA e SCL sui pin 20 e 21 ma è come se la comunicazione I2C modificasse il valore di altri pin. Altro problema è che non sono sicuro della libreria che sto usando, vedendo vari video e tutorial ho installato la libreria Newliquidcrystal. Ne ho provate anche altre chiaramente. In piu, su un tutorial che ho visto usano questa riga di codice

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE) ;

Ora, la numerazione di quei pin è obbligatoria? Ne posso usare altri? Mi spiego meglio, i pin 2 e 3 sono occupati in quanto sono utilizzati per degli interrupt esterni.

La mia idea è stata quella di utilizzare i pin 18, 19, 20 per generare gli interrupt e SDA1 e SCL1 per comandare il display. Solo che non riesco in nessun modo a settare il pin 20 per gli interrupt e neanche SDA1 e SCL1 per il display.

Vi condivido anche il codice, ci saranno porte di uscita settate in assembler, sono i pin 8-->13, 30 e 37.

#include <Keypad.h>
#include <Wire.h>
//extern TwoWire Wire1;
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE) ;

....

void setup() {
  // inizializzo le variabili
  lcd.begin(20, 4);
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Benvenuto");
  delay(5000);
  lcd.clear();
  Serial.begin(2000000);
  //Serial.println("Funge");
  cli(); //stop interrupts

  DDRB = (1 << DDB7) | (1 << DDB6) | (1 << DDB5) | (1 << DDB4);
  DDRH = (1 << DDH6) | (1 << DDH5);
  DDRC = (1 << DDC7)|(1 << DDC0);
  DDRA = (0 << DDA2);

  PORTB = (0 << PB7) | (0 << PB6) | (0 << PB5) | (0 << PB4);
  PORTH = (0 << PH6) | (0 << PH5);
  PORTC = (0 << PC7)|(0 << PC0);
  
  //pinMode(37, OUTPUT);
  //pinMode(30, OUTPUT);
  pinMode(19, INPUT); //definisco i pin utili per gli interrupt esterni
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(34, INPUT);

  TCCR1A = 0; //TIMER UTILIZZATO PER LA FASE S (PER SINCRONISMO)
  TCCR1B = (0 << CS12) | (1 << CS11) | (0 << CS10); //Prescaler nullo, fermo il contatore
  TIMSK1 = (1 << OCIE1C) | (1 << OCIE1B) | (1 << OCIE1A); //abilitazione interrupt
  TIFR1 = (0 << OCF1C) | (0 << OCF1B) | (0 << OCF1A); //flag azzerato raggiungimento valore scelto
  TCNT1 = 0; ///azzero contatore a 16 bit

  TCCR3A = 0; //TIMER UTILIZZATO PER LA FASE R (PER SINCRONISMO)
  TCCR3B = (0 << CS32) | (1 << CS31) | (0 << CS30); //prescaler nullo, fermo il contatore
  TIMSK3 = (1 << OCIE3C) | (1 << OCIE3B) | (1 << OCIE3A); //abilitazione interrupt
  TIFR3 = (0 << OCF3C) | (0 << OCF3B) | (0 << OCF3A); //flag azzerato raggiungimento valore scelto
  TCNT3 = 0; ///azzero contatore a 16 bit

  TCCR4A = 0; //TIMER UTILIZZATO PER LA FASE T (PER SINCRONISMO)
  TCCR4B = (0 << CS42) | (1 << CS41) | (0 << CS40); //Prescaler nullo, fermo il contatore
  TIMSK4 = (1 << OCIE4C) | (1 << OCIE4B) | (1 << OCIE4A); //abilitazione interrupt
  TIFR4 = (0 << OCF4C) | (0 << OCF4B) | (0 << OCF4A); //flag azzerato raggiungimento valore scelto
  TCNT4 = 0; ///azzero contatore a 10 bit

//  TCCR5A = 0; //TIMER UTILIZZATO PER LA FASE T (PER SINCRONISMO)
//  TCCR5B = (0 << CS52) | (1 << CS51) | (0 << CS50); //Prescaler nullo, fermo il contatore
//  TIMSK5 = (1 << OCIE5C) | (1 << OCIE5B) | (1 << OCIE5A); //abilitazione interrupt
//  TIFR5 = (0 << OCF5C) | (0 << OCF5B) | (0 << OCF5A); //flag azzerato raggiungimento valore scelto
//  TCNT5 = 0; ///azzero contatore a 10 bit
//  OCR5A = 53333;

  attachInterrupt(digitalPinToInterrupt(19), sincronismo_RS, RISING); //richiamo l'interrupt quando la tensione AB, collegata sul pin digitale 0 diventa positiva, sincronismo_AB è il nome della funzione
  attachInterrupt(digitalPinToInterrupt(2), sincronismo_ST, RISING); //richiamo l'interrupt quando la tensione BC, collegata sul pin digitale 1 diventa positiva, sincronismo_BC è il nome della funzione
  attachInterrupt(digitalPinToInterrupt(3), sincronismo_TR, RISING); //richiamo l'interrupt quando la tensione CA, collegata sul pin digitale 2 diventa positiva, sincronismo_CA è il nome della funzione

  sei(); //Enable interrupt

Ho inserito solo la parte che penso che serva.
Spero di essere stato abbastanza chiaro, grazie

Corretto usare SDA sul 20 e SCL sul 21, mente, come livbreria, sul LCD I2C c'è un gran casino ed una infinità di librerie, tutte con lo stesso nome, che funzionano in modo diverso ... :angry:

Scarica questa PCF8574_HD44780_I2C.zip (522.4 KB), scritta e manutenuta da un utente del forum, la cui relativa discussione trovi QUI.

E' molto simile a quella che stai usando, è garantita funzionare bene, devi solo studiarti gli esempi per capire come chiamare i vari metodi, specie l'inizializzazione :wink:

Ah ... NON ho capito a che ti servono gli interrupt in relazione al LCD ... :roll_eyes:

Guglielmo

Mi riferisco alla riga di codice

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE) ;

non ho capito se i numeri 2 e 3 si riferisco ai pin della scheda o sono tutt'altra cosa. Perchè se fossero riferiti alla scheda allora qui pin son occupati da due segnali che mi generano interrupt.

Ti ripeto che quella riga di inizializzazione, per me, NON ha senso per I2C ... è un mix di una inizializzazione I2C e di un'inizializzazione con l'LCD classico senza I2C ...
... usa la libreria che ti ho allegato.

Guglielmo

Sto utilizzando la libreria, ma continuo ad avere problemi sugli altri pin. In particolare i pin che vanno da 8-->13 che normalmente vanno HIGH o LOW in base ad un timer interrupt, assumono valori casuali o valori finni HIGH o LOW. Possono questi Pin dipendere dalla I2C?

NO.

Guglielmo