60 nap alatt Arduino #30-#31 - IIC busz és az EEPROM
60 nap alatt Arduino #30-#31 - IIC busz és az EEPROM
Az I2C EEPROM-ot házasítsd a hőmérővel.
A hőmérő a mért eredményét írja ki az LCD-re. Az adatokat mentsd el és CSV formában a PC-re le tudd tölteni.
A hőmérő a mért eredményét írja ki az LCD-re. Az adatokat mentsd el és CSV formában a PC-re le tudd tölteni.
Muszáj hozzászólnom, hogy a macsekot utolérjem
A dataloggerem első változata
Lustaságból nem írtam bele megjegyzéseket, bocsánat ...
Másodpercenként méri a hőmérsékletet.
A 16x2 karakteres LCD kijelző első sorában megjeleníti a dátumot és az
időt, a masodik sorában a pillanatnyi hőmérsékletet, valamint annak min.
illetve max. értékét.
Percenként elmenti ugyanezen adatokat az Ext1 panel 24LC128 EEPROM-ába, egyelőre mindig ugyanabba a címtartományba (1-11), és ugyanakkor kiküldi azokat a soros porton is (a hőmérséklet adatokat HEX formátumban, lustaság )
A képet a Képfeltöltés.hu tárolja. http://www.kepfeltoltes.hu
A dataloggerem első változata
Lustaságból nem írtam bele megjegyzéseket, bocsánat ...
Kód: Egész kijelölése
/*----------------------------------------------------------------
Projekt: AVR-DUINO/Shieldboard Ext1
Fájlnév: DATA_LOGGER.PDE
Dátum: 2012.08.20.
Mcu: ATMega168
Board: Arduino Duemilanove w/ ATmega168
Program: Arduino 0022
Verziószám: V1.00
Szerző: Szegő János
E-mail: szego@umszki.hu
------------------------------------------------------------------
Az LCD kijelzőn megjeleníti az időt és dátumot.
A hőmérő a mért eredményét írja ki az LCD-re.
Az adatokat EEPROM-ba menti, és CSV formában
a PC-re letöltheti (gombnyomásra).
A kijelző bekötése
------------------
DB4..DB7 -> Digital pins 6..9 (PD6,7 és PB0,1), külön portokon !!!
RS -> Digital pin 4 (PD4)
E -> Digital pin 5 (PD5)
------------------------------------------------------------------
*/
#include <LiquidCrystal.h>
#include <Wire.h>
// LCD konfiguráló parancs LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);
byte circle[8] = {
B00110,
B01001,
B01001,
B00110,
B00000,
B00000,
B00000,
};
int Back_light = 13;
// (20)12.08.20 19:00 (We)
byte seconds = 0x00;
byte minutes = 0x00;
byte hours = 0x19;
byte days = 0x20;
byte weekday = 0x00;
byte months = 0x08;
byte years = 0x12;
byte param;
int pcf8563_addr = 0x51;
int lc128_addr = 0x50;
int tc75_addr = 0x48;
int eeprom_addr;
int temperature;
int temp_min = 32000;
int temp_max = -32000;
void setup() {
pinMode(Back_light, OUTPUT);
digitalWrite(Back_light, HIGH);
lcd.begin(16, 2);
lcd.createChar(0, circle);
lcd.clear();
Serial.begin(9600);
Serial.println("Temperature DataLogger V1.0");
Serial.println("---------------------------");
Serial.println();
Wire.begin();
}
void pcf8563_write() {
Wire.beginTransmission(pcf8563_addr);
Wire.send(2);
Wire.send(seconds);
Wire.send(minutes);
Wire.send(hours);
Wire.send(days);
Wire.send(weekday);
Wire.send(months);
Wire.send(years);
Wire.endTransmission();
}
void pcf8563_read(){
Wire.beginTransmission(pcf8563_addr);
Wire.send(2);
Wire.endTransmission();
// 7 bájtot akarunk beolvasni
Wire.requestFrom(pcf8563_addr,7);
if (Wire.available()) {
seconds = Wire.receive();
minutes = Wire.receive();
hours = (Wire.receive()) & 63;
days = (Wire.receive()) & 63;
weekday =(Wire.receive()) & 7;
months = (Wire.receive()) & 31;
years = Wire.receive();
}
}
void time_write() {
lcd.clear();
lcd.setCursor(1, 0);
// LCD üzenet kiiratása
if (months<10) lcd.print(0);
lcd.print(months,HEX);
lcd.print('/');
if (days<10) lcd.print(0);
lcd.print(days,HEX);
lcd.print(" ");
if (hours<10) lcd.print(0);
lcd.print(hours,HEX);
lcd.print(':');
if (minutes<10) lcd.print(0);
lcd.print(minutes,HEX);
lcd.print(':');
if (seconds<10) lcd.print(0);
lcd.print(seconds,HEX);
}
void temp_write() {
lcd.setCursor(0, 1);
temp_min = min(temperature, temp_min);
temp_max = max(temperature, temp_max);
lcd.print(temperature/10);
lcd.print(',');
lcd.print(temperature%10);
lcd.write(0);
lcd.print('C');
lcd.print(' ');
lcd.print(temp_min/10);
lcd.print(',');
lcd.print(temp_min%10);
lcd.print('/');
lcd.print(temp_max/10);
lcd.print(',');
lcd.print(temp_max%10);
}
void tc75_read() {
byte data;
Wire.beginTransmission(tc75_addr);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(tc75_addr, 2);
if (Wire.available()) {
data = Wire.receive();
// negatív eredmény még nincs figyelembe véve
temperature = data * 10;
data = Wire.receive();
// tizedesjegy kompenzálás
if (data>>7) temperature += 5;
}
else {
}
}
void lc128_write (unsigned int eeaddress, byte data) {
byte addr;
Wire.beginTransmission(lc128_addr);
addr = eeaddress >> 8; //Cim magas helyierteke
Wire.send(addr);
addr = eeaddress; //Cim alacsony helyierteke
Wire.send(addr);
Wire.send(data); //A beirando adat
Wire.endTransmission();
delay(5);
}
byte lc128_read (unsigned int eeaddress) {
byte rdata = 0xFF;
byte addr;
Wire.beginTransmission(lc128_addr);
addr = eeaddress >> 8; //Cim magas helyierteke
Wire.send(addr);
addr = eeaddress; //Cim alacsony helyierteke
Wire.send(addr);
Wire.endTransmission();
Wire.requestFrom(lc128_addr,1); //Egy byte-ot olvasunk
if (Wire.available()){
rdata = Wire.receive();
}
return rdata;
}
void param_save() {
byte data;
lc128_write(1,years);
lc128_write(2,months);
lc128_write(3,days);
lc128_write(4,hours);
lc128_write(5,minutes);
data = temperature >> 8;
lc128_write(6,data);
data = temperature;
lc128_write(7,data);
data = temp_min >> 8;
lc128_write(8,data);
data = temp_min;
lc128_write(9,data);
data = temp_max >> 8;
lc128_write(10,data);
data = temp_max;
lc128_write(11,data);
}
void loop() {
lcd.clear();
lcd.print("PCF8563 Clock &");
lcd.setCursor(3, 1);
lcd.print("DataLogger");
delay(5000);
// RTC működés ellenőrzése
pcf8563_read();
if (seconds & 128) pcf8563_write();
while(1) {
pcf8563_read();
time_write();
tc75_read();
temp_write();
delay(1000);
if (seconds == 0) { // most percenként ment
param_save();
// ------------------------
lcd.setCursor(0, 1);
lcd.print('*');
delay(1000);
for (int i=1; i<12; i++) {
param = lc128_read(i);
Serial.print(param,HEX);
}
Serial.println();
// ------------------------
}
}
}
A 16x2 karakteres LCD kijelző első sorában megjeleníti a dátumot és az
időt, a masodik sorában a pillanatnyi hőmérsékletet, valamint annak min.
illetve max. értékét.
Percenként elmenti ugyanezen adatokat az Ext1 panel 24LC128 EEPROM-ába, egyelőre mindig ugyanabba a címtartományba (1-11), és ugyanakkor kiküldi azokat a soros porton is (a hőmérséklet adatokat HEX formátumban, lustaság )
A képet a Képfeltöltés.hu tárolja. http://www.kepfeltoltes.hu
szegoj írta:Muszáj hozzászólnom, hogy a macsekot utolérjem
Egyébként lehagytál már kettővel. A progi pedig jópofa, bár még csak átfutottam.
Viszont van pár kérdésem, bárki megválaszol6ja, aki tudja.
Legelőször is:
Honnan tudja szegény EEPROM vagy egyéb frincfranc, hogy mi most olvasni szeretnénk? Akárhogy nézem a programkódokat, nem látom benne, h az i2c (avagy TWI) R/~W bitjét bárhol is piszkálnánk a címzésnél. (biztos működik a te kódod is, nem próbáltam még ki, mert kell még egy kicsit hardverészkedni, h az LCD és a többi kütyü 1szerre rá legyen kötve az arduinora)
szegoj írta: void pcf8563_write() {
Wire.beginTransmission(pcf8563_addr);
Wire.send(2);
Wire.send(seconds);
Wire.send(minutes);
Wire.send(hours);
Wire.send(days);
Wire.send(weekday);
Wire.send(months);
Wire.send(years);
Wire.endTransmission();
}
itt miért van vége a küldésnek? (Wire.endTransmission())szegoj írta: void pcf8563_read(){
Wire.beginTransmission(pcf8563_addr);
Wire.send(2);
Wire.endTransmission();
Eddig volt kiküldés (azaz megcímeztük és megmondtuk neki, h "2" kódú parancsot hajtsa végre)?
De az előző rutinban (az idő beállításában) is ugyanez a "2" kód szerepelt, csak ott folyamatosan írtad az adatot bele. (Ez tulajdonképpen az első kérdésemmel azonos)
Nem a te kódodat akarom "cikizni" csak nem értem (másoknál is láttam már ilyet)szegoj írta: // 7 bájtot akarunk beolvasni
Wire.requestFrom(pcf8563_addr,7);
if (Wire.available()) {
seconds = Wire.receive();
minutes = Wire.receive();
hours = (Wire.receive()) & 63;
days = (Wire.receive()) & 63;
weekday =(Wire.receive()) & 7;
months = (Wire.receive()) & 31;
years = Wire.receive();
}
}
Miért van így és ez így jó-e (üzembiztos-e)?
Azt mondod a Wire.requestFrom(pcf8563_addr,7); függvénnyel, h hét bájtot szeretnél beolvasni.
Aztán megnézed, h jött-e adat if (Wire.available()), és ha igen, akkor beolvasol HÉT bájtot. De mi van, ha nem küldte még el? Megvárja a kód? (Nem a tied, hanem a "gyári" Wire könyvtár)
A WireRead leírásában nem említik, h várna, de azt sem, h nem vár. Viszont az itteni példa minden beolvasás előtt megnézi, h jött-e be byte.
Amúgy a WireAvailable leírásában az van, h megmondja, h mennyi karakter érkezett be, amit még nem olvastunk ki. Tehát lehet, h if (Wire.available()==7) már korrekt megoldás lenne?
Most már nagyon indulnom kellene itthonról (tudjátok, nézegetni a csajokat), tehát nem olvasok most utána, de az dereng, h 32 byte a Wire buffere, akkor abba beleférhet.
Mi a szép és működő megoldás?
Bocsi, egy kis belekotyogás a stílusba:szegoj írta: void loop() {
lcd.clear();
lcd.print("PCF8563 Clock &");
lcd.setCursor(3, 1);
lcd.print("DataLogger");
delay(5000);
// RTC működés ellenőrzése
pcf8563_read();
if (seconds & 128) pcf8563_write();
while(1) {
pcf8563_read();
time_write();
tc75_read();
temp_write();
delay(1000);
if (seconds == 0) { // most percenként ment
param_save();
// ------------------------
lcd.setCursor(0, 1);
lcd.print('*');
delay(1000);
for (int i=1; i<12; i++) {
param = lc128_read(i);
Serial.print(param,HEX);
}
Serial.println();
// ------------------------
}
}
}
[/code]
A loop() függvényedben a while(1) előtti sorok szebben mutatnának a setup()-ban és akkor nem kéne while(1) sem.
Nyomás vissza a 29. leckét átolvasni .
A leckében is valahol benne van, hogy a R/W+-t az Arduino rakja hozzá, hogy írod vagy olvasod!
A PCF8563T adatlapot vedd elő és világos lesz -> 28. lecke. I2C-t csak adatlap bitrokában érted meg!
Ezzel azt mondod meg, hogy 2. regisztertől akarsz majd valamit csinálni vele. Órát olvasol vagy állítasz be a következőkben....
A nem küldte el/fogadja: NEM RS232/sorosport. A MASTER adja az ütemet! Ő ad órajelet, és a slave _ezzel szinkronban_ csinálhat bármit! -> Philips leírás.
Az I2C NEM LED villogtató!
Komplex és összetett valami. Ha kihagysz 1-2 lépést : kuka. Borul a teljes későbbi tudás. "Tan'tónéni, nem tudom leírni a nevemet, mert a 'R' betűnél beteg voltam "
És ez csak egy vacak egyszerű I2C. A Dallas (1-wire), SPI (SD kártya, ethernet) protokollok az I2C megértése nélkül esélytelenek...
Nálam az I2C megértése, logikája 2 hétvége volt! Mit miért csinálok, hogyan épül fel. És ekkor nem volt csak egy LM75-s hőmérőm + adatlapja.
Itt meg itt a Philips leírás ...
Szóval, ahogy Lenin is mondta: tanulni-tanulni-tanulni....
Off: A felmérés eredménye, ami a #27. lecke volt: "Ki hol tart most az anyagokkal?"
- Időben vagyok: 33%
- kicsit lemaradva 26%
- hát...: 31%
"Lecke szinten:"
jellemző a 18-22. lecke.
És ez csak az elolvasás, kicsit ízlelgetés....
Kód: Egész kijelölése
Iras:
Wire.beginTransmission(cím);
Wire.send(mit_irok_byte1);
Wire.send(mit_irok_byte2);
Wire.send(mit_irok_byte3);
Wire.send(mit_irok_byte4);
Wire.endTransmission();
Olvasas:
Wire.requestFrom(cim,olvasandodarab);
rdata = Wire.receive(); //1. byte olvasva
rdata = Wire.receive(); //2. byte olvasva
rdata = Wire.receive(); //3. byte olvasva
rdata = Wire.receive(); //4. byte olvasva
//Ha olvasandodarab: 3 akkor a 4. byte kérésekor a slave csak pislog, de nem kuld semmit!
Kód: Egész kijelölése
void pcf8563_read(){
Wire.beginTransmission(pcf8563_addr);
Wire.send(2);
Wire.endTransmission();
Ezzel azt mondod meg, hogy 2. regisztertől akarsz majd valamit csinálni vele. Órát olvasol vagy állítasz be a következőkben....
A nem küldte el/fogadja: NEM RS232/sorosport. A MASTER adja az ütemet! Ő ad órajelet, és a slave _ezzel szinkronban_ csinálhat bármit! -> Philips leírás.
Az I2C NEM LED villogtató!
Komplex és összetett valami. Ha kihagysz 1-2 lépést : kuka. Borul a teljes későbbi tudás. "Tan'tónéni, nem tudom leírni a nevemet, mert a 'R' betűnél beteg voltam "
És ez csak egy vacak egyszerű I2C. A Dallas (1-wire), SPI (SD kártya, ethernet) protokollok az I2C megértése nélkül esélytelenek...
Nálam az I2C megértése, logikája 2 hétvége volt! Mit miért csinálok, hogyan épül fel. És ekkor nem volt csak egy LM75-s hőmérőm + adatlapja.
Itt meg itt a Philips leírás ...
Szóval, ahogy Lenin is mondta: tanulni-tanulni-tanulni....
Off: A felmérés eredménye, ami a #27. lecke volt: "Ki hol tart most az anyagokkal?"
- Időben vagyok: 33%
- kicsit lemaradva 26%
- hát...: 31%
"Lecke szinten:"
jellemző a 18-22. lecke.
És ez csak az elolvasás, kicsit ízlelgetés....
24LC04
Ne használjatok i2c óraIC-t és 24LC04 vagy 24LC08 eepromot egy rendszerben.
Úgysem tudtok
1db i2c óraIC, 1 db hőmérő és 1 db 24LC04 eepromot dugtam arduinora.
Azt hittem én kötöttem el valamit, mikor ezt láttam:
A 24LC04-nek van A0, A1 és A2 lába. De nem használja!
A címekből pedig 8 db-ot elfoglal, mert így címzi a memóriáját.
Úgysem tudtok
1db i2c óraIC, 1 db hőmérő és 1 db 24LC04 eepromot dugtam arduinora.
Azt hittem én kötöttem el valamit, mikor ezt láttam:
Kód: Egész kijelölése
I2CScanner ready!
starting scanning of I2C bus from 1 to 127
------------------------------------------
addr: 01 addr: 02 addr: 03 addr: 04
addr: 05 addr: 06 addr: 07 addr: 08
addr: 09 addr: 0A addr: 0B addr: 0C
addr: 0D addr: 0E addr: 0F addr: 10
addr: 11 addr: 12 addr: 13 addr: 14
addr: 15 addr: 16 addr: 17 addr: 18
addr: 19 addr: 1A addr: 1B addr: 1C
addr: 1D addr: 1E addr: 1F addr: 20
addr: 21 addr: 22 addr: 23 addr: 24
addr: 25 addr: 26 addr: 27 addr: 28
addr: 29 addr: 2A addr: 2B addr: 2C
addr: 2D addr: 2E addr: 2F addr: 30
addr: 31 addr: 32 addr: 33 addr: 34
addr: 35 addr: 36 addr: 37 addr: 38
addr: 39 addr: 3A addr: 3B addr: 3C
addr: 3D addr: 3E addr: 3F addr: 40
addr: 41 addr: 42 addr: 43 addr: 44
addr: 45 addr: 46 addr: 47 addr: 48 found!
addr: 49 addr: 4A addr: 4B addr: 4C
addr: 4D addr: 4E addr: 4F addr: 50 found!
addr: 51 found! addr: 52 found! addr: 53 found! addr: 54 found!
addr: 55 found! addr: 56 found! addr: 57 found! addr: 58
addr: 59 addr: 5A addr: 5B addr: 5C
addr: 5D addr: 5E addr: 5F addr: 60
addr: 61 addr: 62 addr: 63 addr: 64
addr: 65 addr: 66 addr: 67 addr: 68
addr: 69 addr: 6A addr: 6B addr: 6C
addr: 6D addr: 6E addr: 6F addr: 70
addr: 71 addr: 72 addr: 73 addr: 74
addr: 75 addr: 76 addr: 77 addr: 78
addr: 79 addr: 7A addr: 7B addr: 7C
addr: 7D addr: 7E addr: 7F
3.6 Device Addressing
A control byte is the first byte received following the
start condition from the master device. The control byte
consists of a 4-bit control code, for the 24LC04B/08B
this is set as 1010 binary for read and write operations.
The next three bits of the control byte are the block
select bits (B2, B1, B0). B2 is a don't care for both the
24LC04B and 24LC08B; B1 is a don't care for the
24LC04B. They are used by the master device to select
which of the two or four 256 word blocks of memory are
to be accessed. These bits are in effect the most sig-nificant bits of the word address.
Tehát van fizikailag ilyen nevű lába, de mindegy mit csinálsz vele, ha olyanod van bekötheted pl. földre vagy tápra, de hagyhatod lebegve is.8.4 A0, A1, A2
These pins are not used by the 24LC04B/08B. They
may be left floating or tied to either VSS or VCC.
A címekből pedig 8 db-ot elfoglal, mert így címzi a memóriáját.
Re: 24LC04
Ezt kifejtenéd bővebben?macsek írta:Ne használjatok i2c óraIC-t és 24LC04 vagy 24LC08 eepromot egy rendszerben.
Úgysem tudtok
Re: 24LC04
Persze.muszer írta:Ezt kifejtenéd bővebben?macsek írta:Ne használjatok i2c óraIC-t és 24LC04 vagy 24LC08 eepromot egy rendszerben.
Úgysem tudtok
Cím-ütközés miatt nem használhatóak.
Az óra az 51h i2c címen lakik.
A 24LC04 illetve 24LC08 elfoglalja mind a 8 címet az 50h-57h tartományban. (egészen értelmetlen tervezés miatt, ugyanis onnan veszi a belső címzéséhez a címinformáció egy részét, h melyik címen szólnak hozzá)
Mivel ugyanarra a címre két I2C eszköz válaszol, így egyik sem tud adatot küldeni, mert összegabalyodnak. (Ha ugyanolyan értékű bitet küldenének, akkor jó, de ha az egyik 1-est, a másik 0-t akkor 0 lesz olvasható)
Re: 24LC04
Így már értem, hogy mire gondoltál.macsek írta:Persze.muszer írta:Ezt kifejtenéd bővebben?macsek írta:Ne használjatok i2c óraIC-t és 24LC04 vagy 24LC08 eepromot egy rendszerben.
Úgysem tudtok
Cím-ütközés miatt nem használhatóak.
Az óra az 51h i2c címen lakik.
A 24LC04 illetve 24LC08 elfoglalja mind a 8 címet az 50h-57h tartományban. (egészen értelmetlen tervezés miatt, ugyanis onnan veszi a belső címzéséhez a címinformáció egy részét, h melyik címen szólnak hozzá)
Mivel ugyanarra a címre két I2C eszköz válaszol, így egyik sem tud adatot küldeni, mert összegabalyodnak. (Ha ugyanolyan értékű bitet küldenének, akkor jó, de ha az egyik 1-est, a másik 0-t akkor 0 lesz olvasható)
Csak a megfogalmazás nem volt érthető számomra, mert nem minden óraIC lakik ezen a címen.
http://www.nxp.com/acrobat_download2/se ... LGUIDE.PDFRobert írta: hol van az a tábla, hogy melyik címtartomány mihez dedikált I2C esetén....