Страница 1 из 2

MQTT+Arduino получение температуры_управление реле

Добавлено: Чт дек 13, 2018 6:39 pm
vovankin
Подскажите знатоки, что делаю не так?

Температуру на сервер mqtt получаю, но управлять реле через ардуино не получается.
В брокер приходят сообщения управления:

test/device/arduino01/rel1 ON
или
test/device/arduino01/rel1 "ON"
Не знаю как правильно должно быть, но не работает ни то ни то.
Такое ощущение, что не хватает какой то команды для того что бы ардуино принял команду и обработал ее.

Сам код взял по ссылке: http://forum.amperka.ru/threads/ardino- ... nhab.7749/

У автора вроде бы все работало.

Код: Выделить всё

#include <SPI.h>
   #include <Ethernet.h>
   #include <PubSubClient.h>
   #include <OneWire.h>
   #include <DallasTemperature.h>
   #define ONE_WIRE_BUS 2
   #define rel1_pin 13
   #define rel2_pin 7

  char REL1; // not sensing light, LED of"test/device/arduino01/rel1")f
   char REL2; // not sensing light, LED off
   char tmp1[10];
   char tmp2[10];
   char tUstav1;
   char StrtUstav11[3];
   unsigned long loopTime;
   unsigned long currentTime;

    

   OneWire oneWire(ONE_WIRE_BUS);
   DallasTemperature sensors(&oneWire);
   DeviceAddress Thermometer1 = { 0x28, 0x1C, 0xC1, 0x5D, 0x06, 0x0, 0x0, 0x43 };
   DeviceAddress Thermometer2 = { 0x28, 0xFF, 0xE7, 0x2C, 0xA6, 0x15, 0x01, 0xCB };
   IPAddress ip(192, 168, 1, 200);
   IPAddress server(192, 168, 1, 9);
   byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };

    
   void callback(char* topic, byte* payload, unsigned int length);

   EthernetClient ethClient;
   PubSubClient client(server, 1883, callback, ethClient);
   
   void callback(char* topic, byte* payload, unsigned int length) {

payload[length] = '\0';
   Serial.print(topic);
   Serial.print(" ");
   String strTopic = String(topic);
   String strPayload = String((char*)payload);
   Serial.println(strPayload);
   if (strTopic == "test/device/arduino01/rel1") {
   if (strPayload == "ON"){REL1 = 1;}
   else if (strPayload == "OFF"){REL1 = 0;}
   }

   else if (strTopic == "test/device/arduino01/rel2") {
   if (strPayload == "ON") {REL2 = 1;}
   else if (strPayload == "OFF") {REL2 = 0;}
   }

   else if (strTopic == "test/device/arduino01/kotel1/get") {
   char tUstav11;
   tUstav11 = atoi((char*)payload);
   if (tUstav11 != tUstav1 ) {
   tUstav1 = tUstav11;
           }
       }
   }

    

   void reconnect() {
   while (!client.connected()) {
   Serial.println("Attempting MQTT connection...");
   // Attempt to connect
   if (client.connect("arduinoClient")) {
   Serial.println("connected");
   }
   else {
   Serial.print("failed, rc=");
   Serial.print(client.state());
   Serial.println(" try again in 5 seconds");
   delay(3000);
   }
   }
   }

    void setup() {

   Serial.begin(9600);
   pinMode(rel1_pin, OUTPUT);
   digitalWrite(rel1_pin, LOW);
   pinMode(rel2_pin, OUTPUT);
   digitalWrite(rel2_pin, LOW);
   
   sensors.begin();
   sensors.setResolution(Thermometer1, 10);
   sensors.setResolution(Thermometer2, 10);
   
   currentTime = millis();
   loopTime = currentTime;
   Ethernet.begin(mac, ip);
    if (client.connect("arduinoClient")) {
////////////////////////////////////////////////
   Serial.println("online"); 
    Serial.println("REL1"); 
   Serial.println(REL1);     
   client.publish("test/device/arduino01/rel1", "OFF");
   client.publish("test/device/arduino01/rel2", "OFF");
   client.publish("test/device/arduino01/kotel1/get", "28");
   client.subscribe("test/device/arduino01/#");

   }

}
   void loop() {
   if (REL1 == 0) digitalWrite(rel1_pin, LOW);
   else if (REL1 == 1) digitalWrite(rel1_pin, HIGH);
    
   if (REL2 == 0) digitalWrite(rel2_pin, LOW);
   else if (REL2 == 1) digitalWrite(rel2_pin, HIGH);
   if ((sensors.getTempC(Thermometer2)) < tUstav1 && REL2==0) {
   REL2 = 1;

   client.publish("test/device/arduino01/rel2", "ON"); 
   Serial.println("REL2 - ON"); 

   }
   else if ((sensors.getTempC(Thermometer2)) >= tUstav1 && REL2==1) {
   REL2=0;
   client.publish("test/device/arduino01/rel2", "OFF");
   Serial.println("REL2 - OFF");
   } 

   client.loop();
 
   currentTime = millis();
  sensors.requestTemperatures();
   if(currentTime >= (loopTime + 15000)){
  if (!client.connected()) {
   reconnect();
   }
   float temperature1 = sensors.getTempC(Thermometer1);
   float temperature2 = sensors.getTempC(Thermometer2);
   dtostrf(temperature1, -2, 1, tmp1);

   Serial.println(tmp1);
   Serial.println("ok");

   client.publish("test/device/arduino01/temp1",tmp1); 
   dtostrf(temperature2, -2, 1, tmp2);
   client.publish("test/device/arduino01/temp2",tmp2); 
   dtostrf(tUstav1, -2, 0, StrtUstav11);
   client.publish("test/device/arduino01/kotel1/get", StrtUstav11);
   Serial.print(StrtUstav11); //8_5

   loopTime = currentTime;
   }
   }

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Чт дек 13, 2018 7:35 pm
ZyaK
Я бы изменил значения on и off на 1 и 0 для начала.
Не знаю как mqtt работает с текстом, но по моему оно передает строку. То есть, что бы Ардуино поняло строку, её надо преобразовать в массив, а из массива выдерживать уже данные.
По крайней мере когда я пытался в еспиху записать двузначное значение температуры от умного дома, еспиха принимала только 1 цифру.

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Чт дек 13, 2018 10:14 pm
olehs
ZyaK писал(а): Чт дек 13, 2018 7:35 pm Я бы изменил значения on и off на 1 и 0 для начала.
Не знаю как mqtt работает с текстом, но по моему оно передает строку. То есть, что бы Ардуино поняло строку, её надо преобразовать в массив, а из массива выдерживать уже данные.
По крайней мере когда я пытался в еспиху записать двузначное значение температуры от умного дома, еспиха принимала только 1 цифру.
в этом скетче используется String, так что проблем не должно быть

ТС, что в мониторе порта показывает?

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Пт дек 14, 2018 6:20 am
ZyaK
Вот так у меня выглядит функция коллбэк

Код: Выделить всё

void callback(char* topic, uint8_t* payload, unsigned int length){
  Serial.print("Message arrived ");
  Serial.print(topic);
  Serial.print(" ");
  String strTopic = String(topic);
  String strPayload = String((char*)payload);
  for (unsigned int i = 0; i < length; i++) {
  Dannie[2]=(char)payload[0];
  Dannie[3]=(char)payload[1];
  if (length == 1)
  {
    Dannie[3] = Dannie[2];
    Dannie[2] = '0';
  }
  Serial.print((char)payload[i]);
  Serial.println("");
  }
  if (strTopic == "KotelElectro/T_Water_EEPROM") 
  {
    eeprom_T_Water_E = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
    EEPROM_SAVE();
    Serial.print(eeprom_T_Water_E);
    Serial.println("");
   }

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Пт дек 14, 2018 7:04 pm
vovankin
В мониторе порта показывает температура+дублируется информация та что поступает брокеру, как будто бы работает команда SerialPrint (не знаю так должно быть или нет).
Но ардуинка ни как не воспринимает те команды на которые вроде бы подписана.

Уважаемый ZyaK, не могли бы вы поделиться своим кодом.
Никак не могу найти работающий код, что бы управлять ардуинкой Majordomo-м по протоколу MQTT и через плату Ethernet шилда.
Сам я совсем не программист.

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Сб дек 15, 2018 9:52 am
ZyaK
да пожалуйста, только они под ЕСПи

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Вс апр 04, 2021 8:44 pm
schel4ok
а зачем у тебя в коде почти в каждой второй строчке встречается client.loop();?
Я думал его надо только один раз внутри void loop() вставить

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Пн апр 05, 2021 2:48 pm
ZyaK
schel4ok писал(а): Вс апр 04, 2021 8:44 pm а зачем у тебя в коде почти в каждой второй строчке встречается client.loop();?
Я думал его надо только один раз внутри void loop() вставить
Не помню точно, но по моему когда 1 раз оно было написано не всегда прилетали данные с сервера, по тому решил напихать везде где можно :D за то работает

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Пн апр 05, 2021 7:27 pm
Vitich
Вот рабочий проект. Использовал Mega2560+ENC28J60

Но на ESP или NodeMCU намного удобнее. Ипрограмму можно написать минут за 15 даже не зная C++

Re: MQTT+Arduino получение температуры_управление реле

Добавлено: Вт апр 06, 2021 8:10 pm
schel4ok
Да. За 15 минут нифига не зная.
Бесят такие