Подключение к внешнему MQTT через ArduinoUNO+Ethernet Shild

Igor Dzherenov
Offline
Зарегистрирован: 21.03.2021

Есть бесплатный MQTT сервер ClusterFly.ru к нему я без проблем смог подключиться через ESP-01,  но она иногда подвисает. Решил попробовать через ArduinoUNO+Ethernet Shild, но не смог найти примеров в интернете как это сделать, полно примеров для локальных MQTT. Единственное что удалось это подключиться через https://www.shiftr.io/ но там своя библиотека и сервер платный. Может кто делал подобный проект, подскажите как реализовать подключение или дайте ссылку на пример.

sadman41
Offline
Зарегистрирован: 19.10.2016

А чем примеры для локальных не подходят?

Igor Dzherenov
Offline
Зарегистрирован: 21.03.2021

непонятно куда и как  там вписывать адрес сервера логин пароль и т.д.

sadman41
Offline
Зарегистрирован: 19.10.2016
Igor Dzherenov
Offline
Зарегистрирован: 21.03.2021

Спасибо, я это все видел, но посмотрев еще раз нашел ошибку не там стояла скобка. 

теперь возникла проблема с получением команд, на отправку все работает замечательно, а на прием если больше 1 топика начинается хаотичная задержка, команда может дойти сразу а может через время выдать все что было отправлено на MQTT брокер, попробовал с разными брокерами эффект одинаковый.

Обработчик использую из примера:

  void callback(char* topic, byte* payload, unsigned int length){
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
  Serial.print((char)payload[i]);

 

 

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Я думаю что проблема как раз в  ArduinoUNO, в ESP 80Mhz а в ArduinoUNO - 16 Mhz.

Очень медленно переваривает ответ.

Igor Dzherenov
Offline
Зарегистрирован: 21.03.2021

Походу в обработчике

я посылал топики вида

user_********/rele1

user_********/rele2

и подписывался

mqttClient.subscribe("user_********/rele1");
mqttClient.subscribe("user_********/rele2");
mqttClient.subscribe("user_********/rele3");

а надо было прописать один раз
mqttClient.subscribe("user_********/rele/#");

и посылать топики

user_********/rele/1

user_********/rele/2

ппц не очевидно конечно

Но через MQTT сервер ClusterFly.ru всеравно не работает.

sadman41
Offline
Зарегистрирован: 19.10.2016

В MQTT много тонких моментов. Накопление данных на брокере, отсутствие синхронизации по времени - это все про MQTT.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Igor Dzherenov пишет:

Но через MQTT сервер ClusterFly.ru всеравно не работает.

Снова MQTT | Аппаратная платформа Arduino

тут масса примеров, попробуйте на ClusterFly.ru
или тут 

http://arduino.ru/forum/proekty/ethernet-vyklyuchatel-nagruzki-v-lokalno...

 

Igor Dzherenov
Offline
Зарегистрирован: 21.03.2021
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <avr/wdt.h>

byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 100);
const char* server = "srv2.clusterfly.ru";           //С сервером srv1.clusterfly.ru не заработало
char *mqtt_user = "user_*******";                   // Логин от сервер
char *mqtt_pass = "pass_********";                   // Пароль от сервера

static char pressure[10];                            // Переменная для перевода
int rele1 = 0;
int rele2 = 0;
int rele3 = 0;

uint32_t timer1, timer2, timer3;

// Шапка Функции Callback (обратный вызов)
void callback(char* topic, byte* payload, unsigned int length);
EthernetClient ethClient;
PubSubClient mqttClient(ethClient);

//Все как в примере
void callback(char* topic, byte* payload, unsigned int length){
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
  Serial.print((char)payload[i]);
  }
  Serial.println();
//Переводим данные в стринг
      String strTopic = String(topic);
      String strPayload = String((char*)payload);
      Serial.println(strPayload); //Выводим то что получили в порт
 //Включение первого реле     
      if (strTopic == "user_********/rele/1") {//Если имя топика равно
           if (strPayload == "1le/#") {        //Если то что пришло равно 1le/# (у меня так приходит "1")
           rele1 = 1;}                         //Записываем в переменную "1"
      else if (strPayload == "0le/#") {        //Если то что пришло равно 0le/# (у меня так приходит "0")
           rele1 = 0;}                         //Записываем в переменную "0"
      Serial.print("Реле1 = ");                //Проверяем что в переменную записалось то что получено
      Serial.println(rele1);    
      }
  //Включение второго реле      
      if (strTopic == "user_********/rele/2") {
           if (strPayload == "1le/#") {
           rele2 = 1;}
      else if (strPayload == "0le/#") {
           rele2 = 0;}
      Serial.print("Реле2 = "); 
      Serial.println(rele2);    
      }
  //Включение третьего реле      
      if (strTopic == "user_********/rele/3") {
           if (strPayload == "1le/#") {
           rele3 = 1;}
      else if (strPayload == "0le/#") {
           rele3 = 0;}
      Serial.print("Реле3 = "); 
      Serial.println(rele3);    
      }
}

//


void setup()
{
  Serial.begin(9600);

  mqttClient.setServer(server, 9991);
  mqttClient.setCallback(callback);

  Ethernet.begin(mac, ip);
  delay(1500);

  wdt_enable(WDTO_8S);     // разрешить watchdog
}

void loop()
{
    mqttClient.loop();
    if (mqttClient.connect("*******",mqtt_user,mqtt_pass)) {         //Если подключились
         if (millis()- timer2 >= 10000){                             //Задержка на отправление
             timer2 = millis(); 
             mqttClient.publish("user_*******/data1",pressure);     //Отправляем данные
             mqttClient.publish("user_*******/data2",pressure);
             mqttClient.publish("user_*******/data3",pressure);
             mqttClient.publish("user_*******/data4",pressure);    
         }
             mqttClient.subscribe("user_*******/rele/#");           //Подписываемся на входящие данные
    }
    
    if (millis()- timer1 >= 20000){
    timer1 = millis(); 

    float P = map(analogRead(0),0,1050,0,1050);                      //Данные с аналогового входа
    Serial.print("Давление:"); 
    Serial.println(P);
    
    dtostrf(P, 4, 0, pressure); // Перевод в char
    }
wdt_reset();    
}

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