Skip to content

Commit

Permalink
RingEEPROM library first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
shuvangkardas committed Feb 20, 2020
0 parents commit e094b06
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 0 deletions.
1 change: 1 addition & 0 deletions .development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Delete this file when ready to publish. This flag ensures that arduino will not index my library
63 changes: 63 additions & 0 deletions examples/example1/example1.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <EEPROM.h>
#include "eep.h"
#define ADDR_PTR 0
#define BUFFER_SIZE 4
#define PACKET_SIZE 3
byte data[6] = {1, 2, 3, 4, 5, 6};
byte dataRead[6];

EEProm myeepRom(10, 10, 6);

void setup()
{
Serial.begin(9600);
//populateEEP();
//myeepRom.populateStatus();

Serial.println("Done");
// myeepRom.printStatusBuf();
// byte ptr = myeepRom._getStatusPtr();
// Serial.print(F("Status ptr: ")); Serial.println(ptr);


}

void loop()
{
myeepRom.printStatusBuf();
byte ptr = myeepRom._getStatusPtr();
Serial.print(F("Status ptr: ")); Serial.println(ptr);
populateData();
myeepRom.savePacket(data);
myeepRom.printStatusBuf();
myeepRom.readPacket(dataRead);
Serial.println(F("------------------------"));
delay(5000);
}

void populateData()
{
Serial.println(F("Generated Data"));
for(byte i =0; i<6;i++)
{
data[i] = random(1,100);
Serial.print(data[i]);Serial.print(" ");
}
Serial.println();
}

void populateEEP()
{
// int currentAdd = STATUS_BUF_START_ADD;
// int firstVal = STATUS_BUF_START_ADD+16;
// EEPROM.put(currentAdd, firstVal);
// EEPROM.put(currentAdd+2, firstVal+1*PARAM_PACKET_SIZE);
// EEPROM.put(currentAdd+4, firstVal+2*PARAM_PACKET_SIZE);
// EEPROM.put(currentAdd+6, firstVal+3*PARAM_PACKET_SIZE);
// EEPROM.put(currentAdd+8, firstVal+4*PARAM_PACKET_SIZE);
//
for (byte i = 0; i < 200; i++)
{
EEPROM.write(i, 0);
}
}
27 changes: 27 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#######################################
#Each line has the name of the keyword, followed by a tab (not spaces)
#######################################

#######################################
# Classes should be KEYWORD1 and are colored orange; functions should be KEYWORD2 and will be brown.
#######################################

#######################################
# Syntax Coloring Map For RingEEPROM
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################



#######################################
# Methods and Functions (KEYWORD2)
#######################################



#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=RingEEPROM
version=0.1.0
author=Shuvangkar Shuvo
maintainer=Shuvangkar Shuvo <[email protected]>
sentence=The library increases the arduino EEPROM Write endurance
paragraph=Arduino Uno/Mega EEPROM wears out after 100k write/erase cycle. So this library will increase the write cycles.
category=Data Storage
url=https://github.com/shuvangkar/RingEEPROM.git
architectures=avr
27 changes: 27 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Hign Endurance EEEPROM
In many situation we need to write the EEPROM memory frequently. Think about an Energy meter application. The energy parameter needs to update frequently in EEPROM to persist the value for a long time.
Let's Think about a situation.
I need to write energy value in eeprom after 10s interval.
- total number of writes for one day would be 8640.
- one month 259.2K

Atmel AVR microcontroller such as atmega328 ensures EEPROM data reliability upto 100k write/erase cycle. Oops!! That means we will cross that limit after 11 days. That is very sad.

One more thing we need to clarify that 100k write/erase cycle for each cell, not for a whole EEPROM memory segment. Here is the point we are going to play with.

# RingEEPROM Arduino Library

![Arduino EEPROM Endurance, EEPROM Ring buffer](/resources/parallel_o_buffer.png "Parallel O Buffer | Source: AVR101: High Endurance EEPROM Storage")

For solving the eeprom wear out problem, I have developed an Arduino library [RingEEPROM]().

The idea is simple. As I cannot write/erase each cell more than 100k times, I will store my value in different cells in each write cycle. So let's consider our buffer size i 8. I am planning to write a byte in EEPROM. As I am using 8 cells for a single byte. Now I get 8*100k = 800k write cycles. That's huge. The bigger buffer size is, the more I get write cycles.




For more information please go through the Microchip [application note](http://ww1.microchip.com/downloads/en/appnotes/doc2526.pdf)

License
----
MIT
Binary file added resources/parallel_o_buffer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions src/eep.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include "eep.h"
#include <EEPROM.h>


//#define EEP_DEBUG
#ifdef EEP_DEBUG
#define debugEep(...) Serial.print(__VA_ARGS__)
#define debugEepln(...) Serial.println(__VA_ARGS__)
#else
#define debugEep(...) __VA_ARGS__
#define debugEepln(...) __VA_ARGS__
#endif


EEProm::EEProm(int addrPtr, byte bufSz, byte paramSize)
{
_initAddr = addrPtr;
_bufSz = bufSz;
_paramPacketSz = paramSize;
//_clrStatusBuf();
}

void EEProm::_clrStatusBuf()
{

for (byte i = 0; i < _bufSz; i++) {
EEPROM.write(_initAddr + i, 0);
}
debugEepln(F("Status Buf Cleared"));
//Extra protection is needed here. after setting zero read and check
// whether all values are zero.
}
byte EEProm::_getStatusPtr()
{
byte ptr;
byte i = 0;
do
{
ptr = EEPROM.read( _initAddr + i);
//debugEepln(i);
} while (++i && ptr && i <= _bufSz);
return i;
}

void EEProm::savePacket(byte *dataBuf)
{
byte statusPtr = _getStatusPtr();
if (statusPtr > _bufSz)
{
debugEepln(F("<<<<<<<<<Buf Full>>>>>"));
_clrStatusBuf();
statusPtr = 1;
}
byte index = statusPtr - 1;
int paramInitAddr = _initAddr + _bufSz;
int paramPtr = paramInitAddr + (index * _paramPacketSz);
debugEep(F("Data Save Addr: ")); debugEepln(paramPtr);
for (byte i = 0; i < _paramPacketSz; i++)
{
int addr = paramPtr + i;
EEPROM.write(addr, dataBuf[i]);
}
EEPROM.write(_initAddr + index, statusPtr); // update status pointer
}

void EEProm::readPacket(byte *dataBuf)
{
byte statusPtr = _getStatusPtr();
byte index = statusPtr - 2;
int paramInitAddr = _initAddr + _bufSz;
int paramPtr = paramInitAddr + (index * _paramPacketSz);
debugEep(F("Data Read Addr: ")); debugEepln(paramPtr);
//byte value;
for(byte i =0 ; i<_paramPacketSz; i++)
{
dataBuf[i] = EEPROM.read(paramPtr+i);
//Serial.print(dataBuf[i]);Serial.print(" ");
}
//Serial.println();
}
void EEProm::printStatusBuf()
{
byte value;
for (byte i = 0; i < _bufSz; i++)
{
value = EEPROM.read( _initAddr + i);
Serial.print(value); Serial.print(" ");
}
Serial.println();
}
void EEProm::printArray(byte *data, byte len)
{
for (byte i = 0; i < len; i++)
{
debugEep(data[i]); debugEep(" ");
}
debugEepln();
}

void EEProm::populateStatus()
{

for (byte i = 0; i < _bufSz - 3; i++)
{
EEPROM.write(_initAddr + i, i + 1);
}
}

25 changes: 25 additions & 0 deletions src/eep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _H_EEP_H_
#define _H_EEP_H_
#include <Arduino.h>

class EEProm
{
public:
EEProm(int addrPtr, byte bufSz, byte paramSize);
void determineAddr();
void savePacket(byte *dataBuf);
void readPacket(byte *dataBuf);
void printStatusBuf();
void printArray(byte *data, byte len);
void populateStatus();
byte _getStatusPtr();
void _clrStatusBuf();
private:

int _initAddr;
byte _bufSz;
byte _paramPacketSz;

};

#endif

0 comments on commit e094b06

Please sign in to comment.