Go Down

Topic: making a library (Read 1 time) previous topic - next topic

a.mlw.walker

hi
I have 8 leds that I want to light up different combinations of at different times.
I have found the best way is to use binary numbers i.e 0b10101010 etc etc. However I have a lot of combinations so I am making #defines for the combinations i.e:
Code: [Select]

#define comb1 0b01010101

etc etc.
I want someone else to be able to edit/add combinations so I want to make a completely seperate file that contains just these. However depending on other conditions within the program one combination can mean two different things. i.e if the user makes a selection, then the combination of leds coming on could be 0b01010101 which due to that selection means something different to a different selection even though the same led's come on. So I want library files that each contain all the combinations for the right situations depending on what selection a user makes.
I think I cna just do it with header files somehow, i.e create a header file for one selection with all the defines in, and another header file with all the combinations in for a different user selection, but how to get the program to select a define from one header file rather than another if the names of the defines are the same?

As a basic example, if the user can make a selection of Boy or girl. Then the user selects hair colour, blonde brown red. Depending on the selection, depends on what leds come on, however the defines would be called the same (blonde brown red) but may have different binary values, so if I have two header files, boy.h and girl.h how does the program know which define to select?
I think that might sound confusing but hopefully someone understands my example?

Tom Carpenter

#1
Jul 03, 2012, 11:21 am Last Edit: Jul 03, 2012, 11:24 am by TCWORLD Reason: 1
Code: [Select]
#define BOY 1

#if defined(BOY)
 #include <boyCombinations.h>
#elif defined(GIRL)
 #include <girlCombinations.h>
#else
 #error please include one of the files
#endif

That would include the boyCombinations.h file only.


Code: [Select]
#define GIRL 1

#if defined(BOY)
 #include <boyCombinations.h>
#elif defined(GIRL)
 #include <girlCombinations.h>
#else
 #error please include one of the files
#endif

That would include the girlCombinations.h file only.


Code: [Select]

#if defined(BOY)
 #include <boyCombinations.h>
#elif defined(GIRL)
 #include <girlCombinations.h>
#else
 #error please include one of the files
#endif

That would give an error as neither are included.


You could use similar "#if defined()" statements to allow the user to choose from a set of header files containing the definitions. You would have to make sure that those statements came before the #include for your library otherwise they wouldn't be present in the library.
~Tom~

dxw00d

If you need the user to make the selection while the sketch is running, then using header files is not going to work.

a.mlw.walker

#3
Jul 03, 2012, 11:39 am Last Edit: Jul 03, 2012, 11:43 am by a.mlw.walker Reason: 1
dxw00d, yea thats what I thought when I read TCWorld's last sentence.... I cant include the library when the user is making a selection....
can the
Code: [Select]

#if
#endif

not rely on a variable rather than a define?
Or what bout making functions in .cpp files with constants in, and then calling the correct function or something?

EDIT:
Or maybe a class? Could be my time to learn c++ classes (I know Java classes) if someone could advise me on how the class would work to do this?

Tom Carpenter

#4
Jul 03, 2012, 11:42 am Last Edit: Jul 03, 2012, 11:44 am by TCWORLD Reason: 1
Ahh right, I must have misread the question - hadn't realised they needed changing during execution.

If thats the case, you will almost certainly have to do it using arrays, rather than #defines. If you need a large number of combinations, you either need to store the arrays using PROGMEM as there is more space in the program memory that the ram, and I would assume the arrays wouldn't need to change (you just select the correct one).
The alternative which may not be an alternative is to try to figure out if there is any mathematical relationship between your combinations that would allow them to be generated on the fly.


Anything with a # in front of it is a preprocessor directive, and doesn't happen during execution - it is all taken care of before the code is even compiled.
e.g.
Your code
Code: [Select]
#define HELLO 1
int hello = HELLO;


What the compiler sees:
Code: [Select]

int hello = 1;


As such, there is nothing the user can do to select a set of #defines to be included - they are not variables, but placeholders to make it easier for the programmer to see what they are writing.
~Tom~

a.mlw.walker

Yeah, a progmem'd array is probably the best bet isnt it.

BTW, how can I put variables in other files (tabs)? It is really annoying that all my global variables HAVE to be in one file with setup and loop at the bottom...

EDIT:
Can I have an enum or something that makes it easier to access the array by a name, rather than by index, because that will get confusing? i.e enums can have values in java...

Tom Carpenter

#6
Jul 03, 2012, 11:47 am Last Edit: Jul 03, 2012, 11:49 am by TCWORLD Reason: 1
Dropdown array at the right. Click new tab. Name it something like: Variables.h (the name isn't important, just the extension), and the put: #include "Variables.h" at the very beginning of your sketch.
All your globals can go in this file. It is rather helpful with large arrays to stop you having to fight your way though them.
~Tom~

a.mlw.walker

Ahh cheers, i'll try that. did you see my edit about using enums?

Tom Carpenter

#8
Jul 03, 2012, 11:51 am Last Edit: Jul 03, 2012, 11:54 am by TCWORLD Reason: 1
I have never used enum's before so couldn't comment on that. But if you dont want to write the indicies, you can use #defines for them, e.g:

Code: [Select]
char array[1000][20];
...
#define CAT 500
#define HAIRY 10
...
array[CAT][HAIRY]


That would access the array index at array[500][10]. This is one of the ways #defines can be very effective. This would make it possible for the user to make a selection.

E.g.
Code: [Select]
char array[1000][2];
...
#define BOY 0
#define GIRL 1
#define COMBINATIONTWO 2
...
if(userSelectedBoy){
  someVaraible = array[COMBINATIONTWO][BOY];
}else{
  someVariable = array[COMBINATIONTWO][GIRL];
}
~Tom~

a.mlw.walker

Oh yeah that could work.
As I understand it, arduino is basically just C++.
I found this:
http://www.cprogramming.com/tutorial/enum.html
which explains enums in C++ can be used like this:
Code: [Select]

enum wind_directions_t {NO_WIND = 4, NORTH_WIND = 3, SOUTH_WIND = 2, EAST_WIND = 1, WEST_WIND = 0};


so perhaps I could use that? which gets around having to define a define for every location in the array?

Tom Carpenter

Correct me if i'm wrong but doesn't that just create a variable that can only take certain numbers? unless I have misunderstood, I can't see how that would help you.

Besides you wouldn't have to have a #define for each index. For example if you have a series of combinations like, combination1, combination2 etc. and they were all stored sequentially, you could do this:

#define CombinationStart 10

array[CombinationStart + 0]; //0th combination
array[CombinationStart + 1]; //1st combination
array[CombinationStart + 2]; //2nd combination

The compiler would automatically optimise these calculations into the correct literals so the arduino wouldn't have to do the additions.
~Tom~

a.mlw.walker

Im not going to correct anything, Im trying to work out what the most efficient way of doing this is.
yeah the way I saw the enumerator was I could do
Code: [Select]

enum boy{brown = 0b01010101, blonde = 0b11110000, red = 0b00001111};

sort of thing, and then i could call on the words brown, blonde, red for the values they represent?

One thing I was also wondering though is where enumerators are stored, ram of flash...

WizenedEE


Im not going to correct anything, Im trying to work out what the most efficient way of doing this is.
yeah the way I saw the enumerator was I could do
Code: [Select]

enum boy{brown = 0b01010101, blonde = 0b11110000, red = 0b00001111};

sort of thing, and then i could call on the words brown, blonde, red for the values they represent?

One thing I was also wondering though is where enumerators are stored, ram of flash...


The names aren't stored anywhere

a.mlw.walker

Sorry I dont understand what you mean?

You mean ram/flash?

so whenever I write brown/blonde/red in the code, when it compiles it will change to the binary value then and there?

PaulS

Quote
when it compiles it will change to the binary value then and there?

Exactly.

Go Up