so the question is if it's possible to declare arrays in another tab?, i.e. not in the tab where you have void setup and void loop. I like to declare functions in different tabs for fast switching but it doesn't seem to work for arrays. I need to declare 16 arrays, and the number will increase and I don't want to have them all in the main tab.
I'm building a midi controller that will send macros, i.e. sets of midi messages.
Now I have 16 macros planned, but I will be adding more as I will expand the hardware.
here is a rough draft:
const int macro01[6] = {1,2,3,4,5,6};
const int macro02[5] = {33,44,55,66,77};
const int macro03[5] = {14,12,43,3,73};
// and so on, 16 arrays and more
const byte buttonArray[2] ={2, 3}; //array of connected buttons
const byte buttonCount = 2; //amount of connected buttons
void setup() {
Serial.begin(9600);
for (byte a=0; a<buttonCount; a++) //Initializes the button pins as inputs
{
pinMode(buttonArray[a], INPUT);
delay(1);
}
}
void loop() {
}
I want to put the macros declared at the top into another tab, or maybe into an external file (if that is a better solution).
I'd like to have the array list in a separate file, maybe a class, text or perhaps an excel file, this would make changing the macros easier with no need to use the Arduino IDE.
What are the options here? Maybe you guys know of some tutorials?
extern const int macro01; instead of extern const int macro01[];
Hrm, I'm still new to the arduino platform, but my C/C++ skills are good enough to say that that shouldn't work. The 1st you stated is not an array, the 2nd one is. However, you cannot state an array as extern without stating the array size (though I think doing that may not work properly either, you'd have to try it to see).
You probably want to put these in a header file (.h extention) and then include that file using the #include "filename.h" directive (where filename.h is the name of the header file you created.
Doing this will do a few things actually.
It will separate the data from the code, which is considered a good idea anyway.
By declaring the array as a const and have it embedded in the code where it is going to be used (as opposed to having it as an extern which will in all likelihood defeat the compiler's optimizer), if you reference only the elements of the array using constants indices, then the array will not actually be saved in your image, freeing up space. Since you're writing these arrays probably as a way of spitting them out again in a sequence (accessing them using a loop), this will probably not be the case, but can be useful to know for other uses.
Things to be careful when using a header file. Don't include the file multiple times as it very similar to as if you took that file and inserted it right where you specified the #include directive. In other words, it would be like you declared all the stuff you have in that file multiple times, resulting in a redeclaration error. There are ways around this by using some other marco directives (look up C macros #if defined/#ifdef/#define/#else/#endif for more info), however, it is unlikely you would be doing this, so I wouldn't worry about it too much.
thanks for all the help, I'll try out the header file option, might just be what I'm looking for.
Quote
this would make changing the macros easier with no need to use the Arduino IDE.
Despite the name, they aren't macros.
yep, I should have written arrays.
However, you cannot state an array as external without stating the array size (though I think doing that may not work properly either, you'd have to try it to see).
I did declare the size of the arrays but not in the main tab.
I did try declaring the arrays with PROGMEM, but then I was getting garbage instead of midi messages. Maybe I overlooked something, I'll have to try it again.
Oops, yeah, your right. Was in a bit of a hurry when I posted that. Nice catch.
marco_c:
you cannot state an array as extern without stating the array size
You can declare it as a point to the same type as the array and it would have to work ...
I think you meant as a pointer, but actually, you and I are both wrong. First I'd like to apologize as I've been using quite a few other languages recently that do bounds checking. Something that C/C++ does NOT do for built in arrays.
You can declare an extern array without bounds and it will work. When declaring an non-extern array, specifying the bounds will only flag an error if the initialization set exceeds the array size stated. However, if you want to access an element that exists beyond the bounds of the array (either negatively or positively), that is quite ok from the compiler's perspective.
In case you didn't get that the first time, C/C++ DOES NO BOUNDS CHECKING ON BUILT IN ARRAYS.
If you have your array in a separate .cpp file and have it declared as an extern pointer in your main file (which is what I think marco_c was suggesting), you would not get an error (I'm not sure why) but what happens is that upon linking, the extern pointer will be the value (not the address) of first element in the array. Not what you want.
So what you can do is one of two things, put the data into a .cpp file or into a .h file.
If you put it into a .h file, it would look like this (EDIT: not something like): macro.h
const int macro01[6] = {1,2,3,4,5,6};
const int macro02[5] = {33,44,55,66,77};
const int macro03[5] = {14,12,43,3,73};
// and so on, 16 arrays and more
mainSketch
#include "macro.h"
const byte buttonArray[2] ={2, 3}; //array of connected buttons
const byte buttonCount = 2; //amount of connected buttons
void setup() {
Serial.begin(9600);
for (byte a=0; a<buttonCount; a++) //Initializes the button pins as inputs
{
pinMode(buttonArray[a], INPUT);
delay(1);
}
}
void loop() {
}
While, if you want to put it into a .cpp file, you would do something like this: macro.cpp
const int macro01[6] = {1,2,3,4,5,6};
const int macro02[5] = {33,44,55,66,77};
const int macro03[5] = {14,12,43,3,73};
// and so on, 16 arrays and more
mainSketch
extern const int macro01[6];
extern const int macro02[5];
extern const int macro03[5];
// and so on, 16 arrays and more
const byte buttonArray[2] ={2, 3}; //array of connected buttons
const byte buttonCount = 2; //amount of connected buttons
void setup() {
Serial.begin(9600);
for (byte a=0; a<buttonCount; a++) //Initializes the button pins as inputs
{
pinMode(buttonArray[a], INPUT);
delay(1);
}
}
void loop() {
}
I say something like because this actually doesn't work. Seems the const is causing problems due to either the optimizer or the optimizer's interaction with the linker. When compiling a const array variable, the variable is given a different prefix to that of a non-const variable. But strangely, an extern const variable name just gets a non-const prefix. Not sure why this is but if you change the .cpp file remove all of the const directives OR add extern directives (one or the other not both), this works fine.
I.e. this:
extern const int macro01[6] = {1,2,3,4,5,6};
extern const int macro02[5] = {33,44,55,66,77};
extern const int macro03[5] = {14,12,43,3,73};
// and so on, 16 arrays and more
or this:
int macro01[6] = {1,2,3,4,5,6};
int macro02[5] = {33,44,55,66,77};
int macro03[5] = {14,12,43,3,73};
// and so on, 16 arrays and more
The header file would, IMHO, be the better choice though.
EDIT: I remember why now extern is required in my 2nd last example. It modifies the symbols for the linker to share the data across modules. I WOULD NOT recommend using my last example as this is a kluge.
As PeterH vaguely pointed out at first and more explicitly later, if using a source (.cpp) file to initialize (define) your data, it is better using extern in a header file declaring that variable while defining it's value in a source file and including that header file in all source files that it is used in (including the source file that defines it) as well as in the main sketch file.
However, putting constants in a header file is fine in practice. DO NOT put non-constants into a header file as this can result in linking problems.
adrian_h:
So what you can do is one of two things, put the data into a .cpp file or into a .h file.
If you put it into a .h file, it would look something like this:
While, if you want to put it into a .cpp file, you would do something like this:
No, and no. That's not the appropriate way to declare and define an initialised array in C++. Google will explain how this works - there's no need for you to try to guess how it works.
PeterH:
No, and no. That's not the appropriate way to declare and define an initialised array in C++. Google will explain how this works - there's no need for you to try to guess how it works.
Sorry? Who's guessing? Not me, that's for sure.
What exactly are you thinking about? Are you talking about C++ containers such as vectors? That's not what was asked here.
it worked, I moved the midi macro arrays to an external .h file, placed it into the library folder,... the sketch compiles and runs as it supposed to. Thanks for the help!