Problem with extern variables

Hello,

I have a problem with my sketch using 'extern'.

In the main file:

const byte someVariable[10] PROGMEM = {0,1,2,3,4,5,6,7,8,9};

setup ()
...

and in a different tab/file I try to add an extern statement, something like:

extern const byte someVariable[10] PROGMEM;

void someFunction(void)
{
  // Example code just to show where I use this.
  someVariable[0] = 4;
  ...
}

But I get an error when trying to compile the sketch. I have search for a solution, but have not found anything that have helped me solve this problem.

The error I get is

sketch/someFunction.cpp:100: undefined reference to `someVariable'

Suggestions?

Not really your question on external, but How do you think the compiler can assign a value to something that is const and in flash memory when you write:

 someVariable[0] = 4;

Sorry for that mistake, forget that statement. I wrote the message in a hurry. It should be:

  if (someVariable[0] == 4) {... }

The real code only read the variable. The problem with compiling and linking remain.

Tabs aren't external. The IDE combines all the files represented by tabs into a single sketch. Globals defined in the main (first) tab are in scope for all other tabs.

The data is in PROGMEM; you can’t read it like that.

Keyword const objects have internal linkage in C++, i.e. they are not visible outside of the compilation unit they are declared in.

ToddL1962:
Keyword const objects have internal linkage in C++, i.e. they are not visible outside of the compilation unit they are declared in.

This works.

.ino file:

extern const uint8_t arraySize;
extern const uint8_t someVariable[];

const uint8_t arraySize = 10;
const uint8_t someVariable[arraySize] PROGMEM = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

void printIt();

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("From setup():");
  for (uint8_t i = 0; i < arraySize; i++) {
    uint8_t b = pgm_read_byte(someVariable + i);
    Serial.println(b);
  }
  Serial.println();
  Serial.println();

  printIt();
}

void loop() {
}

OtherFile.cpp:

#include <Arduino.h>

extern const uint8_t arraySize;
extern const uint8_t someVariable[];

void printIt() {
  Serial.println("From printIt():");
  for (uint8_t i = 0; i < arraySize; i++) {
    uint8_t b = pgm_read_byte(someVariable + i);
    Serial.println(b);
  }
}

Output:

From setup():
0
1
2
3
4
5
6
7
8
9


From printIt():
0
1
2
3
4
5
6
7
8
9

Thanks a lot gfvalvo - it worked!

SteveMann: Tabs aren't external. The IDE combines all the files represented by tabs into a single sketch. Globals defined in the main (first) tab are in scope for all other tabs.

You're talking about using the Arduino-recommended practice of multiple .ino files / tabs. IMO, that's useless. If you use you proper .cpp and .h files / tabs then you can have meaningful code modularity.

TheMemberFormerlyKnownAsAWOL: The data is in PROGMEM; you can't read it like that.

If it is in PROGMEM, how should it be (read)?

Since the arrays are rather small, I have dropped the PROGMEM, but it would be nice to know how this can be done if I have larger arrays I want/must have in PROGMEM.

thehardwareman:
If it is in PROGMEM, how should it be (read)?

Since the arrays are rather small, I have dropped the PROGMEM, but it would be nice to know how this can be done if I have larger arrays I want/must have in PROGMEM.

The way @gfvalvo did it.
Check the PROGMEM reference page.

ToddL1962: Keyword const objects have internal linkage in C++, i.e. they are not visible outside of the compilation unit they are declared in.

You probably meant "static".

TheMemberFormerlyKnownAsAWOL: The way @gfvalvo did it. Check the PROGMEM reference page.

Of cause... did not see that his example used PROGMEM. Silly me... Thanks for all replies.