Arduino std::map returning random values

The name of the pictureThe name of the pictureThe name of the pictureClash 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 structure
command: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









share|improve this question









New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • 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 do Serial.println(key1); from inside the class it prints the correct value.
    – ex080
    1 hour ago














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 structure
command: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









share|improve this question









New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • 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 do Serial.println(key1); from inside the class it prints the correct value.
    – ex080
    1 hour ago












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 structure
command: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









share|improve this question









New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











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 structure
command: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






share|improve this question









New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 4 hours ago





















New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 4 hours ago









ex080

112




112




New contributor




ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






ex080 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











  • 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 do Serial.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






  • 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 do Serial.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










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::






share|improve this answer






















  • 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










Your Answer





StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "540"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);






ex080 is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















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






























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::






share|improve this answer






















  • 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














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::






share|improve this answer






















  • 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












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::






share|improve this answer














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::







share|improve this answer














share|improve this answer



share|improve this answer








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
















  • 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










ex080 is a new contributor. Be nice, and check out our Code of Conduct.









 

draft saved


draft discarded


















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.













 


draft saved


draft discarded














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













































































Comments

Popular posts from this blog

Long meetings (6-7 hours a day): Being “babysat” by supervisor

Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

Confectionery