MEMORY ISSUES

Forum for posting topics and questions about anything.
Post Reply
RetroBoy
Posts: 73
Joined: Sat Feb 26, 2022 11:29 am
Location: U.K.

MEMORY ISSUES

Post by RetroBoy » Thu Jun 16, 2022 8:18 pm

Hi All,

I have an issue with a 'LOOKUP TABLE' and any assistance would help.

I need to display 'SUNRISE/SUNSET' Times in part of my latest project. My PROBLEM is the SUNRISE/SUNSET DATA is 366 values in Seconds from Midnight. At the last check, in total, the 'DATA ONLY' amounts to 2,928 bytes ( 2 Tables x 366 values x 4bytes ). It's great that with just the DAY NUMBER a simple Lookup is all that's required, unfortunately need to use 'long' as MANY values are greater than 65536. ( See DATA below ). When compiled I get zero errors and the NANO is loaded OK, UNFORTUNATELY, it will not RUN ... won't even display an Initializing Screen, DATA commented out it works perfectly. So the real question is ... How can I overcome this issue - is there such a thing as EXTERNAL LOOKUP TABLE nad if so HOW do I create it ( FOO.h ?) ?

If I get rid of the Lookup Data and use a Formula and GPS LAT/LNG to convert the DAY Number to SUNRISE/SUNSET Times takes so long the actual process takes almost 2 seconds per lookup.
Here is example of 2 of the Formulae that are needed if NO Lookup Table:-

DECLINATION=0.006918-0.399912COS(GAMMA)+0.070257SIN(GAMMA)-0.006758COS(2GAMMA)+0.000907SIN(2GAMMA)-0.002697COS(3GAMMA)+0.00148SIN(3GAMMA)

HOUR_ANGLE=ARCCOS((( COS(90.833)/COS(LATITUDE)COS(DECLINATION) )-TAN(LATITUDE)TAN(DECLINATION)))

Any Help Very, very appreciated.

/* --- SUNRISE AND SUNSET DATA IN SECONDS FROM MIDNIGHT ( Min 00000 Max 86399 ) ---
long SUNRISE_SEC[] =
{29806,29796,29783,29766,29746,29722,29695,29665,29631,29594,29554,29511,29464,29415,29362,
29307,29248,29187,29122,29055,28986,28913,28838,28761,28681,28598,28514,28426,28337,28246,
28152,28056,27958,27859,27757,27653,27548,27441,27332,27222,27110,26996,26881,26765,26647,
26528,26407,26286,26163,26038,25913,25787,25659,25531,25402,25271,25140,25008,24876,24742,
24608,24473,24337,24201,24064,23927,23789,23650,23511,23372,23232,23092,22952,22811,22670,
22529,22388,22246,22105,21963,21821,21679,21537,21395,21253,24711,24569,24428,24286,24145,
24004,23863,23723,23582,23442,23303,23164,23025,22887,22749,22612,22476,22340,22204,22070,
21936,21803,21670,21539,21408,21278,21149,21022,20895,20769,20644,20521,20398,20277,20157,
20039,19922,19806,19692,19579,19468,19358,19250,19144,19040,18937,18836,18738,18641,18546,
18453,18363,18274,18188,18104,18023,17944,17867,17793,17722,17653,17587,17523,17463,17405,
17350,17298,17249,17203,17160,17120,17083,17049,17019,16992,16967,16947,16929,16915,16904,
16896,16892,16891,16893,16898,16907,16919,16934,16952,16973,16998,17025,17056,17090,17126,
17166,17208,17253,17301,17351,17404,17459,17517,17577,17640,17705,17772,17841,17912,17985,
18059,18136,18214,18294,18375,18458,18542,18628,18714,18802,18891,18981,19072,19164,19257,
19351,19445,19541,19636,19733,19830,19927,20025,20123,20222,20321,20420,20520,20619,20719,
20820,20920,21020,21121,21221,21322,21423,21524,21624,21725,21826,21927,22027,22128,22229,
22329,22430,22530,22631,22731,22832,22932,23032,23133,23233,23333,23433,23534,23634,23734,
23834,23935,24035,24135,24236,24336,24437,24538,24638,24739,24840,24941,25043,25144,25246,
25348,25450,25552,25655,25757,25860,25963,26067,26170,26274,26379,26483,26588,26693,26798,
26904,27010,27116,27223,27330,27437,27544,27652,27760,27868,27977,28086,28195,28304,28413,
28523,28632,25142,25252,25362,25472,25582,25692,25802,25912,26022,26131,26240,26349,26458,
26566,26674,26781,26887,26993,27099,27203,27307,27409,27511,27611,27711,27809,27906,28001,
28095,28187,28278,28367,28454,28539,28622,28703,28781,28858,28932,29003,29072,29139,29202,
29263,29321,29376,29428,29477,29523,29566,29605,29641,29674,29704,29730,29752,29771,29787,
29799,29808,29813,29815,29813,29809}; // That's all 366 ( Incl Leap Year ) SUNRISE times

long SUNSET_SEC[] =
{57973,58039,58108,58179,58253,58329,58408,58490,58573,58659,58747,58837,58928,59022,59117,
59214,59313,59413,59514,59617,59721,59826,59932,60039,60147,60255,60365,60475,60586,60697,
60809,60922,61034,61147,61261,61374,61488,61602,61716,61830,61944,62059,62173,62287,62401,
62514,62628,62742,62855,62968,63081,63194,63306,63419,63531,63642,63754,63865,63976,64087,
64197,64307,64417,64526,64636,64745,64854,64962,65070,65178,65286,65394,65501,65608,65716,
65822,65929,66036,66142,66248,66354,66460,66566,66672,66778,70483,70589,70694,70800,70905,
71010,71116,71221,71326,71432,71537,71642,71748,71853,71959,72064,72169,72275,72380,72485,
72591,72696,72802,72907,73012,73118,73223,73328,73433,73538,73643,73747,73852,73956,74060,
74164,74268,74371,74473,74576,74678,74779,74880,74981,75080,75179,75278,75375,75472,75568,
75663,75757,75849,75941,76031,76120,76208,76295,76379,76463,76544,76624,76702,76779,76853,
76925,76995,77063,77129,77192,77253,77312,77368,77421,77472,77520,77565,77607,77646,77682,
77716,77746,77773,77797,77818,77835,77850,77861,77868,77873,77874,77871,77866,77857,77845,
77829,77810,77788,77762,77734,77702,77667,77628,77587,77542,77495,77444,77390,77334,77274,
77212,77147,77079,77009,76936,76860,76782,76702,76619,76533,76446,76356,76264,76170,76073,
75975,75875,75773,75669,75563,75455,75346,75235,75123,75008,74893,74776,74657,74538,74416,
74294,74170,74046,73920,73793,73665,73535,73405,73274,73142,73010,72876,72742,72606,72471,
72334,72197,72059,71921,71782,71642,71502,71362,71221,71080,70939,70797,70655,70512,70370,
70227,70084,69941,69797,69654,69511,69367,69224,69081,68937,68794,68651,68508,68365,68223,
68080,67938,67796,67655,67514,67373,67233,67093,66954,66815,66677,66539,66402,66266,66130,
65995,65861,65727,65595,65463,65332,65202,65073,64945,64819,64693,64568,64445,64323,64202,
64082,63964,60247,60132,60018,59906,59795,59687,59579,59474,59370,59268,59169,59071,58975,
58881,58790,58701,58614,58529,58447,58367,58289,58215,58143,58073,58006,57943,57882,57823,
57768,57716,57667,57621,57579,57539,57503,57470,57441,57414,57392,57372,57357,57344,57336,
57330,57329,57331,57336,57345,57358,57374,57394,57417,57444,57474,57508,57545,57585,57629,
57676,57726,57779,57836,57895,57940}; // That's all 366 ( Incl Leap Year ) SUNSET times

*/

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: MEMORY ISSUES

Post by andrew » Mon Jun 20, 2022 9:13 am

. When compiled I get zero errors and the NANO is loaded OK, UNFORTUNATELY, it will not RUN ... won't even display an Initializing Screen, DATA commented out it works perfectly.
TBH I’m surprised it actually compiled and didn’t just give an out or memory error.

You should be able to get around the problem by storing your tables in FLASH memory where your sketch is stored rather than SRAM as you have much more FLASH memory compared to SRAM.

As your tables contain data that doesn’t change you should first declare your tables as constants using the ‘const’ keyworks like this…

  1. const long SUNRISE_SEC[] = {29806,29796……
  2. const long SUNSET_SEC[] = {57973,58039…..

However the ATMega328p on your Nano has a Harvard architecture meaning that programs and data are stored in two completely different places so you need to add an additional keyword called ‘PROGMEM’ to tell the compiler to store the table in flash rather than SRAM like this…

  1. const PROGMEM long SUNRISE_SEC[] = {29806,29796……
  2. const PROGMEM long SUNSET_SEC[] = {57973,58039…..

Because the tables are now in FLASH there will be a few extra steps you’ll need to do to access them. For example if the table was in SRAM you could simply do this to print the second value in the sunrise table:

  1. Serial.println(SUNRISE_SEC[1]);

But to access it from FLASH you’ll need to access them by using the pgm_read_dword() function like this:

  1. Serial.println(pgm_read_dword(&SUNRISE_SEC[1]));

The function requires the memory location of the value you wish to read so note the & at the beginning of the array which means ‘pass the memory location of the value in the array’ instead of the value itself. The function will then return the value stored at that FLASH location as an unsigned integer.

There is one final step you’ll need to do - as previously stated the pgm_read_dword() function will return the value as an ‘unsigned long’, whereas your values are or type ‘signed long’. As they don’t need to be signed you can either declare them as unsigned like this…

  1. const PROGMEM unsigned long SUNRISE_SEC[] = {29806,29796……
  2. const PROGMEM unsigned long SUNSET_SEC[] = {57973,58039…..

… or cast the output from the pgm_read_dword() function to a signed value like this:

  1. Serial.println((long)pgm_read_dword(&SUNRISE_SEC[1]));

For your table I would suggest doing the former.
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

Post Reply

Return to “General Discussion”