{"id":20284946,"url":"https://github.com/chayanforyou/wearleveling","last_synced_at":"2025-04-11T08:38:58.688Z","repository":{"id":37849353,"uuid":"96386807","full_name":"chayanforyou/WearLeveling","owner":"chayanforyou","description":"This Wear Leveling library is for Microcontroller EEPROM to increase its life cycle","archived":false,"fork":false,"pushed_at":"2025-03-27T13:36:54.000Z","size":31,"stargazers_count":27,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-27T14:35:32.780Z","etag":null,"topics":["arduino","avr","eeprom","library","microcontroller","wearlevel"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chayanforyou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-06T04:00:15.000Z","updated_at":"2025-03-27T13:36:57.000Z","dependencies_parsed_at":"2025-03-27T14:40:47.604Z","dependency_job_id":null,"html_url":"https://github.com/chayanforyou/WearLeveling","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chayanforyou%2FWearLeveling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chayanforyou%2FWearLeveling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chayanforyou%2FWearLeveling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chayanforyou%2FWearLeveling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chayanforyou","download_url":"https://codeload.github.com/chayanforyou/WearLeveling/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248362182,"owners_count":21091065,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","avr","eeprom","library","microcontroller","wearlevel"],"created_at":"2024-11-14T14:23:08.328Z","updated_at":"2025-04-11T08:38:58.655Z","avatar_url":"https://github.com/chayanforyou.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WearLeveling\n\nThe technique I am useing is to prefix the data with a 4-byte rolling sequence number where the largest number represents the lastest / current value.\nIn the case of storing 2 bytes of actual data that would give 6 (4-for sequence \u0026 2-for data) bytes total and then I form into a circular queue arrangement so for 1024 bytes of EEPROM (if your EEPROM size is small or max you have to change the value from library file) it would contain 170 entries and increase endurance 170 times if you use one Segment.\n\nThen when booting the largest sequence number can be used to determine both the next sequence number to be used and the current tail of the queue.\nThe following C-code demonstrates, this assumes that upon initial programming the EEPROM area has been erased to values of 0xFF so I ignore a sequence number of 0xFFFFFFFF (as 4-byte sequence no):\n\n\nBy default the `MAX_EEPROM_SEGMENTS` define is set to 2 this means you have two segments available, 0 or 1.\nThis allows you to define an area of EEPROM for one structure and a secondary area of EEPROM for another.\nIf you need more segments you have to change it.\n\n## How it works:\n\n![](https://github.com/user-attachments/assets/6f8c3c7d-0bb1-457e-8718-5b965cd19dcd)\n\nThe image illustrates a data storage optimization technique designed for EEPROM usage. This method involves:\n\n- Prefixing each data entry with a 4-byte rolling sequence number.\n- The highest sequence number represents the most recent or current value.\n- Each entry in memory includes:\n  - `4 bytes` for the sequence/step number (shown in yellow),\n  - `2 bytes` for the actual data (shown in green),\n  - Totaling `6 bytes` per entry.\n\nIn the visual:\n\n- Memory is organized sequentially with each block marked by a 4-byte step followed by 2-byte data.\n- Arrows show the flow of sequence numbers: `01`, `02`, `03`, etc.\n- `FF FF FF FF FF FF` marks unused or erased EEPROM space.\n\nThis structure is used in a circular queue format. For example, in a 1024-byte EEPROM:\n\n- With each entry using 6 bytes, you can store up to `170 entries` (`1024 / 6 ≈ 170`).\n- Once the EEPROM is full, it wraps around and overwrites the oldest entries.\n\n\n![](https://github.com/user-attachments/assets/48115dd2-dae1-41c3-b67c-da3fd96af804)\n\nThis screenshot shows a real EEPROM memory dump using an EEPROM viewer tool (Proteus debugger). It beautifully demonstrates how data is stored using the rolling sequence number technique.\n\nKey Observations:\n\n- The highlighted section shows three entries\n- Each entry is 6 bytes (4 for the step, 2 for data), as per the technique.\n- All other memory locations are still filled with `FF`, meaning they are unwritten/erased.\n- This clearly shows that only 3 writes have occurred so far in this segment.\n- The viewer also shows an ASCII representation on the right (which is mostly dots since these values don’t correspond to readable characters).\n\n## How to use:\n\nI designed this library to address a couple of issues when using EEPROM for data storage:\n\nData corruption is one of this big issues with EEPROM.  From what I've read, the most common reason is a power issue where power drops out and/or brown out detection is not properly configured.\nThe big problem with data corruption is that when the data is read back from the EEPROM, it may be corrupt and the uC will use corrupt data with can lead to all sorts of problems.\nThe second issue is that the EEPROM design limit of 100,000 write cycles. If you are trying to save values periodically, this will be a concern if you are writing the data to the same spot of EEPROM each time.\nThe Library solves both of these problems by using these techniques:\n\n\n## It does all this with three functions:\n```c\nEEPROMwl.begin(const uint8_t amountOfIndexes);\n// or\nEEPROMwl.begin(const uint8_t amountOfIndexes, const uint16_t eepromLengthToUse);\nEEPROMwl.read(const uint8_t idx)\nEEPROMwl.write(const uint8_t idx, const uint16_t value);\nEEPROMwl.update(const uint8_t idx, const uint16_t value);\n```\nThe first IMPORTANT thing I want to mention is the ORDER these commands must be used.\n\nYou must call `EEPROMwl.begin()` first. After that you can call `EEPROMwl.read()` \u0026 `EEPROMwl.write()` as many times as you like.\nThe reason for this order is that Save requires variables that Load set to work properly.\nThis shouldn't be a problem because the general flow of usage for these commands should follow this order:\n\n### Arduino example:\n```c\n#include \u003cEEPROMWearLevel.h\u003e\n\n#define AMOUNT_OF_INDEXES 2\n\n#define INDEX_VAL1 0\n#define INDEX_VAL2 1\n\nvoid setup() {\n  Serial.begin(9600);\n  while (!Serial);\n\n  EEPROMwl.begin(AMOUNT_OF_INDEXES);\n\n  writeConfiguration();\n  readConfiguration();\n}\n\nvoid loop() {\n}\n\nvoid writeConfiguration() {\n  // write value\n  EEPROMwl.write(INDEX_VAL1, 123);\n  EEPROMwl.write(INDEX_VAL2, 32768);\n}\n\nvoid readConfiguration() {\n  // read value\n  Serial.print(F(\"INDEX 1: \"));\n  Serial.println(EEPROMwl.read(INDEX_VAL1));\n\n  Serial.print(F(\"INDEX 2: \"));\n  Serial.println(EEPROMwl.read(INDEX_VAL2));\n}\n```\nMake sure you don't just call `EEPROMwl.write()` to save the `same data` as this is wasteful on EEPROM design life.\nKeep a flag that indicates when the data has changed and also a flag indicating how long it has been since that last save.\nOnly save if the data has changed AND it has been a long enough period of time.\n\n## Special thanks ##\nTo [Antor Ahmed](https://github.com/AntorOfficial)\n\n## Contributions ##\nEnhancements and improvements are welcome.\n\n## License ##\n```\nArduino EEPROMWearLevel Library\nCopyright (c) 2020 Chayan Mistry (https://github.com/chayanforyou).\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchayanforyou%2Fwearleveling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchayanforyou%2Fwearleveling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchayanforyou%2Fwearleveling/lists"}