如何通过引用传递Serial对象到Arduino中的类?

时间:2011-09-17 14:46:11

标签: c++ c pointers arduino

我已经阅读了几天关于针对Arduino的C / C ++中的指针,引用和解引用,并且不能完全理解我所缺少的内容。

我的sketch设置了

Serial.begin(9600);   //Just for logging.
Serial1.begin(9600);  //Arduino Mega-> Other Device

我使用包装类通过调用getStatus()这样的简单函数来通过Serial1发送BYTE。

我遇到的问题是我想让我的课程更有活力,所以我希望我的课程能够使用Serial1,Serial2,Serial3甚至基本的Serial - 但我不知道如何构建我的.h和.cpp文件将它们用作引用。

目前我的班级有一个静态的Serial1,但如果有人想使用我的班级,他们必须将所有内容重命名为Serial,如果他们使用Arduino Uno

在myclass.h中我有类似

的东西
myClass(HardwareSerial *serial);

并在myClass.cpp(构造函数)中:

myClass::myClass(HardwareSerial &serial) {
     _HardSerial = serial;
 ..
}

但是编译器继续对) expected before & or *抱怨。

我尝试了各种各样的方法并且总是得到相同的错误 - 除非我将我的类引用到Serial对象 - 但它说Serial没有定义..

我找不到任何教程,除了 Pointer Resource for Arduino

  

宣言和创作

#include "Print.h"
//datatype* variablename = ⌖
Print* printer = &Serial; Usage
     

用法

//this is the equivalent of Serial.print
printer->print("print using the Serial object"); //notice the -> as opposed to .
//change target address (or which address to point to)
printer = &Serial2;
//this is the equivalent of Serial2.print
printer->print("print using the Serial2 object");

这正是我想要的 - 但似乎我不理解它。我做了他们在那里做的事情,但这对我没用。

编辑1

谢谢,我做了参考方式,因为它更好。不过我仍然会遇到这些错误:

:88: error: 'HardwareSerial' has not been declared

来自.h的第88行:

uint8_t Init(long BaudRate, HardwareSerial& serial);

.h:136: error: ISO C++ forbids declaration of 'HardwareSerial' with no type
.h:136: error: expected ';' before '&' token

来自.h的第136行(这种情况一直在发生 - 我不知道该使用什么,Serial.write?/ Serial?):

private:
HardwareSerial& _HardSerial;

编辑2

所以,基本上是因为我导入文件HardWareserial.h中的myClass.h文件,该文件在我的草图中导入以使用所有myClasses的东西 - 它会杀死草图中的引用并希望我重新定义Serial实例。似乎继承是错误的方式...烦人。草图中使用的默认构造函数是什么?

就像它要求我这样做:

HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1);

真的?我不明白......

3 个答案:

答案 0 :(得分:26)

你正在混合C ++引用和指针。从该示例代码片段看,你应该使用指针,所以我的答案遵循这种风格。但参考文献可能是更好的选择。

您的代码应如下所示:

myclass.h

myClass(HardwareSerial *serial); // ctor
HardwareSerial * _HardSerial; // member within class

myclass.cpp

// Constructor takes address of serial port
myClass::myClass(HardwareSerial *serial) {
 _HardSerial = serial;
...
}

调用代码:

// Gets the address of "Serial1" and passes that to the constructor
myClass(&Serial1); 

如果您想将其作为参考,它将看起来像这样:

myclass.h

myClass(HardwareSerial& serial); // ctor taking reference
HardwareSerial& _HardSerial; // reference member within class

myclass.cpp

// Constructor takes reference to a serial port object
myClass::myClass(HardwareSerial& serial) :
    _HardSerial(serial) // Need to initialise references before body
{
    ...
}

调用代码:

myClass(Serial1); // Compiler automatically uses reference

答案 1 :(得分:7)

在Arduino Leonardo上,我认为Serial实际上不是HardwareSerial的实例,而是Serial_的实例,因为它是虚拟USB链接,而不是普通的USART。

但是,这两个类都是Stream的子类。

所以也许你可以声明Stream*而不是HardwareSerial*

答案 2 :(得分:0)

我对默多克先生的代码有一点改进(顺便说一句,非常感谢你,关于如何初始化一个串行对象的例子让我变得更快乐,编译更沮丧的个人)。

他的方法可以让你将任何硬件串行对象传递给他的类。 默认情况下,我允许您将硬件对象传递(并配置)到类中,但如果您感兴趣,也可以稍后切换软件序列对象。

几乎与他的代码完全相同,除了我用Stream对象替换他的类中的HardwareSerial对象的实例。

myclass.h

myClass(HardwareSerial& serial, int baud, int config); // Constructor taking reference
Stream& _s; // reference member within class

myclass.cpp

// Constructor takes reference to a serial port object
myClass::myClass(HardwareSerial& serial = Serial, int baud = 9600, int config = SERIAL_8N1) :
_s(serial) // Need to initialise references before body
{
    serial.begin(baud, config);  //We guarantee a hardware interface at first
    this->_s = serial;           //The constructor uses the hardware serial class
                             //but we can replace it with a virtual hardware
                             //class if we have to thanks to stream
}