lcd + rtc + 3 tasti ---> tutto su i2c

ciao a tutti!

Sto facendo esperimenti e sono arrivato a un punto morto...

Sto facendo andare un LCD con interfaccia i2c con un RTC sempre con interfaccia i2c e ho questi 3 pulsanti di setup dell'orologio su 3 pin Analogici...

(ho modificato questo RTC shield DS1307: impostare data e ora - Mauro Alfieri Elettronica mettendo anche il displai su i2c)

ora volevo liberare i 3 pin analogici che mi occupano i 3 tasti di setup dell'orologio ma non ci riesco... ho provato a metterli di pin digitali modificando l'attribuzione dei pin e analogread con digitalread == HIGH ma non mi funzia e poi mi occuperebbero 3 pin digitali sempre utili.. ho sentito che ci son tastiere che lavorano in i2c ma non trovo documentazione...
l'ideale sarebbe una tastiera numerica con 4 tasti funzione...

allego stetch modificato per i collegamenti fare riferimento a link sopra

/*
 * RTC & LCD
 *
 * Autore: Mauro Alfieri
 * Tw: @mauroalfieri
 *
 * Web: http://www.mauroalfieri.it
 */
 
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
 

 
#define SET       A0
#define PIU       A1
#define MENO      A2
 
char buffer[10];
unsigned long time=0;
unsigned long timeSet=0;
int  setModeTime=2000;
 
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
 
void setup () {

 
    Wire.begin();
    RTC.begin();
   // lcd.begin(16, 2);
  lcd.init();   
 
 
   // Print a message to the LCD.
  lcd.backlight();
  lcd.print("LCD + RTC I2C");
  lcd.setCursor(0,1);
  lcd.print("Versione 1.0");
 
    if (! RTC.isrunning()) {
      Serial.println("RTC is NOT running!");
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
 
    pinMode( SET, INPUT );
    pinMode( PIU, INPUT );
    pinMode( MENO, INPUT );
}
 
void loop () {
 
    if ( analogRead( SET ) < 1000) { time = millis(); }
 
    DateTime now = RTC.now();
    lcd.clear();
 
    sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
    lcd.setCursor(0,0);
    lcd.print( buffer );
 
    char buffer[10] = "";
 
    sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.setCursor(0,1);
    lcd.print( buffer );
 
    if (time > 0 && setModeTime < (millis() - time) ) { setMode( now ); }
 
    delay(1000);
}
 
void setMode( DateTime now ) {
    boolean setMode = true;
    int setModeLevel = 0;
 
    int _day = now.day();
    int _month = now.month();
    int _year = now.year();
    int _hour = now.hour();
    int _min = now.minute();
    int _sec = now.second();
 
    lcd.clear();
    lcd.setCursor(0,0);
    sprintf(buffer,  "%s: %02d", "Giorno", _day);
    delay( 1000 );
    timeSet = millis();
 
    while ( setMode ) {
      if ( analogRead(SET) > 1000 || analogRead(PIU) > 1000 || analogRead(MENO) > 1000 ) { timeSet = millis(); }
 
      lcd.setCursor(0,0);
 
      // Set Day
      if ( setModeLevel == 0 ) {
        if ( analogRead(PIU) > 1000 && _day < 31) { _day++; }
        if ( analogRead(MENO) > 1000 && _day > 1) { _day--; }
 
        sprintf(buffer,  "%s: %02d", "Giorno", _day);
      }
      // Set Month
      if ( setModeLevel == 1 ) {
        if ( analogRead(PIU) > 1000 && _month < 12) { _month++; }
        if ( analogRead(MENO) > 1000 && _month > 1) { _month--; }
 
        sprintf(buffer,  "%s: %02d", "Mese", _month);
      }
      // Set Year
      if ( setModeLevel == 2 ) {
        if ( analogRead(PIU) > 1000 && _year < 9999) { _year++; }
        if ( analogRead(MENO) > 1000 && _year > 1900) { _year--; }
 
        sprintf(buffer,  "%s: %02d", "Anno", _year);
      }
      // Set Hour
      if ( setModeLevel == 3 ) {
        if ( analogRead(PIU) > 1000 && _hour < 24) { _hour++; }
        if ( analogRead(MENO) > 1000 && _hour > 1) { _hour--; }
 
        sprintf(buffer,  "%s: %02d", "Ora", _hour);
      }
      // Set Minute
      if ( setModeLevel == 4 ) {
        if ( analogRead(PIU) > 1000 && _min < 60) { _min++; }
        if ( analogRead(MENO) > 1000 && _min > 1) { _min--; }
 
        sprintf(buffer,  "%s: %02d", "Minuti", _min);
      }
      // Set Second
      if ( setModeLevel == 5 ) {
        if ( analogRead(PIU) > 1000 && _sec < 60) { _sec++; }
        if ( analogRead(MENO) > 1000 && _sec > 0) { _sec--; }
 
        sprintf(buffer,  "%s: %02d", "Secondi", _sec);
      }
 
      lcd.print( buffer );
      if ( analogRead(SET) > 1000 ) { lcd.clear(); setModeLevel++;  }
      if ( setModeLevel > 5 ) { setModeLevel=0; }
 
      if (timeSet > 0 && (setModeTime*2) < (millis() - timeSet) ) {
         RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec));
         setMode = false;
      }
      delay(200);
    }
}

Hai messo le resistenze pulldown e collegati i pulsanti tra entrata e +5V?

Se vuoi leggere i pulsanti tramite I2C puoi usare un I2C expander tipo PCF8574.

Ciao Uwe

uwefed:
Hai messo le resistenze pulldown e collegati i pulsanti tra entrata e +5V?

Se vuoi leggere i pulsanti tramite I2C puoi usare un I2C expander tipo PCF8574.

Ciao Uwe

Si ho messo tutte le resistenze pulldown è collegato 5v ho poi controllato segnale su pin 4,7v ok.... Ma perché il tipo ha usato le analogiche ?

Non esiste tastiera con già integrato i2c?

CASPA:
Si ho messo tutte le resistenze pulldown è collegato 5v ho poi controllato segnale su pin 4,7v ok.... Ma perché il tipo ha usato le analogiche ?

Si usano i pin analogici in 2 situazioni: o quando si sono terminati i pin digitali oppure se si usano i pin analogici per leggere più pulsanti per pin (usando delle catene di resistenze)

Non esiste tastiera con già integrato i2c?

Penso di sì.

Tastiere da sole io ne ho viste solo a matrici (3x4 o 4x4), invece esistono display con interfaccia I2C predisposti per il collegamento ad una tastiera a matrice.

ok risolto il discorso di avere tasti su pin digitali... (mi ero dimenticato di cambiare alcuni analogRead in digitalRead..... :*)

allego codice funzionante... (anche se non riesco ad eliminare resistenze pulldown esterne abilitando quelle interne )

/*
 * RTC & LCD
 *
 * Autore: Mauro Alfieri
 * Tw: @mauroalfieri
 *
 * Web: http://www.mauroalfieri.it
 */
 
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
 

 
#define SET       2
#define PIU       3
#define MENO      4
 
char buffer[10];
unsigned long time=0;
unsigned long timeSet=0;
int  setModeTime=2000;
 
RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
 
void setup () {

 
    Wire.begin();
    RTC.begin();
    lcd.init();   
 
 
   // Print a message to the LCD.
  lcd.backlight();
  lcd.print("LCD + RTC I2C");
  lcd.setCursor(0,1);
  lcd.print("tasti digitali");
  
    delay(4000); 
 
    if (! RTC.isrunning()) {
      Serial.println("RTC is NOT running!");
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
 
    pinMode( SET, INPUT );
    pinMode( PIU, INPUT );
    pinMode( MENO, INPUT );
    

//   non funziona... se tolgo resistenze
//   digitalWrite (SET,LOW); //attivo resistenza pulldown interna
//   digitalWrite (PIU,LOW); //attivo resistenza pulldown interna
//   digitalWrite (MENO,LOW); //attivo resistenza pulldown interna


}
 
void loop () {
 

  
    if ( digitalRead( SET ) == LOW) { time = millis(); }
 
    DateTime now = RTC.now();
    lcd.clear();
 
    sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
    lcd.setCursor(0,0);
    lcd.print( buffer );
 
    char buffer[10] = "";
 
    sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.setCursor(0,1);
    lcd.print( buffer );
 
    if (time > 0 && setModeTime < (millis() - time) ) { setMode( now ); }
 
    delay(1000);
}
 
void setMode( DateTime now ) {
    boolean setMode = true;
    int setModeLevel = 0;
 
    int _day = now.day();
    int _month = now.month();
    int _year = now.year();
    int _hour = now.hour();
    int _min = now.minute();
    int _sec = now.second();
 
    lcd.clear();
    lcd.setCursor(0,0);
    sprintf(buffer,  "%s: %02d", "Giorno", _day);
    delay( 1000 );
    timeSet = millis();
 
    while ( setMode ) {
      if ( digitalRead(SET) == HIGH || digitalRead(PIU) == HIGH || digitalRead(MENO) == HIGH ) { timeSet = millis(); }
 
      lcd.setCursor(0,0);
 
      // Set Day
      if ( setModeLevel == 0 ) {
        if ( digitalRead(PIU) == HIGH && _day < 31) { _day++; }
        if ( digitalRead(MENO) == HIGH && _day > 1) { _day--; }
 
        sprintf(buffer,  "%s: %02d", "Giorno", _day);
      }
      // Set Month
      if ( setModeLevel == 1 ) {
        if ( digitalRead(PIU) == HIGH && _month < 12) { _month++; }
        if ( digitalRead(MENO) == HIGH && _month > 1) { _month--; }
 
        sprintf(buffer,  "%s: %02d", "Mese", _month);
      }
      // Set Year
      if ( setModeLevel == 2 ) {
        if ( digitalRead(PIU) == HIGH && _year < 9999) { _year++; }
        if ( digitalRead(MENO) == HIGH && _year > 1900) { _year--; }
 
        sprintf(buffer,  "%s: %02d", "Anno", _year);
      }
      // Set Hour
      if ( setModeLevel == 3 ) {
        if ( digitalRead(PIU) == HIGH && _hour < 24) { _hour++; }
        if ( digitalRead(MENO) == HIGH && _hour > 1) { _hour--; }
 
        sprintf(buffer,  "%s: %02d", "Ora", _hour);
      }
      // Set Minute
      if ( setModeLevel == 4 ) {
        if ( digitalRead(PIU) == HIGH && _min < 60) { _min++; }
        if ( digitalRead(MENO) == HIGH && _min > 1) { _min--; }
 
        sprintf(buffer,  "%s: %02d", "Minuti", _min);
      }
      // Set Second
      if ( setModeLevel == 5 ) {
        if ( digitalRead(PIU) == HIGH && _sec < 60) { _sec++; }
        if ( digitalRead(MENO) == HIGH && _sec > 0) { _sec--; }
 
        sprintf(buffer,  "%s: %02d", "Secondi", _sec);
      }
 
      lcd.print( buffer );
      if ( digitalRead(SET) == HIGH ) { lcd.clear(); setModeLevel++;  }
      if ( setModeLevel > 5 ) { setModeLevel=0; }
 
      if (timeSet > 0 && (setModeTime*2) < (millis() - timeSet) ) {
         RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec));
         setMode = false;
      }
      delay(200);
    }
}

ora pero' devo capire come NON usare neanche questi 3 pin digitali utilizzando una i2c...

Tipo questa? ---> http://www.ebay.it/itm/I2C-Serial-20x4-LCD-Dsiplay-Blue-Keypad-Controller-Keypad-/310396462543?pt=UK_BOI_Electrical_Test_Measurement_Equipment_ET&hash=item48451225cf&_uhb=1

ho visto questo---> http://www.ebay.it/itm/281239028259?ssPageName=STRK:MEWAX:IT&_trksid=p3984.m1423.l2649

ma se con 1 interfaccia i2c riesco a fare sia display che tastiera è meglio che utilizzarne 2 ...

// non funziona... se tolgo resistenze
// digitalWrite (SET,LOW); //attivo resistenza pulldown interna

Mi stupirei del contrario, visto che le reistenze interne sono solo di PullUp

Puoi comunque collegare i pulsanti non verso il +5, ma verso massa, abilitare il PullUp interno e cambiare la logica sullo sketch

cioe' i comandi digitalRead( xxx ) == STATO) vanno invertiti.
Dove c'e' un LOW scrivi HIGH e viceversa

ma se con 1 interfaccia i2c riesco a fare sia display che tastiera è meglio che utilizzarne 2

ai fini pratici non cambia niente.

CASPA:
Tipo questa? ---> http://www.ebay.it/itm/I2C-Serial-20x4-LCD-Dsiplay-Blue-Keypad-Controller-Keypad-/310396462543?pt=UK_BOI_Electrical_Test_Measurement_Equipment_ET&hash=item48451225cf&_uhb=1

sì mi riferisco a questa tipologia. Sul numero di Febbraio 2014 di Elettronica IN uscirà un progetto (per ora non posso dire altro :grin:) nel quale sarà presente uno schedino di interfaccia I2C realizzabile "in casa" visto che il PCB è monofaccia e i componenti cono tutti a foro passante; lo schedino è progettato espressamente per i comuni display LCD, ai quali si salda direttamente, trasformandoli, con pochissima spesa in versione I2C.

Mi stupirei del contrario, visto che le reistenze interne sono solo di PullUp

:fearful: ... ero convinto che fossero sia di pullup che di pulldown... chissà dove l'ho letto.. :disappointed_relieved: