4

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

}
  • 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 '16 at 13:39
  • What is wrong with my question? – Isabel Alphonse Jun 10 '16 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 '16 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. – Isabel Alphonse Jun 10 '16 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 '16 at 14:18
6

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);
  }
}
  • 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. – Isabel Alphonse Jun 10 '16 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 '16 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 '16 at 17:13
  • Sorry, I forgot. – Isabel Alphonse Jun 10 '16 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. – needfulthing Apr 8 '18 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?

  • 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. – Isabel Alphonse Jun 10 '16 at 14:51
-1

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
}
  • For reference, Arduino has a EEPROM library as part of its ecosystem. arduino.cc/en/Reference/EEPROM – sa_leinad Oct 16 '18 at 3:54
  • 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 – tech-head-uk Oct 24 '18 at 5:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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