I tried to register a function to do this on demand with the code below but it causes the particle to go unresponsive until a manual reboot. Is this even possible?
int eraseEEPROM(String command)
{
for (int i = 0; i < EEPROM.length(); i++)
{
EEPROM.write(i, 0);
}
Particle.publish("ResetComplete", "ResetCompleted", 60, PRIVATE);
return 1;
}
Actually if you want to reset EEPROM you’d fill it with 0xFF not 0x00.
If you want to erase portions of EEPROM you’d rather have a uint8_t array of approprate size, fill that via memset(arr, 0xFF, sizeof(arr)) and use Particle.put() to store that in EEPROM.
But as @RWB already mentioned there is a well documented function that allows you to erase the entire EEPROM space
@ScruffR
If I did wanted to fill every location with a 0x00 is there any reason why this code doesn’t work? It seems like its filling in those locations but it never gets to that Particle.publish.
int eraseEEPROM(String command)
{
for (int i = 0; i < EEPROM.length(); i++)
{
EEPROM.write(i, 0);
}
Particle.publish("ResetComplete", "ResetCompleted", 60, PRIVATE);
return 1;
}
The code does probably work but will take a very long time as it will require a lot of wear leveling effort and potentially cause multiple page erase cycles which will not just take extra time but also cause unnecessary flash wear.
And since that may take even so long that the cloud connection gets temporarily dropped (as it is not serviced during the time) your Particle.publish() may be failing due to lack of connection.
When you want to debug a certain issue you must make sure that you are not relying on data which in itself may be skewed by other factors and hence lead you to wrong conclusions Particle.publish() is never a good way to debug your code. Serial.print() is better but still not perfect for time critical debugging. For that I’d use digitalWrite() (e.g. on the onboard LED).
However, why would you want to write zeros to EEPROM when this inevitably means the next time you want to write to the same address you need another erase cycle before you can even start writing data?
And if you still wanted, you’d not do it on a byte by byte basis.
What I’m trying to do is evenly wear the EEPROM by incrementing the location on every write but also have the ability to reset EEPROM. Thoughts?
unsigned long count;
int index;
#define lastIndex EEPROM.length() - sizeof(count)
boolean freshStart = true;
//boolean freshStart = false;
void setup() {
Serial.begin(115200);
if (freshStart)
clearEeprom();
//find last count and index in Eeprom with checkEeprom()function
Serial.print("Checking for last stored count = ");
index = checkEeprom();
Serial.println(EEPROM.get(index, count));
Serial.print("Located at EEPROM index = ");
Serial.println(index);
}
void loop() {
//emulate machine cycle incrementing count and index
static boolean machineCycleComplete = false;
static unsigned long lastMachineComplete = 0;
if (millis() - lastMachineComplete >= 2000)
{
machineCycleComplete = true;
lastMachineComplete = millis();
}
//values to incremented by machine cycle
if (machineCycleComplete == true)
{
machineCycleComplete = false;
count += 2;
index += sizeof(count);//increment address by 4 with long
if (index > lastIndex)
index = 0;
EEPROM.put(index, count);
Serial.print("index = ");
Serial.print(index);
Serial.print(" count = ");
Serial.println(count);
machineCycleComplete = false;
}
}
void clearEeprom()
{
Serial.println("Clear Eeprom Cells");
for (int i = 0; i < EEPROM.length(); i++)
{
EEPROM.write(i, 0);
}
Serial.println("All eeprom cells set to zero.");
Serial.println("Initialize freshStart to false and reload program");
while (1);//stop program
}
int checkEeprom()
{
static unsigned long lastValue = 0;
static unsigned long value = 0;
for (int i = 0; i <= lastIndex; i += sizeof(count))
{
lastValue = value;
EEPROM.get(i, value);
if (value < lastValue)//next value is not larger than last
{
return (i - sizeof(count));//last valid index
}
if (i == lastIndex)//no smaller value found or values all equal as zeros
{
return i;
}
}
}
@oraclerouter, the whole point of wear leveling is to automatically change the location of the writes! The DeviceOS already implements wear leveling in the emulated EEPROM. You are actually making it worse by using your approach. In addition, “resetting” the EEPROM won’t really help either. Take a look at the EEPROM hasPendingErase() function to understand the automatic page erasing that occurs due to wear leveling. Also, I’m sure you seen the clear() function for “erasing” the entire EEPROM to 0xFF.
Ideally, you organize your data in one or more structures that you put() and get from EEPROM. Then, you only need to clear the data in the structure(s) (to whatever default values you want) and put() it to EEPROM instead of erasing the entire EEPROM. Let the DeviceOS worry about wear leveling and clearing data pages and focus on just writing and reading data!
@oraclerouter, the locations are “virtual” since wear leveling is deciding where the data actually goes so yes, you can write to the same “location”.