Arduino std::map returning random values
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I'm working with an arduino UNO. I would like to be able to send it set
and get
commands over serial and have it update class data class members accordingly by key value pair. I spoke to users in the cpp room, and they suggested I try using map to map every key to value.
command structurecommand:key:value
ex. set:key1:20
ex. get:key2
I created a class called Uno, assigned all my keys to private data members, and defined set and get functions. However, I am experiencing unintended behavior.
Unintended behavior
The set function ends up setting key1
and key2
to the same value, and the get
function returns a random integer value that wasn't assigned.
#include <ArduinoSTL.h>
#include <string.h>
#include <map>
class Uno
//private
int key1;
int key2;
std::map<String, int Uno::*> keys;
public:
//Constructor
Uno()
key1 = 0;
key2 = 0;
keys["key1"] = &Uno::key1;
keys["key2"] = &Uno::key2;
bool setKey(String key, int value)
if (keys.count(key))
this->*keys[key] = value;
return true;
return false;
int getKey(String key)
if (keys.count(key))
return this->*keys[key];
;
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
bool scan = false; // whether a scan is in progress
Uno myMS; // global declaration of Mass Spec Class
void setup()
// initialize serial:
Serial.begin(9600);
// reserve 250 bytes for the inputString:
inputString.reserve(250);
void loop()
if (stringComplete)
t(inputString); // tokenize and process string
//RESET STRING
inputString = "";
stringComplete = false;
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == 'n')
stringComplete = true;
void t(String inputString)
//get command
String command = getValue(inputString, ':', 0);
if(command == "set")
// get key, get value
String key = getValue(inputString, ':', 1);
int value = (getValue(inputString, ':', 2)).toInt();
Serial.println(myMS.setKey(key,value));
else if(command == "get")
String key = getValue(inputString, ':', 1);
int value = myMS.getKey(key);
Serial.println(value);
else if(command == "stop")
scan = false;
else if(command == "scan")
scan = true;
while(scan)
// Serial.println(myMS.scan());
else
Serial.println("not recognized");
String getValue(String data, char separator, int index)
int found = 0;
int strIndex = 0, -1;
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++) i==maxIndex)
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
EDIT: Here is a REPL IT working demo of concept provided by nwp.
https://repl.it/repls/AntiqueProductiveMineral
Sample output
set:key1:10 ===> 1 (GOOD)
get:key1 ===> 32512
c++ map
New contributor
add a comment |Â
up vote
2
down vote
favorite
I'm working with an arduino UNO. I would like to be able to send it set
and get
commands over serial and have it update class data class members accordingly by key value pair. I spoke to users in the cpp room, and they suggested I try using map to map every key to value.
command structurecommand:key:value
ex. set:key1:20
ex. get:key2
I created a class called Uno, assigned all my keys to private data members, and defined set and get functions. However, I am experiencing unintended behavior.
Unintended behavior
The set function ends up setting key1
and key2
to the same value, and the get
function returns a random integer value that wasn't assigned.
#include <ArduinoSTL.h>
#include <string.h>
#include <map>
class Uno
//private
int key1;
int key2;
std::map<String, int Uno::*> keys;
public:
//Constructor
Uno()
key1 = 0;
key2 = 0;
keys["key1"] = &Uno::key1;
keys["key2"] = &Uno::key2;
bool setKey(String key, int value)
if (keys.count(key))
this->*keys[key] = value;
return true;
return false;
int getKey(String key)
if (keys.count(key))
return this->*keys[key];
;
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
bool scan = false; // whether a scan is in progress
Uno myMS; // global declaration of Mass Spec Class
void setup()
// initialize serial:
Serial.begin(9600);
// reserve 250 bytes for the inputString:
inputString.reserve(250);
void loop()
if (stringComplete)
t(inputString); // tokenize and process string
//RESET STRING
inputString = "";
stringComplete = false;
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == 'n')
stringComplete = true;
void t(String inputString)
//get command
String command = getValue(inputString, ':', 0);
if(command == "set")
// get key, get value
String key = getValue(inputString, ':', 1);
int value = (getValue(inputString, ':', 2)).toInt();
Serial.println(myMS.setKey(key,value));
else if(command == "get")
String key = getValue(inputString, ':', 1);
int value = myMS.getKey(key);
Serial.println(value);
else if(command == "stop")
scan = false;
else if(command == "scan")
scan = true;
while(scan)
// Serial.println(myMS.scan());
else
Serial.println("not recognized");
String getValue(String data, char separator, int index)
int found = 0;
int strIndex = 0, -1;
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++) i==maxIndex)
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
EDIT: Here is a REPL IT working demo of concept provided by nwp.
https://repl.it/repls/AntiqueProductiveMineral
Sample output
set:key1:10 ===> 1 (GOOD)
get:key1 ===> 32512
c++ map
New contributor
why do you think that this is an Arduino question? ... it appears to be a C/C++ question
â jsotola
3 hours ago
1
@jsotola It is an arduino question, because I am running the code on the arduino using the arduino String type. I am also using Serial on the arduino. I'm open to other arduino methods for storing key value pairs.
â ex080
3 hours ago
the 32512 is the return value of getKey if it didn't found the key
â Juraj
1 hour ago
Ok, but that is confusing because I am using the same method toset
. I know the set function is working correctly, because if I doSerial.println(key1);
from inside the class it prints the correct value.
â ex080
1 hour ago
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm working with an arduino UNO. I would like to be able to send it set
and get
commands over serial and have it update class data class members accordingly by key value pair. I spoke to users in the cpp room, and they suggested I try using map to map every key to value.
command structurecommand:key:value
ex. set:key1:20
ex. get:key2
I created a class called Uno, assigned all my keys to private data members, and defined set and get functions. However, I am experiencing unintended behavior.
Unintended behavior
The set function ends up setting key1
and key2
to the same value, and the get
function returns a random integer value that wasn't assigned.
#include <ArduinoSTL.h>
#include <string.h>
#include <map>
class Uno
//private
int key1;
int key2;
std::map<String, int Uno::*> keys;
public:
//Constructor
Uno()
key1 = 0;
key2 = 0;
keys["key1"] = &Uno::key1;
keys["key2"] = &Uno::key2;
bool setKey(String key, int value)
if (keys.count(key))
this->*keys[key] = value;
return true;
return false;
int getKey(String key)
if (keys.count(key))
return this->*keys[key];
;
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
bool scan = false; // whether a scan is in progress
Uno myMS; // global declaration of Mass Spec Class
void setup()
// initialize serial:
Serial.begin(9600);
// reserve 250 bytes for the inputString:
inputString.reserve(250);
void loop()
if (stringComplete)
t(inputString); // tokenize and process string
//RESET STRING
inputString = "";
stringComplete = false;
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == 'n')
stringComplete = true;
void t(String inputString)
//get command
String command = getValue(inputString, ':', 0);
if(command == "set")
// get key, get value
String key = getValue(inputString, ':', 1);
int value = (getValue(inputString, ':', 2)).toInt();
Serial.println(myMS.setKey(key,value));
else if(command == "get")
String key = getValue(inputString, ':', 1);
int value = myMS.getKey(key);
Serial.println(value);
else if(command == "stop")
scan = false;
else if(command == "scan")
scan = true;
while(scan)
// Serial.println(myMS.scan());
else
Serial.println("not recognized");
String getValue(String data, char separator, int index)
int found = 0;
int strIndex = 0, -1;
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++) i==maxIndex)
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
EDIT: Here is a REPL IT working demo of concept provided by nwp.
https://repl.it/repls/AntiqueProductiveMineral
Sample output
set:key1:10 ===> 1 (GOOD)
get:key1 ===> 32512
c++ map
New contributor
I'm working with an arduino UNO. I would like to be able to send it set
and get
commands over serial and have it update class data class members accordingly by key value pair. I spoke to users in the cpp room, and they suggested I try using map to map every key to value.
command structurecommand:key:value
ex. set:key1:20
ex. get:key2
I created a class called Uno, assigned all my keys to private data members, and defined set and get functions. However, I am experiencing unintended behavior.
Unintended behavior
The set function ends up setting key1
and key2
to the same value, and the get
function returns a random integer value that wasn't assigned.
#include <ArduinoSTL.h>
#include <string.h>
#include <map>
class Uno
//private
int key1;
int key2;
std::map<String, int Uno::*> keys;
public:
//Constructor
Uno()
key1 = 0;
key2 = 0;
keys["key1"] = &Uno::key1;
keys["key2"] = &Uno::key2;
bool setKey(String key, int value)
if (keys.count(key))
this->*keys[key] = value;
return true;
return false;
int getKey(String key)
if (keys.count(key))
return this->*keys[key];
;
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
bool scan = false; // whether a scan is in progress
Uno myMS; // global declaration of Mass Spec Class
void setup()
// initialize serial:
Serial.begin(9600);
// reserve 250 bytes for the inputString:
inputString.reserve(250);
void loop()
if (stringComplete)
t(inputString); // tokenize and process string
//RESET STRING
inputString = "";
stringComplete = false;
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == 'n')
stringComplete = true;
void t(String inputString)
//get command
String command = getValue(inputString, ':', 0);
if(command == "set")
// get key, get value
String key = getValue(inputString, ':', 1);
int value = (getValue(inputString, ':', 2)).toInt();
Serial.println(myMS.setKey(key,value));
else if(command == "get")
String key = getValue(inputString, ':', 1);
int value = myMS.getKey(key);
Serial.println(value);
else if(command == "stop")
scan = false;
else if(command == "scan")
scan = true;
while(scan)
// Serial.println(myMS.scan());
else
Serial.println("not recognized");
String getValue(String data, char separator, int index)
int found = 0;
int strIndex = 0, -1;
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++) i==maxIndex)
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
EDIT: Here is a REPL IT working demo of concept provided by nwp.
https://repl.it/repls/AntiqueProductiveMineral
Sample output
set:key1:10 ===> 1 (GOOD)
get:key1 ===> 32512
c++ map
c++ map
New contributor
New contributor
edited 4 hours ago
New contributor
asked 4 hours ago
ex080
112
112
New contributor
New contributor
why do you think that this is an Arduino question? ... it appears to be a C/C++ question
â jsotola
3 hours ago
1
@jsotola It is an arduino question, because I am running the code on the arduino using the arduino String type. I am also using Serial on the arduino. I'm open to other arduino methods for storing key value pairs.
â ex080
3 hours ago
the 32512 is the return value of getKey if it didn't found the key
â Juraj
1 hour ago
Ok, but that is confusing because I am using the same method toset
. I know the set function is working correctly, because if I doSerial.println(key1);
from inside the class it prints the correct value.
â ex080
1 hour ago
add a comment |Â
why do you think that this is an Arduino question? ... it appears to be a C/C++ question
â jsotola
3 hours ago
1
@jsotola It is an arduino question, because I am running the code on the arduino using the arduino String type. I am also using Serial on the arduino. I'm open to other arduino methods for storing key value pairs.
â ex080
3 hours ago
the 32512 is the return value of getKey if it didn't found the key
â Juraj
1 hour ago
Ok, but that is confusing because I am using the same method toset
. I know the set function is working correctly, because if I doSerial.println(key1);
from inside the class it prints the correct value.
â ex080
1 hour ago
why do you think that this is an Arduino question? ... it appears to be a C/C++ question
â jsotola
3 hours ago
why do you think that this is an Arduino question? ... it appears to be a C/C++ question
â jsotola
3 hours ago
1
1
@jsotola It is an arduino question, because I am running the code on the arduino using the arduino String type. I am also using Serial on the arduino. I'm open to other arduino methods for storing key value pairs.
â ex080
3 hours ago
@jsotola It is an arduino question, because I am running the code on the arduino using the arduino String type. I am also using Serial on the arduino. I'm open to other arduino methods for storing key value pairs.
â ex080
3 hours ago
the 32512 is the return value of getKey if it didn't found the key
â Juraj
1 hour ago
the 32512 is the return value of getKey if it didn't found the key
â Juraj
1 hour ago
Ok, but that is confusing because I am using the same method to
set
. I know the set function is working correctly, because if I do Serial.println(key1);
from inside the class it prints the correct value.â ex080
1 hour ago
Ok, but that is confusing because I am using the same method to
set
. I know the set function is working correctly, because if I do Serial.println(key1);
from inside the class it prints the correct value.â ex080
1 hour ago
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
3
down vote
You set CR/LF in Serial Monitor and you test n as end of line in code. and/or you attach the n char to the end of key. The rn or n is parsed/attached to key. The key for get is the "key1rn" or "key1r"
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == 'n')
stringComplete = true;
else
inputString += inChar;
there are obsolete things in your code, like the this->* or Uno::
I have Newline only and it's not working anyways
â KIIV
30 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
You set CR/LF in Serial Monitor and you test n as end of line in code. and/or you attach the n char to the end of key. The rn or n is parsed/attached to key. The key for get is the "key1rn" or "key1r"
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == 'n')
stringComplete = true;
else
inputString += inChar;
there are obsolete things in your code, like the this->* or Uno::
I have Newline only and it's not working anyways
â KIIV
30 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
add a comment |Â
up vote
3
down vote
You set CR/LF in Serial Monitor and you test n as end of line in code. and/or you attach the n char to the end of key. The rn or n is parsed/attached to key. The key for get is the "key1rn" or "key1r"
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == 'n')
stringComplete = true;
else
inputString += inChar;
there are obsolete things in your code, like the this->* or Uno::
I have Newline only and it's not working anyways
â KIIV
30 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
add a comment |Â
up vote
3
down vote
up vote
3
down vote
You set CR/LF in Serial Monitor and you test n as end of line in code. and/or you attach the n char to the end of key. The rn or n is parsed/attached to key. The key for get is the "key1rn" or "key1r"
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == 'n')
stringComplete = true;
else
inputString += inChar;
there are obsolete things in your code, like the this->* or Uno::
You set CR/LF in Serial Monitor and you test n as end of line in code. and/or you attach the n char to the end of key. The rn or n is parsed/attached to key. The key for get is the "key1rn" or "key1r"
void serialEvent()
while (Serial.available())
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == 'n')
stringComplete = true;
else
inputString += inChar;
there are obsolete things in your code, like the this->* or Uno::
edited 23 mins ago
answered 38 mins ago
Juraj
3,8842517
3,8842517
I have Newline only and it's not working anyways
â KIIV
30 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
add a comment |Â
I have Newline only and it's not working anyways
â KIIV
30 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
I have Newline only and it's not working anyways
â KIIV
30 mins ago
I have Newline only and it's not working anyways
â KIIV
30 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
change the serialEvent to not to attach the n to the string
â Juraj
29 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
Right, he's not skipping it in that parser :D
â KIIV
23 mins ago
add a comment |Â
ex080 is a new contributor. Be nice, and check out our Code of Conduct.
ex080 is a new contributor. Be nice, and check out our Code of Conduct.
ex080 is a new contributor. Be nice, and check out our Code of Conduct.
ex080 is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f56400%2farduino-stdmap-returning-random-values%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
why do you think that this is an Arduino question? ... it appears to be a C/C++ question
â jsotola
3 hours ago
1
@jsotola It is an arduino question, because I am running the code on the arduino using the arduino String type. I am also using Serial on the arduino. I'm open to other arduino methods for storing key value pairs.
â ex080
3 hours ago
the 32512 is the return value of getKey if it didn't found the key
â Juraj
1 hour ago
Ok, but that is confusing because I am using the same method to
set
. I know the set function is working correctly, because if I doSerial.println(key1);
from inside the class it prints the correct value.â ex080
1 hour ago