Go Down

Topic: rtc ds1307 (Read 952 times) previous topic - next topic

zinco_mp

Buongiorno a tutti,
vi contatto dopo giorni e notti di prove, ricerche e mal di testa:
ho acquistato una scheda con ds1307 che vedete nel link di seguito:
http://www.ebay.it/itm/Shield-DS-1307-RTC-real-time-clock-memoria-I2C-Arduino-PIC-ART-CL12-/230993139734?pt=LH_DefaultDomain_101&hash=item35c8439816
Usando la libreria "RTClib.h", e nello specifico i vari sketch di esempio riscontro questi problemi, che tra l'altro hanno avuto già alcuni in altri forum, ma che non si capisce bene la soluzione:
- Se faccio partire lo sketch di seguito:
Code: [Select]
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

void setup () {
  Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
    DateTime now = rtc.now();
   
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
   
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
   
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
   
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
   
    Serial.println();
    delay(3000);
}

il seriale mi restituisce date assurde, con o senza batteria. Del tipo 2099/15/22 ed i secondi, a volte non sono consecutivi: per la serie 0:0:1; 0:0:23; 0:0:35 ecc.
Altre volte i secondi scorrono normalmente...mmmah.
Premetto che ho già provato a cambiare batteria, a vedere se è carica(ed effettivamente misuro 3,7-3,8V che è un po' troppo), a vedere se le linguette facessero ben contatto con la batteria misurando col tester.
Per ovviare ho provato anche a scollegare la batteria e mettere a GND il pin BAT. Medesimo risultato.
Alcune volte la data è cambiata dopo aver caricato lo sketch, ma sempre sbagliata.
La data del pc è corretta.
Boh!!!
Idee a riguardo?

zinco_mp

Inoltre ho provato anche un altro sketch esempio: softrtc che utilizza Millis().
In questo caso l'orologio funziona e la data è corretta, ma anche dopo una nottata monitorando l'ora, l'RTC ha accumulato un ritardo di più di 2 minuti in 8 ore di funzionamento.
E dato che l'ho implementato in un programma che gestisce accensioni e spegnimenti ad orari programmati diversi per giorni, se già in 8 ore ha sballato così tanto, figuriamoci dopo un mese...
Vi posto cmq lo sketch
Code: [Select]
// Date and time functions using just software, based on millis() & timer

#include <Wire.h>
#include "RTClib.h"

RTC_Millis rtc;

void setup () {
    Serial.begin(57600);
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
    DateTime now = rtc.now();
   
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
   
    Serial.print(" seconds since 1970: ");
    Serial.println(now.unixtime());
   
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
   
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
   
    Serial.println();
    delay(3000);
}


Vi prego...aiutatemi!!!

steve-cr

La data dell'RTC la devi inserire tu nel momento che fai partire il programma per la prima volta. La batteria serve solo quando togli l'alimentazione, in modo che RTC continui a funzionare alla successiva riaccensione.

Io non ho mai avuto problemi.

Code: [Select]

#include <Wire.h>
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x0E); // select register
  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
  Wire.endTransmission();
}
 
void loop()
{
  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write(0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 3); // request three bytes (seconds, minutes, hours)
 
  while(Wire.available())
  {
    int seconds = Wire.read(); // get seconds
    int minutes = Wire.read(); // get minutes
    int hours = Wire.read();   // get hours
 
    seconds = (((seconds & 0b11110000)>>4)*10 + (seconds & 0b00001111)); // convert BCD to decimal
    minutes = (((minutes & 0b11110000)>>4)*10 + (minutes & 0b00001111)); // convert BCD to decimal
    hours = (((hours & 0b00110000)>>4)*10 + (hours & 0b00001111)); // convert BCD to decimal (assume 24 hour mode)
 
    Serial.print(hours); Serial.print(":"); Serial.print(minutes); Serial.print(":"); Serial.println(seconds);
  }
 
  delay(1000);
}



Oppure puoi usare questo

Code: [Select]

/*
 Creadode under (cc) by Manuel Gonzalez, www.codingcolor.com
 http://creativecommons.org/license/cc-gpl
 Pins 12, 11, 5, 4, 3, 2 to LCD
 Analog pins 4 (SDA),5(SCL) to Chronodot
 Pins 6 (hour), 7(min) buttons
*/

#include <Wire.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//const int hourButtonPin = 6;
//const int minButtonPin = 7;

//int hourButtonState;
//int minButtonState;

int seconds; //00-59;
int minutes; //00-59;
int hours;//1-12 - 00-23;
int day;//1-7
int date;//01-31
int month;//01-12
int year;//0-99;


float Temp() {
  Wire.beginTransmission(0x68);
  Wire.write(0x11);
  Wire.endTransmission();

  Wire.requestFrom(0x68, 2);
  int MSBtemp = Wire.read();
  byte LSBtemp = Wire.read();
  
  if (MSBtemp >> 7 == 1) //controllo il bit 7 per sapere se ho ricevuto un numero negativo
    MSBtemp = ~(~MSBtemp + 1 + 128) + 1;  //  se lo è eseguo la coversione del byte con complemento a 2
  
  float Temperature = (float) (MSBtemp) + (float) ((LSBtemp >> 6) * 0.25);
  return Temperature;
}

void setup()
{

  //pinMode(hourButtonPin,INPUT);
  //pinMode(minButtonPin,INPUT);

  Wire.begin();
  lcd.begin(16,2);
 
 //hourButtonState = 0;
 // minButtonState = 0;
  ////////////////////////////////
  seconds = 00;
  minutes = 20;
  hours = 11;
  day = 6;
  date = 22;
  month = 7;
  year = 14;
  //initChrono();//just set the time once on your RTC
  ///////////////////////////////
}

void loop()
{
 
  //check_buttons();
  get_time();
  get_date();
  display_time();
  display_date();
  delay(1000);
  
  if (seconds == 59 | seconds == 9 | seconds == 19 | seconds == 29 | seconds == 39 | seconds == 49 ) {
  lcd.clear();
  lcd.setCursor (0,0);
  lcd.print ("Temperat.  ");
  lcd.print (Temp());
  
 
  delay (1000);
  lcd.clear ();
  }
 
}


void display_time()
{
  char buf[12];
 
  lcd.setCursor(0, 0);
 
  if(hours == 0)
  {
    lcd.clear();
  }
 
  lcd.print("Time ");  
  lcd.print(itoa(hours, buf, 10));
  lcd.print(":");
 
  if(minutes < 10)
  {
    lcd.print("0");
  }
  lcd.print(itoa(minutes, buf, 10));
 
  lcd.print(":");
 
  if(seconds < 10){
    lcd.print("0");
  }
  lcd.print(itoa(seconds, buf, 10));

}
void display_date()
{
  char buf[12];
 
  lcd.setCursor(0, 1);
  lcd.print("Date ");
 
 
 
  lcd.print(itoa(date, buf, 10));
  lcd.print("/");
  if(month < 10){
    lcd.print("0");
  }  
  lcd.print(itoa(month, buf, 10));
  lcd.print("/");
 
  if(year < 10){
    lcd.print("0");
  }
 
  lcd.print(itoa(year, buf, 10));
}

void initChrono()
{
  set_time();
  set_date();
}


void set_date()
{
  Wire.beginTransmission(104);
  Wire.write(3);
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(date));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void get_date()
{
  Wire.beginTransmission(104);
  Wire.write(3);//set register to 3 (day)
  Wire.endTransmission();
  Wire.requestFrom(104, 4); //get 5 bytes(day,date,month,year,control);

  day  = bcdToDec(Wire.read());
  date  = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year  = bcdToDec(Wire.read());
}

void set_time()
{
   Wire.beginTransmission(104);
   Wire.write(0);
   Wire.write(decToBcd(seconds));
   Wire.write(decToBcd(minutes));
   Wire.write(decToBcd(hours));
   Wire.endTransmission();
}

void get_time()
{
  Wire.beginTransmission(104);
  Wire.write(0);//set register to 0
  Wire.endTransmission();
  Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours);
  seconds = bcdToDec(Wire.read() & 0x7f);
  minutes = bcdToDec(Wire.read());
  hours = bcdToDec(Wire.read() & 0x3f);
 
}

 

 
/*
void setHour()
{
  hours++;
  if(hours > 23)
  {
   hours = 0;
   seconds = 0;
   minutes = 0;
  }
  set_time();
 
}
void setMinutes()
{
  minutes++;  
  if(minutes > 59)
  {
   minutes = 0;
  
  }
  seconds=0;
 
  set_time();
 
}
void check_buttons()
{
  hourButtonState = digitalRead(hourButtonPin);
  minButtonState = digitalRead(minButtonPin);
 
  if(hourButtonState == HIGH){
    setHour();
  }
 
  if(minButtonState == HIGH){
    setMinutes();
  }
}

*/

///////////////////////////////////////////////////////////////////////

byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}
Samantha Cristoforetti: "Mi fai fare un giro sul tuo ultraleggero?". "Certamente, però piloto io !"

Go Up