All variables safe uploaded to the
EEPROM? - Good, than we can modify the main program to use the
variables from it. While compiling the sketch for the variable
upload, you might have noticed how memory consuming the whole thing
is. To deal with the heavy impact on RAM usage, we write the arrays
containing the addresses for the variables stored in the EEPROM in to
the program memory.
Lets start with bringing the address
declarations to the main program. In our room management sketch,
right under “Declaring the variables”, we start a new section and
name it “/////////////EEPROM storage//////////////”. Than we copy
all the variables / arrays, holding the eeprom addresses right under
the new section:
/////////////////////Declaring the Variables///////////////// /////////////EEPROM Storage////////////// int eepromValue = 0; const byte EEPROM_ID = 0x99; const int ID_ADDR = 0; const byte Sensitivity_ADDR = 1; //2 byte value const byte photoCellCutOff_ADDR = 3; //2 byte value const byte photoOutsideOff_ADDR = 5; //2 byte value const int startDelay_ADDR = 374; //1 byte value const int acSwitchDelay_ADDR = 375; //1 byte value const int ac_op_mode_ADDR = 376; //1 byte value const int ac_set_temp_ADDR = 377; //1 byte value const byte delayTime_ADDR[15] PROGMEM = {7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35}; const byte timer_active_ADDR[16][4] PROGMEM = { {37, 38, 39, 40}, {41, 42, 43, 44}, {45, 46, 47, 48}, {49, 50, 51, 52}, {53, 54, 55, 56}, {57, 58, 59, 60}, {61, 62, 63, 64}, {65, 66, 67, 68}, {69, 70, 71, 72}, {73, 74, 75, 76}, {77, 78, 79, 80}, {81, 82, 83, 84}, {85, 86, 87, 88}, {89, 90, 91, 92}, {93, 94, 95, 96}, {97, 98, 99, 100} }; const int room_timers_ADDR[16][4][4] PROGMEM = { { {102, 103, 104, 105}, {106, 107, 108, 109}, {110, 111, 112, 113}, {114, 115, 116, 117} }, { {118, 119, 120, 121}, {122, 123, 124, 125}, {126, 127, 128, 129}, {130, 131, 132, 133} }, { {134, 135, 136, 137}, {138, 139, 140, 141}, {142, 143, 144, 145}, {146, 147, 148, 149} }, { {150, 151, 152, 153}, {154, 155, 156, 157}, {158, 159, 160, 161}, {162, 163, 164, 165} }, { {166, 167, 168, 169}, {170, 171, 172, 173}, {174, 175, 176, 177}, {178, 179, 180, 181} }, { {182, 183, 184, 185}, {186, 187, 188, 189}, {190, 191, 192, 193}, {194, 195, 196, 197} }, { {198, 199, 200, 201}, {202, 203, 204, 205}, {206, 207, 208, 209}, {210, 211, 212, 213} }, { {214, 215, 216, 217}, {218, 219, 220, 221}, {222, 223, 224, 225}, {226, 227, 228, 229} }, { {230, 231, 232, 233}, {234, 235, 236, 237}, {238, 239, 240, 241}, {242, 243, 244, 245} }, { {246, 247, 248, 249}, {250, 251, 252, 253}, {254, 255, 256, 257}, {258, 259, 260, 261} }, { {262, 263, 264, 265}, {266, 267, 268, 269}, {270, 271, 272, 273}, {274, 275, 276, 277} }, { {278, 279, 280, 281}, {282, 283, 284, 285}, {286, 287, 288, 289}, {290, 291, 292, 293} }, { {294, 295, 296, 297}, {298, 299, 300, 301}, {302, 303, 304, 305}, {306, 307, 308, 309} }, { {310, 311, 312, 313}, {314, 315, 316, 317}, {318, 319, 320, 321}, {322, 323, 324, 325} }, { {326, 327, 328, 329}, {330, 331, 332, 333}, {334, 335, 336, 337}, {338, 339, 340, 341} }, { {342, 343, 344, 345}, {346, 347, 348, 349}, {350, 351, 352, 353}, {354, 355, 356, 357} } }; const int ac_forced_on_ADDR[4][2] PROGMEM = { {358, 359}, {360, 361}, {363, 363}, {364, 365} }; const int ac_periode_ADDR[4][2] PROGMEM = { {366, 367}, {368, 369}, {370, 371}, {372, 373} }; const int ac_master_bypass_ADDR[4] PROGMEM = {378, 379, 380, 381}; ///////////Timer and Sensitivity Settings to be changed to individual needs////////////////
You might have noticed right away that
I have changed something already. To store the addresses into the
program memory I added PROGMEM to the array declarations:
const byte delayTime_ADDR[15] = {7, 9,
becomes
const byte delayTime_ADDR[15] PROGMEM =
{7, 9,
and
const byte timer_active_ADDR[16][4] = {
becomes
const byte timer_active_ADDR[16][4]
PROGMEM = {
As simple is that to store a
multidimensional array into the program memory and keep the structure
of the originating array. We change all the arrays containing EEPROM
addresses like described on the two examples.
Now we have to move down in the
declaration part into the menu and user interface section. Right
above the last table being saved to the program memory before the
setup loop we add a new section “//////////////Error
handling/////////////”. And at the last table, where we have
already a couple of error messages we add a couple of things.
ac_sub_8, ac_sub_9 }; ////////////////Error Handling///////////// prog_char error_0[] PROGMEM = "RTC ERR"; prog_char error_1[] PROGMEM = "RTC Read ERR"; //>>>>>>>>>>>>>>ADDITION starts here<<<<<<<<<<<<< prog_char error_2[] PROGMEM = "EEPROM empty!"; prog_char error_3[] PROGMEM = "EEP write error"; //>>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<< PROGMEM const char *error_table[] = { error_0, error_1, //>>>>>>>>>>>>>ADDITION starts here<<<<<<<<<<<<< error_2, error_3 //>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<< }; void setup() { //////////////Start Serial for Debugging///////////////////// #ifdef DA_DEBUG_serial Serial.begin(9600); #endif lcd.begin(16, 2);
Now we move down to the setup loop and
add:
void setup() { //////////////Start Serial for Debugging///////////////////// #ifdef DA_DEBUG_serial Serial.begin(9600); #endif lcd.begin(16, 2); //>>>>>>>>>>>>>ADDITION starts here<<<<<<<<<<<<< lcd.clear(); eepromValue = Mem_readByte(ID_ADDR); //check if the eeprom holds valid data if(eepromValue != EEPROM_ID){ get_error(2, 0); //if not, display an error delay(5000); //load default var values //work with default variables declared //in the declaration section above } else{ //read the values from the eeprom sensitivity = Mem_readInt(Sensitivity_ADDR); //sensitivity photoCellCutOff = Mem_readInt(photoCellCutOff_ADDR); //photocell cut off value for rooms photoOutsideOff = Mem_readInt(photoOutsideOff_ADDR); //photocell cut off value for outside for(int i=0; i<15; i++){ //PIR and AC cut off delay times delayTime[i] = Mem_readInt(pgm_read_byte(&(delayTime_ADDR[i]))); } for(int x=0; x<16; x++){ //holiday lighting and ac timers active settings for(int y=0; y<4; y++){ timer_active[x][y] = Mem_readByte(pgm_read_byte(&(timer_active_ADDR[x][y]))); } } for(int x=0; x<16; x++){ //holiday lighting and ac timer settings for(int y=0; y<4; y++){ for(int z=0; z<4; z++){ room_timers[x][y][z] = Mem_readByte(pgm_read_byte(&(room_timers_ADDR[x][y][z]))); } } } for(int x=0; x<4; x++){ //ac forced on setting for(int y=0; y<2; y++){ ac_forced_on[x][y] = Mem_readByte(pgm_read_byte(&(ac_forced_on_ADDR[x][y]))); } } for(int x=0; x<4; x++){ //seasonal settings for ac use for(int y=0; y<2; y++){ ac_periode[x][y] = Mem_readByte(pgm_read_byte(&(ac_periode_ADDR[x][y]))); } } startDelay = Mem_readByte(startDelay_ADDR); //ac start delay (compressor protection acSwitchDelay = Mem_readByte(acSwitchDelay_ADDR); //ac switch time for op mode 3 ac_op_mode = Mem_readByte(ac_op_mode_ADDR); //ac mode ac_set_temp = Mem_readByte(ac_set_temp_ADDR); //ac temperature setting for(int i=0; i<4; i++){ //ac master bypass ac_master_bypass[i] = Mem_readByte(pgm_read_byte(&(ac_master_bypass_ADDR[i]))); } } //>>>>>>>>>>>>>ADDITION ends here<<<<<<<<<<<<< //printing initialisation message lcd.clear(); lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[4])))); delay(1000); lcd.setCursor(0, 1); lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[3])))); delay(2000); //////////////////defining pin modes//////////////////// pinMode(doorMonitor, OUTPUT); //setting the LED pin to output
If you remember from the last post the
system to write the values to the eeprom having the same array
structure for the values and the address.
To get the right value from the eeprom,
we only need to take the corresponding address array with the
corresponding counter values and we read back the values. Looking at
the delayTime() array, we take the first counter setting of our for
loop which would be delayTime[0] and if we look it up from the
default declaration part, the first value is 120. Now we overwrite
this value with the value we read from the eeprom.
for(int i=0; i<15; i++){ //PIR and AC cut off delay times delayTime[i] = Mem_readInt(pgm_read_byte(&(delayTime_ADDR[i]))); }
We call the function
Mem_readInt(address). Since we have stored all the addresses again in
the program memory, we need to retrieve them form there with
“pgm_read_byte(&(table_name or array_name)). We stored the
arrays in the program memory keeping the whole structure, so the
array name is just the same as we declared it and in this example
delayTime_ADDR[0], which gives us the address “7”. If we now go
back to the sketch we wrote to upload the eeprom values, and check
the values for delayTime_ADDR[0] and delayTime[0], we recall what
value the default delayTime[0] value will be overwritten with and
used by the program. In our case it is 300. It's not difficult. The
only thing you have to take care of is that the array counters for
the values match with the array counters of the address arrays.
To make it work, we copy the functions
we wrote in the upload sketch to the bottom of the Room Management
sketch, right on the end of everything.
No comments:
Post a Comment