Class Arduino IDE学习创建自定义类对象
我正在Arduino上使用GSM模块SIM800,希望学习如何为其创建自己的自定义库。我一直在使用TinyGSM图书馆,并试图从中学习。我觉得这个库对于我的项目需求来说是10倍多,而且很难理解,因为它有很多嵌套函数,不断地反复调用另一个函数,这使得我几乎不可能理解这个代码(至少对于像我这样的begginer程序员来说) 我想创建一个类构造函数,它允许我创建GSM模块对象,然后我可以使用这个对象来使用我在类中声明的任何函数 从tinyGSM库中,我认为对象构造函数的定义如下:Class Arduino IDE学习创建自定义类对象,class,constructor,arduino,gsm,esp32,Class,Constructor,Arduino,Gsm,Esp32,我正在Arduino上使用GSM模块SIM800,希望学习如何为其创建自己的自定义库。我一直在使用TinyGSM图书馆,并试图从中学习。我觉得这个库对于我的项目需求来说是10倍多,而且很难理解,因为它有很多嵌套函数,不断地反复调用另一个函数,这使得我几乎不可能理解这个代码(至少对于像我这样的begginer程序员来说) 我想创建一个类构造函数,它允许我创建GSM模块对象,然后我可以使用这个对象来使用我在类中声明的任何函数 从tinyGSM库中,我认为对象构造函数的定义如下: public:
public:
explicit TinyGsmSim800(Stream& stream) : stream(stream) {
memset(sockets, 0, sizeof(sockets));
}
然而,我不能完全理解为什么会以这种方式宣布它
#include "custom_modem.h"
#include "Arduino.h"
custom_modem :: custom_modem(Serial serial)
{
}
custom_modem :: send_AT_command(String command){
}
更新2
我取得了一些进展。我找到了另一条线索:
为了满足我的需要,我进一步简化了它
我的头文件:
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <Stream.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
void send_AT_command(String command);
private:
Stream * _port;
//Stream& _serial;
};
#endif
#include "custom_modem.h"
#include "Arduino.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
static_cast<HardwareSerial*>(_port)->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
#include "Arduino.h"
#include "String.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
_port->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
String custom_modem::send_AT_command()
{
String return_message; // Crate a string to store a return message
_port->write("AT\n\r"); // Write an "AT" message to serial device. Expecting to receive "OK"
delay(1);
while(_port->available())
{
char c = _port->read(); // Read character at a time
return_message.concat(c); // append a string with the character
}
return return_message;
}
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
String send_AT_command();
private:
HardwareSerial* _port;
};
#endif
然而,这段代码给我带来了很多问题:
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <Stream.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
void send_AT_command(String command);
private:
Stream * _port;
//Stream& _serial;
};
#endif
#include "custom_modem.h"
#include "Arduino.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
static_cast<HardwareSerial*>(_port)->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
#include "Arduino.h"
#include "String.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
_port->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
String custom_modem::send_AT_command()
{
String return_message; // Crate a string to store a return message
_port->write("AT\n\r"); // Write an "AT" message to serial device. Expecting to receive "OK"
delay(1);
while(_port->available())
{
char c = _port->read(); // Read character at a time
return_message.concat(c); // append a string with the character
}
return return_message;
}
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
String send_AT_command();
private:
HardwareSerial* _port;
};
#endif
1。正如您从源文件中看到的,我正在传递
HardwareSerial*串行,然后我将此变量分配给
_port = serial
但是在我的头文件中,_端口被声明为Stream*变量。这是怎么回事
2。为什么我需要使用指针:
在我的源文件中:
custom_modem::custom_modem(HardwareSerial* serial)
在我的头文件中:
custom_modem(HardwareSerial* serial);
参照传递不是更好吗?使用硬件序列&?
有什么区别?指针快把我累死了我不太懂
3。为什么我需要使用这个恼人的演员阵容?
static_cast<HardwareSerial*>(_port)->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
这会给我一个错误
如果你能帮我回答这些问题,我将不胜感激!谢谢
更新3
我为我的类开发了一种方法,用于发送AT命令并返回答案:
String custom_modem::send_AT_command()
{
String return_message; // Crate a string to store a return message
static_cast<HardwareSerial*>(_port)->write("AT"); // Write an "AT" message to serial device. Expecting to receive "OK"
delay(1);
while( static_cast<HardwareSerial*>(_port)->available())
{
char c = static_cast<HardwareSerial*>(_port)->read(); // Read character at a time
return_message.concat(c); // append a string with the character
}
return return_message;
}
它似乎没有返回任何内容:
我相信这可能是我实现send_AT_命令功能的方式的问题
更新4
通过添加行终止/n/r解决了AT命令问题。现在可以了
在尝试通过引用HardwareSerial初始化类时,我仍然存在以下问题:
我的cpp:
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <Stream.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
void send_AT_command(String command);
private:
Stream * _port;
//Stream& _serial;
};
#endif
#include "custom_modem.h"
#include "Arduino.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
static_cast<HardwareSerial*>(_port)->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
#include "Arduino.h"
#include "String.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
_port->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
String custom_modem::send_AT_command()
{
String return_message; // Crate a string to store a return message
_port->write("AT\n\r"); // Write an "AT" message to serial device. Expecting to receive "OK"
delay(1);
while(_port->available())
{
char c = _port->read(); // Read character at a time
return_message.concat(c); // append a string with the character
}
return return_message;
}
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
String send_AT_command();
private:
HardwareSerial* _port;
};
#endif
和标题:
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <Stream.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
void send_AT_command(String command);
private:
Stream * _port;
//Stream& _serial;
};
#endif
#include "custom_modem.h"
#include "Arduino.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
static_cast<HardwareSerial*>(_port)->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
#include "Arduino.h"
#include "String.h"
custom_modem::custom_modem(HardwareSerial* serial)
{
_port = serial;
}
void custom_modem::start_modem(){
_port->begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
}
String custom_modem::send_AT_command()
{
String return_message; // Crate a string to store a return message
_port->write("AT\n\r"); // Write an "AT" message to serial device. Expecting to receive "OK"
delay(1);
while(_port->available())
{
char c = _port->read(); // Read character at a time
return_message.concat(c); // append a string with the character
}
return return_message;
}
#ifndef custom_modem_h
#define custom_modem_h
#include <Arduino.h>
#include <HardwareSerial.h>
#define MODEM_TX 27
#define MODEM_RX 26
class custom_modem
{
public:
custom_modem(HardwareSerial* serial);
void start_modem();
String send_AT_command();
private:
HardwareSerial* _port;
};
#endif
如果我想通过引用使用HardwareSerial,请澄清我必须如何更改代码才能使其正常工作:
如果我同时更改.cpp和头文件:
HardwareSerial* serial
到
这给了我一个错误。我相信这可能与头文件中的变量_port有关:
private:
HardwareSerial* _port;
<> P> >首先,我建议选择一个体面的C++教程。这将对您有很大帮助,因为您目前正忙于处理基本的语言概念(例如指针、引用、继承),如果不理解这些概念,您就无法真正做任何非琐碎的事情。不能说我可以推荐任何最新的材料,但布鲁斯·埃克尔的免费《用C++思考》给我的印象是一本新手友好的书。它有点过时,因为它没有涵盖最新的标准-C++11/14/17/20-但它在语言基础方面做得相当好
至于TinyGSM为什么使用流而不是串行,它更通用。GSM模块还可以有其他通信通道-可能是软件模拟UART、USB串行接口、SPI总线或其他完全相同的模块。如果遵循更抽象的接口,他们将很容易地修改库代码以支持所有这些功能。
请注意,您不必这样做。使用硬件测试,会更容易
Stream是用于读/解析和写/打印类的ArduinoAPI基类
sockets
是一个数组,memset会立即将其初始化为零。你为什么不直接使用那个图书馆呢?因为我大部分都不懂,而且很难理解。遗憾的是,图书馆社区并不十分活跃,因此他们无法帮助我解决一些问题。我想我最好为GSM模块开发自己的小类,并准确地发送我想要的方式和命令。此外,这也是学习如何使用类编写自己的库的绝佳机会TinyGSM库遵循Arduino网络API。其工作方式与Arduino以太网和WiFi库EthernetClient/WiFiClient相同。学习Arduino networking API而不是重新发明Wheel绝对是一件好事。为了设置调制解调器,我很沮丧