Nano+w5500+mqtt, проблема с подключением к сети

Тема в разделе "Проводная и беспроводная связь", создана пользователем yden, 28 мар 2018.

  1. yden

    yden Гик

    Здравствуйте.
    Подскажите пожалуйста, где в коде ошибка. Суть: ардуино нано + w5500 + mqtt. Нужно отправлять\читать топики на этом железе. Там что-то с интернет частью.

    Код:
    Код (C++):
    #include <Bounce.h>
    #include <MQTT.h>
    #include <PubSubClient.h>
    #include <SPI.h>
    #include <Ethernet.h>

    // =======================================================================
    // Конфигурация устройства MQTT:
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xA2 };
    IPAddress ip(192, 168, 1, 73);
    EthernetClient client;

    const char *mqtt_server = "192.168.1.70"; // Имя сервера MQTT
    const int mqtt_port = 1883; // Порт для подключения к серверу MQTT
    const char *mqtt_user = "****"; // Логи от сервер
    const char *mqtt_pass = "****"; // Пароль от сервера
    // =======================================================================

    const byte outPin1 = 5; // ночник холл
    const byte outPin2 = 3; // холл
    const byte outPin3 = 2; // кладовка
    const byte outPin4 = 4; // санузел
    const byte outPin5 = 6; // диммер холл
    const byte outPin6 = 7; // диммер кладовка
    const byte outPin7 = 8; // ночник санузел 1 ступень

    //кнопки
    const byte inButton1 = 15; //вход кнопка1
    const byte inButton2 = 16; //вход кнопка2

    //создаем объект класса Bounce. Указываем пин, к которому подключена кнопка, и время дребезга в мс.
    Bounce bouncer1 = Bounce(inButton1, 150);
    Bounce bouncer2 = Bounce(inButton2, 150);

    boolean flag_button1 = false; //флаг кнопка 1
    boolean flag_button2 = false; //флаг кнопка 2

    //подсчет времени MQTT
    long previousMillis_mqtt = 0;  // храним время последнего подключения
    long interval_mqtt = 10000;     //интервал 3 сек

    //--------------------------------------------------------------------------------------
    // Функция получения данных от сервера MQTT
    void callback(const MQTT::Publish& pub)
    {
      if  (pub.topic() == "ihouse/svet/holl/in")
      {
        if (String(pub.payload_string()) == "1") flag_button1 = true;
        if (String(pub.payload_string()) == "0") flag_button1 = false;

        digitalWrite(outPin2, flag_button1);
        digitalWrite(outPin5, flag_button1);
      }

      if  (pub.topic() == "ihouse/svet/san/in")
      {
        if (String(pub.payload_string()) == "1") flag_button2 = true;
        if (String(pub.payload_string()) == "0") flag_button2 = false;

        digitalWrite(outPin4, flag_button2);
        digitalWrite(outPin7, flag_button2);
      }
    }

    EthernetClient ethClient;
    PubSubClient client(ethClient, mqtt_server, mqtt_port);

    void setup()
    {
      pinMode(inButton1, INPUT);
      pinMode(inButton2, INPUT);

      pinMode(outPin1, OUTPUT);
      digitalWrite(outPin1, LOW);

      pinMode(outPin2, OUTPUT);
      digitalWrite(outPin2, LOW);

      pinMode(outPin3, OUTPUT);
      digitalWrite(outPin3, LOW);

      pinMode(outPin4, OUTPUT);
      digitalWrite(outPin4, LOW);

      pinMode(outPin5, OUTPUT);
      digitalWrite(outPin5, LOW);

      pinMode(outPin6, OUTPUT);
      digitalWrite(outPin6, LOW);

      pinMode(outPin7, OUTPUT);
      digitalWrite(outPin7, LOW);

      Serial.begin(115200);
      Ethernet.begin(mac, ip);
    }

    ////функция светодиод улица
    //void function_led_outdoor (uint16_t time_0, uint16_t time_1)
    //{
    //  static bool state = 0;       // состояние светодиода
    //  static uint32_t future = 0;  // время будущего перескока на другое состояние
    //  if (millis() < future) return; // если время не пришло(нужное значение millis() ) то выйти из функции
    //  state = !state;              // время смены пришло поменяйте состояние
    //  future += state ? time_0 : time_1 ;
    //  // определите новое время для перескока если state = 1 то future=future+time_0
    //  //                                      если state = 0 то future=future+time_1
    //  digitalWrite(led_outdoor, state);
    //}

    //--------------------------------------------------------------------------------------
    // Функция отправки в топик
    void MQTT_Send()
    {
      unsigned long currentMillis_mqtt = millis();

      if (currentMillis_mqtt - previousMillis_mqtt >= interval_mqtt)
      {
        previousMillis_mqtt = currentMillis_mqtt;
        client.publish("ihouse/work/svet_veranda", String(random(100)));
      }
      delay(10);
    }

    void loop()
    {
      //--------------------------------------------------------------------------------------
      //проверка состояния кнопки1 - холл
      if ( bouncer1.update() )
      {
        //если считано значение 1
        if ( bouncer1.read() == HIGH)
        {
          flag_button1 = !flag_button1;

          digitalWrite(outPin2, flag_button1);
          digitalWrite(outPin5, flag_button1);
          client.publish("ihouse/svet/holl/out", String(flag_button1));    
        }
      }

      //--------------------------------------------------------------------------------------
      //проверка состояния кнопки2 - санузел
        if ( bouncer2.update() )
      {
        //если считано значение 1
        if ( bouncer2.read() == HIGH)
        {
          flag_button2 = !flag_button2;

          digitalWrite(outPin4, flag_button2);
          digitalWrite(outPin7, flag_button2);
          client.publish("ihouse/svet/san/out", String(flag_button2));    
        }
      }

      //--------------------------------------------------------------------------------------
      //мигание светодиодом улица
    //  if (currentMillis_diod_interval - previousMillis_diod_interval >= 100000)
    //  {
    //    previousMillis_diod_interval = currentMillis_diod_interval;
    //    interval_diod = random(10000);
    //  }
    //  function_led_outdoor(250, interval_diod);

      //--------------------------------------------------------------------------------------
      // подключаемся к MQTT серверу
      if (Ethernet.status() == WL_CONNECTED)
      {
      if (!client.connected()) {
        Serial.println("Connecting to MQTT server");
        if (client.connect(MQTT::Connect("nano_svet_veranda")
                           .set_auth(mqtt_user, mqtt_pass)))
        {
          Serial.println("Connected to MQTT server");
          client.set_callback(callback);
          client.subscribe("ihouse/svet/holl/in"); // подписывааемся по топик
          client.subscribe("ihouse/svet/san/in"); // подписывааемся по топик
        }
        else
        {
          Serial.println("Could not connect to MQTT server");
        }
      }

      if (client.connected())
      {
        client.loop();
        MQTT_Send();
      }
    }
    Ругается:
    svet_veranda_mqtt:82: error: conflicting declaration 'PubSubClient client'

    благодарю
     
  2. SergeiL

    SergeiL Оракул Модератор

    У Вас в 10 строке
    Код (C++):
    EthernetClient client;
    и ниже перед setup():
    Код (C++):
    PubSubClient client(ethClient, mqtt_server, mqtt_port);
    client и там и там определяется.
     
  3. SergeiL

    SergeiL Оракул Модератор

    И еще момент, если Вы используете библиотеку PubSubClient, зачем Вам MQTT.h?
     
  4. yden

    yden Гик

    Они делают одно и тоже?
     
  5. SergeiL

    SergeiL Оракул Модератор

    Для чтения публикации топиков вполне хватает PubSubClient.
    По описанию MQTT делает тоже самое, но я ее не использовал.
     
  6. yden

    yden Гик

    Ребята, все равно ничего не пойму. Связка ардуино нано + шилд w5100. В интернет не выходит.

    Код (C++):
    #include <Bounce.h>
    #include <PubSubClient.h>
    #include <SPI.h>
    #include <Ethernet.h>

    // =======================================================================
    // Конфигурация устройства MQTT:
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x76 };
    IPAddress ip(192, 168, 1, 76);
    //EthernetClient client;

    const char *mqtt_server = "192.168.1.70"; // Имя сервера MQTT
    const int mqtt_port = 1883; // Порт для подключения к серверу MQTT
    const char *mqtt_user = "****"; // Логи от сервер
    const char *mqtt_pass = "*****"; // Пароль от сервера
    // =======================================================================

    const byte outPin1 = 5; // ночник холл
    const byte outPin2 = 3; // холл
    //const byte outPin3 = 2; // кладовка
    const byte outPin4 = 4; // санузел
    const byte outPin5 = 6; // диммер холл
    //const byte outPin6 = 7; // диммер кладовка
    const byte outPin7 = 8; // ночник санузел 1 ступень

    //кнопки
    const byte inButton1 = 15; //вход кнопка1
    const byte inButton2 = 16; //вход кнопка2

    //создаем объект класса Bounce. Указываем пин, к которому подключена кнопка, и время дребезга в мс.
    Bounce bouncer1 = Bounce(inButton1, 150);
    Bounce bouncer2 = Bounce(inButton2, 150);

    boolean flag_button1 = false; //флаг кнопка 1
    boolean flag_button2 = false; //флаг кнопка 2

    //подсчет времени
    //подсчет времени MQTT
    long previousMillis_mqtt = 0;  // храним время последнего подключения
    long interval_mqtt = 10000;     //интервал 3 сек

    //--------------------------------------------------------------------------------------
    // Функция получения данных от сервера MQTT
    void callback(const MQTT::Publish& pub)
    {
      if  (pub.topic() == "ihouse/svet/holl/in")
      {
        if (String(pub.payload_string()) == "1") flag_button1 = true;
        if (String(pub.payload_string()) == "0") flag_button1 = false;

        digitalWrite(outPin2, flag_button1);
        digitalWrite(outPin5, flag_button1);
      }

      if  (pub.topic() == "ihouse/svet/san/in")
      {
        if (String(pub.payload_string()) == "1") flag_button2 = true;
        if (String(pub.payload_string()) == "0") flag_button2 = false;

        digitalWrite(outPin4, flag_button2);
        digitalWrite(outPin7, flag_button2);
      }

    }

    EthernetClient ethClient;
    PubSubClient client(ethClient, mqtt_server, mqtt_port);

    void setup()
    {
      pinMode(inButton1, INPUT);
      pinMode(inButton2, INPUT);

      pinMode(outPin1, OUTPUT);
      digitalWrite(outPin1, LOW);

      pinMode(outPin2, OUTPUT);
      digitalWrite(outPin2, LOW);

    //  pinMode(outPin3, OUTPUT);
    //  digitalWrite(outPin3, LOW);

      pinMode(outPin4, OUTPUT);
      digitalWrite(outPin4, LOW);

      pinMode(outPin5, OUTPUT);
      digitalWrite(outPin5, LOW);

    //  pinMode(outPin6, OUTPUT);
    //  digitalWrite(outPin6, LOW);

      pinMode(outPin7, OUTPUT);
      digitalWrite(outPin7, LOW);

      Serial.begin(115200);
      Ethernet.begin(mac, ip);
    }

    //--------------------------------------------------------------------------------------
    // Функция отправки в топик
    void MQTT_Send()
    {
      unsigned long currentMillis_mqtt = millis();

      if (currentMillis_mqtt - previousMillis_mqtt >= interval_mqtt)
      {
        previousMillis_mqtt = currentMillis_mqtt;
        client.publish("ihouse/work/svet_veranda", String(random(100)));
      }
      delay(10);
    }

    void loop()
    {
      //--------------------------------------------------------------------------------------
      //проверка состояния кнопки1 - холл
      if ( bouncer1.update() )
      {
        //если считано значение 1
        if ( bouncer1.read() == HIGH)
        {
          flag_button1 = !flag_button1;

          digitalWrite(outPin2, flag_button1);
          digitalWrite(outPin5, flag_button1);
          client.publish("ihouse/svet/holl/out", String(flag_button1));    
        }
      }

      //--------------------------------------------------------------------------------------
      //проверка состояния кнопки2 - санузел
        if ( bouncer2.update() )
      {
        //если считано значение 1
        if ( bouncer2.read() == HIGH)
        {
          flag_button2 = !flag_button2;

          digitalWrite(outPin4, flag_button2);
          digitalWrite(outPin7, flag_button2);
          client.publish("ihouse/svet/san/out", String(flag_button2));    
        }
      }

      //--------------------------------------------------------------------------------------
      // подключаемся к MQTT серверу
      if (ethClient.connected())
      {
      if (!client.connected())
      {
        Serial.println("Connecting to MQTT server");
        if (client.connect(MQTT::Connect("nano_svet_veranda")
                           .set_auth(mqtt_user, mqtt_pass)))
        {
          Serial.println("Connected to MQTT server");
          client.set_callback(callback);
          client.subscribe("ihouse/svet/holl/in"); // подписывааемся по топик
          client.subscribe("ihouse/svet/san/in"); // подписывааемся по топик
        }
        else
        {
          Serial.println("Could not connect to MQTT server");
        }
      }

      if (client.connected())
      {
        client.loop();
        MQTT_Send();
      }
    }
    }
    Шилд какие пины использует?
     
  7. SergeiL

    SergeiL Оракул Модератор

    SPI +CS
     
  8. yden

    yden Гик

    10-13 и 4 ?
     
  9. yden

    yden Гик

    Пинг проходит по локалке. Нет коннекта с mqtt брокером.
     
  10. yden

    yden Гик

    Код (C++):
    // подключаемся к MQTT серверу
      if (ethClient.connected())
      {
        Serial.println("Вася");
        if (!mqtt_client.connected())
        {
          Serial.println("Connecting to MQTT server");
          if (mqtt_client.connect(MQTT::Connect("nano_svet_veranda")
                                  .set_auth(mqtt_user, mqtt_pass)))
          {
            Serial.println("Connected to MQTT server");
            mqtt_client.set_callback(callback);
            mqtt_client.subscribe("ihouse/svet/holl/in"); // подписывааемся по топик
            mqtt_client.subscribe("ihouse/svet/san/in"); // подписывааемся по топик
          }
          else
          {
            Serial.println("Could not connect to MQTT server");
          }
        }

        if (mqtt_client.connected())
        {
          mqtt_client.loop();
          MQTT_Send();
        }
      }
    В монитор "Вася" не выводится.
     
  11. SergeiL

    SergeiL Оракул Модератор

    Вы смотрели примеры, которые идут с библиотекой PubSubClient?
    Знаете как добраться до примеров? Меню <Файл> -> <Примеры> там ищите PubSubClient.

    Посмотрите, там есть пример mqtt_basic.
    Он точно работает, я его брал за основу. В примере все просто описано.
    Вызовы функций там сильно отличаются от вызовов в вашем скетче.

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

    Да, не забудьте, что имя клиента в функции client.connect("arduinoClient") должно быть уникально для брокера. То есть, если у Вас пытается подключиться клиент с таким же именем, оба клинта с одинаковыми именами будут постоянно переподключаться, и не смогут нормально работать.
    На это я напарывался, когда копировал готовый скетч на новое устройство.
    Я его теперь формирую на основании части MAC адреса.
     
  12. yden

    yden Гик

    Мой код я взял со своего же работающего кода для esp8266.
     
  13. SergeiL

    SergeiL Оракул Модератор

    Данные с Амперки: Ethernet Shield занимает пины MOSI, MISO, SCK, а также 10-й в качестве CS для чипа W5500.

    У меня и на Leonardo ETH с W5500 на борту, и на Меге с Амперковским Шилдом, CS на десятом пине, я его не переопределял. (CS на 10 пине по умолчанию).
     
  14. yden

    yden Гик

    хм, убрал строки:
    // if (ethClient.connected())
    // {

    Ардуинка с mqtt заговорила.
     
  15. SergeiL

    SergeiL Оракул Модератор

    Поздравляю!
    Кстати в примерах к PubSubClint такого тоже нет. :)
     
  16. SergeiL

    SergeiL Оракул Модератор

    Связкой Arduino - W5500 - PubSubclient очень доволен, 3 раза тьфу, чтобы не сглазить!
    Когда начинал собирать вместе, даже не рассчитывал на такую стабильность и надежность!
    Даже внешний watchdog слепил. Пока ни разу не сработал, данные идут очень стабильно и по проводным каналам, и по LTE каналу с дачи.