/*
  Arduino EEPROM Reader - Created 2018
    by DonX Developer
  *** This code was created for an Arduino UNO using the Arduino IDE v1.8.4. ***

  Description:
    Read the Arduino on-board EEPROM and display its contents in the Serial monitor

    This has been tested on a UNO, MEGA and a Nano
*/

#include <EEPROM.h>
//create some test data if your EEPROM is currently empty
String testData = "Mr. and Mrs. Dursley, of number four, Privet Drive, were proud to say that they were perfectly normal, thank you very much. They were the last people you'd expect to be involved in anything strange or mysterious, because they just didn't hold with such nonsense.";
bool hex = true;

void setup() {
  Serial.begin(9600);

  //uncommenting this will add the test data to the EEPROM
  //if you want to investigate what is currently stored then leave this line commented
  //storeToEeprom();

  //get and display the EEPROMs contents
  getEepromData();
}

//nothing required in the loop
void loop() {
}


//get data from the EEPROM
void getEepromData()
{
  String currentLine = "";
  String currentHex = "";
  displayHeader(); //get and display the header information
  for (long i = 0; i < EEPROM.length(); i++)//read data from the EEPROM
  {
    if (i % 8 == 0)//display in rows of 8 bytes at a time
    {
      Serial.println(currentLine);//print current 8 bytes of text
      currentLine = "";//reset

      Serial.print(i);//display the memory location range for the current line
      Serial.print(" to ");
      Serial.print(i + 7);
      if (i < 20)
      {
        Serial.print("   ");//this just helps with the formatting in the monitor
      }
      Serial.print("\t");
    }
    byte currentByte = byte(EEPROM.read(i));//get the next byte of data
    if (!hex)
    {
      Serial.print(currentByte);//display decimal
    }
    else
    {
      currentHex = String(currentByte, HEX);//display hexidecimal
      Serial.print(currentHex);
    }
    if (currentByte == 255)//print a period if the value is 255
    {
      currentByte = 46;
    }
    currentLine += char(currentByte);//build up the current text line
    currentLine += " ";//makes it easire to read
    Serial.print("\t");
  }
  Serial.println(currentLine);
}

//display the header for the output
void displayHeader()
{
  int counter = 0;
  //get the count of characters that are already stored
  for (long i = 0; i < EEPROM.length(); i++)//read data from the EEPROM
  {
    byte currentByte = byte(EEPROM.read(i));
    if (currentByte != 255)
    {
      counter++;
    }
  }
  //display the header with dynamic details
  Serial.println("\t Disassembly of Arduino EEPROM. ");
  Serial.print("\t The EEPROM on this Arduino contains ");
  Serial.print(EEPROM.length());
  Serial.println(" bytes");
  Serial.print("\t Of which there are ");
  Serial.print(counter);
  Serial.println(" bytes of user data");
  Serial.println();
  //display colum description line
  Serial.print("Location\t\tDisassembly in ");
  if (hex)
  {
    Serial.print("Hexidecimal");
  }
  else
  {
    Serial.print("Decimal\t");
  }
  Serial.println("\t\t\t\tIn Text");
  //draw line
  for (int i = 0; i < 95; i++)
  {
    Serial.print("_");
  }
  Serial.println();
}


//store test data to the EEPROM
void storeToEeprom()
{
  for (int i = 0; i < testData.length(); i++)//loop through the test data contents anbd add it to the Arduino EEPROM
  {
    EEPROM.write(i, testData[i]);//one byte at a time
  }
}