Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

Нужна помощь Publish и Subscribe в один и тот же топик

Тема в разделе "Общие вопросы по esp8266", создана пользователем Sever44, 20 май 2019.

  1. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Всем привет!
    С дружеской помощью участников форума освоил передачу данных на CloudMQTT в "intopic" и считывание данных из "outtopic".
    Возникла задача:
    Первый модуль публикует данные в определенный топик.
    Второй модуль считывает данные из ЭТОГО ЖЕ топика.
    И вот это и не получается.
    При ручном вводе названия топика и его содержания на сайт MQTT все исправно выводится в порт.
    При подключении "передатчика", "приемник начинает повторять подключения:
    Connecting to MQTT server
    Connected to MQTT server
    1
    и в порт ничего не выводит.
    Вот топики:

    Передатчик (раскрыть)
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    int N;
    const char *ssid = "***";
    const char* const staPass = "***";
    const char *mqtt_server = "***";
    const int mqtt_port = ***;
    const char *mqtt_user = "***";
    const char *mqtt_pass = "***";
    const char *mqtt_client_name = "Neptun";
    #define BUFFER_SIZE 100

    WiFiClient wclient;
    PubSubClient client(wclient, mqtt_server, mqtt_port);

    void setup() {
    Serial.setTimeout(10);
    Serial.begin(9600);
    N = 0;
    }

    void loop() {

    // подключаемся к wi-fi
    if (WiFi.status() != WL_CONNECTED) {
    Serial.println("...");
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, staPass);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
    return;
    Serial.println("WiFi connected");
    }

    // подключаемся к MQTT серверу
    if (WiFi.status() == WL_CONNECTED) {
    if (!client.connected()) {
    Serial.println("Connecting to MQTT server");
    if (client.connect(MQTT::Connect("Neptun")
    .set_auth(mqtt_user, mqtt_pass))) {
    Serial.println("Connected to MQTT server");
    Serial.println("1");
    } else {
    Serial.println("Could not connect to MQTT server");
    }
    }
    if (client.connected()){
    client.loop();
    }
    }
    N++;
    client.publish("Nept_Mess","Message number = "+ String(N));
    delay(3000);
    }


    Приемник (раскрыть)
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>

    const char *ssid = "***";
    const char* const staPass = "***";
    const char *mqtt_server = "****";
    const int mqtt_port = ***;
    const char *mqtt_user = "***";
    const char *mqtt_pass = "***";
    const char *mqtt_client_name = "Neptun";
    #define BUFFER_SIZE 100

    WiFiClient wclient;
    PubSubClient client(wclient, mqtt_server, mqtt_port);

    void setup() {
    Serial.setTimeout(10);
    Serial.begin(9600);
    }

    void loop() {

    // подключаемся к wi-fi
    if (WiFi.status() != WL_CONNECTED) {
    Serial.println("...");
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, staPass);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
    return;
    Serial.println("WiFi connected");
    }

    // подключаемся к MQTT серверу
    if (WiFi.status() == WL_CONNECTED) {
    if (!client.connected()) {
    Serial.println("Connecting to MQTT server");
    if (client.connect(MQTT::Connect("Neptun")
    .set_auth(mqtt_user, mqtt_pass))) {
    Serial.println("Connected to MQTT server");
    client.set_callback(callback);
    client.subscribe("Nept_Mess");
    Serial.println("1");
    } else {
    Serial.println("Could not connect to MQTT server");
    }
    }
    if (client.connected()){
    client.loop();
    }
    }
    }

    void callback(const MQTT::publish& pub)
    {
    Serial.println("2");
    Serial.println(pub.topic());
    Serial.println(pub.payload_string());
    }

    Шестая от конца строка без пробела после::
    "void callback(const MQTT:: Publish& pub)"
    Почему-то иначе в спойлере появляется какая-то рожица.

    Может, я чего-то не понимаю, и это принципиально невозможно?
    Или есть ошибки?
    Прошу помочь.
    Заранее спасибо.
     
  2. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    Что это означает?
    Вы научились выполнять публикацию и подписчиком получать сообщения, это так?
    На обычном ПК, вы подписчиком получаете эти сообщения, которые публикует первый модуль?
    Код дополнительно помещайте в тег CODE

    Вы забыли указать окружение, в котором выполняется сборка. Нет ссылки на библиотеку mqtt, не указана версия библиотеки.
    Как повторить ваш код не понятно.
     
  3. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
     
  4. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    На обычном ПК, вы подписчиком получаете эти сообщения, которые публикует первый модуль?

    Да, есть работающий проект, передающий температуру в смартфон в топик "TEMP" и включающий или выключающий нагреватель при публикации "on" или "off" в топик "Mode" в смартфоне.

    Да в ПК на сайте CloudMQTT сообщения видны.

    Для повторения кода нужно указать все параметры сервера mqtt_server?

    Библиотека в приложенном файле
     

    Вложения:

  5. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    В скетче выполняете публикацию топика "Nept_Mess" и подписчиком поверяете получение топика "TEMP"??? Типа ищем не там где потерял, а там где светло.
    А сайт-то тут причем, подписчик у вас на сайт смотрит?
    У клаудМКУТТ есть ограничения на количество соединений, какой смысл проверять что там на сайте появляется. Клиентом бы проверили (на ПК), чтоб убедится что публикация топика "Nept_Mess" доходит до клиента.
    Фото библиотеки :) Обычно ссылки на библиотеки иначе выглядят.
     
  6. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Nept_Mess и TEMP это разные проекты. Вы спрашивали, научился ли я выполнять публикацию и подписчиком получать сообщения, я упрощенно описал работающий проект с топиками TEMP и Mode.
    Скетчи "Передатчик" и "Приемник" загружены в модули, посмотреть, что видит ПК, я могу только на сайте КлаудМКУТТ. Эта фраза "Клиентом бы проверили (на ПК)" мне непонятна. Я же написал,что в ПК сообщения в топик Nept_Mess видны.
    Ограничения не превышены.
    Я знаю, как выглядят ссылки, просто картинка информативнее - есть и название библиотеки и автор и версия
     
  7. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    Спрашиваю
    Вы отвечаете
    про какой то другой проект а не публикации первого модуля.
    Для ПК есть бесплатные утилиты mosquitto_pub и mosquitto_sub, для публикации и получения сообщений.
    Подписываюсь на сообщения
    Код (Text):
    1.  
    2. alex@my-test-pc:~$ mosquitto_sub -h m21.cloudmqtt.com -p 12345 -u myUser -P myPassword -t 'top1980' -d
    3. Client mosqsub|31666-my-test-pc sending CONNECT
    4. Client mosqsub|31666-my-test-pc received CONNACK
    5. Client mosqsub|31666-my-test-pc sending SUBSCRIBE (Mid: 1, Topic: top1980, QoS: 0)
    6. Client mosqsub|31666-my-test-pc received SUBACK
    7. Subscribed (mid: 1): 0
    8.  
    Публикую
    Код (Text):
    1.  
    2. alex@my-test-pc:~$ mosquitto_pub -h m21.cloudmqtt.com -p 12345 -u myUser -P myPassword -t 'top1980' -m 'test message' -d
    3. Client mosqpub|31668-my-test-pc sending CONNECT
    4. Client mosqpub|31668-my-test-pc received CONNACK
    5. Client mosqpub|31668-my-test-pc sending PUBLISH (d0, q0, r0, m1, 'top1980', ... (12 bytes))
    6. Client mosqpub|31668-my-test-pc sending DISCONNECT
    7.  
    И в подписчике вижу
    Код (Text):
    1.  
    2. Client mosqsub|31666-my-test-pc received PUBLISH (d0, q0, r0, m0, 'top1980', ... (12 bytes))
    3. test message
    4. Client mosqsub|31666-my-test-pc sending PINGREQ
    5. Client mosqsub|31666-my-test-pc received PINGRESP
    6. Client mosqsub|31666-my-test-pc sending PINGREQ
    7. Client mosqsub|31666-my-test-pc received PINGRESP
    8. ...
    9.  
     
    Sever44 нравится это.
  8. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Все, сам разобрался.
    Дело было не в бобине...
    Просто в "Передатчике" и "Приемнике" должны быть разные mqtt_client_name!!!
     
  9. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Все, сам разобрался.
    Дело было не в бобине...
    Просто в "Передатчике" и "Приемнике" должны быть разные mqtt_client_name!!!
    Спасибо за ссылки
     
  10. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    В приведённом коде передатчика и приемника есть только объявление mqtt_client_name и нет его использования.
    Разные или нет ни на что не влияет.
     
  11. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Разве это не "использование".

    if (client.connect(MQTT::Connect("Neptun")
    .set_auth(mqtt_user, mqtt_pass))) {
     
  12. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    В какой строчке кода используется mqtt_client_name, не mqtt_pass и не mqtt_user, а именно mqtt_client_name???

    П.С.
    У публикатора и подписчика, для проверки на клаудМКУТТ я использовал только одного пользователя с одним паролем, по этому и спрашиваю.
     
  13. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Строка 11 - объявляем, строка 41 - используем.
    Код Приемника (раскрыть)
    Код (C):
    1. #include <ESP8266WiFi.h>
    2. #include <PubSubClient.h>
    3.  
    4. //const char *ssid = "***";
    5. const char *ssid = "***";
    6. const char* const staPass = "***";
    7. const char *mqtt_server = "m13.cloudmqtt.com";
    8. const int mqtt_port = ***;
    9. const char *mqtt_user = "***";
    10. const char *mqtt_pass = "***";
    11. const char *mqtt_client_name = "Neptun2";
    12. #define BUFFER_SIZE 100
    13.  
    14. WiFiClient wclient;
    15. PubSubClient client(wclient, mqtt_server, mqtt_port);
    16.  
    17. void setup() {
    18. Serial.setTimeout(10);
    19. Serial.begin(9600);
    20. }
    21.  
    22. void loop() {
    23.  
    24. // подключаемся к wi-fi
    25. if (WiFi.status() != WL_CONNECTED) {
    26. Serial.println("...");
    27. Serial.print("Connecting to ");
    28. Serial.print(ssid);
    29. Serial.println("...");
    30. WiFi.begin(ssid, staPass);
    31.  
    32. if (WiFi.waitForConnectResult() != WL_CONNECTED)
    33. return;
    34. Serial.println("WiFi connected");
    35. }
    36.  
    37. // подключаемся к MQTT серверу
    38. if (WiFi.status() == WL_CONNECTED) {
    39. if (!client.connected()) {
    40. Serial.println("Connecting to MQTT server");
    41. if (client.connect(MQTT::Connect("Neptun2")
    42. .set_auth(mqtt_user, mqtt_pass))) {
    43. Serial.println("Connected to MQTT server");
    44. client.set_callback(callback);
    45. client.subscribe("Nept_Mess");
    46. Serial.println("1");
    47. } else {
    48. Serial.println("Could not connect to MQTT server");
    49. }
    50. }
    51. if (client.connected()){
    52. client.loop();
    53. }
    54. }
    55. } // callback_Neptun_1
    56.  

    Вы путаете понятия mqtt_user (задается при регистрации на сайте КлаудМКТТ) и mqtt_client_name (задаете вы в разделе USER&ACL).
    Следующие данные должны быть одинаковыми в обоих топиках:
    const char *mqtt_server = "m13.cloudmqtt.com";
    const int mqtt_port = ***;
    const char *mqtt_user = "***";
    const char *mqtt_pass = "***";

    mqtt_client_name должны быть разными (во всяком случае, у меня не работало, пока я не сделал их разными).
     
  14. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    В приведённом коде для передатчика и приемника в строке 10
    Код (Text):
    1. #include <ESP8266WiFi.h>
    2. #include <PubSubClient.h>
    3.  
    4. const char *ssid = "***";
    5. const char* const staPass = "***";
    6. const char *mqtt_server = "****";
    7. const int mqtt_port = ***;
    8. const char *mqtt_user = "***";
    9. const char *mqtt_pass = "***";
    10. const char *mqtt_client_name = "Neptun";
    11. #define BUFFER_SIZE 100
    12.  
    вы объявляете mqtt_client_name
    и говорите что mqtt_client_name должны быть разными, а код приводите
    Код (Text):
    1. if (client.connect(MQTT::Connect("Neptun")
    Объясните по каким признакам догадаться что MQTT :: Connect как то связан с тем mqtt_client_name?
     
  15. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Именно эту ошибку я исправил. В первой версии топиков mqtt_client_name были одинаковыми и в Передатчике и в Приемнике. В испрвленной версии кода Приемника mqtt_client_name изменен на Neptun2.

    if (client.connect(MQTT::Connect("Neptun2")
    .set_auth(mqtt_user, mqtt_pass))) - это стандартная запись, используется во всех примерах указанной выше библиотеки. Что тут непонятного?
     
  16. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    533
    Симпатии:
    61
    Во всех пяти примерах (всего их шесть) используется
    Код (Text):
    1. if (client.connect("arduinoClient")) {
    Метод connect для строки объявлен как
    Код (Text):
    1. //! Connect to the server with a client id
    2.    /*!
    3.      \param id Client id for this device
    4.     */
    5.    bool connect(String id);
    в одном из шести примеров используется
    Код (Text):
    1. if (client.connect(MQTT::Connect("arduinoClient")
    2.                      .set_auth("testeruser", "testpass"))) {
    в стеке строится класс MQTT::Connect конструктор которого опять же использует Client id
    Код (Text):
    1. //! Connect with a client ID
    2.     Connect(String cid);
    и у этого класса вызывается метод set_auth для передачи имени пользователя и пароля
    Код (Text):
    1. //! Set the username and password for authentication
    2.     Connect& set_auth(String u, String p)       { _username = u; _password = p; return *this; }
    Нет никаких mqtt_client_name, идентификатор клиента есть, имя пользователя и пароль есть.
    Вы исправили идентификатор клиента, а рассказали что исправили mqtt_client_name, который объявлен у вас на десятой строке и не используется. Для чего вы так сказали, уже не важно. :)
     
  17. Sever44

    Sever44 Новичок

    Сообщения:
    63
    Симпатии:
    1
    Разумеется, используется:
    if (client.connect(MQTT::Connect("arduinoClient")
    .set_auth("testeruser", "testpass")))
    Это же пример!
    mqtt_client_name вы не находите потому, что в примерах используется
    IPAddress server(172, 16, 0, 2);
    а не CloudMQTT.
    Давайте закончим дискуссию.
     
  18. Deonis

    Deonis Новичок

    Сообщения:
    21
    Симпатии:
    0
    По всей видимости Sever44 взял готовый пример, скопировал его не разобравшись (сам грешен) и теперь просто не понимает, что вы пытаетесь ему втолковать зачем объявлять
    Код (Text):
    1. const char *mqtt_client_name = "Neptun";
    если потом при создании подключения он забивает имя клиента вручную...
    Код (Text):
    1. client.connect(MQTT::Connect("Neptun") .set_auth(mqtt_user, mqtt_pass))
    Я думаю, что мысль у него правильная не должно быть двух клиентов с одним именем, а проблема либо с пониманием кода, либо "переклинило" бывает...
     

Поделиться этой страницей