I’m working on a project with the Artemis ATP. Its job is to turn a DC motor in a specific direction based on a schedule it receives via BLE and saves to its memory via emulated EEPROM.
I don’t know why, but when the device is left alone and powered on for somewhere between 5 and 15 minutes, the EEPROM memory resets to 0xFF and I’m not sure why. Below are the relevant sections of EEPROM in terms of DEFINES, variables and functions called in order.
#define BLE_DATA_LENGTH 505
#define BLE_DATA_BUFFER 505
#define LASTSTATEADDRESS 540
#define REFERENCEDAY_01 541
#define REFERENCEDAY_02 542
#define LASTJULIANDATE_01 545
#define LASTJULIANDATE_02 546
#define LASTOPRHOUR 547
void getSchedule(BLEDevice central, BLECharacteristic characteristic);
void setup() {
scheduleGet.setEventHandler(BLEWritten, getSchedule);
EEPROM.init();
EEPROM.setLength(1024 * 1);
initialize();
}
void loop() {
// put your main code here, to run repeatedly:
BLEDevice central = BLE.central();
DateTime now = rtc.now();
unsigned int Minute = now.minute();
unsigned int Second = now.second();
unsigned int currentHour = now.hour();
unsigned int slotCheck = scheduleSlotGet();
if(CheckHour != Hour)
{
CheckHour = now.hour();
setLastDateHour();
}
if(CheckMinute != Minute)
{
CheckMinute = now.minute();
updateTime();
batScanner();
}
switch(numberOfWeeks)
{
case(1):
{
if((Minute == 0 || Minute == 30) && (Second <= 5))
{
updateDoorPosition(slotCheck);
}
break;
}
case(2):
{
if((Minute == 0) && (Second <= 5))
{
updateDoorPosition(slotCheck);
}
break;
}
case(3):
{
if((Minute == 0) && (Second <= 5))
{
updateDoorPosition(slotCheck);
}
break;
}
case(4):
{
if((currentHour % 2 == 0) &&(Minute == 0) && (Second <= 5))
{
updateDoorPosition(slotCheck);
}
break;
}
case(5):
{
if((currentHour % 2 == 0) && (Minute == 0) && (Second <= 5))
{
updateDoorPosition(slotCheck);
}
break;
}
default:
numberOfWeeks = 1;
break;
}
}
void initialize()
{
initializeSchedule();
delay(5);
checkLastDateHour();
delay(5);
initializeDCPosition();
}
void initializeSchedule()
{
char scheduleChar[505];
scheduleChar[0] = EEPROM.read(0);
if(scheduleChar[0] == 0xFF)
{
numberOfWeeks = 1;
scheduleChar[0] = char(numberOfWeeks);
}
else
{
numberOfWeeks = (int)scheduleChar[0];
}
for(int i=1; i < 505 ; i++)
{
scheduleChar[i]=EEPROM.read(i);
weeklySchedule[i-1] = scheduleChar[i];
if(weeklySchedule[i-1] != '0' && weeklySchedule[i-1] != '1')
{
weeklySchedule[i-1] = '1';
scheduleChar[i] = weeklySchedule[i-1];
}
else
{
delay(10);
}
}
scheduleGet.writeValue(scheduleChar);
}
void checkLastDateHour()
{
DateTime now = rtc.now();
unsigned int currentJulianDate = getDayOfYear(now.year(), now.month(), now.day());
byte currentOperationalHour = now.hour();
byte LastSavedJulianDate_01 = EEPROM.read(LASTJULIANDATE_01);
byte LastSavedJulianDate_02 = EEPROM.read(LASTJULIANDATE_02);
byte LastSavedOperationalHour = EEPROM.read(LASTOPRHOUR);
unsigned int lastJulianDate = ((unsigned int)LastSavedJulianDate_01 << 8) +((unsigned int)(LastSavedJulianDate_02));
if(currentJulianDate == lastJulianDate && (currentOperationalHour - LastSavedOperationalHour) < 2)
{
getReferenceDay();
}
else
{
updateReferenceDay();
}
setLastDateHour();
}
void setLastDateHour()
{
DateTime now = rtc.now();
byte LastSavedJulianDate_01 = 0;
byte LastSavedJulianDate_02 = 0;
byte LastSavedOperationalHour = now.hour();
unsigned int currentJulianDate = getDayOfYear(now.year(), now.month(), now.day());
LastSavedJulianDate_01 = (currentJulianDate >> 8);
LastSavedJulianDate_02 = (currentJulianDate);
EEPROM.write(LASTJULIANDATE_01, LastSavedJulianDate_01);
EEPROM.write(LASTJULIANDATE_02, LastSavedJulianDate_02);
EEPROM.write(LASTOPRHOUR, LastSavedOperationalHour);
JulianDate.writeValue(referenceDay);
}
void getReferenceDay()
{
byte referenceDayByte1 = EEPROM.read(541);
byte referenceDayByte2 = EEPROM.read(542);
referenceDay = (referenceDayByte1 << 8) + referenceDayByte2;
JulianDate.writeValue(referenceDay);
}
void updateReferenceDay()
{
byte referenceDayByte1 = 0;
byte referenceDayByte2 = 0;
DateTime now = rtc.now();
unsigned int dayOfWeek = now.dayOfTheWeek();
unsigned int dayOfYear = getDayOfYear(now.year(), now.month(), now.day());
referenceDay = dayOfYear - dayOfWeek;
referenceDayByte1 = (referenceDay >> 8);
referenceDayByte2 = (referenceDay);
EEPROM.write(541, referenceDayByte1);
EEPROM.write(542, referenceDayByte2);
JulianDate.writeValue(referenceDay);
}
void initializeDCPosition()
{
unsigned int ScheduleSlot;
bool CheckState;
bool CurrentState;
ScheduleSlot = scheduleSlotGet();
CheckState = doorControl(ScheduleSlot);
CurrentState = false;
if(CurrentState != CheckState)
{
openDC();
DoorOpened = true;
DoorClosed = false;
}
EEPROM.write(LASTSTATEADDRESS, CheckState);
cageState.writeValue(CheckState);
}
void getSchedule(BLEDevice central, BLECharacteristic characteristic){
char scheduleChar[505];
int dataLength = scheduleGet.readValue(scheduleChar, 505);
numberOfWeeks = (int)scheduleChar[0];
EEPROM.write(0, scheduleChar[0]);
for(int i = 0; i < 504; i++)
{
weeklySchedule[i] = scheduleChar[i+1];
EEPROM.write((i+1),weeklySchedule[i]);
delay(5);
}
scheduleGet.writeValue(scheduleChar);
updateReferenceDay();
}
The problem shows up when initialize() calls initializeSchedule(), which should go into the EEPROM and retrieve the schedule last received when the scheduleGet characteristic was written to by another device. As soon as that characteristic is written to, the device collects the new schedule and writes it to the Artemis’ flash memory. If I turn off the device then and there and turn it back on, then check with nRF connect, the characteristic will have the right schedule. If I leave the device running for several minutes, I can check the characteristic again and find the schedule STILL there. However, if I then turn it off and on again, I will see a blank schedule as the memory reverted to all 0xFFs, and was then adjusted to all 1s by the initialize function.
What’s weird to me is that if I upload a new schedule, turn off the device and leave it for a while, this problem doesn’t occur.
This only happens if I leave the device on and unattended for several minutes. I’m still testing to see if leaving it connected to BLE affects this or not, but for now just assume a BLE connection isn’t relevant.
Does anyone know what might be happening?