====== EEPROM ======
Nayon sok esetben problémát okoz az Arduinok esetén, hogy az adatok alapból nem perzisztálhatók. A perzisztáció azt jelenti, hogy az adatok nem törlődnek újraindítás, komplexebb esetben redundáns átkapcsolás után sem. Az Arduino operatív memóriája teljes mértékben törlődik ilyenkor. A legegyszerűbb megoldás az, hogy az Arduino EEPROM memória-területére tároljuk az ilyen adatokat, vagy egy külső memóriát alkalmazunk adattárolásra, ami lehet akár egy [[hu:arduino:micro_sd_card|SD kártya is]], de egyszerűbb egy külső EEPROM-ot beépíteni. Nyilván a megoldások között segít eligazítani, hogy mennyire akarjuk terhelni az Arduino saját EEPROM-ját, illetve milyen mennyiségű adatot akarunk perzisztálni.
===== Arduino EEPROM =====
A különböző Arduino board-ok eltérő méretű EEPROM-mal rendelkeznek:
* ATmega328P: 1024 bájt
* ATmega168: 512 bájt
* ATmega8: 512 bájt
* ATmega1280: 4096 bájt
* ATmega2560: 4096 bájt
Az EEPROM eléréséhez érdemes az EEPROM könyvtár funkcióit felhasználni: https://www.arduino.cc/en/Reference/EEPROM
A belső EEPROM írásánál ügyelni kell arra, hogy az maximum nagyjából 100.000 írásciklusra alkalmaz. Ez talán soknak tűnik, de ha minden ciklusban adatokat próbálunk oda menteni, gyorsan elérhetjük élettartamának a végét. Nyilván érdemes az írásokat nem túl gyakran bekövetkező eseményekhez, vagy idő-triggerhez kötni.
==== Példaprogram az Arduino EEPROM-hoz ====
/*
* EEPROM Write
*
* Stores values read from analog input 0 into the EEPROM.
* These values will stay in the EEPROM when the board is
* turned off and may be retrieved later by another sketch.
*/
#include
/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int addr = 0;
void setup() {
/** Empty setup. **/
}
void loop() {
/***
Need to divide by 4 because analog inputs range from
0 to 1023 and each byte of the EEPROM can only hold a
value from 0 to 255.
***/
int val = analogRead(0) / 4;
/***
Write the value to the appropriate byte of the EEPROM.
these values will remain there when the board is
turned off.
***/
EEPROM.write(addr, val);
/***
Advance to the next address, when at the end restart at the beginning.
Larger AVR processors have larger EEPROM sizes, E.g:
- Arduno Duemilanove: 512b EEPROM storage.
- Arduino Uno: 1kb EEPROM storage.
- Arduino Mega: 4kb EEPROM storage.
Rather than hard-coding the length, you should use the pre-provided length function.
This will make your code portable to all AVR processors.
***/
addr = addr + 1;
if (addr == EEPROM.length()) {
addr = 0;
}
/***
As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an
EEPROM address is also doable by a bitwise and of the length - 1.
++addr &= EEPROM.length() - 1;
***/
delay(100);
}
{{ :wiki:arduino:at24c256.png?150|AT24C256 I²C EEPROM modul}}
===== AT24C256 I²C EEPROM IC és modul =====
Ebben az esetben az EEPROM funkció [[hu:comm:bus_i2c|I²C]]-n keresztül érhető el. Mivel jó eséllyel úgyis alkalmazunk pár másik [[hu:arduino:comm_example#arduino_i2c_com|Arduino I²C kommunikációs egységet]] is, így már a memóriakezelés nem fog további értékes pin-eket foglalni. Ennek az IC-nek két változata van, az AT24C128 128 kBit - 16 kByte, míg a AT24C256 256 kBit - 32 kByte címezhető, törölhető, de perzisztens adatterületet tartalmaz. Az írás / olvasás bájtonként vagy laponként (64 bájt) történhet.
==== AT24C256 technikai adatok ====
* Tápfeszültség:
* (alacsony feszültésgű mód): 1,8..3,6 V
* (normál feszültésgű mód): 2,7..5,5 V
* Kommunikáció: [[hu:comm:bus_i2c|I²C]]
* Átlapolás mód: 64 byte
* I²C frekvencia kompatibilitás: 1 MHz (5V), 400 kHz (2,7..2,5V), 100 kHz (1,8V)
* Írásciklusok maximális száma: 1 millió
* Működési hőmérséklet: -55..125 °C
* A lábak feszültségtűrése a GND-hez képest: -1..7 V
* Maximális tápfeszültség: 6,25 V
* Kimeneti áram: 5,0 mA
==== AT24C256 IC lábkiosztás ====
{{:wiki:arduino:at24c256_ic.png|AT24C256 IC lábkiosztás}}
**A0, A1:** I²C cím \\
**SDA:** I²C adatport \\
**SCL:** I²C órajel port \\
**WP:** írásvédelem az IC-re \\
**NC:** nincs bekötve \\
Az IC külön is beszerezhető, de egyszerűbb a modult beszerzi, akkor már nem kell bütykölni az [[hu:comm:bus_i2c|I²C]] felhúzóellenállásaival, címzés jumperekkel, és a "drótozással".
==== AT24C256 címkiosztás ====
Az EEPROM címe az A0, A1 pinek (vagy modul esetén jumperek) segítségével így alakul:
{{:wiki:arduino:at24c256_adr.png|AT24C256 címkiosztás}}
==== AT24C256 telegram-felépítés ====
{{:wiki:arduino:at24c256_teleg.png|AT24C256 telegram-felépítés}}
==== Vezetékezés (modul) ====
{{:wiki:arduino:at24c256_wiring.png?600|AT24C256 I²C EEPROM modul vezetékezés}}
==== Szoftver ====
A modulhoz alkalmazásprogram a Githubról is letölthető: https://github.com/cyberp/AT24Cx
/*
* Use the I2C bus with EEPROM 24LC64
* Sketch: eeprom.ino
*
* Author: hkhijhe
* Date: 01/10/2010
*
*
*/
#include
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.write(data[c]);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.read();
}
void setup()
{
char somedata[] = "this is data from the eeprom"; // data to write
Wire.begin(); // initialise the connection
Serial.begin(9600);
i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM
delay(100); //add a small delay
Serial.println("Memory written");
}
void loop()
{
int addr=0; //first address
byte b = i2c_eeprom_read_byte(0x50, 0); // access the first address from the memory
while (b!=0)
{
Serial.print((char)b); //print content to serial port
addr++; //increase address
b = i2c_eeprom_read_byte(0x50, addr); //access an address from the memory
}
Serial.println(" ");
delay(2000);
}