TransWikia.com

Can you access the EEPROM of an ATtiny with Arduino Code?

Arduino Asked by Isabel Alphonse on November 17, 2021

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);

}

4 Answers

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.

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.

Answered by mckenzm on November 17, 2021

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
}

Answered by tech-head-uk on November 17, 2021

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);
  }
}

Answered by RSM on November 17, 2021

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?

Answered by Dampmaskin on November 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP