Class Arduino IDE学习创建自定义类对象

Class Arduino IDE学习创建自定义类对象,class,constructor,arduino,gsm,esp32,Class,Constructor,Arduino,Gsm,Esp32,我正在Arduino上使用GSM模块SIM800,希望学习如何为其创建自己的自定义库。我一直在使用TinyGSM图书馆,并试图从中学习。我觉得这个库对于我的项目需求来说是10倍多,而且很难理解,因为它有很多嵌套函数,不断地反复调用另一个函数,这使得我几乎不可能理解这个代码(至少对于像我这样的begginer程序员来说) 我想创建一个类构造函数,它允许我创建GSM模块对象,然后我可以使用这个对象来使用我在类中声明的任何函数 从tinyGSM库中,我认为对象构造函数的定义如下: public:

我正在Arduino上使用GSM模块SIM800,希望学习如何为其创建自己的自定义库。我一直在使用TinyGSM图书馆,并试图从中学习。我觉得这个库对于我的项目需求来说是10倍多,而且很难理解,因为它有很多嵌套函数,不断地反复调用另一个函数,这使得我几乎不可能理解这个代码(至少对于像我这样的begginer程序员来说)

我想创建一个类构造函数,它允许我创建GSM模块对象,然后我可以使用这个对象来使用我在类中声明的任何函数

从tinyGSM库中,我认为对象构造函数的定义如下:

public:
  explicit TinyGsmSim800(Stream& stream) : stream(stream) {
    memset(sockets, 0, sizeof(sockets));
  }
然而,我不能完全理解为什么会以这种方式宣布它

  • 为什么是流而不是串行
  • 这些插槽是什么?为什么使用memset
  • 这将是我要写的第一个自定义库,我没有太多的课堂经验,希望你们能帮我

    我已经创建了一个cpp文件,我将在其中声明我的构造函数。我还想创建一个send_AT_命令函数,在该函数中,我将传递一个要发送到GSM调制解调器的AT命令字符串。有人能帮助我理解如何正确构建构造函数,以及如何在我的其他函数中进一步使用它吗

    
    #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-但它在语言基础方面做得相当好

  • 如果您看一下,HardwareSerial继承自流。这使得隐式(即编译器将在不被告知的情况下执行此操作)将指向子类的指针转换为指向父类的指针成为可能。请注意,这会产生后果:未声明为虚拟的函数将从父类而不是子类调用。
    至于TinyGSM为什么使用流而不是串行,它更通用。GSM模块还可以有其他通信通道-可能是软件模拟UART、USB串行接口、SPI总线或其他完全相同的模块。如果遵循更抽象的接口,他们将很容易地修改库代码以支持所有这些功能。
    请注意,您不必这样做。使用硬件测试,会更容易

  • 学习指针,你不能没有C或C++编程。我不解释,这是一个较长的故事。实际上,reference几乎是一个指针,只是使用起来稍微友好一些。请随意在代码中使用引用,我当然会这样做。请注意,初始化类的引用成员的方式有所不同:

  • 之所以需要强制转换,是因为您正在通过指向父类的指针访问子类。正如我前面提到的,您还没有准备好解决这个问题,所以在您的课堂上使用HardwareSerial而不是Stream

  • Stream是用于读/解析和写/打印类的ArduinoAPI基类
    sockets
    是一个数组,memset会立即将其初始化为零。你为什么不直接使用那个图书馆呢?因为我大部分都不懂,而且很难理解。遗憾的是,图书馆社区并不十分活跃,因此他们无法帮助我解决一些问题。我想我最好为GSM模块开发自己的小类,并准确地发送我想要的方式和命令。此外,这也是学习如何使用类编写自己的库的绝佳机会TinyGSM库遵循Arduino网络API。其工作方式与Arduino以太网和WiFi库EthernetClient/WiFiClient相同。学习Arduino networking API而不是重新发明Wheel绝对是一件好事。为了设置调制解调器,我很沮丧