eeprom_storeRetrieveCounters.ino 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. void storeCurrentReading(byte _cNum, boolean _force) {
  2. if (_cNum >= 0 && _cNum < COUNTERS_COUNT) {
  3. int _currentEEPROMValue;
  4. _currentEEPROMValue = (int)eeprom_read_word(&eeprom_addr_currentReading[_cNum]);
  5. if (_currentEEPROMValue != currentReading[_cNum] || _force) {
  6. //eeprom_write_word(&eeprom_addr_currentReading[cNum], currentReading[cNum]);
  7. EEPROM.put(eeprom_addr_currentReading[_cNum], currentReading[_cNum]);
  8. EEPROM.put(eeprom_addr_currentReading_backup1[_cNum], currentReading[_cNum]);
  9. EEPROM.put(eeprom_addr_currentReading_backup2[_cNum], currentReading[_cNum]);
  10. Serial.println(F("INFO: Saved current reading to EEPROM."));
  11. }
  12. //storeCurrentImpulses(_cNum, false);
  13. }
  14. }
  15. void restoreLastReading(byte _cNum) {
  16. //currentReading = (int)eeprom_read_word(&eeprom_addr_currentReading);
  17. unsigned long _currentReading, _currentReading_backup1, _currentReading_backup2;
  18. uint16_t _currentImpulsesCount;
  19. EEPROM.get(eeprom_addr_currentReading[_cNum], _currentReading);
  20. EEPROM.get(eeprom_addr_currentReading_backup1[_cNum], _currentReading_backup1);
  21. EEPROM.get(eeprom_addr_currentReading_backup2[_cNum], _currentReading_backup2);
  22. bool _restoredReading = false;
  23. if (debug) {
  24. Serial.println();
  25. Serial.println();
  26. Serial.print(F("trying to restore last reading for C"));
  27. Serial.print(_cNum + 1);
  28. Serial.println("...");
  29. }
  30. if (_currentReading == _currentReading_backup1 && _currentReading == _currentReading_backup2) {
  31. // all good - take the value and go
  32. currentReading[_cNum] = _currentReading;
  33. _restoredReading = true;
  34. //if(debug) Serial.println(F("All stored readings are equal"));
  35. }
  36. else if ( (_currentReading == _currentReading_backup1) ) {
  37. // OK, 2 values are identical - go on
  38. currentReading[_cNum] = _currentReading;
  39. _restoredReading = true;
  40. if (debug) Serial.println(F("INFO: stored readings 1 and 2 are equal"));
  41. }
  42. else if ( (_currentReading == _currentReading_backup2) ) {
  43. // OK, 2 values are identical - go on
  44. currentReading[_cNum] = _currentReading;
  45. _restoredReading = true;
  46. if (debug) Serial.println(F("INFO: stored readings 1 and 3 are equal"));
  47. }
  48. else if ( (_currentReading_backup1 == _currentReading_backup2) ) {
  49. // OK, 2 values are identical - go on
  50. currentReading[_cNum] = _currentReading_backup1;
  51. _restoredReading = true;
  52. if (debug) Serial.println(F("INFO: stored readings 2 and 3 are equal"));
  53. }
  54. else {
  55. // not good - all stored values are different, so we don´t know which one is right
  56. Serial.print(F("ERROR: FAILED to restore last reading of C"));
  57. Serial.println(_cNum + 1);
  58. //printCurrentReading(_cNum);
  59. }
  60. if (_restoredReading) {
  61. //Serial.print(F("Restored reading: "));
  62. //Serial.print(currentReading);
  63. //Serial.print(".");
  64. //Serial.print(currentReadingImpulses);
  65. //Serial.println();
  66. Serial.print(F("INFO: restored reading of C"));
  67. Serial.print(_cNum + 1);
  68. Serial.print("=");
  69. Serial.println(currentReading[_cNum]);
  70. //printCurrentReading(_cNum);
  71. }
  72. }
  73. void restoreAllLastData() {
  74. for (byte i = 0; i < COUNTERS_COUNT; i++) {
  75. restoreLastSavedImpulseCount(i, false);
  76. restoreLastReading(i);
  77. }
  78. }
  79. void printAllCurrentReadings() {
  80. for (byte i = 0; i < COUNTERS_COUNT; i++) {
  81. printCurrentReading(i, 0, false);
  82. }
  83. }
  84. void saveAllCurrentData(bool _force) {
  85. for (byte i = 0; i < COUNTERS_COUNT; i++) {
  86. storeCurrentImpulses(i, false);
  87. //if (_force) storeCurrentReading(i, true);
  88. storeCurrentReading(i, false);
  89. }
  90. Serial.println(F("INFO: saved all current data."));
  91. }
  92. void restoreLastSavedImpulseCount(byte _cNum, bool _printOnly) {
  93. uint16_t _datasets, _offset, _addr, _maxAddrOffset, _nextOffset;
  94. uint16_t _lastWriteCounter = 0;
  95. uint16_t _currentWriteCounter = 0;
  96. uint16_t _currentData = 0;
  97. uint16_t _found_writeCounter = 0;
  98. uint16_t _found_data = 0;
  99. uint16_t _found_offset = 0;
  100. bool _foundData = false;
  101. if (debug || _printOnly) {
  102. Serial.println();
  103. Serial.println();
  104. Serial.print(F("trying to restore last impulses count for C"));
  105. Serial.print(_cNum + 1);
  106. Serial.println("...");
  107. }
  108. _datasets = eeprom_addr_area_length_currentReadingImpulses[_cNum] / eeprom_datasetsize_currentReadingImpulses;
  109. if (debug || _printOnly) {
  110. Serial.print("datasets: ");
  111. Serial.println(_datasets);
  112. Serial.println(F("dSet\toffset\taddr\twC\tlwC\tdata\tvalid"));
  113. }
  114. // iterate over the EEPROM data area to find the dataset with the highest writecounter
  115. for (int i = 0; i < _datasets; i++) {
  116. _offset = i * eeprom_datasetsize_currentReadingImpulses;
  117. _addr = eeprom_addr_area_start_currentReadingImpulses[_cNum] + _offset;
  118. if (debug || _printOnly) {
  119. Serial.print((_offset / eeprom_datasetsize_currentReadingImpulses) + 1);
  120. Serial.print(" \t");
  121. Serial.print(_offset);
  122. Serial.print(" \t");
  123. Serial.print(_addr);
  124. }
  125. if (i > 0) {
  126. _lastWriteCounter = _currentWriteCounter;
  127. }
  128. EEPROM.get(_addr, _currentWriteCounter);
  129. EEPROM.get(_addr + 2, _currentData);
  130. if (debug || _printOnly) {
  131. Serial.print(" \t");
  132. Serial.print(_currentWriteCounter);
  133. Serial.print("\t");
  134. Serial.print(_lastWriteCounter);
  135. Serial.print("\t");
  136. Serial.print(_currentData);
  137. }
  138. if ( i == 0 && _currentWriteCounter > 0) {
  139. // find data in first dataset
  140. _found_offset = _offset;
  141. _found_writeCounter = _currentWriteCounter;
  142. _found_data = _currentData;
  143. _foundData = true;
  144. if (debug || _printOnly) Serial.print("\tY");
  145. }
  146. else if (_currentWriteCounter == (_lastWriteCounter + 1)) {
  147. // this dataset holds valid data
  148. if (debug || _printOnly) Serial.print("\tY");
  149. _found_offset = _offset;
  150. _found_writeCounter = _currentWriteCounter;
  151. _found_data = _currentData;
  152. _foundData = true;
  153. }
  154. else {
  155. // stop the for loop as we already found what we were looking for
  156. // (or did not find anything)
  157. i = _datasets + 1;
  158. if (debug || _printOnly) Serial.print("\tN");
  159. }
  160. if (debug || _printOnly) Serial.println();
  161. }
  162. if (!_foundData) {
  163. if (debug || _printOnly) {
  164. Serial.print(F("NOTHING FOUND - EEPROM area seems empty for C"));
  165. Serial.println(_cNum + 1);
  166. }
  167. if (!_printOnly) {
  168. eeprom_nextoffset_currentReadingImpulses[_cNum] = 0;
  169. eeprom_writecounter_currentReadingImpulses[_cNum] = 1;
  170. }
  171. }
  172. else {
  173. _maxAddrOffset = eeprom_addr_area_length_currentReadingImpulses[_cNum] - eeprom_datasetsize_currentReadingImpulses;
  174. if ((_found_offset + eeprom_datasetsize_currentReadingImpulses) > _maxAddrOffset) {
  175. _nextOffset = 0;
  176. }
  177. else _nextOffset = _found_offset + eeprom_datasetsize_currentReadingImpulses;
  178. if (!_printOnly) {
  179. eeprom_nextoffset_currentReadingImpulses[_cNum] = _nextOffset;
  180. eeprom_writecounter_currentReadingImpulses[_cNum] = _found_writeCounter;
  181. currentReadingImpulses[_cNum] = _found_data;
  182. currentReadingImpulses_saved[_cNum] = _found_data;
  183. Serial.print(F("INFO: restored impulse counter of C"));
  184. }
  185. else {
  186. if (debug || _printOnly) Serial.print(F("INFO: printing stored impulse counter of C"));
  187. }
  188. //if (debug || _printOnly) {
  189. Serial.print(_cNum + 1);
  190. Serial.print(F(": data="));
  191. Serial.print(_found_data);
  192. if (debug || _printOnly) {
  193. Serial.print(F(", wCount="));
  194. Serial.print(_found_writeCounter);
  195. Serial.print(F(", dSet="));
  196. Serial.print((_found_offset / eeprom_datasetsize_currentReadingImpulses) + 1);
  197. Serial.print(F(", offset="));
  198. Serial.print(_found_offset);
  199. Serial.print(F(", nOffset="));
  200. Serial.println(_nextOffset);
  201. }
  202. else Serial.println();
  203. //}
  204. }
  205. //getCurrentReading();
  206. }
  207. void storeCurrentImpulses(byte _cNum, bool _force) {
  208. if (_force || (currentReadingImpulses_saved[_cNum] != currentReadingImpulses[_cNum])) {
  209. uint16_t _addr, _nextAddrOffset, _maxAddrOffset, _datasets;
  210. if (eeprom_writecounter_currentReadingImpulses[_cNum] == 65535) {
  211. // if this write rolls over the writecounter variable (uint16_t)
  212. // set write counter to 1 (0 is defined invalid) and write to offset 0
  213. eeprom_writecounter_currentReadingImpulses[_cNum] = 1;
  214. eeprom_nextoffset_currentReadingImpulses[_cNum] = 0;
  215. }
  216. else {
  217. eeprom_writecounter_currentReadingImpulses[_cNum]++;
  218. }
  219. _addr = eeprom_addr_area_start_currentReadingImpulses[_cNum] + eeprom_nextoffset_currentReadingImpulses[_cNum];
  220. if (debug) {
  221. Serial.print(F("storeCurrentImpulses: C"));
  222. Serial.print(_cNum + 1);
  223. Serial.print(F(" data="));
  224. Serial.print(currentReadingImpulses[_cNum]);
  225. Serial.print(F(", wCount="));
  226. Serial.print(eeprom_writecounter_currentReadingImpulses[_cNum]);
  227. Serial.print(F(", offset="));
  228. Serial.print(eeprom_nextoffset_currentReadingImpulses[_cNum]);
  229. Serial.print(F(", dSet="));
  230. Serial.println((eeprom_nextoffset_currentReadingImpulses[_cNum] / eeprom_datasetsize_currentReadingImpulses) + 1);
  231. }
  232. // write data first, then writecounter, in case a power failure occurs
  233. EEPROM.put(_addr + 2, currentReadingImpulses[_cNum]);
  234. EEPROM.put(_addr, eeprom_writecounter_currentReadingImpulses[_cNum]);
  235. Serial.println(F("INFO: saved current pulses count to EEPROM"));
  236. currentReadingImpulses_saved[_cNum] = currentReadingImpulses[_cNum];
  237. pulsesLastSaved_seconds[_cNum] = seconds;
  238. //_datasets = eeprom_addr_area_length_currentReadingImpulses[_cNum] / eeprom_datasetsize_currentReadingImpulses;
  239. _nextAddrOffset = eeprom_nextoffset_currentReadingImpulses[_cNum] + eeprom_datasetsize_currentReadingImpulses;
  240. _maxAddrOffset = eeprom_addr_area_length_currentReadingImpulses[_cNum] - eeprom_datasetsize_currentReadingImpulses;
  241. if (_nextAddrOffset > _maxAddrOffset) {
  242. eeprom_nextoffset_currentReadingImpulses[_cNum] = 0;
  243. }
  244. else {
  245. eeprom_nextoffset_currentReadingImpulses[_cNum] = _nextAddrOffset;
  246. }
  247. }
  248. }