Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Zegar na DS3231.
#1
Kod:
//#include <config.h>
#include <ds3231.h>

#include "Wire.h"

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20,4);  // Ustawienie adresu ukladu na 0x27

#define DS3231_I2C_ADDRESS 0x68

// Konwersja liczby dziesiętnej do postaci binarnej
byte decToBcd(byte val){
 return( (val/10*16) + (val%10) );
}

// Konwersja liczby binarnej do postaci dziesiętnej
byte bcdToDec(byte val){
 return( (val/16*10) + (val%16) );
}

void setup(){
 Wire.begin();
 Serial.begin(9600);
 // Ustawienie czasu w momencie inicjacji układu:
 // DS3231 seconds, minutes, hours, day, date, month, year
 // setDS3231time(00,01,11,7,11,03,17);

 lcd.begin(20,4);  
 lcd.backlight(); // załączenie podświetlenia
 
 delay(500);  
}

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
 // ustawienie czasu i daty w DS3231
 Wire.beginTransmission(DS3231_I2C_ADDRESS);
 Wire.write(0);                    // określa, że następna wartość ma trafić do rejestru sekund
 Wire.write(decToBcd(second));     // ustawienie sekund
 Wire.write(decToBcd(minute));     // ustawienie minuty
 Wire.write(decToBcd(hour));       // ustawienie godziny
 Wire.write(decToBcd(dayOfWeek));  // ustawienie dnia tygodnia (1=niedziela, 7=sobota)
 Wire.write(decToBcd(dayOfMonth)); // ustawienie dnia (1-31)
 Wire.write(decToBcd(month));      // ustawienie miesiąca(1-12)
 Wire.write(decToBcd(year));       // ustawienie roku (0-99)
 Wire.endTransmission();
}

void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
 Wire.beginTransmission(DS3231_I2C_ADDRESS);
 Wire.write(0); // ustawia rejestr DS3231 na 00h
 Wire.endTransmission();
 Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
 // żąda 7 bajtów danych od modułu DS3231 począwszy od rejestru 00h
 *second = bcdToDec(Wire.read() & 0x7f);
 *minute = bcdToDec(Wire.read());
 *hour = bcdToDec(Wire.read() & 0x3f);
 *dayOfWeek = bcdToDec(Wire.read());
 *dayOfMonth = bcdToDec(Wire.read());
 *month = bcdToDec(Wire.read());
 *year = bcdToDec(Wire.read());
}

void displayTime(){
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
 // retrieve data from DS3231
 readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
 &year);
 
// Przekazanie danych do wyświetlenie w serial monitorze i do LCD

 // CZAS
 // Godziny
   // podczas wyświetlania konwertuje wartość zmiennej typu bitowego do postaci dziesiętnej
 Serial.print(hour, DEC);
 if (hour<10) {
   lcd.setCursor(12,0);
   lcd.print("0");
   lcd.print(hour, DEC);
 } else {
   lcd.setCursor(12,0);
   lcd.print(hour, DEC);
   }
 Serial.print(":");
// lcd.setCursor(14,1);
 lcd.print(":");
 
 // Minuty
 Serial.print(minute, DEC);
 if (minute<10) {
   Serial.print("0");
   lcd.setCursor(15,0);
   lcd.print("0");
   lcd.print(minute, DEC);
 } else {
   lcd.setCursor(15,0);
   lcd.print(minute, DEC);
   }
 Serial.print(":");
 lcd.print(":");
 
 //Sekundy
 if (second<10){
   Serial.print("0");
   lcd.setCursor(18,0);
   lcd.print("0");
   lcd.print(second, DEC);
 } else {
   Serial.print(second, DEC);
   lcd.setCursor(18,0);
   lcd.print(second, DEC);
   }

// DATA
 Serial.print(" ");
 Serial.print(dayOfMonth, DEC);
 Serial.print("/");
 Serial.print(month, DEC);
 Serial.print("/");
 Serial.print(year, DEC);
 lcd.setCursor(0,1);
 lcd.print("0");

 // Dzień
 if (dayOfMonth<10){
   lcd.setCursor(0,1);
   lcd.print("0");
   lcd.print(dayOfMonth, DEC);
 } else {
   lcd.setCursor(0,1);
   lcd.print(dayOfMonth, DEC);
   }
   lcd.print(".");
   
 // Miesiąc
 if (month<10){

   lcd.setCursor(3,1);
   lcd.print("0");
   lcd.print(month, DEC);
 } else {
   lcd.setCursor(3,1);
   lcd.print(month, DEC);
   }
   lcd.print(".");

  //Rok
   lcd.print("20");
   if (year<10){
   lcd.setCursor(8,1);
   lcd.print("0");
   lcd.print(year, DEC);
 } else {
   lcd.setCursor(8,1);
   lcd.print(year, DEC);
   }
 
 Serial.print(" ");
 lcd.setCursor(0,0);
 switch(dayOfWeek){
 case 1:
   Serial.println("Niedziela");
   lcd.print("Niedziela");
   break;
 case 2:
   Serial.println("Poniedzialek");
   lcd.print("Poniedzialek");
   break;
 case 3:
   Serial.println("Wtorek");
   lcd.print("Wtorek");
   break;
 case 4:
   Serial.println("Środa");
   lcd.print("Środa");
   break;
 case 5:
   Serial.println("Czwartek");
   lcd.print("Czwartek");
   break;
 case 6:
   Serial.println("Piątek");
   lcd.print("Piątek");
   break;
 case 7:
   Serial.println("Sobota");
   lcd.print("Sobota");
   break;
 }
}
void loop()
{
 displayTime(); // wyświetlanie czasu rzeczywistego
 delay(1000);   // odśwież co sekundę
}
Mam problem z gotowym programem na Arduino Uno. Na lcd wyświetla czas prawidłowo, to jest 08:09:18 ale w dacie byk, 02.87.2011 a także w dniu tygodnia wyświetla Pi tek bez ą. Nie wiem też jak ustawić aktualną datę i czas z komputera. Moduł DS3231. Źle coś podłączone?
Jak nie chcesz odpowiedzieć to nie pisz !!!
Odpowiedz
#2
(17-01-2018, 10:25)Ronin napisał(a):
Kod:
//#include <config.h>
#include <ds3231.h>

#include "Wire.h"

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20,4);  // Ustawienie adresu ukladu na 0x27

#define DS3231_I2C_ADDRESS 0x68

// Konwersja liczby dziesiętnej do postaci binarnej
byte decToBcd(byte val){
 return( (val/10*16) + (val%10) );
}

// Konwersja liczby binarnej do postaci dziesiętnej
byte bcdToDec(byte val){
 return( (val/16*10) + (val%16) );
}

void setup(){
 Wire.begin();
 Serial.begin(9600);
 // Ustawienie czasu w momencie inicjacji układu:
 // DS3231 seconds, minutes, hours, day, date, month, year
 // setDS3231time(00,01,11,7,11,03,17);

 lcd.begin(20,4);  
 lcd.backlight(); // załączenie podświetlenia
 
 delay(500);  
}

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
 // ustawienie czasu i daty w DS3231
 Wire.beginTransmission(DS3231_I2C_ADDRESS);
 Wire.write(0);                    // określa, że następna wartość ma trafić do rejestru sekund
 Wire.write(decToBcd(second));     // ustawienie sekund
 Wire.write(decToBcd(minute));     // ustawienie minuty
 Wire.write(decToBcd(hour));       // ustawienie godziny
 Wire.write(decToBcd(dayOfWeek));  // ustawienie dnia tygodnia (1=niedziela, 7=sobota)
 Wire.write(decToBcd(dayOfMonth)); // ustawienie dnia (1-31)
 Wire.write(decToBcd(month));      // ustawienie miesiąca(1-12)
 Wire.write(decToBcd(year));       // ustawienie roku (0-99)
 Wire.endTransmission();
}

void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
 Wire.beginTransmission(DS3231_I2C_ADDRESS);
 Wire.write(0); // ustawia rejestr DS3231 na 00h
 Wire.endTransmission();
 Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
 // żąda 7 bajtów danych od modułu DS3231 począwszy od rejestru 00h
 *second = bcdToDec(Wire.read() & 0x7f);
 *minute = bcdToDec(Wire.read());
 *hour = bcdToDec(Wire.read() & 0x3f);
 *dayOfWeek = bcdToDec(Wire.read());
 *dayOfMonth = bcdToDec(Wire.read());
 *month = bcdToDec(Wire.read());
 *year = bcdToDec(Wire.read());
}

void displayTime(){
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
 // retrieve data from DS3231
 readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
 &year);
 
// Przekazanie danych do wyświetlenie w serial monitorze i do LCD

 // CZAS
 // Godziny
   // podczas wyświetlania konwertuje wartość zmiennej typu bitowego do postaci dziesiętnej
 Serial.print(hour, DEC);
 if (hour<10) {
   lcd.setCursor(12,0);
   lcd.print("0");
   lcd.print(hour, DEC);
 } else {
   lcd.setCursor(12,0);
   lcd.print(hour, DEC);
   }
 Serial.print(":");
// lcd.setCursor(14,1);
 lcd.print(":");
 
 // Minuty
 Serial.print(minute, DEC);
 if (minute<10) {
   Serial.print("0");
   lcd.setCursor(15,0);
   lcd.print("0");
   lcd.print(minute, DEC);
 } else {
   lcd.setCursor(15,0);
   lcd.print(minute, DEC);
   }
 Serial.print(":");
 lcd.print(":");
 
 //Sekundy
 if (second<10){
   Serial.print("0");
   lcd.setCursor(18,0);
   lcd.print("0");
   lcd.print(second, DEC);
 } else {
   Serial.print(second, DEC);
   lcd.setCursor(18,0);
   lcd.print(second, DEC);
   }

// DATA
 Serial.print(" ");
 Serial.print(dayOfMonth, DEC);
 Serial.print("/");
 Serial.print(month, DEC);
 Serial.print("/");
 Serial.print(year, DEC);
 lcd.setCursor(0,1);
 lcd.print("0");

 // Dzień
 if (dayOfMonth<10){
   lcd.setCursor(0,1);
   lcd.print("0");
   lcd.print(dayOfMonth, DEC);
 } else {
   lcd.setCursor(0,1);
   lcd.print(dayOfMonth, DEC);
   }
   lcd.print(".");
   
 // Miesiąc
 if (month<10){

   lcd.setCursor(3,1);
   lcd.print("0");
   lcd.print(month, DEC);
 } else {
   lcd.setCursor(3,1);
   lcd.print(month, DEC);
   }
   lcd.print(".");

  //Rok
   lcd.print("20");
   if (year<10){
   lcd.setCursor(8,1);
   lcd.print("0");
   lcd.print(year, DEC);
 } else {
   lcd.setCursor(8,1);
   lcd.print(year, DEC);
   }
 
 Serial.print(" ");
 lcd.setCursor(0,0);
 switch(dayOfWeek){
 case 1:
   Serial.println("Niedziela");
   lcd.print("Niedziela");
   break;
 case 2:
   Serial.println("Poniedzialek");
   lcd.print("Poniedzialek");
   break;
 case 3:
   Serial.println("Wtorek");
   lcd.print("Wtorek");
   break;
 case 4:
   Serial.println("Środa");
   lcd.print("Środa");
   break;
 case 5:
   Serial.println("Czwartek");
   lcd.print("Czwartek");
   break;
 case 6:
   Serial.println("Piątek");
   lcd.print("Piątek");
   break;
 case 7:
   Serial.println("Sobota");
   lcd.print("Sobota");
   break;
 }
}
void loop()
{
 displayTime(); // wyświetlanie czasu rzeczywistego
 delay(1000);   // odśwież co sekundę
}
Mam problem z gotowym programem na Arduino Uno. Na lcd wyświetla czas prawidłowo, to jest 08:09:18 ale w dacie byk, 02.87.2011 a także w dniu tygodnia wyświetla Pi tek bez ą. Nie wiem też jak ustawić aktualną datę i czas z komputera. Moduł DS3231. Źle coś podłączone? Ustawiłem już czas i datę. Tu się ustawia // setDS3231time(00,01,11,7,11,03,17); Tylko polskie litery mi nie wyświetla w Środa, Piątek. Lcd 20x4. 

Jak nie chcesz odpowiedzieć to nie pisz !!!
Odpowiedz
#3
Dla LCD trzeba najpierw zdefiniować polskie litery jako znaki użytkownika, nie zauważyłem takiej definicji w kodzie programu. Nie można napisać "Piątek", trzeba napisać "Pi" + znak użytkownika + "tek". Jeżeli "ą" nie jest wyświetlane w terminalu, jest to wina kodowania polskich liter. Należało by ustawić takie samo kodowanie polskich znaków dla terminala i Atmegi, o ile jest to możliwe. Przy pobieraniu numeru miesiąca trzeba zamaskować najstarszy bit, bo jest tam jeszcze informacja o stuleciu, i to jest przyczyną błędnego podawania daty. Zmień linijkę *month = bcdToDec(Wire.read()); na *month = bcdToDec(Wire.read()) & 0x1f; , czyli wyzeruj trzy najstarsze bity numeru miesiąca i będzie dobrze.
Odpowiedz
#4
(17-01-2018, 20:47)tom5555 napisał(a): Dla LCD trzeba najpierw zdefiniować polskie litery jako znaki użytkownika, nie zauważyłem takiej definicji w kodzie programu. Nie można napisać "Piątek", trzeba napisać "Pi" + znak użytkownika + "tek". Jeżeli "ą" nie jest wyświetlane w terminalu, jest to wina kodowania polskich liter. Należało by ustawić takie samo kodowanie polskich znaków dla terminala i Atmegi, o ile jest to możliwe. Przy pobieraniu numeru miesiąca trzeba zamaskować najstarszy bit, bo jest tam jeszcze informacja o stuleciu, i to jest przyczyną błędnego podawania daty. Zmień linijkę  *month = bcdToDec(Wire.read()); na  *month = bcdToDec(Wire.read()) & 0x1f; , czyli wyzeruj trzy najstarsze bity numeru miesiąca i będzie dobrze.

Datę i godzinę wyświetla dobrze. Czyli Środa 19:55:45 17.01.2018. Próbowałem to dołączyć  do innego programu z czujnikiem ruchu i czujnikiem wilgotności i temperatury. Tam mam polskie litery zdefiniowane bez Ś. Tylko małe litery. Jak ustawić datę i czas w programie wiem. Nie wiem jak zrobić aby odczytać i ustawić czas z komputera. Program z dodaniem rtc niby działa. Wyświetla czas i datę ale czas stoi w miejscu.
Jak nie chcesz odpowiedzieć to nie pisz !!!
Odpowiedz


Skocz do:


Użytkownicy przeglądający ten wątek: 1 gości