Acasă / Atelier / Microcontroler / Arduino / Ceas de timp real (RTC) cu DS1307 si Arduino

Ceas de timp real (RTC) cu DS1307 si Arduino

Deoarecea placa de dezvoltare Arduino se bazeaza pe un microcontroler ATmega 328 (sau cele mai vechi pe ATmega168 sau ATmega8), nu au incorporat un „ceas de timp real”, care sa „numere si sa memoreze” timpul trecut, secunde, ore, zile, luni, ani si in cazul cand placa de dezvoltare a fost deconectata de la sursa de alimentare.
Un integrat care sa faca acest lucru este DS1307 produs de MAXIM INTEGRATED, dupa cum se poate afla din fisa tehnica (datasheet).

Am desenat cu ajutorul programului EAGLE PCB DESIGN SOFTWARE o schema, pentru a realiza si o varianta proprie de cablaj:
Acest modul are modul de comuncare prin protocol i2c (2 fire active, SDA = intrare/iesire date, respectiv SCL = intrare seriala ceas), ceasul intern se bazeaza pe un cristal de cuart de 32,768kHz (cum sunt cele din ceasurile de mana), iar partea de alimentare de rezerva (in cazul intreruperii alimentarii) se realizeaza cu o baterie de 3V tip CR2302 (cum sunt cele de pe placile de baza ale calculatoarelor (PC), dar s epot folsi si 2 inseriate de 1,5V…

Pe site-ul Arduino se gasesc informatii despre libraria RTC-ului, dar si la ROBOFUN. O prezentare pas cu pas a modulul de asamblare a unui kit RTC cu DS1307 si conectare la un Arduino se gaseste la Adafruit Learning System.

Prezentare in limba romana am gasit in articolul http://www.electronicstefan.ro/2013/02/ceas-de-timp-real-rtc-cu-ds1307-si-arduino/ de pe blogul Electronic Stefan.

Schema „clasica” de conectare pentru modulul RTC folosind protocolul de communicare i2c este:

In articolul Using the ATMEGA168/Arduino with a DS1307 Real Time Clock scris de Lewis Loflin gasim o schema si un sketch care soloseste 3 butoane pentru reglajul orelor si minutelor:

#include <Wire.h> // specify use of Wire.h library.

byte blinkPin = 13;
byte SW0 = 4;
byte SW1 = 5;
byte SW2 = 6;

void setup()

{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600);
  pinMode(blinkPin, OUTPUT);
  digitalWrite(blinkPin, 0);

  pinMode(SW0, INPUT);  // for this use a slide switch
  pinMode(SW1, INPUT);  // N.O. push button switch
  pinMode(SW2, INPUT);  // N.O. push button switch

  digitalWrite(SW0, HIGH); // pull-ups on
  digitalWrite(SW1, HIGH);
  digitalWrite(SW2, HIGH);
}

void loop()
{
  Wire.beginTransmission(0x68);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(0x68, 7);
  byte secs = Wire.receive();
  byte mins = Wire.receive();
  byte hrs = Wire.receive();
  byte day = Wire.receive();
  byte date = Wire.receive();
  byte month = Wire.receive();
  byte year = Wire.receive();

  // hours, minutes, seconds

  Serial.print("The time is "); 
  if (hrs < 10) Serial.print("0");
  Serial.print(hrs,HEX);    
  Serial.print(":");
  if (mins < 10) Serial.print("0");
  Serial.print(mins, HEX);
  Serial.print(":");
  if (secs < 10) Serial.print("0");
  Serial.println(secs, HEX);

  // use MM-DD-YYYY

  Serial.print("The date is "); 
  if (month < 10) Serial.print("0");
  Serial.print(month,HEX);    
  Serial.print("-");
  if (date < 10) Serial.print("0");
  Serial.print(date, HEX);
  Serial.print("-");
  Serial.print("20");
  if (year < 10) Serial.print("0");
  Serial.println(year, HEX);
  Serial.println();

  if (!(digitalRead(SW0))) set_time(); // hold the switch to set time
  delay(1000);    //wait a second before next output
  toggle(blinkPin);
} 

// toggle the state on a pin
void toggle(int pinNum) 
{  
  int pinState = digitalRead(pinNum);
  pinState = !pinState;
  digitalWrite(pinNum, pinState); 
}

void set_time()   {
  byte minutes = 0;
  byte hours = 0;

  while (!digitalRead(SW0))  // set time switch must be released to exit
  {
    while (!digitalRead(SW1)) // set minutes
    { 
      minutes++;          
      if ((minutes & 0x0f) > 9) minutes = minutes + 6;
      if (minutes > 0x59) minutes = 0;
      Serial.print("Minutes = ");
      if (minutes >= 9) Serial.print("0");
      Serial.println(minutes, HEX);

      delay(750);
    }

    while (!digitalRead(SW2)) // set hours
    { 
      hours++;          
      if ((hours & 0x0f) > 9) hours =  hours + 6;
      if (hours > 0x23) hours = 0;
      Serial.print("Hours = ");
      if (hours <= 9) Serial.print("0");
      Serial.println(hours, HEX);
      delay(750);
    }

    Wire.beginTransmission(0x68); // activate DS1307
    Wire.send(0); // where to begin
    Wire.send(0x00);          //seconds
    Wire.send(minutes);          //minutes
    Wire.send(0x80 | hours);    //hours (24hr time)
    Wire.send(0x06);  // Day 01-07
    Wire.send(0x01);  // Date 0-31
    Wire.send(0x05);  // month 0-12
    Wire.send(0x09);  // Year 00-99
    Wire.send(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7. 
    Wire.endTransmission();
  }    
}

Am completat schema modululului cu un LED care clipeste cu frecventa de 1Hz:

 

Sursă: Nicu FLORICA

Despre Nicu FLORICA

ELECTRONICA este prima pasiune a mea... am inceput pe la 7 ani cu un radio cu galena, in vacanta de vara, a fost o bucurie enorma sa aud in casti posturi de radio si in loc sa joc fotbal, ascultam la minunea facuta de mine.. Pasiunea asta mi-a fost insuflata de tata, dar mie nu mi-au placut niciodata televizoarele cu lampi, vazand ca se pot testa cu mana, dar nestiind exact unde am primic cateva socuri care m-au cam speriat... Am inceput sa studiez revistele Tehnium, incat pana in 1998 am colectia aproape completa, de multe ori ajungeam intr-un oras si primul loc vizitat era Anticariatul. Am si alte reviste, cat de cat complete: RET, Radio, Electronistul, etc Am construit destule montaje si scheme si marea mea placere e sa imbunatatesc performantele lor.... In revista Tehnium am publicat 2 articole, unul in 1/'95 numit LUMINA DINAMICA si altul in 1/'97 numit INDICATOR TRICOLOR CU LED... BICOLOR. mi-am facut un site numai cu multe scheme: http://www.tehnic.go.ro si activez pe http://www.elforum.ro, unde am ID-ul niq_ro (acest ID il folosesc in toate forumurile si site-urile).

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

*