In the Arduino environment, you need to process the string to get the algorithm of the engine. For example, from the line "a15,s150,p10;a45,s200,p30;" There should be 3 arrays:

 int stepperAngles[] = {15, 45}; int stepperSpeeds[] = {150, 200}; int stepperPauses[] = {10, 30}; 

The string is specified in this format. The number of engine states may vary. Maybe it is worth creating a class, for example Frame in which to store 3 parameters for each state and to make an array from class instances? If so, how is this better done?

    5 answers 5

    I haven't programmed in C ++ for a long time, and never for Arduino, maybe the latter has some limitations that I don't know about. I sketched something like this using vectors and strings:

     vector<int> stepperAngles, stepperSpeeds, stepperPauses; enum state {undefined, angle, speed, pause}; void parse(string str) { state next = undefined; int num = 0; for(int i=0; i<str.size(); i++) { if(str[i] == 'a') next = angle; else if(str[i] == 's') next = speed; else if(str[i] == 'p') next = pause; else if(str[i] >= '0' && str[i] <= '9') { if(num == 0) { num += str[i] - '0'; continue; } num *= 10; num += str[i] - '0'; } else if(str[i] == ',') { if(next == angle) stepperAngles.push_back(num); else if(next == speed) stepperSpeeds.push_back(num); else if(next == pause) stepperPauses.push_back(num); } } } 

    According to my ideas, after a minimal revision, it should work.

    • num probably need to be reset for each next number, also except , to check again ; - Vladimir Gamalyan
    • @Rennorb. To push STL into Arduin is not a good solution. The limitations are simple - RAM - two kilobytes. Processor 20 MIPS (with creak). - gbg
    • @gbg controller esp8266 - Andrew Romanenko

    I would not recommend using this solution in a really working program. There are no error handling tools. That will lead to the most unpredictable results during the operation of the program.

    IMHO, the right solution is to use a regular expression library (and your string is a classic regular expression). Everything is sorted out there, checked and monitored ...

     man 3 regex 
    • one
      The author still has arduino, which imposes a limit on memory / speed. However, if regexs fit into them, this is the simplest and most reliable solution. - Vladimir Gamalyan
    • @VladimirGamalian Arduino environment and the controller esp8266 which is pretty not weak. - Andrew Romanenko

    Here is a decision to come to mind. There is one problem in it. Since it is impossible to dynamically set the size of the array, we had to set it with a constant. To solve the problem in two ways. Or use vector, or pre-determine the maximum size of the array.

     #include <iostream> #include <string> #include <sstream> #include <algorithm> struct Frame{ int a; int s; int p; }; std::istream& operator>>(std::istream &is, Frame &frame){ is.ignore(1); //a is >> frame.a; is.ignore(2); //,s is >> frame.s; is.ignore(2); //,p is >> frame.p; is.ignore(1); //; return is; } int main(){ const int size = 2; int arrA[size] = {0}; int arrS[size] = {0}; int arrP[size] = {0}; std::istringstream is("a15,s150,p10;a45,s200,p30;"); Frame frame; for(int i = 0; i < size && is >> frame; ++i){ arrA[i] = frame.a; arrS[i] = frame.s; arrP[i] = frame.p; } } 
    • And why it is impossible to set the size of an array as a constant? Any stl restrictions in arduin sdk? - Vladimir Gamalyan
    • @VladimirGamalian, you can set the size of a constant. I said that it can not be changed dynamically. And he proposed two ways to solve or take a vector, or an array with a margin - yrHeTaTeJlb
    • Well, then the second question is why you can not change dynamically. - Vladimir Gamalyan
    • @VladimirGamalian, I will answer a question with a question. And how to change the size of the array in the stack? - yrHeTaTeJlb
    • Everything, understood, you have not a vector, did not carefully read. - Vladimir Gamalyan

    Develop a binary protocol and transfer information to the controller in the form in which you need to work with it.

    Parsing the string is too much work for the controller, it’s already weak, barely 20 MIPS does.

    Since you have a web server there, send in your request your arrays encoded in BASE64. Why arrange yourself extra work on parsing?

    • on the controller raised Web server. The string is sent to it in the GET request. - Andrew Romanenko
    • @AndrewRomanenko so send the necessary arrays encoded in base64. Even easier. - gbg
    • The difference in load between base64 parsing and the author's custom line, compared to the presence of a web server, is unlikely to be noticeable. And the line is still readable. Remember how everyone said that json is a sax, a lot of extra bytes. But then it turned out that it is cool to debug, and no one cares about the straining of computers. Those. I would generally send to json (joking) - Vladimir Gamalyan
    • @Vladimir Gamalian I have a modest page in my controller which has a form with an input field for the algorithm. I thought that writing a list of parameters in a row according to a template is the easiest and user-friendly option for an ordinary user. Or do you suggest at the front-end level to generate the correct request by applying a little js? - Andrew Romanenko

    A controversial solution for microcontrollers with limited RAM, but if everything fits, you can use the features of c ++. With a boost it would be shorter, but this is already a completely controversial option. If the memory is completely flat, and vectors / streams are not yet used in the project, then it is better to disassemble by hand, as in the Rennorb answer.

     #include <iostream> #include <string> #include <sstream> #include <vector> using namespace std; struct frame { int a, s, p; frame(const std::string& str) { istringstream sst(str); char c; sst >> skipws >> c >> a >> c >> c >> s >> c >> c >> p; } }; int main() { string s = " a15,s 150, p10 ;a45 ,s200,p30;"; istringstream ss(s); ss >> skipws; vector<frame> vec; string step; while (getline(ss, step, ';').good()) vec.push_back(step); for (auto n: vec) cout << na << ", " << ns << ", " << np << endl; } 

    The current example: https://repl.it/CiYZ/14