Вызов метода в основном скетче из библиотеки.

Мне нужно использовать специальную библиотеку, которая выдает сообщения об ошибках в виде строкового текста. Библиотека использует функцию Serial.println() для отправки сообщений на последовательный монитор Arduino IDE.

Проблема в том, что последовательные линии Arduino подключены к другому устройству, поэтому я не могу использовать последовательный монитор для просмотра сообщений. У меня есть метод в скетче Main Arduino, который отправляет любое текстовое сообщение String, сгенерированное на другое устройство, с помощью команд Udp (беспроводное соединение). Это устройство подключено к последовательному монитору.

Мой вопрос: как я могу вызвать метод Udp внутри основного скетча программы Arduino из вышеупомянутой библиотеки? Это поможет мне преобразовать текстовые сообщения Serial.print() из библиотеки непосредственно в сообщения Udp, чтобы иметь возможность их визуализировать.

Метод Udp, который я использую, объявлен как void UdpSend(String msg) в скетче Arduino. Я хотел бы использовать что-то подобное внутри библиотеки, чтобы обернуть текстовое сообщение и отправить его методу основной программы.

Любой пример или ссылка для получения этой информации помогут.

РЕДАКТИРОВАТЬ1:

@Маженко,

  1. В целевой библиотеке добавлено: void libUdpSend(const char *libMsg);
  2. В скетче я добавил вот такой метод (обработчик связи Udp):

     void libUdpSend(const char *libMsg)
     {
       Udp.begin(localPort);  
       Udp.beginPacket(Udp.remoteIP(), localPort);
       Udp.write(libMsg);    
       Udp.endPacket();   
       delay(40);  
     }
    
  3. Добавлена эта строка в библиотеку (сразу после объявления 1.) для тестирования через удаленный последовательный интерфейс:

    libUdpSend("String wrapper has been implemented SUCCESSFULLY!");
    

При попытке скомпилировать связывающую библиотеку возникает следующее исключение:

ошибка: ожидаемый конструктор, деструктор или преобразование типа перед токеном '(' libUdpSend("Строковая оболочка реализована УСПЕШНО!");

Затем я переключился на String, так как это тот тип, который я хочу обернуть. Те же шаги:

  1. В целевой библиотеке добавлено: void libUdpSend(String *libMsg);
  2. На скетче:

    void libUdpSend(String *libMsg)
    {
      Udp.begin(localPort);  
      Udp.beginPacket(Udp.remoteIP(), localPort);
      Udp.write(libMsg.c_str());    
      Udp.endPacket();   
      delay(40);  
    }
    

Теперь в сообщении об ошибке говорится:

запрос члена «c_str» в «libMsg», который имеет тип указателя «String*» (возможно, вы имели в виду использовать «->» ?)

_

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

Дайте мне знать, что вы думаете по этому поводу.

, 👍0

Обсуждение

У меня есть простая библиотека для отладочных сообщений через Telnet https://github.com/jandrassy/TelnetStream. он создает экземпляр, который можно использовать вместо Serial в любом исходном файле, который включает TelnetStream.h, @Juraj

отправьте отчет об ошибке создателям библиотеки и скажите, что жесткое кодирование последовательного кода для вывода отладки - неправильный поступок., @ratchet freak


1 ответ


2

Связь между скетчом и библиотекой не односторонняя, как многие полагают. Дела могут пойти вполне благополучно в обоих направлениях.

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

Однако сделать это так, как вы предлагаете (и я использую), на самом деле очень просто.

Вы просто создаете функцию в своем скетче и указываете библиотеке использовать ее.

Например, в вашем скетче:

void debug(const char *msg) {
    Serial3.println(msg);
}

И в библиотеке добавьте строку:

void debug(const char *msg);

Тогда в любой точке того же файла (или единицы перевода) вы можете использовать

debug("I am here");

При условии, что файл, в котором вы его используете, является файлом C++ (.cpp). Если это файл C (.c), то вам придется обращаться с ним немного по-другому. Видите ли, C++ портит имена функций (даже таких ванильных функций), что означает, что они не видны файлам C. Поэтому вам нужно сказать компилятору: «Я бы хотел, чтобы это можно было использовать в файле C, пожалуйста».

Что вы делаете с помощью специальной «внешней» оболочки вашей функции:

extern "C" {
    void debug(const char *msg) {
        Serial3.println(msg);
    }
}

И тогда debug() можно будет использовать в файле C так же, как указано выше.

Однако теперь это не будет работать в файле C++... (по кругу...)

Исправить просто: добавьте extern "C" к прототипу в файле C++:

extern "C" {
    void debug(const char *msg);
}

Если вы хотите включить свой «extern» в файл заголовка, который может быть включен в файлы C или C++, очень часто используется такая конструкция, как:

#if defined(__cplusplus)
extern "C" {
#endif

void debug(const char *msg);

#if defined(__cplusplus)
}
#endif

Это добавит оболочку extern "C" для файлов C++ (определяемую наличием макроса __cplusplus), но опустит ее для файлов C.

Я использовал «const char *» в качестве параметра для этого примера, но вы можете выбрать любые параметры, подходящие для вашего использования.

,

@ Маженко, спасибо за ответ. Я реализовал решение так, как вы его предложили, но компилятор выдает ошибку в модифицированной библиотеке. ` ошибка: ожидаемый конструктор, деструктор или преобразование типа перед токеном '(' libUdpSend("Строковая оболочка реализована УСПЕШНО!"); ` Я попытался разместить код здесь, но раздел комментариев имеет очень ограниченный размер. Возможно, я мог бы отправить вам немного больше информации по электронной почте? Есть идеи по поводу чего-то в коде, который мне может не хватать? Кстати, целевой библиотекой является .cpp, поэтому внешняя структура C не требуется. Спасибо -EZ, @Ed Zamper

Просто отредактируйте свой вопрос и добавьте его туда., @Majenko

См. «EDIT 1» в исходном вопросе. Спасибо!, @Ed Zamper