如何根据用户输入创建功能?

时间:2015-08-07 15:10:09

标签: c function parsing arduino

我目前正在开发具有以下一般结构的软件 Arduino 组合项目:

  1. 用户通过终端程序(如CoolTerm
  2. )输入一串命令
  3. 通过USB Serial
  4. 将命令发送到Arduino
  5. 解析第一个命令以及包含的参数
  6. 执行与第一个命令关联的功能
  7. 解析第二个命令以及包含的参数
  8. 执行与第二个命令相关的功能
  9. 等。直到所有命令都被解析并执行
  10. 到目前为止,所有这些都像我期望的那样有效。但是,我正在处理的项目需要非常精确的计时,并且必须解析每个单独的命令会在每个命令执行之间创建大量的处理时间(不确定这是否是正确的术语)。 / p>

    例如,在包含三个命令的用户输入字符串中,在正在解析的第一个命令和正在执行的最后一个命令之间,从开始到结束还有5.8毫秒的处理时间。

    要清楚,我的程序的所有部分都是可用的,包括用户输入,字符串解析和函数执行,如上所述。我需要改进现有代码,而不是纠正错误。

    理想情况下,我认为程序将解析每个命令,“预留”与命令关联的函数,并在所有命令全部被“搁置”后依次执行。这将通过消除在每个函数执行之间继续解析命令的需要而显着缩短处理时间。我不知道如何实现这一目标,或者甚至是否可能。

    用非常基本的C ++伪代码来说明我的想法:

    (假设示例用户输入为“A,B,C”)

    loop() {
    // Example user input received: "A, B, C" corresponds to:
    // functionA, functionB, functionC
    
    String userInput = receiveInput();
    
    // Parse user input
    
    parse(userInput);
    
    // Execute functions specified by user input
    executeFunctions();
    
    }
    
    /*Parsing separates "A, B, C" to functionA, functionB, functionC
    Functions are "set aside" to be executed sequentially,
    the next beginning directly after the last ends*/
    
    executeFunctions{
    
    // Example functions to be executed
    functionA();
    functionB();
    functionC();
    
    }
    

    问题:

    我需要一种基于用户输入或基于其他功能创建功能的方法。通过我所做的广泛研究,我从未听说过这样一个概念,我不确定它是否存在。如果可能的话,这是我想用来继续我的项目的方法,因为我认为这将需要对我的代码进行最少量的重组。

    编辑:

    此项目需要与Arduino 硬件和Arduino IDE兼容。 标准C ++不起作用。

3 个答案:

答案 0 :(得分:3)

您可以使用Command Pattern

基本上,让你的解析器将每个用户输入的不同命令对象放入某种队列中。您可以使用基本功能对象:

struct Command {
    virtual ~Command() {}
    virtual void operator()(); // this will execute the command
};

class FirstCommand : public Command {
    // some private data + constructor
public:
    virtual void operator()() { /* do stuff for this user input */ }
};

class SecondCommand : public Command {
    // some private data + constructor
public:
    virtual void operator()() { /* do stuff for this user input */ }
};

解析器会创建FirstCommandSecondCommand,并将它们存储在std::queue<Command*>或更复杂的内容中。然后,您的消费者代码将通过执行以下操作来执行每个命令:

while (!q.empty() {
    Command* command = q.front();
    (*command)();
    q.pop();
}

使用线程安全队列,消费者代码甚至可以与解析器并行运行。

您可以使用简单指针的函数队列来代替命令对象,但是如果这样做,它们的签名必须相同,而特定命令的构造函数可以是任意的。

答案 1 :(得分:1)

您可以创建功能图。像这样:

typedef void (*ftype)(void);
map<string, ftype> function_map;

现在您将所有功能映射到命令:

function_map["A"] = functionA;
function_map["B"] = functionB;
function_map["C"] = functionC;

现在,在您获取用户输入并解析之后,您可以执行以下操作:

//foreach command
function_map[command]();

Here's a short code demo with primitive parsing

答案 2 :(得分:0)

可能是另一种选择,而不是确切的答案。编写一个解析输入的计算机程序,并通过串口以二进制形式发送命令。这种方式是串行读取(即使在115200也很慢),并且可以避免解析。作为奖励,与终端相比,您的应用程序可以更加用户友好。