C++ 如何通过引用我在 Arduino 中的类来传递 Serial 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7455570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass Serial object by reference to my class in Arduino?
提问by Piotr Kula
I have been reading up a couple of days now about pointers, references and dereferences in C/C++ targeted for the Arduino and can't fully udnerstand what I am missing.
我已经阅读了几天关于针对 Arduino 的 C/C++ 中的指针、引用和取消引用,并且无法完全理解我所缺少的内容。
I have my sketchwhich has a setup of
我有我的草图,它有一个设置
Serial.begin(9600); //Just for logging.
Serial1.begin(9600); //Arduino Mega-> Other Device
I use a wrapper class to send BYTE's over Serial1 by calling a simple function like getStatus()
.
我使用包装类通过调用一个简单的函数(如getStatus()
.
The issue I am having is I would like to make my class more dynamic, so I would like my class to use Serial1, Serial2, Serial3 or even the base Serial - but I do not know how to build my .h and .cpp files to use these as references.
我遇到的问题是我想让我的班级更具动态性,所以我希望我的班级使用 Serial1、Serial2、Serial3 甚至基本 Serial - 但我不知道如何构建我的 .h 和 .cpp 文件将这些用作参考。
At the moment my class has a static Serial1 but if somebody would like to use my class they would have to rename everything to Serial if they use Arduino Uno.
目前我的班级有一个静态的 Serial1 但如果有人想使用我的班级,如果他们使用Arduino Uno ,他们必须将所有内容重命名为 Serial 。
In myclass.h I have something like
在 myclass.h 我有类似的东西
myClass(HardwareSerial *serial);
and in myClass.cpp (constructor):
并在 myClass.cpp(构造函数)中:
myClass::myClass(HardwareSerial &serial) {
_HardSerial = serial;
..
}
But the compiler keeps on moaning about ) expected before & or *
.
但是编译器一直在抱怨) expected before & or *
.
I have tried various ways and always get the same error- except when I reference my class to the Serial object-- but it says Serial was not defined..
我尝试了各种方法并且总是得到相同的错误 - 除非我将我的类引用到 Serial 对象 - 但它说 Serial 未定义..
I can't find any tutorials, except Pointer Resource for Arduino.
我找不到任何教程,除了Arduino 的指针资源。
Declaration and Creation
#include "Print.h" //datatype* variablename = ⌖ Print* printer = &Serial; Usage
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");
声明与创建
#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");
Which is exactly what I want - but it seems I do not understand it. I did what they did there, and it does not work for me.
这正是我想要的 - 但似乎我不明白。我做了他们在那里做的事情,这对我不起作用。
EDIT 1
编辑 1
Thanks, I did it the reference way because it is better yet. I still get these errors, though:
谢谢,我按照参考方式做了,因为它更好。不过,我仍然收到这些错误:
:88: error: 'HardwareSerial' has not been declared
Line 88 from .h:
.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
Line 136 from .h (this keeps on happening- I don't know what to use, Serial.write? / Serial?):
.h 中的第 136 行(这种情况一直在发生 - 我不知道该使用什么,Serial.write?/Serial?):
private:
HardwareSerial& _HardSerial;
EDIT 2
编辑 2
So, basically because I import the HardWareserial.h
file in file myClass.h
which is imported in my sketch to use all myClasses stuff - it kills the references in the sketch and wants me to redefine the Serial instances. It seems like the inheritance is the wrong way around…annoying. What's the default constructor used in the sketch?
所以,基本上是因为我在我的草图中导入的HardWareserial.h
文件中导入文件myClass.h
以使用所有 myClasses 东西 - 它会杀死草图中的引用并希望我重新定义 Serial 实例。似乎继承是错误的方式……烦人。草图中使用的默认构造函数是什么?
It's like it's asking me to do this:
这就像要求我这样做:
HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1);
Really? Again I don't understand...
真的吗?又没看懂。。。
回答by tinman
You're mixing C++ references and pointers. It looks from that example snippet that you should be using pointers, so I have made my answer follow that style. References would probably be a better choice though.
您正在混合 C++ 引用和指针。从该示例片段看来,您应该使用指针,所以我的回答遵循了这种风格。不过,参考可能是更好的选择。
Your code should look something like this:
您的代码应如下所示:
myclass.h
我的类.h
myClass(HardwareSerial *serial); // ctor
HardwareSerial * _HardSerial; // member within class
myclass.cpp
我的类.cpp
// Constructor takes address of serial port
myClass::myClass(HardwareSerial *serial) {
_HardSerial = serial;
...
}
calling code:
调用代码:
// Gets the address of "Serial1" and passes that to the constructor
myClass(&Serial1);
If you wanted to do it as references it would look something like this:
如果你想把它作为参考来做,它看起来像这样:
myclass.h
我的类.h
myClass(HardwareSerial& serial); // ctor taking reference
HardwareSerial& _HardSerial; // reference member within class
myclass.cpp
我的类.cpp
// Constructor takes reference to a serial port object
myClass::myClass(HardwareSerial& serial) :
_HardSerial(serial) // Need to initialise references before body
{
...
}
calling code:
调用代码:
myClass(Serial1); // Compiler automatically uses reference
回答by EternityForest
On the Arduino Leonardo, I believe Serial
is not actually an instance of HardwareSerial
, but rather of Serial_
, due to it being a virtual USB link and not a normal USART.
在 Arduino Leonardo 上,我相信Serial
实际上不是 的实例HardwareSerial
,而是的实例Serial_
,因为它是一个虚拟 USB 链接而不是普通的 USART。
However, both of these classes are subclasses of Stream
.
但是,这两个类都是 的子类Stream
。
So maybe you can declare Stream*
instead of HardwareSerial*
.
所以也许你可以声明Stream*
而不是HardwareSerial*
.
回答by Meek_The_Geek
I have one improvement on Mr Murdoch's code (thanks a lot by the way, following your example on how to initialize a serial object made me a happier, less compiler frustrated individual).
我对默多克先生的代码进行了一项改进(顺便说一句,非常感谢,遵循您关于如何初始化串行对象的示例使我成为一个更快乐,更少编译器沮丧的人)。
His method will let you pass any hardware serial object to his class. Mine by default will let you pass (and configure) a hardware object to the class, but will also let you switch in a software serial object later if you are interested.
他的方法可以让你将任何硬件串行对象传递给他的类。我的默认情况下会让您将硬件对象传递(和配置)到类,但如果您感兴趣,也可以让您稍后切换软件串行对象。
Almost the exact same as his code, except I replace his instance of the HardwareSerial object in his class with the Stream object.
几乎与他的代码完全相同,除了我用 Stream 对象替换了他的类中的 HardwareSerial 对象实例。
myclass.h
我的类.h
myClass(HardwareSerial& serial, int baud, int config); // Constructor taking reference
Stream& _s; // reference member within class
myclass.cpp
我的类.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
}