7

I'm attempting to reduce the amount of RAM being used by my program by writing some values to the EEPROM of my micro controller. I'm currently programming on the ATtiny85 which has 512 Bytes of EEPROM. According to the documentation this is how you write to EEPROM:

#include <EEPROM.h>

void setup() {
  EEPROM.write(0, 1);
  EEPROM.write(1, 0);
  EEPROM.write(2, 3);
  EEPROM.write(3, 2);
  EEPROM.write(4, 1);

}

For some reason this isn't working for me and I can't seem to find the error. Am I programming this wrong or can the EEPROM of the ATtiny simply NOT be accessed with Arduino Code?

Here is the Datasheet: http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet-Summary.pdf

Here is the second sketch I'm using to test the EEPROM:

    #include <EEPROM.h>

void setup() {
  EEPROM.write(0, 1);
  EEPROM.write(1, 0);
  EEPROM.write(2, A3);
  EEPROM.write(3, A2);
  EEPROM.write(4, A1);

byte CLK = EEPROM.read(0);

}

void loop() {

  if(CLK == 1)
  {
    for(int i = 0; i < 3; i++)
    {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
    }
    exit(0); 
  }
  else
  {
    for(int i = 0; i < 100; i++)
    {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
    }
    exit(0);
  }

  exit(0);

}
12
  • I wish I had the ATTiny you have with 512MB of EEPROM, it must be a new one. Please have a look at this arduino.stackexchange.com/help/how-to-ask
    – RSM
    Jun 10, 2016 at 13:39
  • What is wrong with my question? Jun 10, 2016 at 13:48
  • an ATTiny has 512 bytes of EEPROM and you also asked a similar question earlier. You need to add what you have tried to retrieve those values and how you know they have been retrieved properly. The eeprom values have been written to properly in the above 'snippet'. And that's the problem you have not given all your code.
    – RSM
    Jun 10, 2016 at 13:57
  • I didn't write the other EEPROM question. I saw that it was unanswered and decided to ask my own. Also, my question is about the ability of the ATtiny EEPROM to be programmed with Arduino. Like I said, my code was working fine until I switched the value with EEPROM.read(0) which caused the code to just stop working. Jun 10, 2016 at 14:00
  • the ATTiny can be used with the EEPROM library from the arduino ide it is basically a wrapper of the avr/eeprom.h. What also might kill your first cell in EEPROM is repeatedly reading it in the loop. That kills EEPROM cells, they have limited read write cycles. Also why do you have exit(0)
    – RSM
    Jun 10, 2016 at 14:18

4 Answers 4

9

The Arduino EEPROM library is compatible with the ATTiny range of AVR microcontrollers as the library itself is built on the standard Atmel AVR avr/eeprom.h 'library' so it is compatible with all the AVR microcontrollers.

The EEPROM also doesn't take to being written or read to often as EEPROM can wear very quickly. Reading though does not cause much damage though.

Also note that using exit(0); will stop the ATTiny from doing anything else after it is called so I hope your intention is to only run the loop once, if not this would account for either not seeing anything or it only ever running the blinking cycle once.

To answer your follow up question. Yes you can run one sketch to set you values in EEPROM and then use another sketch to read those. That us usually the point of EEPROM it is a memory type that "keeps its value while there is no power".

Also you need to make sure the ATTiny is set to preserve EEPROM during upload with the ISP, this is done with the fuse settings. You need to look for a tutorial on fuse calculators for the AVRs. To set the EESAVE you need to set the High fuse to 0xD7, you can change this in the boards.txt file. Here is a fuse calculator.

If the code that is on your question at the moment is being used you won't be seeing anything as it needs the pins to be set with pinMode. That's a note for others that see this.

Next what you can do is run a basic test code which blinks the LED without anything else going on.

Basically:

void setup(){

 pinMode(0, OUTPUT);

}

void loop(){

 digitalWrite(0, HIGH);
 delay(1000);
 digitalWrite(0, LOW);
 delay(1000);

}

Below is the code you have written, it works I have it running in front of me. I have commented it and changed a few things to make it work as intended, although the intention is not clear.

#include <EEPROM.h>

byte CLK = 0; //This is a global variable with an initial value

void setup() {
  // put your setup code here, to run once:

  EEPROM.write(0, 1); //set the pin to D1
  delay(5); 

  //read from EEPROM address 0
  //this sets the value of the global variable CLK
  CLK = EEPROM.read(0); //place this inside a function

  //just to give an example...
  byte PIN = CLK;   //PIN variable is a local variable 

  pinMode(PIN ,OUTPUT); //using that local variable

}

void loop() {
  // put your main code here, to run repeatedly:

  // Note: the below if() will always be true as the value 
  // of CLK is never change and shouldn't be changed as
  // it will change the pin number of the output

  if (CLK == 1) {
    for (int a = 0; a < 3; a++) {
      digitalWrite(CLK, HIGH);  //this uses the global variable 
      delay(1000);
      digitalWrite(CLK, LOW);
      delay(1000);
    }
    //putting exit(0); will actually stop the program 
    //remove it
//    exit(0);
  }
  else { 
    for (int a = 0; a < 100; a++) {
      digitalWrite(0, HIGH);  //this has a predefined pin no.
      delay(500);
      digitalWrite(0, LOW);   //this has a predefined pin no.
      delay(500);
    }
    //putting exit(0); will actually stop the program 
    //remove it
//    exit(0);
  }
}
7
  • Thanks, it works. My problem now is that I can only use EEPROM.write(); inside of a function and that prevents me from creating a global variable that all my function can use. Jun 10, 2016 at 15:56
  • @IsabelAlphonse ??. The EEPROM.write() is a function and has to be used within a function. I think you need to start with the basics TBH. What I also think you mean is the read part. I have edited my answer to include the code you have written that works.
    – RSM
    Jun 10, 2016 at 16:29
  • @IsabelAlphonse please can you mark one of the answers as accepted so that the StackExchange system doesn't bump it up in a few weeks and also to allow others to find it more easily when searching for the same problem.
    – RSM
    Jun 10, 2016 at 17:13
  • Sorry, I forgot. Jun 10, 2016 at 18:29
  • You said: "The EEPROM also doesn't take to being written or read to often as EEPROM can wear very quickly. " Datasheet says: Memory Flash Endurance: 10,000 Write/Erase Cycles, EEPROM Endurance: 100,000 Write/Erase Cycles. So EEPROM can be written ten times more often than the flash memory. Apr 8, 2018 at 20:04
0

When you upload a new sketch with the default settings, the EEPROM will be cleared.

"The -e option instructs avrdude to perform a chip-erase before programming; this is almost always necessary before programming the flash."

If you're using the Arduino IDE, the -e option is enabled by default. This is probably why it's not working for you.

See also the question Is there a way to preserve EEPROM contents in AVR Atmega when burning a new firmware to flash with avrdude?

1
  • Then my test code should be working at least. I write to the EEPROM in the setup method and set the CLK variable afterwards. But when I enter the loop() method I still can't get my light to blink. Jun 10, 2016 at 14:51
0

Not sure if things have changed so significantly since the question was asked originally but I'll answer using the Atmel AVR libraries.

Don't assign the EEPROM value to a variable as then you are wasting precious SRAM again. EEPROM has unlimited read cycles.

I can't find any current references to EEPROM.read() as a Macro or function in the Arduino IDE. Instead there is the AVR EEPROM library which uses eeprom_read_byte() as shown below.

#include  <avr/eeprom.h>

// the setup routine runs once when you press reset:
void setup() {
/* The "131" value is used to prevent damaging excess EEPROM writes on every restart.
   If you want to try setting a different GPIO pin for LED blink change the test value in
   both the read and following write to EEPROM address 511 */

    if (eeprom_read_byte((uint8_t*)511) != 131) {
       eeprom_write_byte((uint8_t*)511,131);
// Store the GPIO pin number in EEPROM address 1     
       eeprom_write_byte((uint8_t*)1,1); 
    };
// initialize the digital pin as an output.
    pinMode(eeprom_read_byte((uint8_t*)1), OUTPUT); // LED pin value stored in EEPROM address 1
}

// the loop routine runs over and over again forever:

void loop() {
    digitalWrite(eeprom_read_byte((uint8_t*)1), HIGH);
    delay(1000);               // wait for a second
    digitalWrite(eeprom_read_byte((uint8_t*)1), LOW);

    delay(1000);               // wait for a second
}
2
  • For reference, Arduino has a EEPROM library as part of its ecosystem. arduino.cc/en/Reference/EEPROM
    – sa_leinad
    Oct 16, 2018 at 3:54
  • 1
    maybe the reference is there but in Arduino IDE 1.8.5 I am using here if I try and use #include <EEPROM.H> I get a compilation error which is why I posted the working source code I did. C:\Windows\Users1\Users\WINDOWS\AppData\Local\Temp\arduino_modified_sketch_177973\sketch_oct24a.ino:1:20: fatal error: EEPROM.h: No such file or directory Oct 24, 2018 at 5:28
0

It is now very common to read from EEPROM in an ATTiny, particularly an OSCCAL value. It has also been the case for some embedded devices to perform a superfluous write and read back to external EEPROM during POST. Every boot.

> ---snip---
>     current tick:1 sec 
>     EEPROM Init... 
>     Write EE_TEST ==0x7cf u8EEData1=0xaa 
>     Read EE_TEST ==0x7cf u8EEData1=0xaa 
>     [EEPROM 24c16 found!] 
>     EEPROM: Data valid 
>     Restore Configuration from EEPROM to Device... 
>     Show MY MAC Address(from 24c16): (0x00:92:58:01:45:4d) 
>     _24c16_eeprom_word_read: EE_DHCPEN: (01) 
> --- end snip ---

In addition, available cores include options to suppress EEPROM erase in programming, this is fuseable.

In ancient times AVRDUDE would write flash counts to the four bytes terminated by E2END. (the -y option).

You need to include the header. You can check, peek and poke, the contents with a sketch or by using avrdude in terminal mode (-t) with "dump ee".

And yes, it is normal for Arduino work to have a dedicated temporary sketch to load EEPROM data. So SRAM (or FLASH) does not matter, there is a lot of FLASH compared to EEPROM.

Keep it simple and test your results. Depending upon the library or core, it is best to avoid crossing page boundaries as addressing may wrap around to the beginning of the page due to 6 bit truncation as for I2C external EEPROM. Don't trust, verify.

2
  • Is that boot time write intended to be for planned obsolescence or just bad coding practice. If you want to check for the function of storage you could leave a couple byte signature that you read out instead of stressing the EEPROM (internal or external) with regular pointless writes.
    – KalleMP
    May 10, 2022 at 8:49
  • 1
    It was bad coding. I think it was just left in the script from development. Netgear if it helps.
    – mckenzm
    May 10, 2022 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.