duminică, 9 iunie 2013

Ceas de timp real (RTC) cu DS1307 si Arduino (partea a 2-a)

   Am realizat modulul de timp real, o parte cu piese, o parte cu piese recuperate, conform schemei din articolul Ceas de timp real (RTC) cu DS1307 si Arduino conform penultimei scheme.
 
   Am alimentat si conectat modulul RTC la placuta Arduino, constatand ca LED-ul conectat la iesirea SQW se aprinde, chiar daca timpul nu este setat.
 

   Am folosit libraria de la https://codeload.github.com/adafruit/RTClib/zip/master pentru prime teste.
   Codul folosit este cel din exemplul insotitor, deoarece preia data din RTC-ul calculatorului la momentul compilarii sketch-ului si o transfera apoi RTC-ului meu:

// 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);
    Wire.begin();
    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(__DATE__, __TIME__));
  }
}

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);

}


  La acest sketch nu este activata iesirea SQW sa "clipoceasca" cu frecventa de 1Hz,asa ca am inceput sa mai caut,asa ca am dat de urmatoarele articole:
Real Time Clock Module (DS1307) (SKU:DFR0151)
RTC1307 - Real Time Clock
   Am gasit la http://forum.arduino.cc/index.php?topic=3171.5;wap2 o parte de cod:

Serial.begin(9600);
  // code courtesy of Mr. BroHogan (a.k.a. "Life Clock");
  Wire.beginTransmission(0x68);
  Wire.send(0x07);
  Wire.send(0x90);                       // 0x90=1Hz, 0x91=4kHz, 0x92=8kHz, 0x93=32kHz
  Wire.endTransmission();

   Am ajuns la http://forum.arduino.cc/index.php?topic=137067.0, care duce la https://github.com/davidhbrown/RealTimeClockDS1307, rezultatul din exemplul de acolo este:


   Dupa mai multe cautari pe net, am gasit articolul Tutorial: Arduino and the I2C bus – Part One in care se regaseste un sketch, care prezinta modul de comanda al iesirii SQW (pinul 7):


/*
DS1307 Square-wave machine
 Used to demonstrate the four different square-wave outputs from Maxim DS1307
 See page nine of data sheet for more information
 John Boxall - tronixstuff.wordpress.com
 */
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus address, the DS1307 is 0x68
void setup()
{
 Wire.begin();
}
void sqw1() // set to 1Hz
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address
 Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary)
 Wire.endTransmission();
}
void sqw2() // set to 4.096 kHz
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address 
 Wire.write(0x11); // sends 0x11 (hex) 00010001 (binary)
 Wire.endTransmission();
}
void sqw3() // set to 8.192 kHz
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address 
 Wire.write(0x12); // sends 0x12 (hex) 00010010 (binary)
 Wire.endTransmission();
}
void sqw4() // set to 32.768 kHz (the crystal frequency)
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address 
 Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary)
 Wire.endTransmission();
}
void sqwOff()
// turns the SQW off
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0x07); // move pointer to SQW address
 Wire.write(0x00); // turns the SQW pin off
 Wire.endTransmission();
}
void loop()
{
 sqw1();
 delay(5000);
 sqw2();
 delay(5000);
 sqw3();
 delay(5000);
 sqw4();
 delay(5000);
 sqwOff();
 delay(5000);
}

   Un exemplu al modificarii celor 5 variante de frecvente pe pinul SQW(zero, 1Hz, 4096Hz, 8192Hz, respectiv 32768Hz) se regaseste in filmuletul numit DS1307 square-wave demonstration:
   Tot acolo se face o trimitere la alt articol numit Blinky the one-eyed clock unde gasim tot ce ne trebuie, asa ca am reusit si eu sa faca LED-ul sa "clipoceaca" si sa citesc pe monitorul serial data si ora:


// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part from http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/

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

RTC_DS1307 RTC;

void setup () {
    Serial.begin(9600);
    Wire.begin();
  
// part code from http://tronixstuff.wordpress.com/
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    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(__DATE__, __TIME__));
  }
}

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.println();
    delay(3000);
}


   Avand in vedere ca am achitionat o placuta breadboard SYB-120 si niste fire cu conectori tata-tata si tata-mama, am facut repede legaturile pentru RTC si LCD folosind protocolul de comunicare i2c:
   Am combinat sketch-ul din articolul Interfata i2c la LCD pentru Arduino cu cel anterior, obtinand:


// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
// add part with LCD from http://blog.gotencool.com/2012/03/arduino-lcd-via-i2c.html
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
RTC_DS1307 RTC;

void setup () {
   lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
    
   // Serial.begin(9600);
    Wire.begin();
  
// part code from http://tronixstuff.wordpress.com/
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    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(__DATE__, __TIME__));
  }
}

void loop () {
   DateTime now = RTC.now();
   lcd.setCursor(6, 0);
   lcd.print(now.hour(), DEC);
   lcd.print(":");
   lcd.print(now.minute(), DEC);
   lcd.print(":");
   lcd.print(now.second(), DEC);
   lcd.print(" "); 
    
   lcd.setCursor(5, 1);
   lcd.print(now.day(), DEC);
   lcd.print("/");
   lcd.print(now.month(), DEC);
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(""); 
  
   delay(1000);
}
   Am facut 2 filmulete cu ce am realizat:
RTC DS1307 LCD1602A using i2c with Arduino (I)
RTC DS1307 LCD1602A using i2c with Arduino (II)

   Am conectat si senzorul de temperatura si umiditate DHT11, combinand cu ultimul sketch din articolul Ministatie meteo cu senzorul DHT11 si.. Arduino, obtinand:


// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/
// add part with LCD from http://blog.gotencool.com/2012/03/arduino-lcd-via-i2c.html
// adapted sketch by niq_ro from http://nicuflorica.blogspot.ro/

#include <DHT.h>
#define DHTPIN A2     // what pin we're connected DHT11
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);



#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
RTC_DS1307 RTC;

void setup () {
  dht.begin();
  lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
    
   // Serial.begin(9600);
    Wire.begin();
  
// part code from http://tronixstuff.wordpress.com/
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    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(__DATE__, __TIME__));
  }
}

void loop () {
   DateTime now = RTC.now();
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  
   lcd.setCursor(0, 0);
   lcd.print(now.hour(), DEC);
   lcd.print(":");
   lcd.print(now.minute(), DEC);
   lcd.print(":");
   lcd.print(now.second(), DEC);
   lcd.print(" "); 
   
   lcd.setCursor(10, 0);
   lcd.print("t=");
   lcd.print(t);
   lcd.write(0b11011111);
   lcd.print("C");
    
   lcd.setCursor(0, 1);
   lcd.print(now.day(), DEC);
   lcd.print("/");
   lcd.print(now.month(), DEC);
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(""); 
   
   lcd.setCursor(10, 1);
   lcd.print("H=");
   lcd.print(h);
   lcd.print("%");
  
   delay(1000);
}

apoi inca unu', care se numeste date and hour, temperature and humidity with RTC DS1307 DHT11 LCD on i2c with Arduino (II)
   Deoarece valorile afisate ale secundelor, minutelor, orelor, zilelor si lunilor dintr-o cifra se afisau doar asa, dintr-o cifra, am pus sa apara un zero in fata, iar la ore un spatiu...
   Sketch-ul a devenit:
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// adapted sketch for DHT11 by by niq_ro from http://nicuflorica.blogspot.ro
// version 4.0

#include <DHT.h>
#define DHTPIN A2     // what pin we're connected DHT11
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);


#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2); // 0x20 is adresss for LCC 16x2
RTC_DS1307 RTC;

void setup () {
  dht.begin();
  lcd.init(); 
  lcd.backlight(); //backlight is now ON
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a logo message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("www.tehnic.go.ro");  
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay (2500);
  lcd.clear();
  
  lcd.setCursor(0, 0);
  lcd.print("ceas cu calendar");  
  lcd.setCursor(0, 1);
  lcd.print("temp. si umidit.");
  delay (2500);
  lcd.clear();  
  lcd.setCursor(0, 0);
  lcd.print("ceas cu calendar"); 
  lcd.setCursor(2, 1);
  lcd.print("versiunea 4.0");
  delay (2500);
  lcd.clear();  
  
  Wire.begin();
  
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
Wire.endTransmission();
// end part code from http://tronixstuff.wordpress.com/

    RTC.begin();
// RTC.adjust(DateTime(__DATE__, __TIME__));
// if you need set clock... just remove // from line above this
  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(__DATE__, __TIME__));
  }
}

void loop () {
   DateTime now = RTC.now();
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  
   lcd.setCursor(1, 0);
   if ( now.hour() < 10)
   {
     lcd.print(" "); 
     lcd.print(now.hour(), DEC);
   }
   else
   {
   lcd.print(now.hour(), DEC);
   }
   lcd.print(":");
   if ( now.minute() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.minute(), DEC);
   }
   else
   {
   lcd.print(now.minute(), DEC);
   }
   lcd.print(":");
   if ( now.second() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.second(), DEC);
   }
   else
   {
   lcd.print(now.second(), DEC);
   }
   lcd.print(" "); 
   
   lcd.setCursor(12, 0);
   lcd.print(t);
   lcd.write(0b11011111);
   lcd.print("C");
    
   lcd.setCursor(0, 1);
   if ( now.day() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.day(), DEC);
   }
   else
   {
   lcd.print(now.day(), DEC);
   }
   lcd.print("/");
   if ( now.month() < 10)
   {
     lcd.print("0"); 
     lcd.print(now.month(), DEC);
   }
   else
   {
   lcd.print(now.month(), DEC);
   }
   lcd.print("/");
   lcd.print(now.year(), DEC);
   lcd.print(""); 
   
   lcd.setCursor(12, 1);
   lcd.print(h);
   lcd.print("%u");
  
   delay(500);
}
   Am creat un simbol pentru umiditate (un pahar umplut pe jumatate) folosindu-ma de informatiile de la ROROID:



6 comentarii:

  1. Fascinant-de cite ori postati ceva primesc mesaj-acum 25 de ani citeam articolele ing. Sergiu Florica (fiei tarina usoara). Am vrut si eu sa invat C++ pentru a programa microcontrolere dar sunt prea batrin sa ma pot schimba si nici timp nu mai am. Multa sanatate si viata lunga .-----un ucenic din barlad

    RăspundețiȘtergere
    Răspunsuri
    1. nu trebuie sa invatati tot C-ul, Arduino foloseste unul simplificat si sunt f. multe exemple pe net, oricum eu incerc sa scriu cat mai detaliat si cu sursa programului ... daca aveti nevoie o sa
      incerc sa va ajut...daca stiu

      Ștergere
  2. Poate incercati un ceas cu 2 matrici 8x8 si max7219

    RăspundețiȘtergere
    Răspunsuri
    1. poate... dupa ce o sa cumpar matrici ... dar nu cred ca ajung doar 2 afisaje... 4 mai degraba.....

      Ștergere
  3. Respectați ceea ce ați făcut minunat aici. Am timpul de instalare și temperatura instalată. Acum vreau ca anunțul să nu fie 11: 6: 8, dar 11:06:08 arata. Cum pot să obțin asta? Salutări din Germania / Berlin

    RăspundețiȘtergere
    Răspunsuri
    1. se inlocuieste 0 cu spatiu, de exemplu a minute:

      if ( now.minute() < 10)
      {
      lcd.print(" ");
      lcd.print(now.minute(), DEC);
      }
      else
      {
      lcd.print(now.minute(), DEC);
      }


      if ( now.minute() < 10)
      {
      lcd.print("0");
      lcd.print(now.minute(), DEC);
      }
      else
      {
      lcd.print(now.minute(), DEC);
      }

      Ștergere