Reputation: 1138
I am trying to get a Hash Table or Dictionary to work on the Arduino Mega 2560. My goal is to have something like
dictionary[ENGLISH]["ACCOUNT"] = "Account";
dictionary[ENGLISH]["DATE_AND_TIME"] = "Date and Time";
dictionary[ENGLISH]["IDLE"] = "Idle";
dictionary[ENGLISH]["Language"] = "Languge"
dictionary[ENGLISH]["MAIN_MENU"] = "Main Menu";
dictionary[ENGLISH]["PRESCRIPTION"] = "Prescription";
dictionary[ENGLISH]["SETTINGS"] = "Settings";
dictionary[ENGLISH]["SOUND"] = "Sound";
where ENGLISH is essentially a constant 0, and I will have SPANISH and FRENCH as well (1 and 2 respectively). That is, an array of 3 dictionary elements.
On a first Google search, I found a link to a library that models the C++ STL, but it is not working on Arduino 1.0.3 for me at all. I was wondering if anybody had an alternative for using maps/hash tables in arduino for me, or a fix to get the library mentioned working.
For some context of my situation, I am modeling a menu system via a touchscreen on the Arduino, it has to accept 3 languages (for the buttons). The chosen language is found in a location in EEPROM and I'll keep it in the variable 'lang', when I need to print something to the screen, I'll do something like:
screen.print(dictionary[lang]["SOUND"], CENTER, 23);
and depending on the 'lang' the user has chosen, it will print accordingly, ideally.
Upvotes: 17
Views: 52432
Reputation: 4150
I think a hash table may be unnecessary here, and there are good reasons to avoid it on this platform anyway.
Usually in such situations there is no need for a string key, since the key is visible only inside your code, and the key is not interacted with from outside your program. Thus, the usual solution is to have a (pseudo) integer key, in the form of #define
which is handled by the preprocessor and not your program:
#define kWORDIDX_LANGUAGE 1
#define kWORDIDX_SOUND 2
#define kWORDIDX_MAINMENU 3
#define kWORDIDX_SPAGHETTI 4
...
dictionary[ENGLISH][kWORDIDX_SOUND] = "Sound";
...
You can then access your dictionary entries like this Sreen.print(dictionary[lang][kWORDIDX_SOUND], CENTER, 23);
or something similar.
The advantages of this approach are:
#define
d keys, you get a compile error, which is what you wantArduino is a memory-constrained platform: it has very limited memory. The problem with using a real hash map is as follows:
int
s (usually). Using #define
keys, which are converted by the compiler to integer literals, you are using 1, 2, or 4 bytes per key (depending on your compiler settings), whereas each string key requires strlen(s) + 1
memory space to store. This space is actually used twice: once in Flash (that is where variables are initialized from) and once in SRAM.PROGMEM
keyword. If you build your dictionary using a hash map, this route will not be available to you. On the other hand, given a #define
-type indexing scheme as above, it will be very easy to store all your language strings as PROGMEM
strings.Upvotes: 31
Reputation: 5442
You can also use a data structure to define a dictionary:
typedef struct {
uint8_t lang;
char* sound;
char* value;
} langDictionary;
Then you can define an array of the structure with the values to be used:
const langDictionary myDictionaryArr[] {
{0, "ENGLISH", "Settings"},
{1, "SPANISH", "Ajustes"},
{2, "FRENCH", "Paramètres"}
};
And finally you can use the array to search the properties:
void setup() {
Serial.begin(115200);
for(uint8_t i = 0; i < sizeof(myDictionaryArr)/sizeof(langDictionary); ++i) {
Serial.println(myDictionaryArr[i].value); //Prints the values: "Settings", "Ajustes" and "Paramètres"
}
}
Upvotes: 11
Reputation: 444
while i perfectly agree with the previous answers, the arduino playground has as "HashMap Library for Arduino".
Upvotes: 4