Serial.begin() в библиотеке

Тема в разделе "Arduino & Shields", создана пользователем risele, 1 сен 2017.

  1. risele

    risele Нерд

    Добрый день!

    Пишу библиотеку, которая общается с сторонними устройствами через Serial.
    Столкнулся с проблемой инициализации в виде отсутствия у класса Stream метода begin():
    Код (Text):
    'class Stream' has no member named 'begin'
    Как, в таком случае, заставить библиотеку проинициализировать порт с нужной мне скоростью? Делать это в main() совсем не хочется.

    В классе порт хранится как
    Код (C++):
    Stream* _serial;
    В конструктор передается аналогично.

    Используется, разумеется, так:
    Код (C++):
    _serial -> begin(BaudRate,SERIAL_8N2);
     
  2. qwone

    qwone Гик

    Вы не можете спрятать сериал в класс. Он уже объявлен. Но не запущен. Serial.begin(); это запуск.
     
  3. risele

    risele Нерд

    Я не понял, что вы имеете в виду под "Спрятать".
    Я передаю в конструктор класса ссылку на объект Serial1/2/3.
    Далее мой класс оперирует этим объектом.
    На самом деле задача моей библиотеки - только инициализировать порт и передать его дальше, в ModbusMaster.

    Решение честно подсмотрено в работающей библиотеке ModbusMaster.
    Их конструктор:
    Код (C++):
    void ModbusMaster::begin(Stream &serial)
    {
      _serial = &serial;
    }
    Их "хранение" Serial в private: поле:
    Код (C++):
    Stream* _serial;
    Их использование:
    Код (C++):
    _serial->write(u8ModbusADU[i]);
    Лишнее, разумеется, опустил.
     
  4. qwone

    qwone Гик

    А так что не судьба?
    Код (C++):
     
    #include<HardwareSerial.h>
    extern HardwareSerial Serial;
    Serial.begin(9600);
     
  5. sslobodyan

    sslobodyan Гик

    Так будет жесткая привязка к определенному сериалу. Для библиотеки очень плохая практика, поскольку потребуется правка исходников под конкретный порт.
     
  6. qwone

    qwone Гик

    А нужна ли эта универсальность? Все равно так или иначе надо в будущем допиливать.
     
  7. sslobodyan

    sslobodyan Гик

    Ну тогда и библиотеки в топку - давайте всегда весь код с нуля писать.
    Библиотеки для того и созданы, чтобы их подключить и использовать, а не лазить по исходникам и что-то там править под каждый новый проект.
     
  8. qwone

    qwone Гик

    Ну не надо так перебарщивать. Если жить так миллионером, а иначе зачем жить,давайте выпьем яду. Есть стандартные библиотеки, есть широко распространенные. Но я вот не думаю, что ТC пишет такую. Но по своему небольшому опыту я заметил, что как не напишу для себя библиотеку, так она уже для меня устарела. И ее надо переписывать.
     
  9. sslobodyan

    sslobodyan Гик

    Отлично. Вопрос - зачем тогда библиотеки? Копируйте куски кода напрямую - все равно ведь править.
     
  10. qwone

    qwone Гик

    Тоже интересный вопрос? Но ответ будет верен только тогда, когда уточните ДЛЯ КОГО? От самих библиотек не холодно, не жарко.Кому-то нужны, а кто-то на них забил. Вот и ищите зачем нужны библиотеки тому, кто на них забил.
     
  11. rkit

    rkit Гуру

    Хранить в библиотеке не Stream, а HardwareSerial, очевидно.
     
    Последнее редактирование: 2 сен 2017
  12. DetSimen

    DetSimen Guest

    А ты храни его как
    Serial *_serial
    а еще лучше, как Print *_serial. Тогда хоть чо передавай в конструктор, хоть &lcd какой-нибудь
     
  13. risele

    risele Нерд

    Не знал, что так можно :) Спасибо!
    В итоге сработало, но храню указатель.

    Код (C++):

    #include <HardwareSerial.h>
    class myclass
    {
        public:
        myclass(HardwareSerial &serial)
        void begin()
        void write(int value)
        private:
        HardwareSerial *_serial;
    };

    myclass::myclass(HardwareSerial &serial)
    {
        _serial = serial;
    }
    void myclass::begin()
    {
        _serial -> begin(38400);
    }
    void myclass::write(int value)
    {
        _serial -> write(value);
    }
     
    arkadyf нравится это.
  14. DetSimen

    DetSimen Guest

    надо бы сам объект класса Serial инициализировать снаружи, в setup() например, а в конструктор твоего класса передавать указатель на уже готовый объект. А лучше, для универсальности, передавать указатель на базовый класс Print. Чтобы ничего не переделывая, легким движением указателя, печатать не только в Serial, а и в LCD или TFT, буде такие появяца.
     
    Последнее редактирование модератором: 5 сен 2017
    b707 и arkadyf нравится это.
  15. risele

    risele Нерд

    честно говоря, сомневаюсь, что кто-то будет пытаться работать с Modbus через LCD =)
     
  16. qwone

    qwone Гик

    Консоль она и в Африке консоль. А куда она подключена уже не важно. в Modbus или Lcd. Другой вопрос. Ардуинщики они такие Ардуинщике, без готового чужого скетча в Инете у них руки на программирования не стоят. А тут задача серьезная.