Se afișează postările cu eticheta ceas de timp real. Afișați toate postările
Se afișează postările cu eticheta ceas de timp real. Afișați toate postările

miercuri, 13 mai 2015

Ceas de timp real cu DS3231 si ... Arduino

   Pana acum am folosit pentru a partea de ceasuri module sau integrate propriu-zise DS1307, dar am observat ca precizia lor nu este asa ridicata, asa ca am achizitionat, acum ceva timp, si un modul cu DS3231, care este mult mai precis, avand si o compensare cu temperatura.
   Pentru a vedeam cum lucreaza am folosit un sketch gasit la http://www.goodliffe.org.uk/arduino/rtc_ds3231.php, care prezinta data, ora si temperatura pe ecranul de monitorizare seriala, de asemenea, reglajul se face tot prin intermediul ecranului de monitorizare seriala, scriind un text de genul T1124154091014.
   Schema de conectare este foarte simpla, conectandu-se alimentarea (5V si GND) si firele de comunicatie pe protocol i2c (SDA si SCL). Montajul cu o placa Arduino Mega si un modul de ceas cu DS3231 arata asa:
   Pe ecranul de monotorizare seriala apare:
iar pentru a schimba ora/data:
   Formatul de programare a orei si date este urmatorul de genul T0058113130515, care are urmatoarea semnificatie:
- 00: secundele (din 2 cifre: 00..59)
- 58: minutele (din 2 cifre: 00..59)
- 11: ora (din 2 cifre: 00..23)
- 3: numarul zilei din saptamana, in cazul meu, miercuri a 3-a zi din saptamana (o singura cifra: 1..7)
- 13: ziua: 1..31
- 05: luna: 1..12
- 15: ultimele 2 cifre din an: 00..99

   Sketch-ul modificat de mine sa arata ziua in romana si dupa valoarea temperaturii grad Celsius este:
// original sketch from http://www.goodliffe.org.uk/arduino/rtc_ds3231.php
#include <Wire.h>
#define DS3231_I2C_ADDRESS 104

// SCL - pin A5
// SDA - pin A4
// To set the clock, run the sketch and use the serial monitor.
// Enter T1124154091014; the code will read this and set the clock. See the code for full details.
//
byte seconds, minutes, hours, day, date, month, year;
char weekDay[4];

byte tMSB, tLSB;
float temp3231;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
 
  watchConsole();
 
 
  get3231Date();
 
  Serial.print(weekDay); Serial.print(", "); Serial.print(date, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" - ");
  Serial.print(hours, DEC); Serial.print(":"); 
  if (minutes < 10){
    Serial.print("0");
    Serial.print(minutes, DEC); 
  }
  else{
     Serial.print(minutes, DEC); 
  }
  Serial.print(":"); 
  if (seconds < 10){
    Serial.print("0");
    Serial.print(seconds, DEC); 
  }
  else{
    Serial.print(seconds, DEC); 
  }
  Serial.println(" ");
   Serial.print("  Temp: "); Serial.print(get3231Temp());
Serial.println("^C ");
Serial.println(" _______________________");
Serial.println(" ");
  delay(10000); //10 sec
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

void watchConsole()
{
  if (Serial.available()) {      // Look for char in serial queue and process if found
    if (Serial.read() == 84) {      //If command = "T" Set Date
      set3231Date();
      get3231Date();
      Serial.println(" ");
    }
  }
}
 
void set3231Date()
{
//T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year)
//T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
//Example: 02-Feb-09 @ 19:57:11 for the 3rd day of the week -> T1157193020209
// T1124154091014
  seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result.  
  minutes = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hours   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  day     = (byte) (Serial.read() - 48);
  date    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  month   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  year    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.write(decToBcd(seconds));
  Wire.write(decToBcd(minutes));
  Wire.write(decToBcd(hours));
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(date));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}


void get3231Date()
{
  // send request to receive data starting at register 0
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(0x00); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes

  if(Wire.available()) {
    seconds = Wire.read(); // get seconds
    minutes = Wire.read(); // get minutes
    hours   = Wire.read();   // get hours
    day     = Wire.read();
    date    = Wire.read();
    month   = Wire.read(); //temp month
    year    = Wire.read();
       
    seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode)
    day     = (day & B00000111); // 1-7
    date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
    month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
    year    = (((year & B11110000)>>4)*10 + (year & B00001111));
  }
  else {
    //oh noes, no data!
  }
 
  switch (day) {
    case 1:
      strcpy(weekDay, "Luni");
      break;
    case 2:
      strcpy(weekDay, "Marti");
      break;
    case 3:
      strcpy(weekDay, "Miercuri");
      break;
    case 4:
      strcpy(weekDay, "Joi");
      break;
    case 5:
      strcpy(weekDay, "Vineri");
      break;
    case 6:
      strcpy(weekDay, "Sambata");
      break;
    case 7:
      strcpy(weekDay, "Duminica");
      break;
  }
}

float get3231Temp()
{
  //temp registers (11h-12h) get updated automatically every 64s
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
 
  if(Wire.available()) {
    tMSB = Wire.read(); //2's complement int portion
    tLSB = Wire.read(); //fraction portion
   
    temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
    temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
  }
  else {
    //oh noes, no data!
  }
   
  return temp3231;
}
   Am facut si un filmulet numit https://youtu.be/M8XoTKW9MJo:
   Am conectat si un afisaj LED cu cifre din 7 segmente la care am adaugat si un senzor de temperatura si umiditate DHT11 si am incarcat ultimul sketch prezentat in articolul de la http://nicuflorica.blogspot.ro/2013/07/afisaje-led-cu-7-segmente-si-arduino-ii.html
   Schema de conectare este:
    Sketch-ul mentionat este:
/*
 6-13-2011
 Spark Fun Electronics 2011
 Nathan Seidle

 This code is public domain but you buy me a beer if you use this and we meet 
 someday (Beerware license).

 4 digit 7 segment display:
 http://www.sparkfun.com/products/9483
 Datasheet: 
 http://www.sparkfun.com/datasheets/Components/LED/7-Segment/YSD-439AR6B-35.pdf

 This is an example of how to drive a 7 segment LED display from an ATmega
 without the use of current limiting resistors. This technique is very common 
 but requires some knowledge of electronics - you do run the risk of dumping 
 too much current through the segments and burning out parts of the display. 
 If you use the stock code you should be ok, but be careful editing the 
 brightness values.

 This code should work with all colors (red, blue, yellow, green) but the 
 brightness will vary from one color to the next because the forward voltage 
 drop of each color is different. This code was written and calibrated for the 
 red color.

 This code will work with most Arduinos but you may want to re-route some of 
 the pins.

 7 segments
 4 digits
 1 colon
 =
 12 pins required for full control 

 */
// modified connexion by niq_ro from http://nicuflorica.blogspot.com
// for my Luckylight KW4-563ASA
// dataseet: http://www.tme.eu/ro/Document/dfc2efde2e22005fd28615e298ea2655/KW4-563XSA.pdf

int digit1 = 11; //PWM Display pin 12 (digit1 is common anonds A1 from right side)
int digit2 = 10; //PWM Display pin 9 (digit2 is  common A2)
int digit3 = 9; //PWM Display pin 8 (digit3 is common anods A3)
int digit4 = 6; //PWM Display pin 6 (digit4 is common anods, from left side)

//Pin mapping from Arduino to the ATmega DIP28 if you need it
//http://www.arduino.cc/en/Hacking/PinMapping
int segA = 2; //Display pin 11
int segB = 3; //Display pin 7
int segC = 4; //Display pin 4
int segD = 5; //Display pin 2
int segE = 12; //Display pin 1
int segF = 7; //Display pin 10
int segG = 8; //Display pin 5
int segDP = 13; // Display pin 3

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

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;

// 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/


void setup() {

  Wire.begin();
  RTC.begin();
// RTC.adjust(DateTime(__DATE__, __TIME__));
// if you need set clock... just remove // from line above this

// part code for flashing LED
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
// Wire.write(0x00); // turns the SQW pin off
 Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave at 1Hz
// Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary) 32kHz

Wire.endTransmission();

  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__));
  }
  
  
 dht.begin();

  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);
  pinMode(segDP, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);
  
//  pinMode(13, OUTPUT);

 Serial.begin(9600);
 Serial.println("test for niq_ro");
}

void loop() {
digitalWrite(segDP, HIGH);
  DateTime now = RTC.now();
   int timp = now.hour()*100+now.minute();
//   int timp = (now.minute(), DEC);
//   displayNumber(12); // this is number to diplay
//   int timp = 1234;
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(" -> ");
  Serial.print(timp);
  Serial.println(" !");
  
   int h = dht.readHumidity();
   int t = dht.readTemperature();

   for(int i = 1000 ; i >0  ; i--) {
     displayNumber(t); // this is number to diplay
   }
   
   for(int i = 1000 ; i >0  ; i--) {
     displayNumber1(h); // this is number to diplay
   }
   
   for(int i = 1000 ; i >0  ; i--) {
     if (timp > 1000) displayNumber01(timp); 
     else displayNumber02(timp); 
   } 
  
}


//Given a number, we display 10:22
//After running through the 4 numbers, the display is left turned off

//Display brightness
//Each digit is on for a certain amount of microseconds
//Then it is off until we have reached a total of 20ms for the function call
//Let's assume each digit is on for 1000us
//Each digit is on for 1ms, there are 4 digits, so the display is off for 16ms.
//That's a ratio of 1ms to 16ms or 6.25% on time (PWM).
//Let's define a variable called brightness that varies from:
//5000 blindingly bright (15.7mA current draw per digit)
//2000 shockingly bright (11.4mA current draw per digit)
//1000 pretty bright (5.9mA)
//500 normal (3mA)
//200 dim but readable (1.4mA)
//50 dim but readable (0.56mA)
//5 dim but readable (0.31mA)
//1 dim but readable in dark (0.28mA)

void displayNumber(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW


  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
      digitalWrite(digit1, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      lightNumber(11); // display degree symbol
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      lightNumber(12); // display C letter
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    }
     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber1(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW


  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
      digitalWrite(digit1, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      lightNumber(10); // display degree symbol
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      lightNumber(13); // display C letter
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    }
     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber01(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
     digitalWrite(digit1, DIGIT_ON);
     digitalWrite(segDP, HIGH);
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      digitalWrite(segDP, LOW);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 

     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber02(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
     lightNumber(10); 
     digitalWrite(segDP, HIGH);
     break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      digitalWrite(segDP, LOW);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 

     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 


//Given a number, turns on those segments
//If number == 10, then turn off number
void lightNumber(int numberToDisplay) {

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

  switch (numberToDisplay){

  case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 1:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 2:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 3:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 4:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 5:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 6:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 7:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 8:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 9:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  // all segment are ON
  case 10:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  
  // degree symbol made by niq_ro
  case 11:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  // C letter made by niq_ro
  case 12:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  
  // H letter made by niq_ro
  case 13:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;
  }
}

   Am facut un film numit DS3231, DHT11 pe afisaj LED multiplexat comandate de Arduino, penru a vedea cum sunt afisate datele:


marți, 11 noiembrie 2014

Modul de afisare cu 8 cifre LED din 7 segmente fiecare controlate de MAX7219 (III)

   In articolele precedente (partea I si partea a II-a), am realizat un ceas cu reglaj manual al orei si cu informatii despre temperatura si umiditate.
   Temperatura si umiditatea sunt masurate de senzorul DHT22 (AM2302), cu o precizie destul de mare: +0,50C, respectiv +2% umiditate (%RH).
   Partea de ceas este realizata cu integratul DS1307, care are o mica baterie pentru a functiona si cand este intrerupta alimentarea ceasului propriu-zis.
   Partea de afisare este realizata pe afisoare led cu 8 cifre a cate 7 segmente, comandate de un integrat MAX7219.
   Initial, timpii de afisare erau de 3 secunde pentru temperatura si umiditate si 10 secunde pentru ora, dar am constatat ca acest mod este prea "static", asa ca am schimbat la 3 secunde fiecare afisare; era si o mica problema la afisarea cifrelor multiplu de 10, cand aparea pentru scurt timp litera "A", cand modificam manual orele si minutele.
   Schema de conectare este identica:
   Sketch-ul modificat este:
// adapted sketch by niq_ro from http://arduinotehniq.blogspot.com
// and http://nicuflorica.blogspot.ro
// version 1.0.b in 10.11.2014, Craiova - Romanaia

// source for LEDControl: http://embedded-lab.com/blog/?p=6862
#include "LedControl.h" 
/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
#include "DHT.h"
#define DHTPIN 7     // what pin we're connected to D7
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// if is just sensor:
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

// decralaration for type of value
float t1;
int t, h;

// 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/

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

RTC_DS1307 RTC;

byte SW0 = A0;
byte SW1 = A1;
byte SW2 = A2;

// use for hexa in zecimal conversion
int zh1, uh1, ore1;
int zm1, um1, miniti1;

void setup()
{
// Initialize MAX7219 device
lc.shutdown(0,false); // Enable display 
lc.setIntensity(0,11); // Set brightness level (0 is min, 15 is max) 
lc.clearDisplay(0); // Clear display register 
 
// Initialize HTD sensor
dht.begin();

    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__));
// 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/
  }

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

/*
 Serial.begin(9600);
 Serial.println("test for niq_ro");
 Serial.println("------------------");
*/
}

void loop()
{
 // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
t1 = dht.readTemperature();
t1 = 10*t1;
t = t1;
  
/* test part  
// test humidity value
h = 37;
// test temperature value
t = 19;
*/

// 
lc.clearDisplay(0); // Clear display register 
temperatura (t);
umiditate (h);
delay(3000);

lc.clearDisplay(0); // Clear display register 
for(int j=0; j<6; j++){
DateTime now = RTC.now();
int ora0 = now.hour();
int minut0 = now.minute();
int second0 = now.second();
/*
// serial monitor
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(" -> ");
  Serial.print(ora1);
  Serial.println(":");
  Serial.print(minut1);
  Serial.print(":");
  Serial.print(second1);
  Serial.println("------------------");
*/
ora (ora0, minut0, second0);
if (!(digitalRead(SW0))) set_time(); // hold the switch to set time

delay (500);
}

}


void umiditate (int umidit)
{
int zu = int(umidit/10); // determin cifra zecilor
int uu = umidit - 10*zu; // determin cifra unitatilor
  
lc.setDigit(0,2,zu, false); // afisez un 5 pe coloana 2
lc.setDigit(0,1,uu, false); // afisez un 0 pe coloana 1
lc.setRow(0,0,B0110111);  // afisez litera "H"
}

void temperatura (int temper)
{
int st = int(temper/100); // determin cifra sutelor
temper = temper - 100*st; // restul numarului de la zeci si unitati 
int zt = int(temper/10); // determin cifra zecilor
int ut = temper - 10*zt; // determin cifra unitatilor
  
lc.setDigit(0,7,st, false); // afisez un 5 pe coloana 7
lc.setDigit(0,6,zt, true); // afisez un 0 pe coloana 1 si virgula
lc.setDigit(0,5,ut, false); // afisez un 5 pe coloana 7
//lc.setRow(0,5,B1100011); // afisez un semn de grad pe coloana 5
lc.setRow(0,4,B1001110); // afisez un C pe coloana 4
}

void ora (int ora1, int minut1, int second1) 
{
// hour
int zo = int(ora1/10); // determin cifra zecilor
int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zo >= 1) lc.setDigit(0,7,zo, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uo, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
int zm = int(minut1/10); // determin cifra zecilor
int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
int zs = int(second1/10); // determin cifra zecilor
int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,zs, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,us, false); // afisez unitatile de minute pe coloana 0 (dreapta) 
}

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

  while (!digitalRead(SW0))  // set time switch must be released to exit
  {
    minutes1=minutes;
    hours1=hours;
    
     
    while (!digitalRead(SW1)) // set minutes
    { 
     minutes++;  
     if ((minutes & 0x0f) > 9) minutes = minutes + 6;
     if (minutes > 0x59) minutes = 0;

   // converting hexa in zecimal:
    zh1 = hours / 16;
    uh1 = hours - 16 * zh1 ;
    ore1 = 10 * zh1 + uh1; 
    zm1 = minutes / 16;
    um1 = minutes - 16 * zm1 ;
    miniti1 = 10 * zm1 + um1; 
      
       
lc.clearDisplay(0); // Clear display register 
// hour
//int zo = int(ora1/10); // determin cifra zecilor
//int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zh1 >= 1) lc.setDigit(0,7,zh1, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uh1, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
//int zm = int(minut1/10); // determin cifra zecilor
//int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm1, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um1, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
//int zs = int(second1/10); // determin cifra zecilor
//int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,0, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,0, false); // afisez unitatile de minute pe coloana 0 (dreapta) 

 
      Serial.print("Minutes = ");
      if (minutes >= 9) Serial.print("0");
      Serial.println(minutes, HEX);
    delay(250);    
    }

    while (!digitalRead(SW2)) // set hours
    { 
     hours++;          
      if ((hours & 0x0f) > 9) hours =  hours + 6;
      if (hours > 0x23) hours = 0;
     
   // converting hexa in zecimal:
    zh1 = hours / 16;
    uh1 = hours - 16 * zh1 ;
    ore1 = 10 * zh1 + uh1; 
    zm1 = minutes / 16;
    um1 = minutes - 16 * zm1 ;
    miniti1 = 10 * zm1 + um1; 
  
lc.clearDisplay(0); // Clear display register 
// hour
//int zo = int(ora1/10); // determin cifra zecilor
//int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zh1 >= 1) lc.setDigit(0,7,zh1, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uh1, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
//int zm = int(minut1/10); // determin cifra zecilor
//int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm1, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um1, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
//int zs = int(second1/10); // determin cifra zecilor
//int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,0, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,0, false); // afisez unitatile de minute pe coloana 0 (dreapta) 

      Serial.print("Hours = ");
      if (hours <= 9) Serial.print("0");
      Serial.println(hours, HEX);
    delay(250);
    }

    Wire.beginTransmission(0x68); // activate DS1307
    Wire.write(0); // where to begin
    Wire.write(0x00);          //seconds
    Wire.write(minutes);          //minutes
    Wire.write(0x80 | hours);    //hours (24hr time)
    Wire.write(0x06);  // Day 01-07
    Wire.write(0x01);  // Date 0-31
    Wire.write(0x05);  // month 0-12
    Wire.write(0x09);  // Year 00-99
    Wire.write(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7. 
    Wire.endTransmission();
  
    // converting hexa in zecimal:
    zh1 = hours / 16;
    uh1 = hours - 16 * zh1 ;
    ore1 = 10 * zh1 + uh1; 
    zm1 = minutes / 16;
    um1 = minutes - 16 * zm1 ;
    miniti1 = 10 * zm1 + um1; 
    
lc.clearDisplay(0); // Clear display register 
// hour
//int zo = int(ora1/10); // determin cifra zecilor
//int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zh1 >= 1) lc.setDigit(0,7,zh1, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uh1, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
//int zm = int(minut1/10); // determin cifra zecilor
//int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm1, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um1, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
//int zs = int(second1/10); // determin cifra zecilor
//int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,0, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,0, false); // afisez unitatile de minute pe coloana 0 (dreapta) 
  }  
}
   Am facut un mic filmulet numit statie meteo cu DHT22 si ceas reglabil cu DS1307 pe afisaj cu 8 cifre LED (3), care prezinta modul de functionare al montajului:
   Am mai constatat ca noaptea intensitatea luminoasa poate deranja, asa ca am pus un buton fara retinere (ca si celelalte) pentru a regla contrastul, deoarece libraria LedControl permite controlarea contrastului in 16 trepte.
   Schema devine:
iar sketch-ul este:
// adapted sketch by niq_ro from http://arduinotehniq.blogspot.com
// and http://nicuflorica.blogspot.ro
// version 1.0.c in 10.11.2014, Craiova - Romanaia

// source for LEDControl: http://embedded-lab.com/blog/?p=6862
#include "LedControl.h" 
/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain
#include "DHT.h"
#define DHTPIN 7     // what pin we're connected to D7
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// if is just sensor:
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

// decralaration for type of value
float t1;
int t, h;

// 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/

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

RTC_DS1307 RTC;

byte SW0 = A0;
byte SW1 = A1;
byte SW2 = A2;
byte SW3 = A3; // for contrast

// use for hexa in zecimal conversion
int zh1, uh1, ore1;
int zm1, um1, miniti1;

// contrast control
int contr = 11;

void setup()
{
// Initialize MAX7219 device
lc.shutdown(0,false); // Enable display 
lc.setIntensity(0,contr); // Set brightness level (0 is min, 15 is max) 
lc.clearDisplay(0); // Clear display register 
 
// Initialize HTD sensor
dht.begin();

    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__));
// 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/
  }

 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
 pinMode(SW3, INPUT);  // N.O. push button switch

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

/*
 Serial.begin(9600);
 Serial.println("test for niq_ro");
 Serial.println("------------------");
*/
}

void loop()
{
 // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
t1 = dht.readTemperature();
t1 = 10*t1;
t = t1;
  
/* test part  
// test humidity value
h = 37;
// test temperature value
t = 19;
*/

// 
lc.clearDisplay(0); // Clear display register 
for(int j=0; j<6; j++){
temperatura (t);
umiditate (h);
//delay(3000);
if (!(digitalRead(SW3))) {
  contr++;
  if (contr==16) contr=1;
lc.setIntensity(0,contr); // Set brightness level (0 is min, 15 is max) 
delay (50);
}
delay(500);
}

lc.clearDisplay(0); // Clear display register 
for(int j=0; j<6; j++){
DateTime now = RTC.now();
int ora0 = now.hour();
int minut0 = now.minute();
int second0 = now.second();
/*
// serial monitor
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print(" -> ");
  Serial.print(ora1);
  Serial.println(":");
  Serial.print(minut1);
  Serial.print(":");
  Serial.print(second1);
  Serial.println("------------------");
*/
ora (ora0, minut0, second0);
if (!(digitalRead(SW0))) set_time(); // hold the switch to set time

if (!(digitalRead(SW3))) {
  contr++;
  if (contr==16) contr=1;
lc.setIntensity(0,contr); // Set brightness level (0 is min, 15 is max) 
delay (50);
}
delay (500);
}

}


void umiditate (int umidit)
{
int zu = int(umidit/10); // determin cifra zecilor
int uu = umidit - 10*zu; // determin cifra unitatilor
  
lc.setDigit(0,2,zu, false); // afisez un 5 pe coloana 2
lc.setDigit(0,1,uu, false); // afisez un 0 pe coloana 1
lc.setRow(0,0,B0110111);  // afisez litera "H"
}

void temperatura (int temper)
{
int st = int(temper/100); // determin cifra sutelor
temper = temper - 100*st; // restul numarului de la zeci si unitati 
int zt = int(temper/10); // determin cifra zecilor
int ut = temper - 10*zt; // determin cifra unitatilor
  
lc.setDigit(0,7,st, false); // afisez un 5 pe coloana 7
lc.setDigit(0,6,zt, true); // afisez un 0 pe coloana 1 si virgula
lc.setDigit(0,5,ut, false); // afisez un 5 pe coloana 7
//lc.setRow(0,5,B1100011); // afisez un semn de grad pe coloana 5
lc.setRow(0,4,B1001110); // afisez un C pe coloana 4
}

void ora (int ora1, int minut1, int second1) 
{
// hour
int zo = int(ora1/10); // determin cifra zecilor
int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zo >= 1) lc.setDigit(0,7,zo, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uo, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
int zm = int(minut1/10); // determin cifra zecilor
int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
int zs = int(second1/10); // determin cifra zecilor
int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,zs, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,us, false); // afisez unitatile de minute pe coloana 0 (dreapta) 
}

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

  while (!digitalRead(SW0))  // set time switch must be released to exit
  {
    minutes1=minutes;
    hours1=hours;
    
     
    while (!digitalRead(SW1)) // set minutes
    { 
     minutes++;  
     if ((minutes & 0x0f) > 9) minutes = minutes + 6;
     if (minutes > 0x59) minutes = 0;

   // converting hexa in zecimal:
    zh1 = hours / 16;
    uh1 = hours - 16 * zh1 ;
    ore1 = 10 * zh1 + uh1; 
    zm1 = minutes / 16;
    um1 = minutes - 16 * zm1 ;
    miniti1 = 10 * zm1 + um1; 
      
       
lc.clearDisplay(0); // Clear display register 
// hour
//int zo = int(ora1/10); // determin cifra zecilor
//int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zh1 >= 1) lc.setDigit(0,7,zh1, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uh1, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
//int zm = int(minut1/10); // determin cifra zecilor
//int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm1, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um1, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
//int zs = int(second1/10); // determin cifra zecilor
//int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,0, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,0, false); // afisez unitatile de minute pe coloana 0 (dreapta) 

 
      Serial.print("Minutes = ");
      if (minutes >= 9) Serial.print("0");
      Serial.println(minutes, HEX);
    delay(250);    
    }

    while (!digitalRead(SW2)) // set hours
    { 
     hours++;          
      if ((hours & 0x0f) > 9) hours =  hours + 6;
      if (hours > 0x23) hours = 0;
     
   // converting hexa in zecimal:
    zh1 = hours / 16;
    uh1 = hours - 16 * zh1 ;
    ore1 = 10 * zh1 + uh1; 
    zm1 = minutes / 16;
    um1 = minutes - 16 * zm1 ;
    miniti1 = 10 * zm1 + um1; 
  
lc.clearDisplay(0); // Clear display register 
// hour
//int zo = int(ora1/10); // determin cifra zecilor
//int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zh1 >= 1) lc.setDigit(0,7,zh1, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uh1, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
//int zm = int(minut1/10); // determin cifra zecilor
//int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm1, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um1, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
//int zs = int(second1/10); // determin cifra zecilor
//int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,0, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,0, false); // afisez unitatile de minute pe coloana 0 (dreapta) 

      Serial.print("Hours = ");
      if (hours <= 9) Serial.print("0");
      Serial.println(hours, HEX);
    delay(250);
    }

    Wire.beginTransmission(0x68); // activate DS1307
    Wire.write(0); // where to begin
    Wire.write(0x00);          //seconds
    Wire.write(minutes);          //minutes
    Wire.write(0x80 | hours);    //hours (24hr time)
    Wire.write(0x06);  // Day 01-07
    Wire.write(0x01);  // Date 0-31
    Wire.write(0x05);  // month 0-12
    Wire.write(0x09);  // Year 00-99
    Wire.write(0x10); // Control 0x10 produces a 1 HZ square wave on pin 7. 
    Wire.endTransmission();
  
    // converting hexa in zecimal:
    zh1 = hours / 16;
    uh1 = hours - 16 * zh1 ;
    ore1 = 10 * zh1 + uh1; 
    zm1 = minutes / 16;
    um1 = minutes - 16 * zm1 ;
    miniti1 = 10 * zm1 + um1; 
    
lc.clearDisplay(0); // Clear display register 
// hour
//int zo = int(ora1/10); // determin cifra zecilor
//int uo = ora1 - 10*zo; // determin cifra unitatilor
if (zh1 >= 1) lc.setDigit(0,7,zh1, false); // afisez zecile de ore pe coloana 7 (in stanga)
lc.setDigit(0,6,uh1, false); // afisez unitatile de ore pe coloana 6
lc.setRow(0,5,B0000001);  // afisez o liniuta pe coloana 5
// minutes
//int zm = int(minut1/10); // determin cifra zecilor
//int um = minut1 - 10*zm; // determin cifra unitatilor
lc.setDigit(0,4,zm1, false); // afisez zecile de minute pe coloana 4
lc.setDigit(0,3,um1, false); // afisez unitatile de minute pe coloana 3
lc.setRow(0,2,B0000001);  // afisez o liniuta pe coloana 2
// seconds
//int zs = int(second1/10); // determin cifra zecilor
//int us = second1 - 10*zs; // determin cifra unitatilor
lc.setDigit(0,1,0, false); // afisez zecile de secunde pe coloana 1
lc.setDigit(0,0,0, false); // afisez unitatile de minute pe coloana 0 (dreapta) 
  }
}
   Am facut alt filmulet numit statie meteo cu DHT22 si ceas reglabil cu DS1307 pe afisaj cu 8 cifre LED (4) cu noua varianta:
15.06.2015
   Am primit de la Janos Baricz, care are meritul de a ma convinge sa fac acest ceas cu indicator de temperatura si umiditate, cateva poze cu montajul de ceas: