{"id":14107,"date":"2022-04-01T19:49:04","date_gmt":"2022-04-01T19:49:04","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/eeprom-part-1-avr-internal-eeproms"},"modified":"2024-10-30T20:43:37","modified_gmt":"2024-10-30T20:43:37","slug":"eeprom-part-1-avr-internal-eeproms","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms","title":{"rendered":"EEPROM Part 1 &#8211; AVR internal EEPROMs"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"uber-den-beitrag\">About this post<\/h2>\n\n<p>Development boards based on AVR microcontrollers, such as the Arduino UNO, MEGA2560, Nano, Pro Mini and some others, have a small EEPROM (<span class=\"ILfuVd\"><span class=\"hgKElc\">Electrically Erasable Programmable Read-Only Memory<\/span><\/span>). The EEPROM is ideal for storing small amounts of data that the microcontroller should not forget even after power off.<\/p>\r\n<p>The ESP32 and ESP8266 boards also have read-only memories that can be controlled with the EEPROM library.<\/p>\r\n<p>Those who read my article about the <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/hx711-based-balance\" target=\"_blank\" rel=\"noopener\">HX711-based scale<\/a> may remember that the calibration values could be stored in the EEPROM there. This is much more convenient than manually adding them into the program code.<\/p>\r\n<p>In this post I will show which functions you use to write to and read from the EEPROM. This is simple for data types with a defined size, such as bytes, integers or floats. A bit more demanding is the handling of strings or character arrays. That&#8217;s why I&#8217;m going into this topic particularly intensively.<\/p>\r\n<p>The article is structured as follows:<\/p>\r\n<ul>\r\n<li><a href=\"#einfuhrung-was-ist-ein-eeprom\">What is an EEPROM?<\/a><\/li>\r\n<li><a href=\"#die-funktionen-der-eeprom-bibliothek\">The functions of the EEPROM library<\/a><\/li>\r\n<li><a href=\"#schreib-und-lesegeschwindigkeit\">Write and read speed<\/a><\/li>\r\n<li><a href=\"#character-arrays-und-strings-auf-dem-eeprom-speichern\">Storing character arrays and strings on the EEPROM<\/a>\r\n<ul>\r\n<li><a href=\"#character-arrays\">Character Arrays<\/a><\/li>\r\n<li><a href=\"#strings\">Strings<\/a><\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><a href=\"#anwendungsbeispiel\">Application example: Telephone directory with ready-made SMS<\/a><\/li>\r\n<\/ul>\r\n\n<h2 class=\"wp-block-heading\" id=\"einfuhrung-was-ist-ein-eeprom\">Introduction &#8211; what is an EEPROM? <\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"kurze-entwicklungsgeschichte-des-eeprom\">Brief development history of the EEPROM<\/h3>\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-large is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-1024x923.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"923\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-1024x923.jpg\" alt=\"Relic from another epoch: an EPROM\" class=\"wp-image-13852\" style=\"width:256px;height:231px\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-1024x923.jpg 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-300x271.jpg 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-768x693.jpg 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-1536x1385.jpg 1536w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445-1320x1190.jpg 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/WNFF4445.jpg 1648w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Relic from another epoch: an EPROM<\/figcaption><\/figure>\n<\/div>\n<p>The development history of the EEPROM is in its name. Evolution proceeded as follows:<\/p>\r\n<ul>\r\n<li><strong>ROM<\/strong> &#8211; <strong>Read<\/strong> <strong>Only<\/strong> <strong>Memory<\/strong>: this type of memory is immutable. The memory content is determined during production.<\/li>\r\n<li><strong>PROM<\/strong> &#8211; <strong>Programmable <strong>Read<\/strong> <strong>Only<\/strong> <strong>Memory<\/strong>: this memory can be programmed once.<\/strong><\/li>\r\n<li><strong>EPROM<\/strong> &#8211; <strong>Erasable<\/strong> Programmable <strong>Read<\/strong> <strong>Only<\/strong> <strong>Memory<\/strong>: with this further development, the ROM could also be erased again, for example with UV light.<strong><\/strong><\/li>\r\n<li><strong>EEPROM<\/strong> &#8211; <strong>Electrically<\/strong> <strong>Erasable<\/strong> Programmable <strong>Read<\/strong> <strong>Only<\/strong> <strong>Memory<\/strong>: this most modern variant is electrically erasable, so also by software.<strong><\/strong><\/li>\r\n<\/ul>\r\n<p><strong>Flash memory<\/strong>, as used in SD cards, is also based on EEPROM technology. A major difference is that the EEPROM can be written and deleted byte by byte, while this is done on the flash memory sector by sector. This is one of the reasons why the flash memory is much faster.<\/p>\r\n\n<h3 class=\"wp-block-heading\" id=\"eigenschaften-von-eeproms\">Features of EEPROMs<\/h3>\n\n<p>EEPROMs are used when small amounts of data are to be stored permanently and are not subject to frequent changes. Their disadvantage is the limited number of write operations. Manufacturers guarantee between 10,000 and 1,000,000 write cycles. In addition, the writing process is extremely slow &#8211; we&#8217;ll get to that.&nbsp;<\/p>\r\n\n<h3 class=\"wp-block-heading\" id=\"eeprom-speicher-im-arduino\">The internal EEPROM of the Arduino <\/h3>\n\n<p>The EEPROM memory is part of the underlying microcontroller. The Arduino Mega 2560 is based on the ATmega2560, which has an EEPROM of 4 KB. The boards based on the ATmega328P, such as the Arduino UNO, have a 1 KB EEPROM. For Arduino boards that are available with different microcontrollers, such as the Arduino Pro Mini (Atmega328P or Atmega168) you have to check which one is used. The service life is 100,000 write cycles.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"die-funktionen-der-eeprom-bibliothek\">The functions of the EEPROM library<\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"put-get-und-length\">put(), get() and length()<\/h3>\n\n<p>We start with a simple task. Three integer values are to be written first into the EEPROM, then read out and finally output to the serial monitor.<\/p>\r\n<p>First, we need to integrate the EEPROM library, which is an integral part of the Arduino IDE when using AVR boards. It is not necessary for us to create an EEPROM object. However, when using an ESP32 or ESP8266 based board, it is necessary to initialize the EEPROM with <code>EEPROM.begin(size in byte);<\/code>. I only write this in the first example sketch. In the other sketches, you have to add the line yourself.<\/p>\r\n<p>The function <code>EEPROM.put(addr, var)<\/code> writes the variable <code>var<\/code> to the EEPROM. It starts at the address <code>addr<\/code>. In the example sketch, this is address 0. Since an integer comprises two bytes, memory addresses 0 and 1 are occupied. We set the next integer value at address 2 and thus occupy memory locations 2 and 3. This means that you have to keep track of the addresses when writing.<\/p>\r\n<p>If you are unsure about the size of the variable, you can use the <code>sizeof(var)<\/code> function to determine it.<\/p>\r\n<p>The <code>put()<\/code>function does not care which address you apply. You could also start at 357. The function does not check whether a memory address already contains data or not. For example, if you were to store the second integer at addresses 1 and 2, there would be no warnings. The first integer value would be partially overwritten.<\/p>\r\n<p>The function <code>EEPROM.get(addr, var)<\/code> reads the EEPROM at the address <code>addr<\/code>. It stores the content in the variable <code>var<\/code>. The variable type determines how many memory addresses will be read.&nbsp;<\/p>\r\n<p>The function <code>EEPROM.length()<\/code> returns the total size of the EEPROM memory.<\/p>\r\n<p>This is the sketch:<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_basic.ino\" data-enlighter-title=\"eeprom_basic.ino\">#include &lt;EEPROM.h&gt;\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n\/\/  EEPROM.begin(1024); \/\/ uncomment if you use an ESP32 or ESP8266\r\n\/\/  delay(1000); \r\n  int int0 = 42, int1 = 9999, int2 = -13756;\r\n  int readInt = 0; \u00a0 \u00a0 \u00a0\r\n  Serial.print(\"Size of EEPROM: \");\r\n  Serial.println(EEPROM.length());\r\n\r\n  unsigned int address = 0;\r\n  unsigned int increment = (sizeof(int));\r\n  Serial.print(\"increment: \");\r\n  Serial.println(increment);\r\n  \r\n  \/\/ Write:\r\n  EEPROM.put(address, int0);\r\n  address += increment;\r\n  EEPROM.put(address, int1);\r\n  address += increment;\r\n  EEPROM.put(address, int2);\r\n\r\n  \/\/ Read:\r\n  address = 0;\r\n  EEPROM.get(address, readInt);\r\n  Serial.print(\"1. Integer: \");\r\n  Serial.println(readInt);\r\n\r\n  address += increment;\r\n  EEPROM.get(address, readInt);\r\n  Serial.print(\"2. Integer: \");\r\n  Serial.println(readInt);\r\n\r\n  address += increment;\r\n  EEPROM.get(address, readInt);\r\n  Serial.print(\"3. Integer: \");\r\n  Serial.println(readInt);\r\n\r\n  \/\/ uncomment the following for ESP32 \/ ESP8266\r\n  \/*\r\n  if (EEPROM.commit()) { \/\/ validate the changes\r\n    Serial.println(\"EEPROM successfully committed\");\r\n  } else {\r\n    Serial.println(\"ERROR! EEPROM commit failed\");\r\n  }\r\n  *\/\r\n\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n<p>\u00a0<\/p>\r\n<\/div>\n\n<p>And here is the output:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_basic_example.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"349\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_basic_example.png\" alt=\"Output of eeprom_basic.ino\" class=\"wp-image-13755\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_basic_example.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_basic_example-300x146.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of eeprom_basic.ino<\/figcaption><\/figure>\n<\/div>\n<h3 class=\"wp-block-heading\" id=\"write-read-update-und-eeprom\">write(), read(), update() and EEPROM[]<\/h3>\n\n<p>Alternatively, you can write to the EEPROM using <code>EEPROM.write(addr, var)<\/code>. However, <code>byte<\/code> must be variable of the type <code>var<\/code>. To save an integer value with this function, you would first have to split it into its two bytes (4 bytes when using an ESP32 or ESP8266) and write them individually to the EEPROM.<\/p>\r\n<p>The function <code>EEPROM.update(addr, var)<\/code> does the same as <code>EEPROM.write(addr, var)<\/code>, but writes <code>var<\/code> only if the value is different from the current value at that memory address. On the one hand, this brings speed advantages, on the other hand, it increases the life span of the EEPROM. However, this is only noticeable if only a small proportion of what you write on the EEPROM is actually new. Otherwise, the chance is 1 : 256 that the correct value is already in memory. With text to be saved, it looks a little better.<\/p>\r\n<p>The counterpart to <code>EEPROM.write()<\/code> is <code>EEPROM.read(addr)<\/code>. This function reads a single byte at the address <code>addr<\/code>.<\/p>\r\n<p>With <code>EEPROM[addr]<\/code> you address the EEPROM as an array. <code>EEPROM[addr] = var<\/code> writes a value, <code>var = EEPROM[addr]<\/code> reads a value. And again, <code>var<\/code> is mandatory of the byte data type.<\/p>\r\n<p>Here is a small sketch:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_write_read_update.ino\" data-enlighter-title=\"eeprom_write_read_update.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  byte readVal = 0;\r\n  \r\n  \/\/ write:\r\n  EEPROM.write(0,255);\r\n  EEPROM.update(523,42);\r\n  EEPROM[37] = 111;\r\n\r\n  \/\/ read and print:\r\n  readVal = EEPROM[0];\r\n  Serial.print(\"Address 0:   \");\r\n  Serial.println(readVal);\r\n  \r\n  readVal = EEPROM.read(523);\r\n  Serial.print(\"Address 523: \");\r\n  Serial.println(readVal);\r\n  \r\n  EEPROM.get(37, readVal);\r\n  Serial.print(\"Address 37:  \");\r\n  Serial.println(readVal); \r\n}\r\n\r\nvoid loop(){}\r\n<\/pre>\r\n<p>&nbsp;<\/p>\r\n\n<p>Here&#8217;s what the output looks like:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_read_update.png\"><img loading=\"lazy\" decoding=\"async\" width=\"735\" height=\"139\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_read_update.png\" alt=\"EEPROM functions: Output of eeprom_write_read_update.ino\" class=\"wp-image-13764\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_read_update.png 735w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_read_update-300x57.png 300w\" sizes=\"auto, (max-width: 735px) 100vw, 735px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of eeprom_write_read_update.ino<\/figcaption><\/figure>\n<\/div>\n<p>In the following, I will mainly use the functions put() and get(), also for writing individual bytes.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"schreib-und-lesegeschwindigkeit\">Write and read speed <\/h2>\n\n<p>Writing data to EEPROMs is a very slow process. I &#8220;measured&#8221; this with the following sketch.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_write_speed.ino\" data-enlighter-title=\"eeprom_write_speed.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  \r\n  unsigned long duration = 0;\r\n  unsigned long start = millis();\r\n  \r\n  for(int address=0; address&lt;1024; address++){\r\n    EEPROM.write(address,42);\r\n  }\r\n  duration = millis() - start;\r\n\r\n  Serial.print(\"duration [ms]: \");\r\n  Serial.println(duration);\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n<p>It took all of 3.5 seconds to fill the entire EEPROM with data:<\/p>\r\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"111\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_speed.png\" alt=\"EEPROM Speed Test: &#13;&#10;Output of eeprom_write_speed.ino\" class=\"wp-image-13782\" style=\"width:716px;height:111px\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_speed.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_write_speed-300x47.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><figcaption class=\"wp-element-caption\">Output of eeprom_write_speed.ino<\/figcaption><\/figure>\n\n<p>So you need about 3.4 milliseconds to write a single byte. To illustrate this: If you wanted to store a 4 GB movie at this speed, it would take about 157 days!<\/p>\r\n<p>The reading process is almost 2000 times faster. With the following sketch, you can test this:<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_read_speed.ino\" data-enlighter-title=\"eeprom_read_speed.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  \r\n  byte b = 0;\r\n  unsigned long a = 0;\r\n  unsigned long duration1 = 0;\r\n  unsigned long duration2 = 0;\r\n  unsigned long duration = 0;\r\n  unsigned long start = micros();\r\n  \r\n  for(int address=0; address&lt;1024; address++){\r\n    EEPROM.get(address,b);\r\n    a += b; \/\/ dummy use of b\r\n  }\r\n  duration1 = micros() - start;\r\n\r\n  a = 0;\r\n  start = micros();\r\n  for(int address=0; address&lt;1024; address++){\r\n    a += b;\r\n  }\r\n  duration2 = micros() - start;\r\n\r\n  duration = duration1 - duration2;\r\n\r\n  Serial.print(\"duration1 [\u00b5s]: \");\r\n  Serial.println(duration1);\r\n  Serial.print(\"duration2 [\u00b5s]: \");\r\n  Serial.println(duration2);\r\n  Serial.print(\"duration [\u00b5s]: \");\r\n  Serial.println(duration);\r\n  Serial.print(\"dummy: \");\r\n  Serial.println(a); \r\n}\r\nvoid loop(){}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<p>The sketch looks quite complex for what it is supposed to do. However, simply reading the contents of memory without using the data causes the compiler to simply &#8220;optimize away&#8221; the process.<\/p>\r\n<p>Since the loop and the calculation also take some time, I measured the time needed for these operations again separately and then subtracted it.<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_speed.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"143\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_speed.png\" alt=\"EEPROM Speed Test: Output eeprom_read_speed.ino\" class=\"wp-image-13780\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_speed.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_speed-300x60.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output eeprom_read_speed.ino<\/figcaption><\/figure>\n<\/div>\n<p>The reading of the entire EEPROM takes 1924 \u03bcs, i.e. about 1.88 \u03bcs per byte.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"vertiefung\">Deepening<\/h2>\n\n<p>The following sketch writes the numbers 65 to 74 as bytes to the addresses 0 to 9. For verification, the numbers are read out and output to the serial monitor.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_write_bytes.ino\" data-enlighter-title=\"eeprom_write_bytes.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  byte byteArray[10];\r\n  byte startValue = 65;\r\n  \r\n  for(int i=0; i&lt;10; i++){\r\n    EEPROM.put(i, startValue + i);\r\n  }\r\n  \r\n  for(int i=0; i&lt;10; i++){\r\n    EEPROM.get(i, byteArray[i]);\r\n  }\r\n  for(int i=0; i&lt;10; i++){\r\n    Serial.print(\"byteArray[\");\r\n    Serial.print(i);\r\n    Serial.print(\"]: \");\r\n    Serial.println(byteArray[i]);\r\n  }\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n<p>The data on the EEPROM does not indicate which data types it is or at which address a value begins and where it ends. The following sketch interprets the data in different ways as bytes, characters, integer, float and long.<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_different_interpretation.ino\" data-enlighter-title=\"eeprom_different_interpretation.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  byte byteArray[10];\r\n  char charArray[10];\r\n  unsigned int uintArray[5];\r\n  float floatVal = 0.0;\r\n  long longVal = 0;\r\n  int intArray[5];\r\n  \r\n  for(int i=0; i&lt;10; i++){\r\n    EEPROM.get(i, byteArray[i]);\r\n  }\r\n  for(int i=0; i&lt;10; i++){\r\n    Serial.print(\"byteArray[\");\r\n    Serial.print(i);\r\n    Serial.print(\"]: \");\r\n    Serial.print(byteArray[i]);\r\n    Serial.print(\", 0x\");\r\n    Serial.println(byteArray[i], HEX);\r\n  }\r\n  for(int i=0; i&lt;10; i++){\r\n    EEPROM.get(i, charArray[i]);\r\n  }\r\n  for(int i=0; i&lt;10; i++){\r\n    Serial.print(\"charArray[\");\r\n    Serial.print(i);\r\n    Serial.print(\"]: \");\r\n    Serial.println(charArray[i]);\r\n  }\r\n  for(int i=0; i&lt;5; i++){\r\n    EEPROM.get(2*i, uintArray[i]); \r\n  }\r\n  for(int i=0; i&lt;5; i++){\r\n    Serial.print(\"uintArray[\");\r\n    Serial.print(i);\r\n    Serial.print(\"]: \");\r\n    Serial.print(uintArray[i]);\r\n    Serial.print(\", 0x\");\r\n    Serial.println(uintArray[i], HEX);\r\n  }\r\n  for(int i=0; i&lt;5; i++){\r\n    EEPROM.get(2*i, intArray[i]); \r\n  }\r\n  EEPROM.get(0, floatVal);\r\n  Serial.print(\"Float Value:  \");\r\n  Serial.println(floatVal);\r\n  EEPROM.get(4, longVal);\r\n  Serial.print(\"Long Value:   \");\r\n  Serial.println(longVal);\r\n}\r\nvoid loop(){}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<p>And this is what the output looks like:<\/p>\r\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_different_interpretation.png\"><img loading=\"lazy\" decoding=\"async\" width=\"911\" height=\"591\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_different_interpretation.png\" alt=\"Output of eeprom_different_interpretation.ino\" class=\"wp-image-13772\" style=\"width:840px;height:544px\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_different_interpretation.png 911w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_different_interpretation-300x195.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_different_interpretation-768x498.png 768w\" sizes=\"auto, (max-width: 911px) 100vw, 911px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of eeprom_different_interpretation.ino<\/figcaption><\/figure>\n\n<p>This last sketch is only to clarify once more that you must know exactly where your data is located on the EEPROM and which data type it is. Without that, it&#8217;s just &#8220;data salad&#8221;.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"character-arrays-und-strings-auf-dem-eeprom-speichern\">Writing character arrays and strings to the EEPROM<\/h2>\n\n<p>There are options for &#8220;text&#8221; variables. Either you use character arrays (array of chars) or string objects. Character arrays require less program memory and RAM, on the other hand there are very convenient functions to deal with strings.<\/p>\r\n<p>The difference between strings and the variable types used so far is their variable length. So, you not only have to know at which address they start on the EEPROM, but also where they end. But how? The answer is: Strings are terminated with the null character <code>'\\0'<\/code>. The null character (ASCII code 0) is not to be confused with the zero (ASCII code 48). When declaring a character array, due to null termination, one more element must be added to the number of readable characters, for example:<\/p>\r\n<p><code>char myCharArray[5] = \"four\";<\/code><\/p>\r\n\n<h3 class=\"wp-block-heading\" id=\"character-arrays\">Character Arrays<\/h3>\n\n<h4 class=\"wp-block-heading\" id=\"allgemeines-uber-character-arrays\">General information about character arrays<\/h4>\n\n<p>In the last section, we had saved the characters &#8220;ABCDEFGHIJ&#8221; on the EEPROM. The string occupies addresses 0 through 9. The following sketch adds the null character to the address 10. After this operation, the string can be read in one go, even if the length is not known. To illustrate this, I intentionally reserved more characters than necessary for the array <code>myCharArray<\/code> in the following sketch.&nbsp;<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_make_char_array_and_read.ino\" data-enlighter-title=\"eeprom_make_char_array_and_read.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  Serial.begin(9600);\r\n  EEPROM.put(10,'WPML_BUFFER_MASK_7');\r\n  \r\n  char myCharArray[20];\r\n  EEPROM.get(0,myCharArray);\r\n  \r\n  Serial.print(\"myCharArray: \");\r\n  Serial.println(myCharArray);\r\n  Serial.print(\"Length: \");\r\n  Serial.println(sizeof(myCharArray));\r\n\r\n  String myString = String(myCharArray);\r\n  Serial.print(\"myString:    \");\r\n  Serial.println(myString);\r\n  Serial.print(\"Length: \");\r\n  Serial.println(myString.length());\r\n}\r\n\r\nvoid loop(){}<\/pre>\r\n\n<p>Here&#8217;s what the output looks like:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"181\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_make_char_array_and_read.png\" alt=\"\" class=\"wp-image-13817\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_make_char_array_and_read.png 728w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_make_char_array_and_read-300x75.png 300w\" sizes=\"auto, (max-width: 728px) 100vw, 728px\" \/><\/figure>\n\n<p>Although <code>myCharArray<\/code> can have up to 20 characters, it is displayed correctly via the <code>println()<\/code> function. When converting to a String object, the characters after the null character are ignored.<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"mehrere-character-arrays-auf-den-eeprom-schreiben\">Writing multiple character arrays to the EEPROM<\/h4>\n\n<p>Now I want to show you how to write several character arrays to the EEPROM. In the following sketch, the character arrays are first declared and then passed one after the other to a function that writes the arrays character by character to the EEPROM. It is necessary to always calculate the current address.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_write_multiple_char_arrays.ino\" data-enlighter-title=\"eeprom_write_multiple_char_arrays.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  int address = 0;\r\n  char myCharArray0[] = \"Arduino's\";\r\n  char myCharArray1[] = \"EEPROM\";\r\n  char myCharArray2[] = \"can\";\r\n  char myCharArray3[] = \"be very\";\r\n  char myCharArray4[] = \"useful\";\r\n  \r\n  Serial.begin(9600);\r\n\r\n  address = writeToEEPROM(address, myCharArray0);\r\n  address = writeToEEPROM(address, myCharArray1);\r\n  address = writeToEEPROM(address, myCharArray2);\r\n  address = writeToEEPROM(address, myCharArray3);\r\n  address = writeToEEPROM(address, myCharArray4);\r\n}\r\n\r\nvoid loop(){}\r\n\r\nint writeToEEPROM(int addr, char *cArr){\r\n  int i=0; \r\n  \r\n  do{\r\n    EEPROM.put(addr + i, cArr[i]);\r\n    i++;   \r\n  }while(cArr[i-1] != 'WPML_BUFFER_MASK_8');\r\n  \r\n  addr += i;  \r\n  return addr;\r\n}<\/pre>\r\n\n<p>Since strings can take up a lot of memory, functions to which they are passed do not work with copies, but with the originals. The name of a character array is the pointer to its first element. With this, <code>writeToEEPROM(address, myCharArray0);<\/code> passes the array <code>myCharArray0<\/code> as a pointer. Accordingly, it must be received in the function <code>writeToEEPROM()<\/code> as a pointer, which is indicated by the &#8220;*&#8221; operator.<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"mehrere-character-arrays-vom-eeprom-lesen\">Reading multiple character arrays from the EEPROM<\/h4>\n\n<p>The readout works similarly:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_read_multiple_char_arrays.ino\" data-enlighter-title=\"eeprom_read_multiple_char_arrays.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  char myCharArray[30]; \/\/ max 29 characters expected\r\n  Serial.begin(9600);\r\n\r\n  for(int i=0; i&lt;5; i++){\r\n    readNextCharArray(myCharArray);\r\n    Serial.println(myCharArray);\r\n  }\r\n}\r\n\r\nvoid loop(){}\r\n\r\nvoid readNextCharArray(char* cArr){\r\n  static int address = 0;\r\n  int i = 0;\r\n  cArr[i] = ' ';\r\n\r\n  do{\r\n    EEPROM.get(address + i, cArr[i]);\r\n    i++;\r\n  }while(cArr[i-1] != 'WPML_BUFFER_MASK_9');\r\n  \r\n  address += i;\r\n}<\/pre>\r\n\n<p>With <code>char myCharArray[30]<\/code> I declare a character array at a length of up to 29 characters plus the null character. The array is passed as a pointer to readNextCharArray() and ist there filled with life, so to speak. I have solved the bookkeeping for the address differently here for a change. It is calculated as &#8220;static int&#8221; in the writing function.<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"201\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays.png\" alt=\"Output of eeprom_read_several_char_arrays.ino\" class=\"wp-image-13810\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays-300x84.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><figcaption class=\"wp-element-caption\">Output of eeprom_read_several_char_arrays.ino<\/figcaption><\/figure>\n<\/div>\n<h4 class=\"wp-block-heading\" id=\"warum-zeichenweises-schreiben-und-lesen\">Why writing and reading character by character? <\/h4>\n\n<p>Above I had read the &#8220;ABCDEFGHIJ&#8221; array &#8220;in one go&#8221; and not character by character. Why not in the last examples? Unfortunately, this does not work so easily after passing to the function. Here&#8217;s a test:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_read_test.ino\" data-enlighter-title=\"eeprom_read_test.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  char myCharArray[30]; \/\/ max 29 characters expected\r\n  Serial.begin(9600);\r\n\r\n  EEPROM.get(0,myCharArray);\r\n  \r\n  Serial.print(\"Char Array (setup): \");\r\n  Serial.println(myCharArray);\r\n  readCharArray(myCharArray); \r\n}\r\n\r\nvoid loop(){}\r\n\r\nvoid readCharArray(char* cArr){\r\n  char myLocalCharArray[30];\r\n  Serial.print(\"Char Array (passed to readCharArray): \");\r\n  Serial.println(cArr);\r\n  EEPROM.get(0,cArr);\r\n  Serial.print(\"Char Array (read from EEPROM in readCharArray): \");\r\n  Serial.println(cArr);\r\n  EEPROM.get(0,myLocalCharArray);\r\n  Serial.print(\"Char Array (read from EEPROM in readCharArray as local array of chars): \");\r\n  Serial.println(myLocalCharArray);\r\n}<\/pre>\r\n\n<p>The <code>Serial.println()<\/code> command works after the transfer, but reading does <code>EEPROM.get(0, cArr)<\/code> not work properly:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_test.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"170\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_test.png\" alt=\"Output of eeprom_read_test.ino\" class=\"wp-image-13890\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_test.png 900w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_test-300x57.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output__eeprom_read_test-768x145.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of eeprom_read_test.ino<\/figcaption><\/figure>\n<\/div>\n<h4 class=\"wp-block-heading\" id=\"eine-alternative\">An alternative<\/h4>\n\n<p>Instead of the null character, you could also write the length of the character array to be stored at the beginning character array. Then you know how many characters you need to read before the next character array begins. This replaces the null character on the EEPROM. The space needed is therefore the same. <\/p>\r\n\n<h3 class=\"wp-block-heading\" id=\"strings\">Strings<\/h3>\n\n<h4 class=\"wp-block-heading\" id=\"mehrere-strings-auf-den-eeprom-schreiben\">Writing multiple strings to the EEPROM<\/h4>\n\n<p>Even when passings string objects to functions, you should work with the originals in functions and not create local copies. To do this, the String object is simply preceded by the address operator &#8220;&amp;&#8221; in the function declaration. Otherwise, the procedure is similar:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_write_multiple_strings.ino\" data-enlighter-title=\"eeprom_write_multiple_strings.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  int address = 0;\r\n  String myString0 = \"Arduino's\";\r\n  String myString1 = \"EEPROM\";\r\n  String myString2 = \"can\";\r\n  String myString3 = \"be very\";\r\n  String myString4 = \"useful\";\r\n  Serial.begin(9600);\r\n\r\n  address = writeToEEPROM(address, myString0);\r\n  address = writeToEEPROM(address, myString1);\r\n  address = writeToEEPROM(address, myString2);\r\n  address = writeToEEPROM(address, myString3);\r\n  address = writeToEEPROM(address, myString4);\r\n}\r\n\r\nvoid loop(){}\r\n\r\nint writeToEEPROM(int address, String &amp;stringToWrite){\r\n  for(unsigned int i=0; i&lt;stringToWrite.length(); i++){\r\n    EEPROM.put(address, stringToWrite[i]);\r\n    address++;\r\n  }\r\n  EEPROM.put(address, '\\0');\r\n  address++;\r\n  return address;\r\n}<\/pre>\n\n<p>As you can see, we do not save the String object as such, but again as a character array.<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"mehrere-strings-vom-eeprom-lesen\">Reading multiple strings from the EEPROM<\/h4>\n\n<p>Since the strings were stored as character arrays on the EEPROM, you could simply read them with the Sketch eeprom_read_multiple_char_arrays.ino. But I would like to show here how to work with strings instead.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_read_multiple_strings.ino\" data-enlighter-title=\"eeprom_read_multiple_strings.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  int address = 0;\r\n  String myString = \"\";\r\n  Serial.begin(9600);\r\n\r\n  for(int i=0; i&lt;5; i++){\r\n    readNextString(myString);\r\n    Serial.println(myString);\r\n  }\r\n}\r\n\r\nvoid loop(){}\r\n\r\nvoid readNextString(String &amp;stringToRead){\r\n  static int address = 0;\r\n  stringToRead = \"\";\r\n  char c = ' ';\r\n\r\n  while(c != '\\0'){\r\n    EEPROM.get(address,c);\r\n    address++;\r\n    stringToRead += c; \r\n  }\r\n}<\/pre>\r\n<p>&nbsp;<\/p>\r\n\r\n\n<p>Of course, the output is the same as when reading by using character arrays:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays.png\"><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"201\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays.png\" alt=\"Output of eeprom_read_multiple_strings.ino\" class=\"wp-image-13810\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays.png 716w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_read_several_char_arrays-300x84.png 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of eeprom_read_multiple_strings.ino<\/figcaption><\/figure>\n<\/div>\n<h2 class=\"wp-block-heading\" id=\"anwendungsbeispiel\">Application example: Telephone directory with ready-made SMS<\/h2>\n\n<p>A few weeks ago, a reader asked me how the EEPROM and <a href=\"https:\/\/wolles-elektronikkiste.de\/en\/sim800l-module\" target=\"_blank\" rel=\"noopener\">SIM800L<\/a> modules could be used to send ready-made SMS at the push of a button. By the way, that was also the trigger for writing this article.<\/p>\r\n<p>This task is no longer a big challenge. First, the phone numbers and the ready-made SMS are stored on the EEPROM as follows.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_write_telephone_directory.ino\" data-enlighter-title=\"eeprom_write_telephone_directory.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nvoid setup(){\r\n  int address = 0;\r\n  String Herbert = \"+491731234567,Hi Herbert, let's have a beer this evening, do you have time?\";\r\n  String John = \"+492323223323,Hi John, can you call me tomorrow?\";\r\n  String Grandma = \"+497776665554444,Hi Grandma, don't forget to take your medicine!\";\r\n  String Tina = \"+49876543210,Hi Tina, I will arrive in 30 minutes\";\r\n  String Pizza = \"+492345654321,Hi Pizza-Service, No. 18 with extra garlic, please\";\r\n  \r\n  Serial.begin(9600);\r\n\r\n  address = writeToEEPROM(address, Herbert);\r\n  address = writeToEEPROM(address, John);\r\n  address = writeToEEPROM(address, Grandma);\r\n  address = writeToEEPROM(address, Tina);\r\n  address = writeToEEPROM(address, Pizza);\r\n}\r\n\r\nvoid loop(){}\r\n\r\nint writeToEEPROM(int address, String &amp;stringToWrite){\r\n  for(unsigned int i=0; i&lt;stringToWrite.length(); i++){\r\n    EEPROM.put(address, stringToWrite[i]);\r\n    address++;\r\n  }\r\n  EEPROM.put(address, '\\0');\r\n  address++;\r\n  return address;\r\n}<\/pre>\r\n\n<p>This post is about the EEPROM and not the SIM800L module. That&#8217;s why I&#8217;m just focusing on how the entries are read from the EEPROM. The recipients of the SMS are defined as an enum called &#8220;smsRecipient&#8221;. The order must correspond to the order of the entries on the EEPROM. If you now want to send a text message to John, you will get to the phone number and the message as follows:<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"eeprom_get_entry_from_telephone_directory.ino\" data-enlighter-title=\"eeprom_get_entry_from_telephone_directory.ino\">#include &lt;EEPROM.h&gt;\r\n\r\nenum smsRecipient {Herbert, John, Grandma, Tina, Pizza}; \r\n\r\nvoid setup(){\r\n  String smsString = \"\";\r\n  smsRecipient sendTo = John;\r\n  Serial.begin(9600);\r\n\r\n  readSmsString(smsString, sendTo);\r\n  Serial.println(smsString);\r\n  String phone = smsString.substring(0, smsString.indexOf(\",\"));\r\n  String message = smsString.substring(smsString.indexOf(\",\")+1, smsString.length());\r\n  Serial.println(\"Phone:\");\r\n  Serial.println(phone);\r\n  Serial.println(\"Message:\");\r\n  Serial.println(message);\r\n}\r\n\r\nvoid loop(){}\r\n\r\nvoid readSmsString(String &amp;stringToRead, smsRecipient sendTo){\r\n  unsigned int address = 0;\r\n  stringToRead = \"\";\r\n  char c = ' ';\r\n  unsigned int counter = 0;\r\n  \r\n  while(counter &lt; sendTo){\r\n    address++;\r\n    EEPROM.get(address,c);\r\n    if(c == '\\0'){\r\n      counter++;\r\n    }\r\n  }\r\n  c = ' ';\r\n  while(c != '\\0'){\r\n    address++;\r\n    EEPROM.get(address,c);\r\n    stringToRead += c; \r\n  }\r\n}<\/pre>\r\n<\/div>\r\n\n<p>Herbert is 0, John is 1. So, you have to search for the first null character on the EEPROM. Everything between the first and second null character is stored in a string. The first comma of the string separates the phone number from the message. The two parts can be split into individual strings via the convenient <code>substring()<\/code> and <code>indexOf()<\/code> functions. In this example, I first output the entire string, then the number and finally the message on the serial monitor:<\/p>\r\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_get_sms_entry.png\"><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"195\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_get_sms_entry.png\" alt=\"\" class=\"wp-image-13837\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_get_sms_entry.png 728w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/output_eeprom_get_sms_entry-300x80.png 300w\" sizes=\"auto, (max-width: 728px) 100vw, 728px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of eeprom_get_entry_from_telephone_directory.ino<\/figcaption><\/figure>\n<\/div>\n<p>Not much is missing to complete the sketch:&nbsp; a few buttons are queried in a loop whether they have been pressed. The buttons are assigned to SMS recipients, for example: &#8220;If key 1 is pressed, then smsRecipient = John&#8221;. How to send SMS messages with the SIM800L module, I have described in my post about the SIM800L module.<\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"ausblick\">Outlook<\/h2>\n\n<p>If you have to store larger amounts of data, you don&#8217;t get very far with the internal EEPROM, at least this is true for the AVR-based boards. Therefore, I will show in a second part how to control external IC2 based EEPROMs. In a third part, I will deal with SPI based EEPROMs.<\/p>\r\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it. <\/p>\n","protected":false},"author":1,"featured_media":13856,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[543,567],"tags":[1727,1726,1728,1725,1733,1731,1730,1729,1732],"class_list":["post-14107","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-boards-and-microcontrollers","category-other-stuff","tag-array-of-chars-en","tag-avr-en","tag-character-strings","tag-eeprom-en","tag-eeprom-en-2","tag-get-en","tag-put-en","tag-strings-en","tag-update-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>EEPROM Part 1 - AVR internal EEPROMs &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"EEPROM Part 1 - AVR internal EEPROMs &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-01T19:49:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-30T20:43:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/EEPROM_Beitragsbild.png\" \/>\n\t<meta property=\"og:image:width\" content=\"969\" \/>\n\t<meta property=\"og:image:height\" content=\"969\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"EEPROM Part 1 &#8211; AVR internal EEPROMs\",\"datePublished\":\"2022-04-01T19:49:04+00:00\",\"dateModified\":\"2024-10-30T20:43:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms\"},\"wordCount\":2288,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/EEPROM_Beitragsbild.png\",\"keywords\":[\"array of chars\",\"AVR\",\"character strings\",\"EEPROM\",\"EEPROM[]\",\"get\",\"put\",\"Strings\",\"update\"],\"articleSection\":[\"Boards and Microcontrollers\",\"Other stuff\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms\",\"name\":\"EEPROM Part 1 - AVR internal EEPROMs &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/EEPROM_Beitragsbild.png\",\"datePublished\":\"2022-04-01T19:49:04+00:00\",\"dateModified\":\"2024-10-30T20:43:37+00:00\",\"description\":\"AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/EEPROM_Beitragsbild.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/EEPROM_Beitragsbild.png\",\"width\":969,\"height\":969},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/eeprom-part-1-avr-internal-eeproms#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"EEPROM Part 1 &#8211; AVR internal EEPROMs\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"EEPROM Part 1 - AVR internal EEPROMs &#8226; Wolles Elektronikkiste","description":"AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms","og_locale":"en_US","og_type":"article","og_title":"EEPROM Part 1 - AVR internal EEPROMs &#8226; Wolles Elektronikkiste","og_description":"AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms","og_site_name":"Wolles Elektronikkiste","article_published_time":"2022-04-01T19:49:04+00:00","article_modified_time":"2024-10-30T20:43:37+00:00","og_image":[{"width":969,"height":969,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/EEPROM_Beitragsbild.png","type":"image\/png"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"EEPROM Part 1 &#8211; AVR internal EEPROMs","datePublished":"2022-04-01T19:49:04+00:00","dateModified":"2024-10-30T20:43:37+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms"},"wordCount":2288,"commentCount":5,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/EEPROM_Beitragsbild.png","keywords":["array of chars","AVR","character strings","EEPROM","EEPROM[]","get","put","Strings","update"],"articleSection":["Boards and Microcontrollers","Other stuff"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms","url":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms","name":"EEPROM Part 1 - AVR internal EEPROMs &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/EEPROM_Beitragsbild.png","datePublished":"2022-04-01T19:49:04+00:00","dateModified":"2024-10-30T20:43:37+00:00","description":"AVR microcontrollers have an EEPROM in which you can store data permanently. I show you how to write to and read from it.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/EEPROM_Beitragsbild.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2022\/02\/EEPROM_Beitragsbild.png","width":969,"height":969},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/eeprom-part-1-avr-internal-eeproms#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"EEPROM Part 1 &#8211; AVR internal EEPROMs"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/14107","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=14107"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/14107\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/13856"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=14107"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=14107"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=14107"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}