Problema Rtc 1307: non mantiene ora precisa

Buona sera a tutti, mi serve nuovamente il vostro aiuto. Praticamente il mio modulo rtc 1307 non mantiene bene l'ora nel senso che in un mese mi ritrovo circa mezz'ora avanti. Ora, premettendo che non vorrei modificare tutto lo sketch per sostituire questo rtc con uno più preciso, conoscete qualche modo per "rallentare" questo modello di rtc a livello hardware? Leggevo di mettere un condensatore in parallelo al quarzo: secondo voi potrebbe essere una soluzione? Conoscete qualche altro modo sempre nell'ottica hardware? Grazie infinite
PS questa è la parte di codice che riguarda l'Rtc (se può servire):

#include <DS1307RTC.h>
#include <Wire.h>

// adj real time correction(increase adjs second for day"
    if (hour() == 23 && minute() == 59 && second() == 60-adjs){ 
      setTime(23,59,59,day(),month(),year());
      // also update RTC
      RTC.set(now());
    }
  
    // automatic legal time correction +1
    if (ltime==1 && hour() == 2 && minute() == 00 && second() == 00 && weekday() == 1 && month()== 3 && day() > 24 ){ 
      setTime(03,00,00,day(),month(),year());
      memltime=0;
      // also update RTC
      RTC.set(now());
    }
  
    // automatic legal time correction -1
    if (memltime == 0 && ltime==1 && hour() == 3 && minute() == 00 && second() == 00 && weekday() == 1 && month()== 10 && day() > 24 ){ 
      setTime(02,00,00,day(),month(),year());
      memltime=1;
      // also update RTC
      RTC.set(now());

Mi sembra mooooolto strano, i DS1307 non sono il massimo della precisione (se paragonati ai DS3231), ma comunque l'errore massimo difficilmente supera ± qualche secondo nelle 24 ore.

Il datasheet dice chiaramente:

The DS1307 uses an external 32.768kHz crystal. The oscillator circuit does not require any external resistors or capacitors to operate.

E aggiunge poi:

The accuracy of the clock is dependent upon the accuracy of the crystal and the accuracy of the match between the capacitive load of the oscillator circuit and the capacitive load for which the crystal was trimmed. Additional error will be added by crystal frequency drift caused by temperature shifts. External circuit noise coupled into the oscillator circuit may result in the clock running fast.

Ora, salvo che veramente non hai preso prodotti di bassa qualità, con dei cristalli monnezza ... mi sa più di qualche cosa software che di un problema del RTC ... :roll_eyes:

Guglielmo

Scusa ma cosa fa questo pezzo di codice ? Tutte le notti risetti l'ora "rubando" alcuni secondi ?
Sei sicuro di sto pezzo ? Se sballi l'ora di pochi secondi ogni giorno... dopo 1 mese hai una mezz'ora
Tra l'altro posti un pezzo di codice da cui non sappiamo quanto vale la variabile adjs

1 Like

avete ragione, ma nella fretta mi ero dimenticato di specificare anche la variabile. Premetto che lo sketch non è mio. Ora vi posto il codice completo in modo da fare prima.

// include the library code:
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Time.h>
#include <Tone.h>
#include <Wire.h>

// DS13O7 support
#include <DS1307RTC.h>
#include <Wire.h>

// external EEPROM define type 24C64 address 0
#define DEV_ADDR 0x50
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
  int rdata = data;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(rdata);
  Wire.endTransmission();
}

byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) {
    rdata = Wire.read();
  }
  return rdata;
}

byte vp =32; // test counter char for external eprom


// declare the tones as an array
Tone sound;

const int DTMF[] = { 2200, 3300, 4600, 3800, 3800, 3800, 3800, 10000, 10000, 2200, 2200, 2200, 2200, 2200, 2200, 10000, 10000, 10000, 3800, 3800};

byte si=0;    //variable increment counter note sound

// Tone output pin
const byte TONE_PIN = A1;

// default parameters array
//                       HH  MM Pat Med  HH  MM Pat Med  HH  MM Pat Med  HH  MM Pat Med
const byte def_par[] = {  8,  0,  1,  1,  8, 30,  1,  2,  9,  0,  1,  3,  9, 30,  1,  4,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};

//declaration variables
int analogpin = 0;      //variable input analog buttons
byte keycount = 0;      //counter effective push button

byte keyDW = 0;          //button key Down
byte keyUP = 0;         //button key Up
byte keyACK = 0;       // button key aquisition alarm

byte keyESC = 0;       // button key exit function
byte keyCFG = 0;       // button key configuration system

byte push = 0;            // variable status botton
byte mempush = 0;         // variable memory botton pressed

int prg = 0;             // variable status program configuration
byte memalarm = 0;        // variable status alarm
int s_old = 0;           // memory old minute alarm
byte alarm = 0;           // alarm active

int sel = 0;              // select view alarms
byte lamp = 0;             // blink on/off
byte sold = 0;             // memory second old

int tast = 0;             // value increase / decrease parameter
int ho_old=0;             // mem old hour set
int mi_old=0;             // mem old minute set
int da_old=0;             // mem old day set
int mo_old=0;             // mem old month set
int ye_old=0;              // mem old year set

byte alm_h[33];           // array variable alarm hour view
byte alm_m[33];           // array variable alarm minute view
byte med[33];              // array variable alarm medicinale view
byte pat[33];              // array variable alarm patient

byte medic[1];             // variable view led alarm auxiliary

byte mtast;                // memory pressure key up or down

byte mmin=0;               // memory counter for auto-clear segnalation alarm

byte min_old=0;            // counter minute for auto-clear segnalation delay

byte adjs=48;              // adj off-set second time for day when not use the RTC

byte ltime=1;              // legal time

byte memltime=0;            // memory change legal time

byte _lang=0;                // memory select language  // tuxduino: underscore prefix means don't access this variable directly; use getCurrLang(), setCurrLang() instead

  /*/////////*/
//int ramLibera = freeRam(); // define freeRam(); function for view sram free  //R.0.5d


//
// Localization management by tuxduino
//
// list of defined languages
enum {
    LANG_FIRST = 0,
    LANG_EN = 0,
    LANG_IT = 1,
    LANG_LAST = 1,
};

// eeprom memory address of language setting by tuxduino
const byte EE_LANG_ADDR = 128;

// number of defined languages by tuxduino
const byte NUM_LANGS = LANG_LAST + 1;

// max size of localized string (including null-terminator)
// const byte MAX_STR_LEN = 17

// localized strings by tuxduino
const char* strings[][NUM_LANGS] = {
//   0123456789012345    0123456789012345
    "SetDefault_ALARM", "Allarmi_predef. ",        //  0
    "Patient_"        , "Paziente"        ,        //  1
    "Medicine______"  , "Medicina______"  ,        //  2
    "____NO_ALARM____", "_NESSUN_ALLARME_",        //  3
    "SET_hours_______", "Impostazione_ore",        //  4
    "SET_minutes_____", "Impostaz._minuti",        //  5
    "SET_day_________", "Impostaz._giorno",        //  6
    "SET_month_______", "Impostaz.___mese",        //  7
    "SET_year________", "Impostaz.___anno",        //  8
    "SET_ADJ_sec_time", "Regol.sec.giorno",        //  9
    "SET_Day.Sav.Time", "Attiv.ora_legale",        // 10
    "SET_Lang.__EN/IT", "Linguaggio_EN/IT",        // 11
    "SET_Sound.Pat._1", "Suoneria_Paz.__1",        // 12
    "SET_Sound.Pat._2", "Suoneria_Paz.__2",        // 13
    "  Time:"         , "   Ore:"         ,        // 14
    "Pat.:"           , "Paz.:"           ,        // 15
    "SET_hour____AL"  , "SET_ore_____AL"  ,        // 16
    "SET_min.____AL"  , "SET_minuti__AL"  ,        // 17
    "SET_Patient_AL"  , "SET_Pazient_AL"  ,        // 18
    "SET_Medicin_AL"  , "SET_Medicin_AL"  ,        // 19
};

// localized strings identifiers by tuxduino
enum {
   STR_SET_DEFAULT_ALARM = 0,
   STR_PATIENT     = 1,
   STR_MEDICINE    = 2,
   STR_NO_ALARM    = 3,
   STR_SET_HOURS   = 4,
   STR_SET_MINUTES = 5,
   STR_SET_DAY     = 6,
   STR_SET_MONTH   = 7,
   STR_SET_YEAR    = 8,
   STR_ADJ_SEC     = 9,
   STR_SET_LEGAL_TIME = 10,
   STR_SET_LANG    = 11,
   STR_SET_SOUND_PAT_1 = 12,
   STR_SET_SOUND_PAT_2 = 13,
   STR_TIME        = 14,
   STR_PAT         = 15,
   STR_SET_HOUR_AL = 16,
   STR_SET_MIN_AL  = 17,
   STR_SET_PATIENT_AL = 18,
   STR_SET_MEDICINE_AL = 19
};

// the the localized version of the specified string by tuxduino
const char* getString(byte stringId) {
    return strings[stringId][_lang];
}

// select language; the selection is stored in eeprom by tuxduino
void setCurrLang(byte langId) {
    if (langId < NUM_LANGS) {
        _lang = langId;
        EEPROM.write(EE_LANG_ADDR, _lang); 
    }
}

// get current language selection by tuxduino
byte getCurrLang() {
    return _lang;
}

// read the currently selected language from eeprom by tuxduino
// initialize eeprom setting if necessary
void initLangFromEeprom() {
    byte lang;
    
    lang = EEPROM.read(EE_LANG_ADDR);       // read language setting from eeprom
    if (lang > LANG_LAST) {                 // if the value is invalid
        lang = LANG_FIRST;                  // set it to a default value
        EEPROM.write(EE_LANG_ADDR, lang);   // and save it
    }
    
    // update global variable by tuxduino
    _lang = lang;
}


// declare variable matrix by tuxduino R05G
const byte NUM_ROWS = 4;
const byte NUM_COLS = 4;
byte rowPins[NUM_ROWS] = {  2,  3,  4,  5 };
byte colPins[NUM_ROWS] = {  6,  7,  8,  9 };
byte cnt = 0;
byte value = 1;

byte sel_sound1=0;          // memory select sound patient 1
byte sel_sound2=0;          // memory select sound patient 2

// initialize the library with the numbers of the interface pins //ATTENZIONE, PIN DISPLAY. MA CON I2C?
  LiquidCrystal lcd(A2, A3, 10, 11, 12, 13);


void setup() {

  //  bug Rev.0.5g1
//  lang=EEPROM.read(0);  // read language by eprom
//  if (lang>1) {lang=0;EEPROM.write(0,0);}//set to standard language "GB" if no setting

    initLangFromEeprom(); // by tuxduino
    
  sel_sound1=EEPROM.read(129);  // read sound patient 1
  if (sel_sound1>9) {sel_sound1=0;EEPROM.write(129,0);}//set to standard sound patient 1

  sel_sound2=EEPROM.read(130);  // read sound patient 2
  if (sel_sound2>9) {sel_sound2=0;EEPROM.write(130,0);}//set to standard sound patient 2

  /*/////////*/
Serial.begin(9600);  // start serial monitor //R.0.5d
Wire.begin(); 
 
 
  sound.begin(TONE_PIN);
  sound.play(DTMF[3], 500);

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  // Print a message version project to the LCD on start-up.
  lcd.print("ArduoMemoryR1.0c");
  lcd.setCursor(0, 1);
  lcd.print("By Giuseppe & Co");  
  //analogButtons.checkButtons();
  delay (1000);
  
// verify push down at start up for default parameter set
//  if (digitalRead(keyDW)== 1) { // key down start up active
  if (analogRead(analogpin)>=676 && analogRead(analogpin)<=678) { // key down start up active
  
  lcd.setCursor(0, 1);
  lcd.print(getString(STR_SET_DEFAULT_ALARM));  //R.0.5f
    sound.play(DTMF[4], 500);
      for (int i=0; i <= 31; i++){
        alm_h[i+1]=def_par[(i*4)];
        EEPROM.write((i*4), def_par[(i*4)]);  
        
        alm_m[i+1]=def_par[(i*4)+1];
        EEPROM.write((i*4)+1, def_par[(i*4)+1]);      
        
        pat[i+1]=def_par[(i*4)+2];
        EEPROM.write((i*4)+2,def_par[(i*4)+2]);
        
        med[i+1]=def_par[(i*4)+3];
        EEPROM.write((i*4)+3, def_par[(i*4)+3]);
      }
      
  } else {
        for (int i=0; i <= 31; i++){
          alm_h[i+1]=EEPROM.read(i*4);      
          alm_m[i+1]=EEPROM.read((i*4)+1);      
          pat[i+1]=EEPROM.read((i*4)+2);
          med[i+1]=EEPROM.read((i*4)+3);
        }
    delay (1000);
  }  
  
  //set start Time(hr,min,sec,day,month,yr);
  //setTime(12,00,00,21,11,2012);
  // set RTC DS1307 as current time source R.1.0.0
  setSyncProvider(RTC.get);

  
  //test leds and buzzer for 2 second
  sound.play(DTMF[1], 500);
  allOn(1);//all led on patient 1
  lcd.setCursor(0, 1);
  lcd.print("Patient_TEST__01");
  delay (1000);
  //lcd.setCursor(0, 0);
  lcd.setCursor(0, 1);
  lcd.print("Patient_TEST__02");
  allOff();
  sound.play(DTMF[1], 500);
  
  allOn(0);//all led on patient 2
  delay (1000);
  //lcd.setCursor(0, 0);  //R.0.5d
  allOff();
  lcd.clear();

}// end setup


//************************************************************************************* 
//*************************************************************************************

void loop() {
       
    // adj real time correction(increase adjs second for day"
    if (hour() == 23 && minute() == 59 && second() == 60-adjs){ 
      setTime(23,59,59,day(),month(),year());
      // also update RTC
      RTC.set(now());
    }
  
    // automatic legal time correction +1
    if (ltime==1 && hour() == 2 && minute() == 00 && second() == 00 && weekday() == 1 && month()== 3 && day() > 24 ){ 
      setTime(03,00,00,day(),month(),year());
      memltime=0;
      // also update RTC
      RTC.set(now());
    }
  
    // automatic legal time correction -1
    if (memltime == 0 && ltime==1 && hour() == 3 && minute() == 00 && second() == 00 && weekday() == 1 && month()== 10 && day() > 24 ){ 
      setTime(02,00,00,day(),month(),year());
      memltime=1;
      // also update RTC
      RTC.set(now());
    }

  // verify if is active all's alarms (1-32)
  // PS.: The first section n. 0 is used for view segnalation alarm when active
  for (int i=1; i <= 32; i++){

    if (alm_h[i] == hour() && alm_m[i] == minute() && med[i] != 0 && prg==0 && memalarm == 0 ){
    alarm = 1;
    alm_h[0] = alm_h[i];
    alm_m[0] = alm_m[i];
    pat[0] = pat[i];
    med[0] = med[i];
    }
  } // end for i active alarms

  //read status button acknoleg 
  push = 0;    //reset memory push pressed

//// assign the push button read select
  inputbuttons();
  if (keyCFG== HIGH) {push = 5; }// key cgf system select  
  if (keyESC== HIGH) {push = 4; }// key esc select
  
  if (keyDW== HIGH) {push = 3; }// key down select
  if (keyUP== HIGH) {push = 2; }// key up select
  if (keyACK== HIGH) {push = 1; }// key ENTER/ACK select

  if (push == 2) {
  byte b = i2c_eeprom_read_byte(DEV_ADDR, 0);
  Serial.println(b);
  Serial.println(vp);
  }
  if (push == 3) {
  vp=vp+1;  
  i2c_eeprom_write_byte(DEV_ADDR, 0 , vp);
  }
 
  if (keyDW== 0 && keyUP== 0 && keyACK== 0 && keyESC== 0 && keyCFG== 0) {mempush = 0; }// reset memory push button & exe function

  if (push == 1 && alarm == 1 && mempush == 0) {// acknoleg alarm
    mempush=1;
    memalarm = 2;
    alarm = 0;
    rexit();
    medic[0] = med[0];  
    verirow();  
  }
 
  // reset memory alarm old 
  if (push == 1 && alarm == 0 && memalarm == 1 && mempush==0) {
    mempush = 1;
    gen_reset();
    }

  // verify new minute in alarm for automatically noise off
  if (second() == s_old && memalarm == 1) {
    alarm = 0;
    } 

  // reset total alarm and memory after minute
  if (second() == s_old && memalarm == 2) {
    gen_reset();
    } 
 
  // set start minute memory alarm and view single medicine
  if (alarm == 1 && memalarm == 0) {
    memalarm = 1;
    s_old = 59;
    min_old = minute();
    mmin = 0;
    }// end if set start minute memory alarm 

  // increase minute counter memory of alarm segnalation
  if (memalarm == 1 && min_old != minute()) {
    mmin++; 
    min_old = minute(); 
    }
  
  // reset auto-clear memory alarm segnalation after 30 minutes
  if (memalarm == 1 && mmin == 30) {
    gen_reset();   
    }
 
  // generation blink second
  if (sold != second()) {
    sold = second();
    lamp = not lamp;   
    }
 
  // active alarm noise segnalation
    if (lamp == 1 && alarm == 1 && memalarm != 2) {
      noise_alarm();//call noise alarm segnalation
    } else {
      si=0;
    }
 
  //write the time & date o LCD
  if (prg == 0){
    lcd.setCursor(0, 0);
    printDigits(hour());// hour current time
 
  if (lamp == 1) {lcd.print("*");
    } else {
    lcd.print(":");
    } //segnalation run second 
   
    printDigits(minute());//minute current time

  //view date & patient blinking if alarm is run
  if (lamp == 1 && memalarm == 1) {
    //reset all led
    allOff();
    lcd.setCursor(0, 0);
    printDigits(alm_h[0]);
    lcd.print(".");
    printDigits(alm_m[0]);
    lcd.setCursor(6, 0);

    lcd.print(getString(STR_PATIENT));
    lcd.setCursor(14, 0);
    printDigits(pat[0]);

    lcd.setCursor(0, 1);
    lcd.print(getString(STR_MEDICINE));
    lcd.setCursor(14, 1);
    printDigits(med[0]);
    } else {
    medic[0] = med[0];  
    verirow();
    //view current date
    lcd.print("_");
    printDigits(day());
    lcd.print("/");
    printDigits(month());
    lcd.print("/");
    printDigits(year());
    }
    
    if (prg == 0 && memalarm == 0){
      lcd.setCursor(0, 1);
      lcd.print(getString(STR_NO_ALARM));
      }

  }  //end write the time & date in standby mode


  configuration();  // call configuration subroutine

  /*/////////*/
//  Serial.println(ramLibera); //view memory free
  //Serial.println(weekday()); //view week day for test legal time
 
}//end loop program

//************************************************************************

  /*/////////*/
//function for check free sram  //R.0.5d
//int freeRam () {
//  extern int __heap_start, *__brkval; 
//  int v; 
//  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
//  }


void noise_alarm(){
  //generation noise alarm for patient
  if (pat[0]==1) {
    si=si+sel_sound1;
    if (si > 20) {si=1;}
    sound.play(DTMF[si], 50+(sel_sound1*200));
  }
  if (pat[0]==2) {
    si=si+sel_sound2;  
    if (si > 20) {si=1;}
    sound.play(DTMF[si], 50+(sel_sound2*200));
  }  
}


void configuration(){
// configuration system program parameters

      if (prg == 81) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_HOURS));// by tuxduino
        lcd.setCursor(0, 1);
        ho_old = ho_old + tast;
        if (ho_old > 23 || ho_old < 0) {ho_old = 0;} 
        tast = 0;
        printDigits(ho_old);
        }

      if (prg == 82) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_MINUTES));// by tuxduino
        lcd.setCursor(0, 1);
        mi_old = mi_old + tast;
        if (mi_old > 59 || mi_old < 0) {mi_old = 0;} 
        tast = 0;
        printDigits(mi_old);
        }

      if (prg == 83) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_DAY));// by tuxduino
        lcd.setCursor(0, 1);
        da_old = da_old + tast;
        if (da_old > 31 || da_old < 1) {da_old = 1;} 
        tast = 0;
        printDigits(da_old);
        }

      if (prg == 84) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_MONTH));// by tuxduino
        lcd.setCursor(0, 1);
        mo_old = mo_old + tast;
        if (mo_old > 12 || mo_old < 1) {mo_old = 1;} 
        tast = 0;
        printDigits(mo_old);
        }

      if (prg == 85) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_YEAR));// by tuxduino
        lcd.setCursor(0, 1);
        ye_old = ye_old + tast;
        if (ye_old > 2030 || ye_old < 1970) {ye_old = 2012;} 
        tast = 0;
        printDigits(ye_old);
        }

      if (prg == 86) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_ADJ_SEC));// by tuxduino
        lcd.setCursor(0, 1);
        adjs = adjs + tast;
        if (adjs > 59 || adjs < 0) {adjs = 0;} 
        tast = 0;
        printDigits(adjs);
        }

      if (prg == 87) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_LEGAL_TIME));// by tuxduino
        lcd.setCursor(0, 1);
        ltime = ltime + tast;
        if (ltime > 1 || ltime < 0) {ltime = 0;} 
        tast = 0;
        printDigits(ltime);
        memltime=0;
        }
        
      if (prg == 88) {
        byte lang;
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_LANG));// by tuxduino
        lcd.setCursor(0, 1);
        lang = getCurrLang() + tast;
        if (lang > LANG_LAST) {
            lang = LANG_FIRST;
        }
        setCurrLang(lang);
        tast = 0;
        printDigits(lang);
        memltime=0;
      }
        
      if (prg == 89) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_SOUND_PAT_1));// by tuxduino
        lcd.setCursor(0, 1);
        sel_sound1 = sel_sound1 + tast;
        //check the sound patient n.1 selected        
        if (sel_sound1 > 9 || sel_sound1 < 0) {sel_sound1 = 0;}
        EEPROM.write(129,sel_sound1); 
        tast = 0;
        printDigits(sel_sound1);
        memltime=0;
        }

      if (prg == 90) {
        lcd.setCursor(0, 0);
        lcd.print(getString(STR_SET_SOUND_PAT_2));// by tuxduino
        lcd.setCursor(0, 1);
          //check the sound patient n.2 selected        
        sel_sound2 = sel_sound2 + tast;
        if (sel_sound2 > 9 || sel_sound2 < 0) {sel_sound2 = 0;}
        EEPROM.write(130,sel_sound2); 
        tast = 0;
        printDigits(sel_sound2);
        memltime=0;
        }

  //check the end of configuration system
      if (prg == 91) {
        lcd.clear();
        prg = 0;
        sel = 0;
        alarm = 0;
        memalarm = 0;
        tast=0;
        mtast=0;
        setTime(ho_old,mi_old,0,da_old,mo_old,ye_old);  //set new time&date
        // also update RTC
        RTC.set(now());
        }

// configuration parameters of alarms 

  //increase or decrease hour alarm select
      if (prg == 1) {
        alm_h[sel+1] = alm_h[sel+1] + tast;
          if (alm_h[sel+1] > 23 || alm_h[sel+1] < 0) {alm_h[sel+1] = 0;} 
        checkhour(alm_h[sel+1]);
          //write to eprom the parameter change
        EEPROM.write((sel*4)+prg-1, alm_h[sel+1]);
        }
  //increase or decrease minute alarm select
      if (prg == 2) {
        alm_m[sel+1] = alm_m[sel+1] + tast;
          if (alm_m[sel+1] > 59 || alm_m[sel+1] < 0) {alm_m[sel+1] = 0;} 
        checkmin(alm_m[sel+1]);
          //write to eprom the parameter change
        EEPROM.write((sel*4)+prg-1, alm_m[sel+1]);
        }
  //increase or decrease patient alarm select
      if (prg == 3) {
        pat[sel+1] = pat[sel+1] + tast;
          if (pat[sel+1]> 2 || pat[sel+1] < 1) {pat[sel+1] = 1;} 
        checkpat(pat[sel+1]);
          //write to eprom the parameter change       
        EEPROM.write((sel*4)+prg-1, pat[sel+1]);
        }
  //increase or decrease medicine alarm select
      if (prg == 4) {
        med[sel+1] = med[sel+1] + tast;
          if (tast != 0) {mtast=1;}// memory pressure key up or down
      
      //verify patient select for to assigne the medicine     
          if ((med[sel+1]> 16 || med[sel+1] < 0) && pat[sel+1] == 1) {med[sel+1] = 0;} 
//          if ((med[sel+1]> 32 || med[sel+1] < 17) && pat[sel+1] == 2) {med[sel+1] = 17;} //bug R05h 24-11-2012     
          if (med[sel+1]==1 && pat[sel+1] == 2) {med[sel+1] = 17;}                                            //bug R05h 24-11-2012     
          if ((med[sel+1]> 32 || med[sel+1] < 0 || med[sel+1] ==16) && pat[sel+1] == 2) {med[sel+1] = 0;}     //bug R05h 24-11-2012     

        checkmed(med[sel+1]);
          //write to eprom the parameter change        
        EEPROM.write((sel*4)+prg-1, med[sel+1]);
          //parameter view on displey
        med[0]=med[sel+1];
        pat[0]=pat[sel+1];
         verirow();
          if (mtast == 1) {// verify pressure key up or down
            mtast=0;// reset memory pressure key up or down
            verirow();
          }
      }

      if (prg == 5) {//exit prog time and date
      gen_reset();//general reset
      
      }

// acknoleg alarms and confirm configurations parameters

  if (push == 1 && mempush == 0) {// verify preseed enter button (ACK)
    
    if (mempush ==0 && prg >= 1 && prg < 5 ) {// enter select change parameter of alarm
      mempush=1;
      prg = prg + 1;
      lcd.clear();
      rexit();//reset and exit program parameter
      }

    if (mempush ==0 && prg == 81) {// confirm hour time
      mempush=1;
      prg = prg + 1;
      lcd.clear();
      mi_old = minute();//set minute memory for autoexit after 1 minute
      rexit();
      }

    if (mempush ==0 && prg == 82) {// confirm minute time
      mempush=1;
      prg = prg + 1;
      lcd.clear();
      da_old = day();
      rexit();
      }

    if (mempush ==0 && prg == 83) {// confirm day date
      mempush=1;
      prg = prg + 1;
      lcd.clear();
      mo_old = month();
      rexit();
      }

    if (mempush ==0 && prg == 84) {// confirm month date
      mempush=1;
      prg = prg + 1;
      lcd.clear();
      ye_old = year();
      rexit();
      }

    if (mempush ==0 && (prg >= 85 && prg <= 90) ) {// confirm year date, adjs, legal time
      mempush=1;
      prg = prg + 1;
      lcd.clear();
      rexit();
      }
      
    if (prg == -1) {// editor select alarm for change
      mempush=1;  //bug Rev.0.5a
      prg = 1;
      lcd.clear();
      rexit();
      }
  }// end acknoleg alarms

//test pressure key
////  if (push == 1) {Serial.println("ent");}
////  if (push == 2) {Serial.println("up");}
////  if (push == 3) {Serial.println("down");}

    // decrease the parameter select
    if (push == 3 && prg >= 1 && mempush == 0) {  //decrease data
      mempush = 1;
      tast=-1;
      rexit();
      }
      
    // increase the parameter select
    if (push == 2 && prg >= 1 && mempush == 0) {    //increase data
      mempush = 1;
      tast=1;
      rexit();
      }

    // verify the push pressed for open configuration system
    if (push == 5 && prg == 0 && mempush == 0 && (memalarm == 0 || memalarm ==2)) {  //open configuration system
      mempush = 1;
      memalarm=0;
      alarm=0;
      prg = 81;
      ho_old = hour();  //memory old hour before change
      lcd.clear();
      sel = 0;
      rexit();
      //push=0;
      }

    // verify the push pressed for open configuration alarms
    if (push == 3 && prg == 0 && mempush == 0 && (memalarm == 0 || memalarm ==2)) {    //open configuration parameters alarms
      mempush = 1;
      memalarm=0;
      alarm=0;
      prg = -1;
      sel = 0;
      rexit();
      }

 // verify the push pressed for open configuration alarms
    if (push == 2 && prg == 0 && mempush == 0 && (memalarm == 0 || memalarm ==2)) {    //open configuration parameters alarms
      mempush = 1;
      memalarm=0;
      alarm=0;
      prg = -1;
      sel = 31;
      rexit();
      }

    // increase the alarm view
    if (push == 3 && prg == -1 && mempush == 0) {  //increase view
      mempush = 1;
      memalarm=0;
      alarm=0;
      sel = sel + 1;
      rexit();
      if (sel > 31) {sel = 31;}   
      }

    // decrease the alarm view
    if (push == 2 && prg == -1 && mempush == 0) {    //decrease view
      mempush = 1;
      sel = sel - 1;
      rexit();
      if (sel < 0) {sel = 0;}   
      } 

    // verify the time for insert the new parameter
    if ((s_old == second() || push==4) && prg != 0){//reset automatically function if don't touch buttons
      lcd.clear();
      prg = 0;
      sel = 0;
      alarm = 0;
      memalarm = 0;
      med[0]=0;
      tast=0;
      mtast=0;
      //verirow();
      allOff();
      s_old=second();
      rexit();
      }

  //view the parameters set of alarms
    if (prg == -1){
    lcd.setCursor(0, 0);
    lcd.print("AL");
    lcd.print(sel+1);
    lcd.print(getString(STR_TIME));
    printDigits(alm_h[sel+1]);
    lcd.print(".");
    printDigits(alm_m[sel+1]);
    lcd.print(" ");
    lcd.setCursor(0, 1);
    lcd.print(getString(STR_PAT));
    printDigits(pat[sel+1]);
    lcd.print("__Med.:");
    printDigits(med[sel+1]);
    }
  }


void gen_reset(){// general reset clear view all memory segnalation
  prg=0;
  sel=0;
  memalarm = 0;
  medic[0]=0;
  med[0]=0;
  alm_h[0]=0;
  alm_m[0]=0;
  pat[0]=0;
  tast=0;
  mtast=0;
  lcd.clear();
  // reset all led and all line led
  allOff();    
  }

void rexit(){ //reset timer 1 minute for auto exit program
  s_old = second()-1;
  if (s_old < 0) {s_old = 59;}      
  sound.play(DTMF[5], 50);
  }

void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0
    if(digits < 10)
    lcd.print('0');
    lcd.print(digits);
  }// end void printDigit


void checkhour(int digh){// utility for print description set hour of alarm
  lcd.setCursor(0, 0);
  lcd.print(getString(STR_SET_HOUR_AL));// by tuxduino
  lcd.print(sel+1);
  lcd.print(" ");   
  lcd.setCursor(0, 1);
  tast = 0;
  printDigits(digh);
  }

void checkmin(int digm){// utility for print description set minute of alarm
  lcd.setCursor(0, 0);
  lcd.print(getString(STR_SET_MIN_AL));// by tuxduino
  lcd.print(sel+1);
  lcd.print(" ");   
  lcd.setCursor(0, 1);
  tast = 0;
  printDigits(digm);
  }

void checkpat(int digp){// utility for print description set patient of alarm
  lcd.setCursor(0, 0);
  lcd.print(getString(STR_SET_PATIENT_AL));// by tuxduino
  lcd.print(sel+ 1);
  lcd.print(" ");   
  lcd.setCursor(0, 1);
  tast = 0;
  printDigits(digp);
  }

void checkmed(int dige){// utility for print description set medicine of alarm
  lcd.setCursor(0, 0);
  lcd.print(getString(STR_SET_MEDICINE_AL));// by tuxduino
  lcd.print(sel + 1);
  lcd.print(" ");   
  lcd.setCursor(0, 1);
  tast = 0;
  printDigits(dige);
  }


// function set all led to OFF by tuxduino
void allOff() {
    byte i;
    
    for (i = 0; i < NUM_COLS; i++) {
        pinMode(colPins[i], INPUT);
    }
    
    for (i = 0; i < NUM_ROWS; i++) {
        pinMode(rowPins[i], INPUT);
    }
  }

// function set all led to ON by tuxduino
void allOn(byte highOrLow) {
    byte i;
    
    for (i = 0; i < NUM_COLS; i++) {
        pinMode(colPins[i], OUTPUT);
        digitalWrite(colPins[i], highOrLow);
    }
    
    for (i = 0; i < NUM_ROWS; i++) {
        pinMode(rowPins[i], OUTPUT);
        digitalWrite(rowPins[i], !highOrLow);
    }
  }



void verirow() {
  // select patient 1 or 2 and adj number of medicine (modified for insert writeCell on release R05G1)
  if(med[0] >16){cnt=med[0]-17; value=0;} else {cnt=med[0]-1; value=1;}
  writeCell(cnt,value);
}

// function by tuxduino, insert by Giuseppe G. in the software release R.05G
// cellNumber: 0..ROW*COLS
// value: HIGH=1=patient2 or LOW=0=patient1

void writeCell(byte cellNum, byte value) {
    byte row;
    byte col;
    
    row = cellNum / NUM_COLS;
    col = cellNum % NUM_COLS;
    
    allOff();

    pinMode(colPins[col], OUTPUT);
    digitalWrite(colPins[col], value);

    pinMode(rowPins[row], OUTPUT);
    digitalWrite(rowPins[row], !value);
  }
  

//function select button pressed insert on R_1_0_0a
void inputbuttons()
{  
  int ib=0;
  ib = analogRead(analogpin);
  if (keycount == 5 && ib>=676 && ib <=678) {keyDW=1; } else {keyDW=0; }// key down  
  if (keycount == 5 &&ib>=438 && ib <=440) {keyUP=1; } else {keyUP=0; }// key up  
  if (keycount == 5 &&ib>=240 && ib <=242) {keyACK=1; } else {keyACK=0; }// key ack / Enter 

  if (keycount == 5 &&ib>=193 && ib <=195) {keyESC=1; } else {keyESC=0; }// key Esc
  if (keycount == 5 &&ib>=119 && ib <=121) {keyCFG=1; } else {keyCFG=0; }// key CFG system

  if (keycount > 30 ) {keycount=0; } // repeat time key pressed
  if (ib < 1000) {keycount++; } else {keycount=0; }// key press = 0  
 
}

//end sketch ArduinoMemory Reminder By Giuseppe G. (FABLAB Torino)

È scritto chiaramente che serve per la correzione se non si usa un RTC!

Grazie infinite. Basta, quindi, commentare questa riga di codice?


byte adjs=48;              // adj off-set second time for day when not use the RTC

No. Puoi impostare la variabile a zero.

... oppure elimini la variabile e tutto questo blocco:

// adj real time correction(increase adjs second for day" 
if (hour() == 23 && minute() == 59 && second() == 60-adjs){
setTime(23,59,59,day(),month(),year()); // also update RTC RTC.set(now()); 
}

Grazie infinite, mi sono perso in un bicchier d'acqua. Buon weekend.

Grazie, altrettanto a te :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.