#include problems

A friend who is a proper C programmer (as opposed to a newbie to C++ like me) gave me a tiny bit of code which includes

#include
#include

but they seem to throw up an error when compiling.

compilation terminated
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

I commented out sections of the code bit by and traced it down to these two include statements as the problem.

Now he probably wrote it up in C++ or C# so the Arduino IDE may not have the necessary libraries included.

However I have used “map” in other code before in the Arduino IDE and it works, so I am not sure what the difference is between the map that is obviously included, and the #include

My code that has worked

turn = map(ch1,1035,1835,-255,255);

his code seems a little more complex like it is trying to retrieve a value from a remote call. (his looks like Spanish to me at the moment)

std::map<int, int> curveVals = {{ 0, 0}, {10, 1}, {15, 2}, {25, 3}, {35, 4}, {45, 5}, {55, 6}, {65, 7}, {75, 8}, {85, 9}, {95, 10}, {105, 12}, {115, 15},
  {125, 18}, {135, 21}, {145, 24}, {155, 27}, {165, 30}, {175, 34}, {185, 39}, {195, 45}, {205, 52}, {215, 61}, {225, 72}, {235, 85}, {245, 100}, {256, 0}}};

I put this error down to me needing to add #include and #include libraries to Arduino IDE
are these already in the Arduino IDE under another include or do I need to add them?

I have looked at Arduino - Libraries / https://www.arduino.cc/en/Guide/Libraries and a few other things that say how to add libraries, but it would seem to me something so common as map and string should already be included, and if they aren’t I don’t know where to get them.

Try putting “.h” in the name of the library.

#include <map.h>
#include <string.h>

string.h is a standard C library.

Here’s a reference on the map library

MorganS:
Try putting “.h” in the name of the library.

#include <map.h>

#include <string.h>




string.h is a standard C library. 

[Here's a reference on the map library](http://en.cppreference.com/w/cpp/container/map)

Thanks for the reference Morgan. I thought adding a .h might help so I tried it before, but alas same error message. I also figured they should be included in the library but wasn’t certain… I have included the whole code just in case it is being triggered by something else.

//At top of page

  #include <map.h>
  #include <string.h> 
or
  #include <map
  #include <string>  

//Section of code in loop 

std::map<int, int> curveVals = {{ 0, 0}, {10, 1}, {15, 2}, {25, 3}, {35, 4}, {45, 5}, {55, 6}, {65, 7}, {75, 8}, {85, 9}, {95, 10}, {105, 12}, {115, 15},
  {125, 18}, {135, 21}, {145, 24}, {155, 27}, {165, 30}, {175, 34}, {185, 39}, {195, 45}, {205, 52}, {215, 61}, {225, 72}, {235, 85}, {245, 100}, {256, 0}}};

  auto iPcnt = curveVals.upper_bound(abs(move));
  Serial.println(" iMove = " + std::to_string(abs(move)) + " " + (--iPcnt)->first); Serial.println();
  iPcnt = curveVals.upper_bound(abs(turn));
  Serial.println(" iTurn = " + std::to_string(abs(turn)) + " " + (--iPcnt)->first); Serial.println();

The lack of a .h ending is a C++ thing, and “string” and “map” are part of the C++ Standard Template Library that the arduino environment does not support by default.

westfw: The lack of a .h ending is a C++ thing, and "string" and "map" are part of the C++ Standard Template Library that the arduino environment does not support by default.

So are you saying I need to add them to the Ardunio IDE to access them?

Tried

  //#include <map>
  #include <string.h>

and it didn’t throw up an error, but I can’t test fully until I sort out the “map” since it is part of the same code.

Seem to have solved the problem by downloading and installing two zip libraries. ArduinoSTL-master.zip and StandardCplusplus-master.zip.

  #include <ArduinoSTL.h>
  #include <StandardCplusplus.h>  
  #include <map>
  #include <string.h>

seems to try and compile now but comes up with a different error.

sketch_Sabertooth_Output2:48: error: could not convert ‘{{0, 0}, {10, 1}, {15, 2}, {25, 3}, {35, 4}, {45, 5}, {55, 6}, {65, 7}, {75, 8}, {85, 9}, {95, 10}, {105, 12}, {115, 15}, {125, 18}, {135, 21}, {145, 24}, {155, 27}, {165, 30}, {175, 34}, {185, 39}, {195, 45}, {205, 52}, {215, 61}, {225, 72}, {235, 85}, {245, 100}, {256, 0}}’ from ‘’ to ‘std::map<int, int>’

std::map<int, int> curveVals = {{0,0},{10,1},{15,2},{25,3},{35,4},{45,5},{55,6},{65,7},{75,8},{85,9},{95,10},{105,12},{115,15},{125,18},{135,21},{145,24},{155,27},{165,30},{175,34},{185,39},{195,45},{205,52},{215,61},{225,72},{235,85},{245,100},{256,0}};

sketch_Sabertooth_Output2:51: error: ‘to_string’ is not a member of ‘std’

Serial.println(" iMove = " + std::to_string(abs(move)) + " " + (–iPcnt)->first); Serial.println();

^

sketch_Sabertooth_Output2:53: error: ‘to_string’ is not a member of ‘std’

Serial.println(" iTurn = " + std::to_string(abs(turn)) + " " + (–iPcnt)->first); Serial.println();

^

Using library ArduinoSTL-master at version 1.0.2 in folder: C:\Users\Laptop\Documents\Arduino\libraries\ArduinoSTL-master
Using library StandardCplusplus-master in folder: C:\Users\Laptop\Documents\Arduino\libraries\StandardCplusplus-master (legacy)
exit status 1
could not convert ‘{{0, 0}, {10, 1}, {15, 2}, {25, 3}, {35, 4}, {45, 5}, {55, 6}, {65, 7}, {75, 8}, {85, 9}, {95, 10}, {105, 12}, {115, 15}, {125, 18}, {135, 21}, {145, 24}, {155, 27}, {165, 30}, {175, 34}, {185, 39}, {195, 45}, {205, 52}, {215, 61}, {225, 72}, {235, 85}, {245, 100}, {256, 0}}’ from ‘’ to ‘std::map<int, int>’

 from '<brace-enclosed initializer list>' to 'std::map<int, int>'

It looks like initializing a map from a “brace-enclosed initializer” (the {{1,1}, {2,2},…} text that you have) is a “C++ v11” feature (2011 version of the standard), that is probably not supported by the arduino libraries you found.

The to_string() problem looks like a known bug (in gcc, not arduino specifically): 52015 – std::to_string does not work under MinGW

you haven’t posted the whole program, but based on the tiny pieces you have posted, I’m thinking that the chances that this program will run on Arduino without significant modifications are pretty low… Yeah, the “Arduino language” is C++, but it’s not C++ like desktop programmers use.

westfw:
It looks like initializing a map from a “brace-enclosed initializer” (the {{1,1}, {2,2},…} text that you have) is a “C++ v11” feature (2011 version of the standard), that is probably not supported by the arduino libraries you found.

The to_string() problem looks like a known bug (in gcc, not arduino specifically): 52015 – std::to_string does not work under MinGW

you haven’t posted the whole program, but based on the tiny pieces you have posted, I’m thinking that the chances that this program will run on Arduino without significant modifications are pretty low… Yeah, the “Arduino language” is C++, but it’s not C++ like desktop programmers use.

I figured it was a syntax error but was hoping it wasn’t, and that his code would work. He was trying to give me a more elegant way of doing this… Since I come from a VB back ground I started off trying to use Switch Case with range identifiers, but unfortunately C++ doesn’t support that, so I then whittled it down to two sizeable IF statements, he was trying to make it even tidier for me with the code he supplied. Is it possible to get a modified version of what he wrote to work? Without being able to step through it I don’t really know what he was trying to achieve.

If I was guess at what he was doing, since both curves are mapped the same it looks like he has tried to create a generic mapped table that both “move” and “turn” can use (and even if he wasn’t trying to do that, it’s not a bad idea).

}{
  std::map<int, int> curveVals = {{0,0},{10,1},{15,2},{25,3},{35,4},{45,5},{55,6},{65,7},{75,8},{85,9},{95,10},{105,12},{115,15},
  {125,18},{135,21},{145,24},{155,27},{165,30},{175,34},{185,39},{195,45},{205,52},{215,61},{225,72},{235,85},{245,100},{256,0}};

  auto iPcnt = curveVals.upper_bound(abs(move));
  Serial.println(" iMove = " + std::to_string(abs(move)) + " " + (--iPcnt)->first); Serial.println();
  iPcnt = curveVals.upper_bound(abs(turn));
  Serial.println(" iTurn = " + std::to_string(abs(turn)) + " " + (--iPcnt)->first); Serial.println();

}{  
  iMove = move;
  if (iMove > 0) bPos = true; else bPos = false, iMove = abs(iMove);
}{
       if (iMove > 0 && iMove < 11) iPcnt = 0; else if (iMove > 10 && iMove < 16) iPcnt = 1; else if (iMove > 15 && iMove < 26) iPcnt = 2; 
  else if (iMove > 25 && iMove < 36) iPcnt = 3; else if (iMove > 35 && iMove < 46) iPcnt = 4; else if (iMove > 45 && iMove < 56) iPcnt = 5;
  else if (iMove > 55 && iMove < 66) iPcnt = 6; else if (iMove > 65 && iMove < 76) iPcnt = 7; else if (iMove > 75 && iMove < 86) iPcnt = 8;
  else if (iMove > 85 && iMove < 96) iPcnt = 9; else if (iMove > 95 && iMove < 106) iPcnt = 10; else if (iMove > 105 && iMove < 116) iPcnt = 12;
  else if (iMove > 115 && iMove < 126) iPcnt = 15; else if (iMove > 125 && iMove < 136) iPcnt = 18; else if (iMove > 135 && iMove < 146) iPcnt = 21;
  else if (iMove > 145 && iMove < 156) iPcnt = 24; else if (iMove > 155 && iMove < 166) iPcnt = 27; else if (iMove > 165 && iMove < 176) iPcnt = 30;
  else if (iMove > 175 && iMove < 186) iPcnt = 34; else if (iMove > 185 && iMove < 196) iPcnt = 39; else if (iMove > 195 && iMove < 206) iPcnt = 45;
  else if (iMove > 205 && iMove < 216) iPcnt = 52; else if (iMove > 215 && iMove < 226) iPcnt = 61; else if (iMove > 225 && iMove < 236) iPcnt = 72;
  else if (iMove > 235 && iMove < 246) iPcnt = 85; else if (iMove > 245 && iMove < 256) iPcnt = 100; else iPcnt = 0;
  sMsg = iMove, sMsg1 = iPcnt;
  Serial.println(" iMove = " + sMsg + " " + sMsg1); Serial.println();
  iMove = 0;
}{
    iTurn = turn;
  if (iTurn > 0) bPos = true; else bPos = false, iTurn = abs(iTurn);
}{
       if (iTurn > 0 && iTurn < 11) iPcnt1 = 0; else if (iTurn > 10 && iTurn < 16) iPcnt1 = 1; else if (iTurn > 15 && iTurn < 26) iPcnt1 = 2; 
  else if (iTurn > 25 && iTurn < 36) iPcnt1 = 3; else if (iTurn > 35 && iTurn < 46) iPcnt1 = 4; else if (iTurn > 45 && iTurn < 56) iPcnt1 = 5;
  else if (iTurn > 55 && iTurn < 66) iPcnt1 = 6; else if (iTurn > 65 && iTurn < 76) iPcnt1 = 7; else if (iTurn > 75 && iTurn < 86) iPcnt1 = 8;
  else if (iTurn > 85 && iTurn < 96) iPcnt1 = 9; else if (iTurn > 95 && iTurn < 106) iPcnt1 = 10; else if (iTurn > 105 && iTurn < 116) iPcnt1 = 12;
  else if (iTurn > 115 && iTurn < 126) iPcnt1 = 15; else if (iTurn > 125 && iTurn < 136) iPcnt1 = 18; else if (iTurn > 135 && iTurn < 146) iPcnt1 = 21;
  else if (iTurn > 145 && iTurn < 156) iPcnt1 = 24; else if (iTurn > 155 && iTurn < 166) iPcnt1 = 27; else if (iTurn > 165 && iTurn < 176) iPcnt1 = 30;
  else if (iTurn > 175 && iTurn < 186) iPcnt1 = 34; else if (iTurn > 185 && iTurn < 196) iPcnt1 = 39; else if (iTurn > 195 && iTurn < 206) iPcnt1 = 45;
  else if (iTurn > 205 && iTurn < 216) iPcnt1 = 52; else if (iTurn > 215 && iTurn < 226) iPcnt1 = 61; else if (iTurn > 225 && iTurn < 236) iPcnt1 = 72;
  else if (iTurn > 235 && iTurn < 246) iPcnt1 = 85; else if (iTurn > 245 && iTurn < 256) iPcnt1 = 100; else iPcnt1 = 0;
  sMsg = iTurn, sMsg1 = iPcnt1;
  Serial.println(" iTurn = " + sMsg + " " + sMsg1); Serial.println();   
  iTurn = 0;
}{

Just had an idea that might achieve the same result... Not exactly sure how this would work right now in code but...

Since the mapping is static, and the same ranges are used for both "turn" and "move", and it can be used on the negative and positive as long as a boolean flag is kept, there might be a way for me to create a two dimensional array to store half the values in setup(), and a much simpler comparison done in the loop(). Should result in a quarter of the size code.

I’d just do something like:

byte curveVals[][2] = {{ 0, 0}, {10, 1}, {15, 2}, {25, 3}, {35, 4},
               {45, 5}, {55, 6}, {65, 7}, {75, 8}, {85, 9},
               {95, 10}, {105, 12}, {115, 15}, {125, 18},
               {135, 21}, {145, 24}, {155, 27}, {165, 30},
               {175, 34}, {185, 39}, {195, 45}, {205, 52},
               {215, 61}, {225, 72}, {235, 85}, {245, 100},
               {255,100} // last value
};

int map_to_curveVal(int input)
{
    // I'm not sure this is needed...
    if (input > 255) {
    return 0;  // handle our ONE output val larger than a byte
    }

    for (byte i=0; i < sizeof(curveVals)/2 - 1; i++) {
    if (input >= curveVals[i][0] && input < curveVals[i+1][0]) {
        return curveVals[i][1];
    }
    }
    return -1;
}

Yeah, C++ “map” might do something more efficient than a linear search through the table. But it’s not a very BIG table, so it probably doesn’t matter…

Replace the to_string() calls with separate print statements:

//Serial.println(" iMove = " + std::to_string(abs(move)) + " " + (--iPcnt)->first); Serial.println();
  iPcnt = curveVals.upper_bound(abs(turn));
// becomes
Serial.print(" iMove = ");
Serial.print(abs(move));
Serial.print(" ");
Serial.print((--iPcnt)->first);
Serial.println(); Serial.println();