How long does the internal EEPROM of an Atmel ATmega328 last for? Let’s find out…

Updated 18/03/2013

Some time ago I published a short tutorial concerning the use of the internal EEPROM belonging to the Atmel ATmega328 (etc.) microcontroller in our various Arduino boards. Although making use of the EEPROM is certainly useful, it has a theoretical finite lifespan – according to the Atmel data sheet (download .pdf) it is 100,000 write/erase cycles.

One of my twitter followers asked me “is that 100,000 uses per address, or the entire EEPROM?” – a very good question. So in the name of wanton destruction I have devised a simple way to answer the question of EEPROM lifespan. Inspired by the Dangerous Prototypes’ Flash Destroyer, we will write the number 170 (10101010 in binary) to each EEPROM address, then read each EEPROM address to check the stored number. The process is then repeated by writing the number 85 (01010101 in binary) to each address and then checking it again. The two binary numbers were chosen to ensure each bit in an address has an equal number of state changes.

After both of the processes listed above has completed, then the whole lot repeats. The process is halted when an incorrectly stored number is read from the EEPROM – the first failure. At this point the number of cycles, start and end time data are shown on the LCD.

In this example one cycle is 1024 sequential writes then reads. One would consider the entire EEPROM to be unusable after one false read, as it would be almost impossible to keep track of individual damaged EEPROM addresses. (Then again, a sketch could run a write/read check before attempting to allocate data to the EEPROM…)

If for some reason you would like to run this process yourself, please do not do so using an Arduino Mega, or another board that has a fixed microcontroller. (Unless for some reason you are the paranoid type and need to delete some data permanently). Once again, please note that the purpose of this sketch is to basically destroy your Arduino’s EEPROM. Here is the sketch:

Arduino

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

/*

Arduino EEPROM killer

John Boxall - http://tronixstuff.com - May 2011

CC by-sa

Note: This sketch will destroy your Arduino's EEPROM

Do not use with Arduino boards that have non-replaceable microcontrollers

Sketch assumes DS1307 already contains current date and time

*/

#include <EEPROM.h>

#include <LiquidCrystal.h>

LiquidCrystallcd(4,5,6,7,8,9);

#include "Wire.h"

#define DS1307_I2C_ADDRESS 0x68

// all these bytes necessary for time and date data

bytesecond,minute,hour,dayOfWeek,dayOfMonth,month,year;

bytesday,smonth,ssecond,sminute,shour;

bytefday,fmonth,fsecond,fminute,fhour;

// to store number of cycles. Should be enough

longcycles=0;// maximum size is 2,147,483,647

intzz=0;

voidsetup()

{

lcd.begin(16,2);// fire up the LCD

Wire.begin();// and the I2C bus

}

// Convert normal decimal numbers to binary coded decimal

bytedecToBcd(byteval)

{

return((val/10*16)+(val%10));

}

// Convert binary coded decimal to normal decimal numbers

bytebcdToDec(byteval)

{

return((val/16*10)+(val%16));

}

// Gets the date and time from the ds1307

voidgetDateDs1307(byte*second,

byte*minute,

byte*hour,

byte*dayOfWeek,

byte*dayOfMonth,

byte*month,

byte*year)

{

// Reset the register pointer

Wire.beginTransmission(DS1307_I2C_ADDRESS);

Wire.write(0);

Wire.endTransmission();

Wire.requestFrom(DS1307_I2C_ADDRESS,7);

// A few of these need masks because certain bits are control bits

*second=bcdToDec(Wire.read()&0x7f);

*minute=bcdToDec(Wire.read());

*hour=bcdToDec(Wire.read()&0x3f);// Need to change this if 12 hour am/pm

If you are unfamiliar with the time-keeping section, please see part one of my Arduino+I2C tutorial. The LCD used was my quickie LCD shield – more information about that here. Or you could always just send the data to the serial monitor box – however you would need to leave the PC on for a loooooong time… So instead the example sat on top of an AC adaptor (wall wart) behind a couch (sofa) for a couple of months:

The only catch with running it from AC was the risk of possible power outages. We had one planned outage when our house PV system was installed, so I took a count reading before the mains was turned off, and corrected the sketch before starting it up again after the power cut. Nevertheless, here is a short video – showing the start and the final results of the test:

So there we have it, 1230163 cycles with each cycle writing and reading each individual EEPROM address. If repeating this odd experiment, your result will vary.

Well I hope someone out there found this interesting. Please refrain from sending emails or comments criticising the waste of a microcontroller – this was a one off.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.