从数组 class 属性填充并执行回调
Populate and execute callbacks from array class attribute
我最近开始学习 C++/Arduino,并且正在努力抽象我的一些 Arduino 代码,以使其更易于管理。
我正在尝试构建一个 class,其中包含 2 个数组作为其属性,一个用于存储表示命令的字符串,第二个用于存储指向这些函数的指针。
下面的代码 有效 (编译),但是当上传到设备时 listen
和 execute
函数似乎都不起作用。我找了很多地方,但找不到我哪里出错了。
/* main.ino */
// SETUP
#include "SoftwareSerial.h"
SoftwareSerial bt(btRx, btTx);
#include "CMD.h"
const int cmdMax = 6;
ArriCMD cmd;
// COMMANDS
void cmdStatus()
{
Serial.println("OK");
}
// START
void setup()
{
Serial.begin(9600);
bt.begin(9600);
cmd.add("AH+STAT", cmdStatus);
}
void loop()
{
cmd.listen(bt);
}
/* ArriCMD.h */
#ifndef ArriCMD_h
#define ArriCMD_h
#include "Arduino.h"
#include "SoftwareSerial.h"
class ArriCMD
{
public:
ArriCMD();
void add(String cmd, void (*cb)());
void listen(SoftwareSerial serial);
void execute(String cmd);
private:
int _max = 16;
int _amt = 0;
String _cmds[16];
void (*_cbs[16])();
};
/* ArriCMD.cpp */
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "ArriCMD.h"
ArriCMD::ArriCMD()
{
//
}
void ArriCMD::add(String cmd, void (*cb)())
{
if (_amt < _max) {
_cmds[_amt] = cmd;
_cbs[_amt] = *cb;
}
}
void ArriCMD::listen(SoftwareSerial serial)
{
if (serial.available()) {
String cmd = serial.readString();
Serial.print(cmd);
execute(cmd);
}
}
void ArriCMD::execute(String cmd)
{
for (int i = 0; i < _amt; i++) {
if (cmd == _cmds[i]) {
_cbs[i]();
}
}
}
虽然我从事编程已有十多年,但 C++ 和微控制器对我来说是全新的,我们将不胜感激任何和所有帮助。
一旦我对自己的代码质量感到更加满意,我确实打算开源这些库以及它们所针对的后续平台。
您似乎忘记增加命令计数器 _amt
void ArriCMD::add(String cmd, void (*cb)())
{
if (_amt < _max) {
_cmds[_amt] = cmd;
_cbs[_amt] = *cb;
_amt++; // <-- here, don't you need it?
}
}
除此之外,在您的代码中使用原始数组和原始函数指针是否有某些特殊原因?我不使用 Arduino,所以我不确定,但也许这个解决方案更简洁:
class ArriCMD
{
public:
ArriCMD();
void add(String cmd, std::function<void()> cb);
void listen(SoftwareSerial serial);
void execute(String cmd);
private:
std::map<String, std::function<void()> > _cmdMap;
};
我最近开始学习 C++/Arduino,并且正在努力抽象我的一些 Arduino 代码,以使其更易于管理。 我正在尝试构建一个 class,其中包含 2 个数组作为其属性,一个用于存储表示命令的字符串,第二个用于存储指向这些函数的指针。
下面的代码 有效 (编译),但是当上传到设备时 listen
和 execute
函数似乎都不起作用。我找了很多地方,但找不到我哪里出错了。
/* main.ino */
// SETUP
#include "SoftwareSerial.h"
SoftwareSerial bt(btRx, btTx);
#include "CMD.h"
const int cmdMax = 6;
ArriCMD cmd;
// COMMANDS
void cmdStatus()
{
Serial.println("OK");
}
// START
void setup()
{
Serial.begin(9600);
bt.begin(9600);
cmd.add("AH+STAT", cmdStatus);
}
void loop()
{
cmd.listen(bt);
}
/* ArriCMD.h */
#ifndef ArriCMD_h
#define ArriCMD_h
#include "Arduino.h"
#include "SoftwareSerial.h"
class ArriCMD
{
public:
ArriCMD();
void add(String cmd, void (*cb)());
void listen(SoftwareSerial serial);
void execute(String cmd);
private:
int _max = 16;
int _amt = 0;
String _cmds[16];
void (*_cbs[16])();
};
/* ArriCMD.cpp */
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "ArriCMD.h"
ArriCMD::ArriCMD()
{
//
}
void ArriCMD::add(String cmd, void (*cb)())
{
if (_amt < _max) {
_cmds[_amt] = cmd;
_cbs[_amt] = *cb;
}
}
void ArriCMD::listen(SoftwareSerial serial)
{
if (serial.available()) {
String cmd = serial.readString();
Serial.print(cmd);
execute(cmd);
}
}
void ArriCMD::execute(String cmd)
{
for (int i = 0; i < _amt; i++) {
if (cmd == _cmds[i]) {
_cbs[i]();
}
}
}
虽然我从事编程已有十多年,但 C++ 和微控制器对我来说是全新的,我们将不胜感激任何和所有帮助。
一旦我对自己的代码质量感到更加满意,我确实打算开源这些库以及它们所针对的后续平台。
您似乎忘记增加命令计数器 _amt
void ArriCMD::add(String cmd, void (*cb)())
{
if (_amt < _max) {
_cmds[_amt] = cmd;
_cbs[_amt] = *cb;
_amt++; // <-- here, don't you need it?
}
}
除此之外,在您的代码中使用原始数组和原始函数指针是否有某些特殊原因?我不使用 Arduino,所以我不确定,但也许这个解决方案更简洁:
class ArriCMD
{
public:
ArriCMD();
void add(String cmd, std::function<void()> cb);
void listen(SoftwareSerial serial);
void execute(String cmd);
private:
std::map<String, std::function<void()> > _cmdMap;
};