Использование последовательного порта в коде

Я хочу написать функцию, определяющую последовательный порт на основе флага, но не уверен, что это возможно.

Например:

void writeToSerial(bool useSerial1)
{
   SerialPortClass serialPortObject; // Есть ли способ определить общий объект последовательного порта и повторно использовать его ниже?

   if (useSerial1)
   {
      serialPortObject = Serial1;
   }
   else
   {
      serialPortObject = Serial2;
   }

   serialPortObject.write("test123");
}

, 👍1

Обсуждение

Отвечает ли это на ваш вопрос? Передача HardwareSerial и SoftwareSerial как свойства класса, @Juraj


2 ответа


2

Согласно источникам в c:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial* (на платформе Windows), вы можете использовать указатель на Класс Stream (поскольку Serial унаследованы от Stream).

Итак, ваша функция может выглядеть так:

void writeToSerial(bool useSerial1)
{
   Stream* serialPortObject;

   if (useSerial1)
   {
      serialPortObject = &Serial1;
   }
   else
   {
      serialPortObject = &Serial2;
   }

   serialPortObject->write("test123");
}
,

Обратите внимание, что последовательный порт должен быть уже инициализирован, чтобы это работало, так как в Stream отсутствует метод begin(). Если вам нужно вызвать begin() или end(), вы должны использовать указатель на HardwareSerial., @Edgar Bonet


1

Это неправильный ответ, а скорее предложение пересмотреть свои подход. Код, размещенный в вопросе, очевидно, просто упрощенный например, и печать «test123», скорее всего, не является вашей конечной целью. я предполагаю то, что вы действительно хотите сделать, это распечатать некоторую информацию о некоторых переменные. Затем вы можете собрать эти переменные в структуру данных ( объект C++) и сделайте writeToSerial() методом этого объекта. объект можно распечатать так:

myDataStructure::writeToSerial(true);   // печатается в Serial1
myDataStructure::writeToSerial(false);  // печатается в Serial2

В этом случае я предлагаю вместо этого явно использовать print() (или println()) объект на соответствующий последовательный порт, например:

Serial1.print(myDataStructure);
Serial2.print(myDataStructure);

Это делает код понятным и простым в обслуживании.

Очевидно, что вы не можете просто так печатать произвольные объекты, так как Serial1 и Serial2 понятия не имеют, как их сериализовать. Но дело в том, что вы можете научить их! Сделайте свой класс производным от Printable, реализуйте виртуальный метод printTo(), и вы будете может распечатать его на любой последовательный порт, ЖК-дисплей или что-то еще, что понимает print():

class MyDataStructure : public Printable {
public:
    size_t printTo(Print& p) const {
        return p.print("test123");
    }
};

MyDataStructure someData;

void setup() {
    Serial1.begin(9600);
    Serial2.begin(9600);
    Serial1.println(someData);
    Serial2.println(someData);
}

void loop(){}

См. ответ на вопрос Можно ли напечатать пользовательский объект, передав его в Serial.print()? для примера с фактическими данными в объект.

,