60 nap alatt Arduino #33 - I2C órachipek

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
blaci
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2012. február 6. hétfő, 7:00

HozzászólásSzerző: blaci » 2012. november 8. csütörtök, 20:03

Robert írta:A beállítás vagy a vissszaolvasás nem jó?

A kiolvasás, hibázik, de csak ez, az általam kreált függvény. A változók értékét kiíratom a soros portra, miután meghívom, onnan látom, hogy rossz.

Avatar
blaci
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2012. február 6. hétfő, 7:00

HozzászólásSzerző: blaci » 2012. november 12. hétfő, 21:09

blaci írta:Üdv!

A tanfolyami példa programot szerettem volna továbbfejleszteni, és szeretném, ha nem állítana be valamit, ha már korábban beállítottam, és az órachip meg úgy is megjegyezte. Ehhez írtam az alábbi függvényt, amit a setup() -ból hívok meg, de nem igazán akar működni. Valamiért az év, a nap, az óra és a perc rendben, de a többi eléggé ötletszerű értékeket ad.
Az eredeti példaprogram amúgy rendesen működik.
Mi lehet a gond?



void ido_kerdez()
{
Wire.beginTransmission(I2C_RTC);
Wire.write(0x02);
result = Wire.endTransmission();
if (result) SetError(ERROR_RTC_GET);
Wire.requestFrom(I2C_RTC, 7);
second_old = Wire.read();
if (second & 0x80) SetError(ERROR_CLOCK_INTEGRITY);
second_old = BcdToDec(second & 0b01111111);
second = second_old;
minute_old = BcdToDec(Wire.read());
minute = minute_old;
hour_old = BcdToDec(Wire.read());
hour = hour_old;
day = BcdToDec(Wire.read());
weekday = BcdToDec(Wire.read());
month = Wire.read();
century = (month & 0x80);
month = BcdToDec(month & 0b01111111);
year = BcdToDec(Wire.read());
}


Megtaláltam a hiba okát, az alábbi két sor volt a problémás.

Kód: Egész kijelölése

  day = BcdToDec(Wire.read() & 0x3f);
  weekday = BcdToDec(Wire.read() & 0x07);


Avatar
Robert
Elektronbűvölő
Hozzászólások: 9738
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. november 12. hétfő, 21:13

A day és a weekday nem jelenik meg másutt hibaként.
Ezek egymástól függetlenek. Azaz nem hat ki a többi időadatra.

ggombai
Újonc
Újonc
Hozzászólások: 1
Csatlakozott: 2013. január 26. szombat, 11:53

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: ggombai » 2013. január 26. szombat, 12:13

Tisztelt urak!

Segítséget szeretnék kérni PCF8563T ora chip el kapcsolatosan.

Megpróbáltam beállítani a tavir ext1 shield en lévő RTC a következő programkód alapján.
Minden szépen működik az időt LCD re iratom ám azonban ha megpróbálom elhagyni a beállításra vonatkozó részt akkor
az történik hogy induláskor az óra visszaáll 2000 01 01 00:00 ra.
A másodperc rendesen számlál de a többi nem változik.
Tehát a következő történik. egy programkóddal beállítom az őrát. majd küldök egy másikat az artuinora amiben már nincs a beállítás rész csak az időt szeretném kiolvasni de olyan mintha nem jegyezné meg a dátumot órát percet, csak a mp adat jó.

Mi lehet a baj? kezdő vagyok elnézést ha butaságot kérdeznék.

Nagyon köszönöm!


A kód itt olvasható:



/* PCF8563T orachip
60 nap alatt arduino tanfolyam
Magyarra forditotta es arduino 1.0-ra atirta: Macsek
2012.08.29
(c) TavIR http://avr.tavir.hu */

#include "Wire.h"
//I2C lesz hasznalva

//#define DEBUG // Hibakereso be/kikapcsolas
#define I2C_RTC 0x51 // 7 bites chip cim
#define ERROR_LED 13 //hibaLED

// Hibak
#define HIBA_ORA_BEALL 1 // Ido nem beallithato
#define HIBA_ORA_KIOLV 2 // Ido nem kiolvashato
#define HIBA_ORA_ELEM 3 // RTC ora hibas lehet (elemhiba)

byte evszazad;
byte ev;
byte ho;
byte nap;
byte het_napja;
byte ora;
byte ora_volt; // idovaltozas volt-e kiolvasas alatt
byte perc;
byte perc_volt; // idovaltozas volt-e kiolvasas alatt
byte mp;
byte mp_volt; // idovaltozas volt-e kiolvasas alatt
byte eredmeny;

//napok karakterszintu tombben (byte-k egymas utan, nem szoveglanckent tarolva!)??
//napok tombben, egyenkent lezaro nullaval, azaz karakterlancokbol allo tomb
char* het_napjai[] = {
"Vasarnap", "Hetfo", "Kedd",
"Szerda", "Csutortok", "Pentek", "Szombat"};

// fuggvenyek
byte bcd2dec(byte);
byte dec2bcd(byte);
void hibaJelzes(int);
void serial_print2(byte);

void setup()
{
pinMode(ERROR_LED, OUTPUT); // HibaLED INIT
Wire.begin(); // IIC busz inicializalas
Serial.begin(9600); // Sorosport inicializalas

// Valami kezdoadat beallitasa
ev = 11; // Ev (0-99)
ho = 12; // Honap (1-12)
nap = 31; // Nap (1-31)
het_napja = 0; // Het napja: 0 - vasarnap! (0-6)
ora = ora_volt = 23; // Ora (0-23)
perc = perc_volt = 59; // Perc (0-59)
mp = mp_volt = 53; // Masodperc (0-59)

Wire.beginTransmission(I2C_RTC); // Orachip megszolitasa irasra
Wire.write(0); // 0. regisztertol akarok irni
Wire.write(0); // 0. cim: Control es statusbitek 1
Wire.write(0); // 1. cim: Control es statusbitek 2
Wire.write(dec2bcd(mp)); // 2. cim: Masodperc
Wire.write(dec2bcd(perc)); // 3. cim: Perc
Wire.write(dec2bcd(ora)); // 4. cim: Ora
Wire.write(dec2bcd(nap)); // 5. cim: Nap
Wire.write(dec2bcd(het_napja)); // 6. cim: Het napja
Wire.write(dec2bcd(ho)); // 7. cim: Honap (evszazadbit: 0)
Wire.write(dec2bcd(ev)); // 8. cim: Ev
Wire.write(0b10000000); // 9. cim: Ebresztes perc + tiltobit
Wire.write(0b10000000); // 10. cim: Ebresztes ora + tiltobit
Wire.write(0b10000000); // 11. cim: Ebresztes nap + tiltobit
Wire.write(0b10000000); // 12. cim: Ebresztes het napja + tiltobit
Wire.write(0b10000011); // 13. cim: Kimeneti frekvencia 1 Hz
Wire.write(0); // 14. cim: Visszaszamlalas tiltva
Wire.write(0); // 15. cim: Visszaszamlalasi ertek: 0
Wire.endTransmission();
eredmeny = Wire.endTransmission();

#ifdef DEBUG
Serial.print("Beallitas eredmenye: ");
Serial.println(eredmeny);
#endif

if (eredmeny != 0)
hibaJelzes(HIBA_ORA_BEALL);
}

void loop()
{
Wire.beginTransmission(I2C_RTC); //OraIC megszolitasa olvasasra
Wire.write(0x02); // A 0x02-es regisztertol akarok olvasni
eredmeny = Wire.endTransmission();

#ifdef DEBUG
Serial.print("Az oraIC megszolitasa olvasasra sikeres: ");
Serial.println(eredmeny);
#endif

if (eredmeny != 0)
hibaJelzes(HIBA_ORA_KIOLV);

Wire.requestFrom(I2C_RTC, 1);
mp = Wire.read();
if (mp & 0x80)
hibaJelzes(HIBA_ORA_ELEM);
mp = bcd2dec(mp & 0b01111111);
if (mp != mp_volt) // Megnezzuk valtozott-e a masodperc
{
mp_volt = mp;
if (mp == 0) // Ha a masodperc 0, akkor a percet kiolvassuk
{
Wire.requestFrom(I2C_RTC, 1);
perc = bcd2dec(Wire.read());
if (perc != perc_volt) // Perc valtozott-e
{
perc_volt = perc;
if (perc == 0) // Ha a perc : 0, akkor kell az ora is
{
Wire.requestFrom(I2C_RTC, 1);
ora = bcd2dec(Wire.read());
if (ora != ora_volt) // Az ora valtozott-e
{
ora_volt = ora;
if (ora == 0) // Ha az ora nulla, akkor kell az egyeb adatok
{
//Meg negy adat kell: nap, het napja, honap (+evszazad), ev
Wire.requestFrom(I2C_RTC, 4);
nap = bcd2dec(Wire.read());
het_napja = bcd2dec(Wire.read());
ho = Wire.read();
evszazad = (ho & 0x80);
ho = bcd2dec(ho & 0b01111111);
ev = bcd2dec(Wire.read());
}
}
}
}
}

//milyen evszazad van?
Serial.print(20+evszazad);
// //Lehetne igy is:
// if (evszazad)
// Serial.print("21");
// else
// Serial.print("20");

//honap is ket szamjeggyel irando
//meg a tobbi oraadat is
//mert pl. egy szamjegyu ev eseten hulyen nezne ki
serial_print2(ev); // ket szamjegyesen ir
Serial.print(".");
serial_print2(ho); // lehetne ide is tombot kiiratni, mint a het napjainal
Serial.print(".");
serial_print2(nap);
Serial.print(". ");

//milyen nap van?
Serial.print(het_napjai[het_napja]);
Serial.print("(");
Serial.print(het_napja);
Serial.print("), ");

serial_print2(ora);
Serial.print(":");
serial_print2(perc);
Serial.print(":");
serial_print2(mp);
Serial.println(); // uj sor
}
}

// BCD - Decimalis atalakitas
byte bcd2dec(byte value)
{
return ((value / 16) * 10 + value % 16);
}

// Decimalis - BCD atalakitas
byte dec2bcd(byte value){
return (value / 10 * 16 + value % 10);
}

void hibaJelzes(int error)
// Ha hiba van, villogjon a D13 LED
// annyit amennyi a hiba!
{
while(1) // Folyton folyvast
{
for (byte index = 0; index < error; index++)
{
digitalWrite(ERROR_LED, HIGH);
delay(500);
digitalWrite(ERROR_LED, LOW);
delay(500);
}
delay(1000);
}
}

// Legalabb ket szamjegyen irja ki a kapott szamot
// (tehat ha kell, bevezeto nullaval) a soros portra
void serial_print2(byte kiirando)
{
if (kiirando<10)
Serial.print(0);
Serial.print(kiirando);
}

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9738
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: Robert » 2013. január 26. szombat, 15:53

_Saját_ kódod?
Valaol bennmarad a beállítás.

Avatar
zolcsi
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2012. október 24. szerda, 6:00

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: zolcsi » 2013. január 31. csütörtök, 13:46

Sziasztok,

Nekem is hasonló gondjaim vannak.
Robi programját kicsit átalakítottam. A beállító részt kivettem, csak kiolvasok az RTC chipből. És még annyi, hogy LCD-re is kiíratom. Figyelem, hogy bekapcsolás utáni állapotról, vagy folyamatos állapotról van-e szó. Ha bekapcs. után vagyok, akkor minden idő és dátum adatot kiolvasok.
A gond az, hogy véletlenszerű a működése. Néha jól jelez, néha nem. Reset nyomására van amikor megjavul, van amikor pont erre romlik el.
Az a gyanúm, hogy rossz értéket olvas ki az RTC chipből. De miért??? Vagy program bug? Kösz ha van ötletetek.

Üdv,

Zoli


A kód:

/* PCF8563T orachip
60 nap alatt arduino tanfolyam
(c) TavIR http://avr.tavir.hu */

#include "Wire.h"
//I2C lesz hasznalva
#include <LiquidCrystal.h>

LiquidCrystal lcd(4,5,6,7,8,9);

//#define DEBUG
// Hibakereso be/kikapcsolas
#define I2C_RTC 0x51
// 7 bites chip cim
#define ERROR_LED 13
//hibaLED

// Hibak
#define ERROR_RTC_SET 1
// Ido nem beallithato
#define ERROR_RTC_GET 2
// Ido nem kiolvashato
#define ERROR_CLOCK_INTEGRITY 3
// RTC ora hibas lehet (elemhiba)

byte result = 0;
byte second = 0;
byte second_old = 0;
// idovaltozas volt-e kiolvasas alatt
byte minute = 0;
byte minute_old = 0;
// idovaltozas volt-e kiolvasas alatt
byte hour = 0;
byte hour_old = 0;
// idovaltozas volt-e kiolvasas alatt
byte weekday = 0;
byte day = 0;
byte month = 0;
byte year = 0;
byte century = 0;
boolean after_powerup = true;
//String s="";

//napok karakterszintu tombben (byte-k egymas utan, nem szoveglanckent tarolva!)
/*char* weekdayname[] = {"Vas", "Het",
"Ked", "Sze", "Csu", "Pen",
"Szo"};*/


// fuggvenyek
/*byte BcdToDec(byte);
byte DecToBcd(byte);
void SetError(int);*/

void setup()
{
pinMode(ERROR_LED, OUTPUT);
// HibaLED INIT
Wire.begin();
// IIC busz inicializalas
Serial.begin(9600);
// Sorosport inicializalas
lcd.begin(16,2);
lcd.clear();

// Valami kezdoadat beallitasa
/* second_old = second = 00;
// Masodperc (0-59)
minute_old = minute = 50;
// Perc (0-59)
hour_old = hour = 10;
// Ora (0-23)
weekday = 4;
// Het napja: 0 - vasarnap! (0-6)
day = 31;
// Nap (1-31)
month = 1;
// Honap (1-12)
year = 13;
// Ev (0-99)
Wire.beginTransmission(I2C_RTC);
// Orachip megszolitasa irasra
Wire.write(0);
// 0. regisztertol akarok irni
Wire.write(0);
// Control es statusbitek 1
Wire.write(0);
// Control es statusbitek 2
Wire.write(DecToBcd(second));
// Masodperc
Wire.write(DecToBcd(minute));
// Perc
Wire.write(DecToBcd(hour));
// Ora
Wire.write(DecToBcd(day));
// Nap
Wire.write(DecToBcd(weekday));
// Het napja
Wire.write(DecToBcd(month));
// Honap (evszazadbit: 0)
Wire.write(DecToBcd(year));
// Ev
Wire.write(0b10000000);
// Ebresztes perc + tiltobit
Wire.write(0b10000000);
// Ebresztes ora + tiltobit
Wire.write(0b10000000);
// Ebresztes nap + tiltobit
Wire.write(0b10000000);
// Ebresztes het napja + tiltobit
Wire.write(0b10000011);
// Kimeneti frekvencia 1 Hz
Wire.write(0);
// Visszaszamlalas tiltva
Wire.write(0);
// Visszaszamlalasi ertek: 0
Wire.endTransmission();
result = Wire.endTransmission();*/

#ifdef DEBUG
Serial.print("Beallitas eredmenye: ");
Serial.println(result, DEC);
#endif

if (result) SetError(ERROR_RTC_SET);
}

void loop()
{
Wire.beginTransmission(I2C_RTC);
//OraIC megszolitasa olvasasra
Wire.write(0x02);
// A 0x02-es regisztertol akarok olvasni
result = Wire.endTransmission();
#ifdef DEBUG
Serial.print("Az oraIC megszolitasa olvasasra sikeres: ");
Serial.println(result, DEC);
#endif
if (result) SetError(ERROR_RTC_GET);

Wire.requestFrom(I2C_RTC, 1);
second = Wire.read();
if (second & 0x80)
SetError(ERROR_CLOCK_INTEGRITY);

second = BcdToDec(second & 0b01111111);
if ((second != second_old) || (after_powerup))
// Megnezzuk valtozott e a masodperc, vagy közvetlen bekapcsolás után vagyunk-e
{
second_old = second;
if ((second == 0) || (after_powerup))
// Ha a masodperc 0, akkor a percet kiolvassuk
{
Wire.requestFrom(I2C_RTC, 1);
minute = BcdToDec(Wire.read());
if ((minute != minute_old) || (after_powerup))
// Perc valtozott-e
{
minute_old = minute;
if ((minute == 0) || (after_powerup))
// Ha a perc : 0, akkor kell az ora is
{
Wire.requestFrom(I2C_RTC, 1);
hour = BcdToDec(Wire.read());
if ((hour != hour_old) || (after_powerup))
// Az ora valtozott-e
{
hour_old = hour;
if ((hour == 0) || (after_powerup))
// Ha az ora nulla, akkor kell az egyeb adatok
{
//Meg negy adat kell: nap, het napja, honap (+evszazad), ev
Wire.requestFrom(I2C_RTC, 4);
day = BcdToDec(Wire.read());
weekday = BcdToDec(Wire.read());
month = Wire.read();
century = (month & 0x80);
month = BcdToDec(month & 0b01111111);
year = BcdToDec(Wire.read());
after_powerup = false;
}
}
}
}
}
//milyen nap van?
lcd.clear();
lcd.home();
// Serial.print(weekdayname[weekday]);
// Serial.print("(");
Serial.print(weekday, DEC);
Serial.print(")");

/* lcd.print(weekdayname[weekday]);
lcd.print("(");
lcd.print(weekday);
lcd.print(")");*/



//milyen evszazad van?
if (century) {
Serial.print(" 21");
lcd.print("21"); }
else {
Serial.print(" 20");
lcd.print("20"); }
//egyszamjegyu ev eseten hulyen nezne ki
if (year < 10) {
Serial.print("0");
lcd.print("0"); }
Serial.print(year, DEC);
lcd.print(year, DEC);
Serial.print("-");
lcd.print(".");
//honap is ket szamjeggyel irando
//meg a tobbi oraadat is
if (month < 10) {
Serial.print("0");
lcd.print("0"); }
Serial.print(month,DEC);
lcd.print(month,DEC);
Serial.print("-");
lcd.print(".");
if (day < 10) {
Serial.print("0");
lcd.print("0"); }
Serial.print(day, DEC);
lcd.print(day, DEC);
lcd.print(". ");
Serial.print(" ");
//lcd.print(day,' ');
lcd.print(weekday);


lcd.setCursor(0,1);

if (hour < 10) {
Serial.print("0");
lcd.print("0"); }
Serial.print(hour,DEC);
lcd.print(hour,DEC);
Serial.print(":");
lcd.print(":");
if (minute < 10) {
Serial.print("0");
lcd.print("0"); }
Serial.print(minute, DEC);
lcd.print(minute, DEC);
Serial.print(":");
lcd.print(":");
if (second < 10) {
Serial.print("0");
lcd.print("0"); }
Serial.println(second, DEC);
lcd.print(second, DEC);
}
}

// BCD - Decimalis atalakitas
byte BcdToDec(byte value)
{
return ((value / 16) * 10 + value % 16);
}

// Decimalis - BCD atalakitas
byte DecToBcd(byte value){
return (value / 10 * 16 + value % 10);
}

void SetError(int error)
// Ha hiba van, villogjon a D13 LED
// annyit amennyi a hiba!
{
while(1) // Forever
{
for (byte index = 0; index < error;
index++)
{
digitalWrite(ERROR_LED, HIGH);
delay(500);
digitalWrite(ERROR_LED, LOW);
delay(500);
}
delay(1000);
}
}

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9738
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: Robert » 2013. január 31. csütörtök, 14:39

Az Órachipet nem reseteled és lehet megszakadt kiolvasás.
Az okozhat problémát.


A kiolvasás előtt _nem_ címzed meg, hogy az _órachippel_ akarsz beszélgetni.... Azaz valamit, valahonnan visszaolvasol....

János
Újonc
Újonc
Hozzászólások: 1
Csatlakozott: 2013. december 11. szerda, 16:22

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: János » 2014. február 15. szombat, 14:54

Kedves mindenki!
Lenne egy megjegyzésem/kérdésem és egy tapasztalatom.

A megjegyzés: char* , vagy más, csillagozott változóra vonatkozóan az én észlelésem szerint az eddigi leckékben nem volt utalás, mégis ezt látom a 33. lecke programjának bevezető részében.
Én néztem el valamit, vagy tényleg ismeretlen lehet, de ez eddig senkinek nem tűnt fel?
Mi az értelme ennek a csillagnak?

A tapasztalat: az óra kiolvasásakor az adott másodperctől függően az óra, nap, hét napja, hó, év változók lehetetlen értékeket vettek fel. Minden percben 0-19 sec-ig OK, 20-39 sec-ig a hónapot jelző szám 20-al többet mutatott, 40-59 sec-ig a hónapot, a napot, az órát jelző szám is 40-el többet (és nem volt normális a hét napját adó szám sem). Azok a bitek billentek be/ki a hibás működéskor, amelyek az adott regiszterben x-el vannak jelölve, tehát nem tartalmaznak értékes adatot. Más megoldást nem találtam, mint &-el kimaszkolni a hasznos biteket, így a működés kifogástalan. Esetleg van ötlet az óra IC ilyen furcsa viselkedésére?

Üdv:
János

Avatar
irak
Biztosítékgyilkos
Hozzászólások: 73
Csatlakozott: 2005. november 2. szerda, 7:00
Tartózkodási hely: Győr
Kapcsolat:

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: irak » 2014. február 15. szombat, 20:41

Hello!

A C nyelv szépsége, a mutatók :D

A char * annyit jelent, hogy egy char típusú változóra mutató mutató jön létre.
Indirekt adatelérésnél, vagy tömböknél van haszna.

Keress rá a neten, sok leírás van a témában.

M.Lajos
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2017. július 15. szombat, 20:05

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: M.Lajos » 2017. szeptember 20. szerda, 16:39

Sziasztok, hasonló a problémám amiről írnak többen de nem látok valódi megoldást.
Szóval egy PCF8563T chipes áramkört próbálok a tanfolyam példaprogramjával, amin mindenki gyakorlatozott.

A dolgot egyszerű leírni:
1./ lefordítom és áttöltöm a programot, az beállítja kezdő időpontnak a 2011.12.31 stb. és szépen számol is a soros konzolon
2./ kikommentelem a programból az időpont beállítására vonatkozó parancsokat, lefordítom és áttöltöm erre 2000.01.01 -től kezd ketyegni az óra
RTF-ben jó elem van, megnéztem.

Van valakinek tippje mi miatt veszíti el a chip a kezdő időpont beállítást.
Sajnos guglin és youtube-n nem találtam használható ötletet. Az áramkörön ilyen tüskék vannak mint:
int, cot, scl, sda, gnd, vcc
Az int, cot nem tudom mire jó, de lehet hogy semmi köze a problémámhoz.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9738
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: Robert » 2017. szeptember 21. csütörtök, 13:09

Kód?
Eszközrajz?


Az EXT1en levő holmival megy. Ami a visszaállás oka:
- tápfesz. alacsony (akkutápfesz)
- kódban el van rontva valami
- hibás chip
http://www.tavir.hu - a gazda :)

M.Lajos
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2017. július 15. szombat, 20:05

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: M.Lajos » 2017. szeptember 22. péntek, 11:42

Köszönöm a választ.

1./ Tehát az "eredeti" kódot használtam, csak kikommenteltem belőle a beállítást.
Lásd alább.

Kód: Egész kijelölése

/*  PCF8563T orachip
 60 nap alatt arduino tanfolyam
 (c) TavIR http://www.tavir.hu  */

 
#include "Wire.h"
//I2C lesz hasznalva
 
//#define DEBUG
// Hibakereso be/kikapcsolas
#define I2C_RTC 0x51
// 7 bites chip cim
#define ERROR_LED 13
//hibaLED
 
// Hibak
#define ERROR_RTC_SET 1
// Ido nem beallithato
#define ERROR_RTC_GET 2
// Ido nem kiolvashato
#define ERROR_CLOCK_INTEGRITY 3
// RTC ora hibas lehet (elemhiba)
 
byte result;
byte second;
byte second_old;
// idovaltozas volt-e kiolvasas alatt
byte minute;
byte minute_old;
// idovaltozas volt-e kiolvasas alatt
byte hour;
byte hour_old;
// idovaltozas volt-e kiolvasas alatt
byte weekday;
byte day;
byte month;
byte year;
byte century;
//napok karakterszintu tombben (byte-k egymas utan, nem szoveglanckent tarolva!)
char* weekdayname[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
 
// fuggvenyek
byte BcdToDec(byte);
byte DecToBcd(byte);
void SetError(int);
 
void setup()
{
  pinMode(ERROR_LED, OUTPUT);
  // HibaLED INIT
  Wire.begin();
  // IIC busz inicializalas
  Serial.begin(9600);
  // Sorosport inicializalas

  // Valami kezdoadat beallitasa
  second_old = second = 53;
  // Masodperc (0-59)
  minute_old = minute = 59;
  // Perc (0-59)
  hour_old = hour = 23;
  // Ora (0-23)
  weekday = 0;
  // Het napja: 0 - vasarnap! (0-6)
  day = 31;
  // Nap (1-31)
  month = 12;
  // Honap (1-12)
  year = 11;
  // Ev (0-99)

/*  ------------------------------- ALÁBBI SZEKCIÓ KIHAGYVA ---------------------
  Wire.beginTransmission(I2C_RTC);
  // Orachip megszolitasa irasra
  Wire.send(0);
  // 0. regisztertol akarok irni
  Wire.send(0);     
  // Control es statusbitek 1
  Wire.send(0);     
  // Control es statusbitek 2
  Wire.send(DecToBcd(second));
  // Masodperc
  Wire.send(DecToBcd(minute));
  // Perc
  Wire.send(DecToBcd(hour));
  // Ora
  Wire.send(DecToBcd(day));
  // Nap
  Wire.send(DecToBcd(weekday));
  // Het napja
  Wire.send(DecToBcd(month));
  // Honap (evszazadbit: 0)
  Wire.send(DecToBcd(year));
  // Ev
  Wire.send(0b10000000);
  // Ebresztes perc + tiltobit
  Wire.send(0b10000000);
  // Ebresztes ora + tiltobit
  Wire.send(0b10000000);
  // Ebresztes nap + tiltobit
  Wire.send(0b10000000);
  // Ebresztes het napja + tiltobit
  Wire.send(0b10000011);
  // Kimeneti frekvencia 1 Hz
  Wire.send(0);
  // Visszaszamlalas tiltva
  Wire.send(0);
  // Visszaszamlalasi ertek: 0
  Wire.endTransmission();
  result = Wire.endTransmission();
 
#ifdef DEBUG
  Serial.print("Beallitas eredmenye: ");
  Serial.println(result, DEC);
#endif
*/ ------------------------------------------------- EDDIG -----------------------------------

  if (result) SetError(ERROR_RTC_SET);
}
 
void loop()
{
  Wire.beginTransmission(I2C_RTC);
  //OraIC megszolitasa olvasasra
  Wire.send(0x02);
  // A 0x02-es regisztertol akarok olvasni
  result = Wire.endTransmission();
#ifdef DEBUG
  Serial.print("Az oraIC megszolitasa olvasasra sikeres: ");
  Serial.println(result, DEC);
#endif
  if (result) SetError(ERROR_RTC_GET);
 
  Wire.requestFrom(I2C_RTC, 1);
  second = Wire.receive();
  if (second & 0x80) SetError(ERROR_CLOCK_INTEGRITY);
  second = BcdToDec(second & 0b01111111);
  if (second != second_old)
  // Megnezzuk valtozott e a masodperc
  {
    second_old = second;
    if (second == 0)
    // Ha  amasodperc 0, akkor a percet kiolvassuk
    {
      Wire.requestFrom(I2C_RTC, 1);
      minute = BcdToDec(Wire.receive());
      if (minute != minute_old)
      // Perc valtozott-e
      {
        minute_old = minute;
        if (minute == 0)
        // Ha  aperc : 0, akkor kell az ora is
        {
          Wire.requestFrom(I2C_RTC, 1);
          hour = BcdToDec(Wire.receive());
          if (hour != hour_old)
          // Az ora valtozott-e
          {
            hour_old = hour;
            if (hour == 0)
            // Ha az ora nulla, akkor kell az egyeb adatok
            {
              //Meg negy adat kell: nap, het napja, honap (+evszazad), ev
              Wire.requestFrom(I2C_RTC, 4);
              day = BcdToDec(Wire.receive());
              weekday = BcdToDec(Wire.receive());
              month = Wire.receive();
              century = (month & 0x80);
              month = BcdToDec(month & 0b01111111);
              year = BcdToDec(Wire.receive());
            }
          }
        }
      }
    }
    //milyen nap van?
    Serial.print(weekdayname[weekday]);
    Serial.print("(");
    Serial.print(weekday, DEC);
    Serial.print(")");
    //milyen evszazad van?
    if (century)
      Serial.print(" 21");
    else
      Serial.print(" 20");
    //egyszamjegyu ev eseten hulyen nezne ki
    if (year < 10) Serial.print("0");
    Serial.print(year, DEC);
    Serial.print("-");
    //honap is ket szamjeggyel irando
    //meg a tobbi oraadat is
    if (month < 10) Serial.print("0");
    Serial.print(month,DEC);
    Serial.print("-");
    if (day < 10) Serial.print("0");
    Serial.print(day, DEC);
    Serial.print("");
    if (hour < 10) Serial.print("0");
    Serial.print(hour,DEC);
    Serial.print(":");
    if (minute < 10) Serial.print("0");
    Serial.print(minute, DEC);
    Serial.print(":");
    if (second < 10) Serial.print("0");
    Serial.println(second, DEC);
  }
}
 
// BCD - Decimalis atalakitas
byte BcdToDec(byte value)
{
  return ((value / 16) * 10 + value % 16);
}
 
// Decimalis - BCD atalakitas
byte DecToBcd(byte value){
  return (value / 10 * 16 + value % 10);
}
 
void SetError(int error)
// Ha hiba van, villogjon a D13 LED
// annyit amennyi a hiba!
{
  while(1) // Forever
  {
    for (byte index = 0; index < error; index++)
    {
      digitalWrite(ERROR_LED, HIGH);
      delay(500);
      digitalWrite(ERROR_LED, LOW);
      delay(500);
    }
    delay(1000);
  }
}

Szerk Admin: Használd a CODE gombot!
Úgy gondoltam ez a megoldás meg fogja hagyni a korábban beállított időt.

2./ Így néz ki az áramkör:
Admin: a képet mentés után ide is lehet csatolni!
Az áramkörnek külön nem találtam leírását egyébként. Ez amiatt lehet érdekes, hogy abban lehetne valami arról, hogy mikor tartja a beállításokat.
Láttam olyan RTC-t ahol azon kívül, hogy elem volt az áramkörben 2 tüske rövidre zárása kellett ahhoz, hogy tartsa a beállításokat.

3./ Táp kérdéssel kapcsolatosan. A multiméter 3.06 voltot mutat, ha rámérek.
Esetleg próbáljam meg hálózatos 3 volt-al?

4./ Nem tudom az áramköri hibáját hogyan lehet kimutatni? Kíváncsi lennék a metodikára.
Nincs meg a kellő jogosultságod a hozzászóláshoz csatolt állományok megtekintéséhez.

Avatar
csegebiga
Pákabűvész
Hozzászólások: 225
Csatlakozott: 2015. március 27. péntek, 21:27

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: csegebiga » 2017. szeptember 22. péntek, 13:33

Keress rá a chipre! PCF8563T
Teljes datasheet fent van.
https://www.nxp.com/docs/en/data-sheet/PCF8563.pdf
Nem ez okozza a gondot?
I2C-bus slave address: read A3h and write A2h

Lehet, hogy más címen írható és olvasható az íc buszon a chip?
A példában a 51h van belevésve.onnan olvasna és oda írna.
Az i2c scanner hol jelzi az eszközt?
A nemlétező címről olvasás után a program generál belőle adatot, nem?

M.Lajos
Újonc
Újonc
Hozzászólások: 6
Csatlakozott: 2017. július 15. szombat, 20:05

Re: 60 nap alatt Arduino #33 - I2C órachipek

HozzászólásSzerző: M.Lajos » 2017. szeptember 22. péntek, 19:52

Köszönöm a választ és tippeket.

1./ Az i2cscanner az 51h-n jelzi és azt is használom. Ahogy írom először fut az a kód ami tárolja/tárolná a kezdő időpontot.
2./ A doksi által adott két cím egybevág az 51h-val mivel nekünk a kódban az utolsó bit "híján" kell a címet megadnunk. Ha A2h vagy A3h utolsó bitjét levágom éppen 51h lesz belőle. (azaz A2h fele :D )

Mindenesetre kísérletezek még, meg a doksit is megpróbálom jobban átnézni.


Vissza: “60 nap alatt Arduino - Házi feladatok”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 3 vendég