Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Best way to store large data in eeprom

Best way to store large data in eeprom

Scheduled Pinned Locked Moved Development
14 Posts 3 Posters 4.3k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • TetnobicT Offline
    TetnobicT Offline
    Tetnobic
    wrote on last edited by
    #1

    Hi,
    In my node (ATMega328p) I want to store a duration in seconde in Eeprom....
    This duration can range from 0 to 86400 (1day :))
    I think use the method :
    void saveState(uint8_t pos, uint8_t value);
    but uint8_t can only store value range from 0 to 255 :(

    So, I found 2 solutions :

    • Cut the duration in 2 variables : 1 for minutes, 1 for seconds, and store them at 2 differents positions.
    • Store in a uint32_t type and not use saveState method but use mySensor internal method : hwWriteConfigBlock(__buf, __pos, __length) with the correct param.

    In your opinion, what is the best choice ? or perhaps an other solution ?

    Thanks in advance

    mfalkviddM 1 Reply Last reply
    0
    • hekH Offline
      hekH Offline
      hek
      Admin
      wrote on last edited by
      #2

      Third option:

      int duration = 4000;
      
      saveState(0, (duration >> 8) & 0xff);
      saveState(1, duration & 0xff);
      
      // And loading 
      
      duration = loadState(0) << 8 + loadState(1);
      
      
      TetnobicT 1 Reply Last reply
      1
      • TetnobicT Tetnobic

        Hi,
        In my node (ATMega328p) I want to store a duration in seconde in Eeprom....
        This duration can range from 0 to 86400 (1day :))
        I think use the method :
        void saveState(uint8_t pos, uint8_t value);
        but uint8_t can only store value range from 0 to 255 :(

        So, I found 2 solutions :

        • Cut the duration in 2 variables : 1 for minutes, 1 for seconds, and store them at 2 differents positions.
        • Store in a uint32_t type and not use saveState method but use mySensor internal method : hwWriteConfigBlock(__buf, __pos, __length) with the correct param.

        In your opinion, what is the best choice ? or perhaps an other solution ?

        Thanks in advance

        mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by mfalkvidd
        #3

        @Tetnobic the first solution won't work. There are 1440 minutes in a day :)

        I use the method suggested by hek when storing the highscore for my MySesnors-powered Tetris game (soon to be published), except that I use an unsigned int.

        Using highByte(), lowByte() and word() might be more readable than the bit shifting though. Like this:

        unsigned int duration = 4000;
        
        saveState(0, highByte(duration));
        saveState(1, lowByte(duration));
        
        // And loading 
        
        duration = word(loadState(0), loadState(1));
        
        1 Reply Last reply
        1
        • hekH hek

          Third option:

          int duration = 4000;
          
          saveState(0, (duration >> 8) & 0xff);
          saveState(1, duration & 0xff);
          
          // And loading 
          
          duration = loadState(0) << 8 + loadState(1);
          
          
          TetnobicT Offline
          TetnobicT Offline
          Tetnobic
          wrote on last edited by Tetnobic
          #4

          @hek thanks for your Nice 3d solution,
          I do not usually use the bit shifting technique, I guess the max value is 8 * 2 bits : 65 535 ?

          @mfalkvidd right 1440 minutes in a day... I am a goat... Thanks for the methods, I think I will use this...

          mfalkviddM 1 Reply Last reply
          0
          • TetnobicT Tetnobic

            @hek thanks for your Nice 3d solution,
            I do not usually use the bit shifting technique, I guess the max value is 8 * 2 bits : 65 535 ?

            @mfalkvidd right 1440 minutes in a day... I am a goat... Thanks for the methods, I think I will use this...

            mfalkviddM Offline
            mfalkviddM Offline
            mfalkvidd
            Mod
            wrote on last edited by mfalkvidd
            #5

            @Tetnobic correct, the max value for a 16-bit unsigned integer is 2^16-1 which is 65535. See https://www.arduino.cc/en/Reference/UnsignedInt for details.

            TetnobicT 1 Reply Last reply
            0
            • mfalkviddM mfalkvidd

              @Tetnobic correct, the max value for a 16-bit unsigned integer is 2^16-1 which is 65535. See https://www.arduino.cc/en/Reference/UnsignedInt for details.

              TetnobicT Offline
              TetnobicT Offline
              Tetnobic
              wrote on last edited by
              #6

              @mfalkvidd so not enough to store 1 day (86400s) :( , can I do same things with int32 ?

              mfalkviddM 1 Reply Last reply
              0
              • TetnobicT Tetnobic

                @mfalkvidd so not enough to store 1 day (86400s) :( , can I do same things with int32 ?

                mfalkviddM Offline
                mfalkviddM Offline
                mfalkvidd
                Mod
                wrote on last edited by
                #7

                @Tetnobic true, nice catch :)

                32 bits (unsigned long) would work. You'd have to use bit shift though, I don't think there are equivalents for high/lowByte and word.

                unsigned long duration = 4000;
                
                saveState(0, (duration >> 24) & 0xff);
                saveState(1, (duration >> 16) & 0xff);
                saveState(2, (duration >> 8) & 0xff);
                saveState(3, duration & 0xff);
                
                duration = loadState(0) << 24 + loadState(1) << 16 + loadState(2) << 8 + loadState(3);
                

                But your original idea with hwWriteConfigBlock would be easier to read I think.

                TetnobicT 1 Reply Last reply
                1
                • mfalkviddM mfalkvidd

                  @Tetnobic true, nice catch :)

                  32 bits (unsigned long) would work. You'd have to use bit shift though, I don't think there are equivalents for high/lowByte and word.

                  unsigned long duration = 4000;
                  
                  saveState(0, (duration >> 24) & 0xff);
                  saveState(1, (duration >> 16) & 0xff);
                  saveState(2, (duration >> 8) & 0xff);
                  saveState(3, duration & 0xff);
                  
                  duration = loadState(0) << 24 + loadState(1) << 16 + loadState(2) << 8 + loadState(3);
                  

                  But your original idea with hwWriteConfigBlock would be easier to read I think.

                  TetnobicT Offline
                  TetnobicT Offline
                  Tetnobic
                  wrote on last edited by
                  #8

                  @mfalkvidd yes for this solution, I guess that hwWriteConfigBlock method access to the eeprom in one time, contrary to bit shifting technique that need 4 saveState so 4 access to the eeprom ?

                  1 Reply Last reply
                  0
                  • TetnobicT Offline
                    TetnobicT Offline
                    Tetnobic
                    wrote on last edited by Tetnobic
                    #9

                    I try this :

                    #define EEPROM_SLEEP_DURATION_ADDRESS 0
                    
                    uint32_t sleepDurationInS = 86399;
                    
                    hwWriteConfigBlock((void*)sleepDurationInS, (void*)(EEPROM_LOCAL_CONFIG_ADDRESS+EEPROM_SLEEP_DURATION_ADDRESS), 32);
                    
                     hwReadConfigBlock((void*)&sleepDurationInS, (void*)(EEPROM_LOCAL_CONFIG_ADDRESS+EEPROM_SLEEP_DURATION_ADDRESS), 32);
                    

                    but seems no work :( my node freeze at this method

                    mfalkviddM 1 Reply Last reply
                    0
                    • TetnobicT Tetnobic

                      I try this :

                      #define EEPROM_SLEEP_DURATION_ADDRESS 0
                      
                      uint32_t sleepDurationInS = 86399;
                      
                      hwWriteConfigBlock((void*)sleepDurationInS, (void*)(EEPROM_LOCAL_CONFIG_ADDRESS+EEPROM_SLEEP_DURATION_ADDRESS), 32);
                      
                       hwReadConfigBlock((void*)&sleepDurationInS, (void*)(EEPROM_LOCAL_CONFIG_ADDRESS+EEPROM_SLEEP_DURATION_ADDRESS), 32);
                      

                      but seems no work :( my node freeze at this method

                      mfalkviddM Offline
                      mfalkviddM Offline
                      mfalkvidd
                      Mod
                      wrote on last edited by
                      #10

                      @Tetnobic that looks correct to me, but I am no c/c++ expert so pointers and casting is scary for me :) Hopefully someone with better skills can give some clarity.

                      The code in the security personalizer seems to use the same syntax.

                      1 Reply Last reply
                      0
                      • hekH Offline
                        hekH Offline
                        hek
                        Admin
                        wrote on last edited by
                        #11

                        Length should be 4 not 32.

                        TetnobicT 1 Reply Last reply
                        2
                        • hekH hek

                          Length should be 4 not 32.

                          TetnobicT Offline
                          TetnobicT Offline
                          Tetnobic
                          wrote on last edited by Tetnobic
                          #12

                          @hek right :) sizeof uint32_t : 4

                          it works with :

                          #define EEPROM_SLEEP_DURATION_ADDRESS 0
                          
                          uint32_t sleepDurationInS = 86399;
                          
                          hwWriteConfigBlock((void*)&sleepDurationInS, (void*)(EEPROM_LOCAL_CONFIG_ADDRESS+EEPROM_SLEEP_DURATION_ADDRESS), 4);
                          
                           hwReadConfigBlock((void*)&sleepDurationInS, (void*)(EEPROM_LOCAL_CONFIG_ADDRESS+EEPROM_SLEEP_DURATION_ADDRESS), 4);
                          
                          1 Reply Last reply
                          3
                          • TetnobicT Offline
                            TetnobicT Offline
                            Tetnobic
                            wrote on last edited by
                            #13

                            Just for info, I found others methods to save data in eeprom :
                            in <avr/eeprom.h> there is :

                            uint8_t 	eeprom_read_byte (const uint8_t *__p)
                            uint16_t 	eeprom_read_word (const uint16_t *__p)
                            uint32_t 	eeprom_read_dword (const uint32_t *__p)
                            float 	eeprom_read_float (const float *__p)
                            void 	eeprom_read_block (void *__dst, const void *__src, size_t __n)
                            void 	eeprom_write_byte (uint8_t *__p, uint8_t __value)
                            void 	eeprom_write_word (uint16_t *__p, uint16_t __value)
                            void 	eeprom_write_dword (uint32_t *__p, uint32_t __value)
                            void 	eeprom_write_float (float *__p, float __value)
                            void 	eeprom_write_block (const void *__src, void *__dst, size_t __n)
                            void 	eeprom_update_byte (uint8_t *__p, uint8_t __value)
                            void 	eeprom_update_word (uint16_t *__p, uint16_t __value)
                            void 	eeprom_update_dword (uint32_t *__p, uint32_t __value)
                            void 	eeprom_update_float (float *__p, float __value)
                            void 	eeprom_update_block (const void *__src, void *__dst, size_t __n)
                            

                            It is to these methods that the aliases are made in the file MyHwATMega328.h :)

                            #define hwReadConfig(__pos) eeprom_read_byte((uint8_t*)(__pos))
                            #define hwWriteConfig(__pos, __val) eeprom_update_byte((uint8_t*)(__pos), (__val))
                            #define hwReadConfigBlock(__buf, __pos, __length) eeprom_read_block((void*)(__buf), (void*)(__pos), (__length))
                            #define hwWriteConfigBlock(__buf, __pos, __length) eeprom_update_block((void*)(__buf), (void*)(__pos), (__length))
                            
                            mfalkviddM 1 Reply Last reply
                            0
                            • TetnobicT Tetnobic

                              Just for info, I found others methods to save data in eeprom :
                              in <avr/eeprom.h> there is :

                              uint8_t 	eeprom_read_byte (const uint8_t *__p)
                              uint16_t 	eeprom_read_word (const uint16_t *__p)
                              uint32_t 	eeprom_read_dword (const uint32_t *__p)
                              float 	eeprom_read_float (const float *__p)
                              void 	eeprom_read_block (void *__dst, const void *__src, size_t __n)
                              void 	eeprom_write_byte (uint8_t *__p, uint8_t __value)
                              void 	eeprom_write_word (uint16_t *__p, uint16_t __value)
                              void 	eeprom_write_dword (uint32_t *__p, uint32_t __value)
                              void 	eeprom_write_float (float *__p, float __value)
                              void 	eeprom_write_block (const void *__src, void *__dst, size_t __n)
                              void 	eeprom_update_byte (uint8_t *__p, uint8_t __value)
                              void 	eeprom_update_word (uint16_t *__p, uint16_t __value)
                              void 	eeprom_update_dword (uint32_t *__p, uint32_t __value)
                              void 	eeprom_update_float (float *__p, float __value)
                              void 	eeprom_update_block (const void *__src, void *__dst, size_t __n)
                              

                              It is to these methods that the aliases are made in the file MyHwATMega328.h :)

                              #define hwReadConfig(__pos) eeprom_read_byte((uint8_t*)(__pos))
                              #define hwWriteConfig(__pos, __val) eeprom_update_byte((uint8_t*)(__pos), (__val))
                              #define hwReadConfigBlock(__buf, __pos, __length) eeprom_read_block((void*)(__buf), (void*)(__pos), (__length))
                              #define hwWriteConfigBlock(__buf, __pos, __length) eeprom_update_block((void*)(__buf), (void*)(__pos), (__length))
                              
                              mfalkviddM Offline
                              mfalkviddM Offline
                              mfalkvidd
                              Mod
                              wrote on last edited by
                              #14

                              @Tetnobic the hw* functions is a way to abstract the underlying hardware. Many MySensors fans use non-avr hardware, for example ESP8266.

                              You can of course choose to optimize for a single platform in your own sketches, but we strive to make the MySensors example sketches available for as many platforms as possible.

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              10

                              Online

                              11.7k

                              Users

                              11.2k

                              Topics

                              113.1k

                              Posts


                              Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • MySensors
                              • OpenHardware.io
                              • Categories
                              • Recent
                              • Tags
                              • Popular