Как передать объект Serial ссылкой на мой класс в Arduino? - PullRequest
11 голосов
/ 17 сентября 2011

Я уже пару дней читаю об указателях, ссылках и разыменованиях в C / C ++, предназначенных для Arduino, и не могу полностью понять, что мне не хватает.

У меня есть набросок с настройкой

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

Я использую класс-оболочку для отправки байтов через Serial1, вызывая простую функцию, такую ​​как getStatus().

У меня проблема в том, чтоЯ хотел бы сделать мой класс более динамичным, поэтому я хотел бы, чтобы мой класс использовал 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

Строка 88 от .h:

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

Строка 136 от .h (это продолжается - я не знаю, чтоuse, Serial.write? / Serial?):

private:
HardwareSerial& _HardSerial;

EDIT 2

Итак, в основном, потому что я импортирую файл HardWareserial.h в файл myClass.h, который импортирован в мой эскизиспользовать весь материал myClasses - он убивает ссылки в эскизе и хочет, чтобы я переопределил экземпляры Serial.Кажется, что наследство неправильное ... раздражает.Какой конструктор по умолчанию используется в эскизе?

Как будто он просит меня сделать это:

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

Правда?Опять не понимаю ...

Ответы [ 3 ]

26 голосов
/ 17 сентября 2011

Вы смешиваете ссылки и указатели на 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
7 голосов
/ 24 октября 2013

В Arduino Leonardo, я считаю, Serial на самом деле не экземпляр HardwareSerial, а скорее Serial_, поскольку он является виртуальным USB-каналом, а не обычным USART.

Однако оба эти класса являются подклассами Stream.

Так что, возможно, вы можете объявить Stream* вместо HardwareSerial*.

1 голос
/ 21 марта 2016

У меня есть одно улучшение в коде мистера Мердока (кстати, большое спасибо, после того, как ваш пример инициализации последовательного объекта сделал меня более счастливым, менее разочарованным компилятором человеком).Вы передаете любой аппаратный серийный объект его классу.Мой по умолчанию позволит вам передать (и настроить) аппаратный объект классу, но также позволит вам позже включить программный серийный объект, если вам это интересно.

Почти точно так же, как и его код, кромеЯ заменяю его экземпляр объекта HardwareSerial в своем классе на объект Stream.

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
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...