Partnerzy

Astro-Miejsca


URANIA

astroturystyka

100 lat IAU

IAU

Comet

Centrum Nauki Kepler

Planetarium Wenus

ERC

Centrum Nauk Przyrodniczych

Orion,serwis,astronomii,PTA

POLSA

Astronomia Nova

Astronarium

forum astronomiczne

IPCN

Portal AstroNet

Puls Kosmosu

Forum Meteorytowe

kosmosnautaNET

kosmosnautaNET

Nauka w Polsce

astropolis

astromaniak

PTMA

PTR

heweliusz

heweliusz

ESA

Astronomers Without Borders

Hubble ESA

Space.com

Space Place

Instructables

Tu pełno nauki

Konkursy

Olimpiady Astronomiczne
Olimpiada Astronomiczna przebiega w trzech etapach.
Zadania zawodów I stopnia są rozwiązywane w warunkach pracy domowej. Zadania zawodów II i III stopnia mają charakter pracy samodzielnej. Zawody finałowe odbywają się w Planetarium Śląskim. Tematyka olimpiady wiąże ze sobą astronomię, fizykę i astronomiczne aspekty geografii. Olimpiady Astronomiczne


Urania Postępy Astronomii - konkurs dla szkół


astrolabium

Organizatorem konkursu astronomicznego jest Fundacja dla Uniwersytetu Jagiellońskiego a patronat nad akcją sprawuje Obserwatorium Astronomiczne im. Mikołaja Kopernika będące instytutem Wydziału Fizyki, Astronomii i Informatyki Stosowanej Uniwersytetu Jagiellońskiego w Krakowie.
Zobacz szczegóły »

astrolabium

konkurs, astronomiczny

AstroSklepy

Serwis Astro - 30 lat AstroDoświadczenia!

Astro Schopy
 Firma ScopeDome

Planeta Oczu

Astrocentrum

Arduino zegar na RTC DS3231

Podłączenie RTC do Arduino jest banalne. Pamiętamy tylko o napięciu zasilania bo może ono być 3.3V lub 5V. Zegar RTC jest podłączany do magistrali I2C podobnie jak wyświetlacz LCD w naszym projekcie. One ze sobą nie kolidują, bo na tej magistrali możemy podpiąć znacznie więcej urządzeń. Muszą mieć tylko różne adresy. Aby je ustalić warto uruchomić specjalny program skaner I2C (wynik zobaczymy na "serialmonitorze"):
// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
 
#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 

void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}



W naszym programie wpiszemy datę i czas początkowy do zegara ręcznie. W tym celu najpierw znajdujemy wiersz nr 40 z funkcją:
 //setDS3231time(00,24,23,14,15,11,17);.
Usuwamy komentarz i wpisujemy w miejsce liczb aktualne dane. Zapisujemy plik i wysyłamy przez USB do Arduino. Potem ponownie przywracamy komentarz i wysyłamy program do naszej płytki. Od teraz RTC będzie liczył czas sam, a my tylko będziemy pobierali jego wartości do wyświetlenia na ekranie LCD czy porcie szeregowym.

Teraz już możemy zmontować i uruchomić nasz zegar i wgrać oprogramowanie wyświetlające czas i temperaturę:
//Podłączenie pinów RTC3231 do Arduino Uno
//RTC na I2C: (SDA) D-A4, (SCL) C-A5
//LCD na I2C z konwerterem do tych samych pinów jak RTC

#include <DS3231.h> //https://github.com/jarzebski/Arduino-DS3231
#include <TimeLib.h>
#include "Wire.h"
#include <LiquidCrystal_I2C.h> 

LiquidCrystal_I2C lcd(0x3f,16,2);  // Ustawienie adresu ukladu na 0x3f

#define DS3231_I2C_ADDRESS 0x68

DS3231 clock;
RTCDateTime dt;

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

// symbol domku do temperatury http://omerk.github.io/lcdchargen/
byte customChar[8] = {
  0b00100,
  0b01110,
  0b11111,
  0b10101,
  0b10101,
  0b11111,
  0b11111,
  0b00000
};

void setup(){
  Wire.begin();
  Serial.begin(9600);
  // Ustawienie czasu w momencie inicjacji układu:
  // DS3231 seconds, minutes, hours, day (numer dnia tygodnia), date, month, year
  //setDS3231time(00,31,20,6,17,11,17);
  lcd.begin(16,2); //deklaracja wierszy wyświetlacza musi byc przed lcd.create.Char(0,customChar);
  lcd.createChar(0,customChar);// utworzenie znaku domka
  lcd.backlight(); // załączenie podświetlenia 
  lcd.setCursor(0,0);
  lcd.print((char)0);
  lcd.print("Prosty zegar RTC na DS3231");
  delay(1000);
  lcd.clear();
    
}

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
  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(0,0); 
    lcd.print("0");
    lcd.print(hour, DEC); 
  } else {
    lcd.setCursor(0,0); 
    lcd.print(hour, DEC); 
    }
  Serial.print(":");
  lcd.setCursor(2,0); 
  lcd.print(":");
  
  // Minuty
  //Serial.print(minute, DEC);
  if (minute<10) {
    Serial.print("0");
    Serial.print(minute, DEC);
    lcd.setCursor(3,0); 
    lcd.print("0");
    lcd.print(minute, DEC); 
  } else {
    lcd.setCursor(3,0); 
    lcd.print(minute, DEC);
    Serial.print(minute, DEC);
    }
  Serial.print(":");
  lcd.setCursor(5,0);
  lcd.print(":");
  
  //Sekundy
  if (second<10){
    Serial.print("0");
    Serial.print(second, DEC);
    lcd.setCursor(6,0); 
    lcd.print("0");
    lcd.print(second, DEC); 
  } else {
    Serial.print(second, DEC);
    lcd.setCursor(6,0); 
    lcd.print(second, DEC); 
    }

// DATA
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print("20");
  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(11,1); 
  switch(dayOfWeek){
  case 1:
    Serial.println("Niedziela");
    lcd.print("Nd");
    break;
  case 2:
    Serial.println("Poniedzialek");
    lcd.print("Pn");
    break;
  case 3:
    Serial.println("Wtorek");
    lcd.print("Wt");
    break;
  case 4:
    Serial.println("Sroda");
    lcd.print("Sr");
    break;
  case 5:
    Serial.println("Czwartek");
    lcd.print("Czw");
    break;
  case 6:
    Serial.println("Piatek");
    lcd.print("Pt");
    break;
  case 7:
    Serial.println("Sobota");
    lcd.print("So");
    break;
  }
}
// temperatura z DS3231
void displayTemp(){
  clock.forceConversion();
  lcd.setCursor(9,0);
  lcd.print((char)0);
  lcd.print(clock.readTemperature(),1);
  lcd.print((char)223);
  lcd.print("C");
}

void loop()
{
  displayTime(); // wyświetlanie czasu rzeczywistego
  displayTemp(); // wyswietla temperature
  delay(1000);   // odśwież co sekundę
}



W naszym programie zdefiniowany jest symbol domku, by pokazać, że temperatura jest mierzona wewnątrz pomieszczenia, gdzie stoi zegar. Przydatna do tego jest strona do generowanie kodu binarnego takich i innych zaprojektowanych przez nas znaków - http://omerk.github.io/lcdchargen/.

W sekcji woid setup() zdeklarowany jest znak domku:
void setup(){
  Wire.begin();
  Serial.begin(9600);
  // Ustawienie czasu w momencie inicjacji układu:
  // DS3231 seconds, minutes, hours, day (numer dnia tygodnia), date, month, year
  //setDS3231time(00,31,20,6,17,11,17);
  lcd.begin(16,2); //deklaracja wierszy wyświetlacza musi byc przed lcd.create.Char(0,customChar);
  lcd.createChar(0,customChar);// utworzenie znaku domka
  lcd.backlight(); // załączenie podświetlenia 
  lcd.setCursor(0,0);
  lcd.print((char)0);
  lcd.print("Prosty zegar RTC na DS3231");
  delay(1000);
  lcd.clear();
    
}

Tu znak ten miał nr 3 i musi on być taki sam jak w deklaracji w setup(). Ale można go sobie zmień w zakresie od 0 do 7. Z jakiegoś powodu na stronie kodera jest przykład użycia znaku w postaci lcd.write((uint8_t)3);, ale to nie działa i trzeba zrobić tak jak tu napisałem.
Brak komentarzy. Może czas dodać swój?

Dodaj komentarz

Zaloguj się, aby móc dodać komentarz.

Oceny

Tylko zarejestrowani użytkownicy mogą oceniać zawartość strony
Zaloguj się , żeby móc zagłosować.

Brak ocen. Może czas dodać swoją?
31,935,760 unikalne wizyty