Global variable definition

Hi, is there a way to define global variable which would be visible in imported library?

How can I define variable for example:

const int FLOOR_ALARM_MEM_ADDR = 2;

to be visible also in cpp files I import into main sketch?

I've created one confiig.h and that header is being import in sketch but when I import that config.h also in class header where I want to use some variable I have error about redeclaration of same variable

lonas: I've created one confiig.h and that header is being import in sketch but when I import that config.h also in class header where I want to use some variable I have error about redeclaration of same variable

.

You can create a global variable in a header, yes.

So, you create a header (.h) file with this:

extern const int FLOOR_ALARM_MEM_ADDR;

and in your implementation(.cpp):

const int FLOOR_ALARM_MEM_ADDR = 2;

anti it should be accessible to your sketch...

but I would like to have one place with all configuration like this : const int FLOOR_ALARM_MEM_ADDR = 2; visible in all classes I'm using.

I'm using EEPROM in couple places so I want to have address in one configuration file which I can use in multiple classess

How to achieve that ?

can you show an example of what it is you are trying to do?

Ok I think I got what You are saying - looks like it works so what I have is:

Config.h file with configuration as You specified
extern int REBOOT_ATTEMPT_MEM_ADDR1 = 2;

and now when I’m including that config file inside 2 other classes for example

#ifndef Blinker_h
	#define Blinker_h

  #include <Arduino.h>
  #include <MQTTClient.h>
  #include <Config.h>

and

#ifndef MyGSM_h
	#define MyGSM_h

  #include <Arduino.h>
  #include <MQTTClient.h>
  #include <HardwareSerial.h>
 #include <Config.h>

I do not see redefinition error - so that seems to work.

extern did the job - thanks!

I have moved all configuration into config file - but unfortunetly it do not work - I have an error like:

/tmp/build4747471638271714506.tmp/MQTTHandler/MQTTHandler.cpp.o:(.bss.ARDUINO_1_IP+0x0): multiple definition of `ARDUINO_1_IP' /tmp/build4747471638271714506.tmp/button.cpp.o:(.bss.ARDUINO_1_IP+0x0): first defined here

So Im importing config.h inside button.h and MQTTHandler.h - how to solve that conflict

here how ARDUINO_1_IP is defined in config.h

extern const IPAddress ARDUINO_1_IP(192, 168, 1, 51);

EDIT: Solved - instead of extern I need to use static

lonas: EDIT: Solved - instead of extern I need to use static

But I thought you wanted it visible to other files.

extern int REBOOT_ATTEMPT_MEM_ADDR1 = 2;

Lose the assignment.

Delta_G: But I thought you wanted it visible to other files.

static works as expected

I have another question: how can I define variable on sketch level which will be visible in class without setter?

Use case is like I want to add name for each arduino at sketch level and use that inside classes

how can I define variable on sketch level which will be visible in class without setter?

You can't.

There is an nice workaround for this.

Create class which will store that under EEPROM.

On sketch level define:

void setup() 
{
  Serial.begin(9600);
  Ethernet.begin(TEST_MAC, TEST_IP, MY_DNS, MY_GATEWAY, MY_SUBNET);
  
  memoryVariables.setArduinoId(ARDUINO_TEST_ID);
  memoryVariables.init();

and later inside classes You can use that like this:

String Logger::decorateLog(String log)
{
  return memoryVariables.getArduinoName() + " (" + String(millis()) + ") " + log;
}

Hi,

Is there a way to put a const structure to "PROGMEM" in a header file and access its members from the main sketch? I'd like to create a multi level menustructure and put it to a .h/.cpp file because the sketch gets too long.

You just need an extern declaration for it in the sketch.

This simple sketch worked:

    #include <avr/pgmspace.h>

    struct MenuEntryStructure {
          const char *text;                         // pointer to text in progmem (RAM saving)
          unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
          unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
          unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
          unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
          void (*fp)(void);                     // pointer to a selectable function
    };

    /* MenuStructure for storing in ROM!!!
    The numbering: first digit - submenu (0 is main menu) 1-9, second digit: subsub menu 1-9, third digit: menuitem 0-9
    At the end of each lines line numbers are provided from 0-end continuously for Array numbers!!!
    */

    const char PROGMEM menu_000[14] = "[  FOMENU   ]";      //00
    const char PROGMEM menu_001[14] = "Submenu1";       //01
    const char PROGMEM menu_002[14] = "Submenu2";       //02
    const char PROGMEM menu_003[14] = "Main4";          //03
    const char PROGMEM menu_004[14] = "Main5";          //04
    const char PROGMEM menu_005[14] = "Main6";          //05
    const char PROGMEM menu_006[14] = "Main7";          //06
    const char PROGMEM menu_007[14] = "Main8";          //07
    const char PROGMEM menu_008[14] = "Main9";          //08
    const char PROGMEM menu_009[14] = "Main10";          //09

    const char PROGMEM menu_100[14] = "[  SUBENU1  ]";      //10
    const char PROGMEM menu_101[14] = "Sub1-2";         //11
    const char PROGMEM menu_102[14] = "Sub1-3";         //12
    const char PROGMEM menu_103[14] = "Sub1-4";         //13
    const char PROGMEM menu_104[14] = "Sub1-5";         //14
    const char PROGMEM menu_105[14] = "Return";         //15

    const char PROGMEM menu_200[14] = "[  SUBENU2  ]";      //16
    const char PROGMEM menu_201[14] = "Sub2-2";         //17
    const char PROGMEM menu_202[14] = "Sub2-3";         //18
    const char PROGMEM menu_203[14] = "Sub2-4";         //19
    const char PROGMEM menu_204[14] = "Sub2-5";         //20
    const char PROGMEM menu_205[14] = "Return";         //21

    extern const struct MenuEntryStructure PROGMEM lcdmenu [22] = {
      {menu_000, 10, 0, 0, 0, 0},       //pointer to menupoint string, num of items in actual (sub)menu, prev item num
      {menu_001, 10, 1, 2, 10, 0},      //next item num, onselect menuitem num, pointer to onselect function or null
      {menu_002, 10, 1, 3, 16, 0},      //for item number please see remarks at end of menupoint string initialisation lines
      {menu_003, 10, 2, 4, 3, 0},
      {menu_004, 10, 3, 5, 4, 0},
      {menu_005, 10, 4, 6, 5, 0},
      {menu_006, 10, 5, 7, 6, 0},
      {menu_007, 10, 6, 8, 7, 0},
      {menu_008, 10, 7, 9, 8, 0},
      {menu_009, 10, 8, 9, 9, 0},

      {menu_100, 6, 10, 10, 10, 0},
      {menu_101, 6, 11, 12, 11, 0},
      {menu_102, 6, 11, 13, 12, 0},
      {menu_103, 6, 12, 14, 13, 0},
      {menu_104, 6, 13, 15, 14, 0},
      {menu_105, 6, 14, 15, 1, 0},

      {menu_200, 6, 16, 16, 16, 0},
      {menu_201, 6, 17, 18, 17, 0},
      {menu_202, 6, 17, 19, 18, 0},
      {menu_203, 6, 18, 20, 19, 0},
      {menu_204, 6, 19, 21, 20, 0},
      {menu_205, 6, 20, 21, 2, 0},
    };

    void setup(){
      Serial.begin(57600);
      while(!Serial);
      Serial.println("OK");
    }


    void loop(){
     
      for (int i = 0; i < 22; i++){
        char * ptr = (char *) pgm_read_word (&(lcdmenu[i].text));
        Serial.println(ptr);
      }
        Serial.flush();
        exit(0);
    }

This sketch with the .h file been compiled without error but did not work as I meant:

MenuStruct.h

    /*
       menustruct.h - Library to build an LCD menustructure in an external source code file

       Created by nor_bee, Jan 5. 2016
       
    */

    #ifndef MenuStruct_h
       #define MenuStruct_h
       
       #include "Arduino.h"
       #include <avr/pgmspace.h> // Has to be included in this file as well!!!

       class MenuStruct
       {
          public:
                         
          // Data declarations of variables in cpp file
                    
          struct MenuEntryStructure{
             const char *text;                         // pointer to text in progmem
             unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
             unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
             unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
             unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
             void (*fp)(void);
          };

          /* At the end of each lines line numbers are provided from 0-end continuously for array/struct member numbers */

          char menu_000[14];               //00
          char menu_001[14];               //01
          char menu_002[14];               //02
          char menu_003[14];               //03
          char menu_004[14];               //04
          char menu_005[14];               //05
          char menu_006[14];               //06
          char menu_007[14];               //07
          char menu_008[14];               //08
          char menu_009[14];               //09

          char menu_100[14];               //10
          char menu_101[14];               //11
          char menu_102[14];               //12
          char menu_103[14];               //13
          char menu_104[14];               //14
          char menu_105[14];               //15

          char menu_200[14];               //16
          char menu_201[14];               //17
          char menu_202[14];               //18
          char menu_203[14];               //19
          char menu_204[14];               //20
          char menu_205[14];               //21

       
          struct MenuEntryStructure LCDMENU [22];             // MenuStructure STRUCT ARRAY


    //    void MenuItemIext(unsigned char _menuItemNum);
       
          private:                                 //just for reference until I figure out a valuable function

       };
    #endif

MenuStruct.cpp

    #include "Arduino.h"
    #include <avr/pgmspace.h>                       // Has to be in this file as well!!!
    #include "MenuStruct.h"

    struct MenuEntryStructure {
          const char *text;                         // pointer to text in progmem (RAM saving)
          unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
          unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
          unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
          unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
          void (*fp)(void);                         // pointer to onselect function
    };


    const char PROGMEM menu_000[14] = "[  FOMENU   ]";         //00
    const char PROGMEM menu_001[14] = "Submenu1";            //01
    const char PROGMEM menu_002[14] = "Submenu2";            //02
    const char PROGMEM menu_003[14] = "Main4";               //03
    const char PROGMEM menu_004[14] = "Main5";               //04
    const char PROGMEM menu_005[14] = "Main6";               //05
    const char PROGMEM menu_006[14] = "Main7";               //06
    const char PROGMEM menu_007[14] = "Main8";               //07
    const char PROGMEM menu_008[14] = "Main9";               //08
    const char PROGMEM menu_009[14] = "Main10";               //09

    const char PROGMEM menu_100[14] = "[  SUBENU1  ]";         //10
    const char PROGMEM menu_101[14] = "Sub1-2";               //11
    const char PROGMEM menu_102[14] = "Sub1-3";               //12
    const char PROGMEM menu_103[14] = "Sub1-4";               //13
    const char PROGMEM menu_104[14] = "Sub1-5";               //14
    const char PROGMEM menu_105[14] = "Return";               //15

    const char PROGMEM menu_200[14] = "[  SUBENU2  ]";         //16
    const char PROGMEM menu_201[14] = "Sub2-2";               //17
    const char PROGMEM menu_202[14] = "Sub2-3";               //18
    const char PROGMEM menu_203[14] = "Sub2-4";               //19
    const char PROGMEM menu_204[14] = "Sub2-5";               //20
    const char PROGMEM menu_205[14] = "Return";               //21

    const struct MenuEntryStructure PROGMEM LCDMENU[22] = {
       {menu_000, 10, 0, 0, 0, 0},            //pointer to menupoint string, num of items in actual (sub)menu, prev item num
       {menu_001, 10, 1, 2, 10, 0},         //next item num, onselect menuitem num, pointer to onselect function or null
       {menu_002, 10, 1, 3, 16, 0},            //for item number please see remarks at end of menupoint string initialisation lines
       {menu_003, 10, 2, 4, 3, 0},
       {menu_004, 10, 3, 5, 4, 0},
       {menu_005, 10, 4, 6, 5, 0},
       {menu_006, 10, 5, 7, 6, 0},
       {menu_007, 10, 6, 8, 7, 0},
       {menu_008, 10, 7, 9, 8, 0},
       {menu_009, 10, 8, 9, 9, 0},

       {menu_100, 6, 10, 10, 10, 0},
       {menu_101, 6, 11, 12, 11, 0},
       {menu_102, 6, 11, 13, 12, 0},
       {menu_103, 6, 12, 14, 13, 0},
       {menu_104, 6, 13, 15, 14, 0},
       {menu_105, 6, 14, 15, 1, 0},

       {menu_200, 6, 16, 16, 16, 0},
       {menu_201, 6, 17, 18, 17, 0},
       {menu_202, 6, 17, 19, 18, 0},
       {menu_203, 6, 18, 20, 19, 0},
       {menu_204, 6, 19, 21, 20, 0},
       {menu_205, 6, 20, 21, 2, 0},
    };

.ino file:

    #include <avr/pgmspace.h>
    #include "MenuStruct.h"

    MenuStruct menustruct;

    void setup() {
       Serial.begin(57600);
    }

    void loop() {

       unsigned char k;
     
       for(k=0 ; k < 22; k++) {
         Serial.print((int) k);
        Serial.print(' ');
        strcpy_P(textBuffer, (char*)pgm_read_word(&(menustruct.LCDMENU[k].text)));
        Serial.println(textBuffer);
      }
      Serial.flush();
      exit(0);
    }

This sketch is using three times more RAM than the simple one moreover it can not read back the menuitem strings from PROGMEM.

Thanks for your suggestions!

Class definitions can not write to PROGMEM. Class instances (i.e. code in the constructor) can't either, since they are created at run time, and PROGMEM is written to only when the sketch is uploaded.

https://forum.arduino.cc/index.php?topic=353045.0

Here is an example,doing the same thing that might help.