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

Передача данных с МЖД в Arduino.

Добавлено: Чт авг 07, 2025 8:20 pm
karsotrade
Хоть я и не "новичек" но решил сюда отписать т.к. проблема вроде простая, но я конкретно затупил с ее решением.
Суть проблемы в передаче с мжд двух или трех значных данных.
Сейчас у меня это работает так:
в мжд есть метод -

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

$url='http://192.168.21.8/$r';
getURL($url,0);
При его запуске передается например символ "r" на ардуину по этому адресу (ip ардуины).
На ардуине (Mega+W5100) ловим это:

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

if (client){                                                                                     
  boolean currentLineIsBlank = true;                                                             
  while (client.connected()) {                                                                
if (client.available()) {                                                                        
  char c = client.read();                                                                       
if (newInfo && c == '  '){                                                                       
  newInfo = 0;                                                                                   
  }
if (c == '$'){                                                                                  
  newInfo = 1;                                                                                   
  }
if (newInfo == 1){                                                                               
  Serial.println (c);
if (c == 'r' )                                                             
  {  выполнение команды  }
  
  if (c == '\n') {                                        
currentLineIsBlank = true; }                            
else if (c != '\r') {                                   
currentLineIsBlank = false; }
if (c == '\n' && currentLineIsBlank)                    
{break;}                                                
}}
delay (1);                                              
client. stop(); 
Все работает замечательно, но в этом варианте символ отправляется только однозначный, команд у меня до сотни, поэтому надо двух-трех значные символы или числа отправляемые на ардуину (каждый символ соответствует своей команде).
Подскажите пожалуйста как это реализовать.

Re: Передача данных с МЖД в Arduino.

Добавлено: Пт авг 08, 2025 7:17 am
ZyaK
не проще взять ЕСПи?

вот кусок кода еспи общается с атмегой по уарту

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

void read_uart()
{
  if (Serial.available() > 0)
  { 
    int com = (Serial.read());
    if(Start_flag == 1)
    {
      Dannie[A]=com;
      A++;
      if (com==0x0A)
      {
        Stop_flag = 1;
        Start_flag = 0;
      }
      if (A>5)
      {
        Start_flag = 0;
        Stop_flag = 0;
        A = 0;
      }
    }
    else
    {
      if (com=='q')
      {
        Start_flag=1;
        A = 0;
        Dannie[A]=com;
        A++;
      }
    }
  if (Stop_flag == 1)
  {
    switch(Dannie[1])
    {
      case 'a':
      {
        Hysteresis_E = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
        
        Serial.println("case a");
        Serial.print("Hysteresis_EEPROM");
        Serial.println("");
        Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        client.publish(Hysteresis_EEPROM, String(Hysteresis_E).c_str());
        client.loop();
       }
      break;
      case 'b':
      {
        T_Water_E = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
        Serial.println("case b");
        Serial.print("T_Water_EEPROM");
        Serial.println("");
        Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        client.publish(T_Water_EEPROM, String(T_Water_E).c_str());
        client.loop();
      }
      break;
      case 'c':
      {
        T_Oil_E = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
        Serial.println("case c");
        Serial.print("T_Oil_EEPROM");
        Serial.println("");
        Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        client.publish(T_Oil_EEPROM, String(T_Oil_E).c_str());
        client.loop();
      }
      break;
      case 'g':
      {
        Stand = (Dannie[3]-48)*1;
        Serial.println("case g");
        Serial.print("Standby");
        Serial.println("");
        //Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        if(Stand == 0)
        {
          Status = 1;          
        }
        else
        {
          Status = 0;
        }
       client.publish(Power, String(Status).c_str());
       client.loop();
      }
      break;
      client.loop();
      case 'd':
      {
        Pres = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
        Serial.println("case d");
        Serial.print("Pressure");
        Serial.println("");
        Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        client.publish(Pressure, String(Pres).c_str());
        client.loop();
      }
      break;
      case 'e':
      {
        T_Oil_a = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
        Serial.println("case e");
        Serial.print("T_Oil_actual");
        Serial.println("");
        Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        client.publish(T_Oil_actual, String(T_Oil_a).c_str());
        client.loop();
      }
      break;
      client.loop();
      case 'f':
      {
        T_Water_a = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
        Serial.println("case f");
        Serial.print("T_Water_actual");
        Serial.println("");
        Serial.print(Dannie[2]);
        Serial.println(Dannie[3]);
        client.publish(T_Water_actual, String(T_Water_a).c_str());
        client.loop();
      }
      break; 
    }
    Stop_flag=0;
    }
  }
}
вот кусок кода приёма данных по mqtt

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

void callback(char* topic, uint8_t* payload, unsigned int length){
  Serial.print("Message arrived ");
  Serial.print(topic);
  Serial.print(" ");
  Serial.println(" ");
  String strTopic = String(topic);
  String strPayload = String((char*)payload);
  for (unsigned int i = 0; i < length; i++) {
  Dannie[1]=(char)payload[0];
  Dannie[2]=(char)payload[1];
  Dannie[3]=(char)payload[2];
  Dannie[4]=(char)payload[3];
  Dannie[5]=(char)payload[4];
  if (length == 1)
  {
    Dannie[2] = Dannie[1];
    Dannie[1] = '0';
    Dannie[3] = '0';
    Dannie[4] = '0';
    Dannie[5] = '0';
    Serial.print("length = 1");
    Serial.println();
  }
  if (length == 2)
  {
    Dannie[3] = Dannie[2];
    Dannie[2] = Dannie[1];
    Dannie[1] = '0';
    Dannie[4] = '0';
    Dannie[5] = '0';
    Serial.print("length = 2");
    Serial.println();
  }
  if (length == 3)
  {
    Dannie[4] = Dannie[3];
    Dannie[3] = Dannie[2];
    Dannie[2] = Dannie[1];
    Dannie[1] = '0';
    Dannie[5] = '0';
    Serial.println("length = 3");
  }
  if (length == 4)
  {
    Dannie[5] = Dannie[4];
    Dannie[4] = Dannie[3];
    Dannie[3] = Dannie[2];
    Dannie[2] = Dannie[1];
    Dannie[1] = '0';
    Serial.println("length = 4");
  }
    Serial.print("Dannie [1] = ");
    Serial.println(Dannie[1]);
    Serial.print("Dannie [2] = ");
    Serial.println(Dannie[2]);
    Serial.print("Dannie [3] = ");
    Serial.println(Dannie[3]);
    Serial.print("Dannie [4] = ");
    Serial.println(Dannie[4]);
    Serial.print("Dannie [5] = ");
    Serial.println(Dannie[5]);
    Serial.println();
    Serial.println();
  }
  if (strTopic == "KotelElectro/T_home_read") 
   {
    if(length == 1)
    {
       T_read = (Dannie[2]-48)*1;
    }
    else
    {
      if(Dannie[4] == '.')
      {
        T_read = ((Dannie[5]-48)*1+(Dannie[3]-48)*10+(Dannie[2]-48)*100);
        T_read = T_read/10;        
      }
      else
      {
        T_read = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
      }
    }
    
     Serial.print("T_read = ");
     Serial.print(T_read);
     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.print(eeprom_T_Water_E);
    Serial.println("");
    
   }
   if (strTopic == "KotelElectro/Ogidanie") 
   {
    if(length == 1)
    {
       T_ogidanie = (Dannie[2]-48)*1;
    }
    else
    {
      T_ogidanie = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
    }
     
     Serial.print("T_ogidanie = ");
     Serial.print(T_ogidanie);
     Serial.println("");
   }
   if (strTopic == "KotelElectro/Hysteresis_EEPROM") 
   {
      if(length == 1)
    {
       eeprom_Hysteresis_E = (Dannie[2]-48)*1;
    }
    else
    {
      eeprom_Hysteresis_E = (Dannie[3]-48)*1+(Dannie[2]-48)*10;
    }

Re: Передача данных с МЖД в Arduino.

Добавлено: Пт авг 08, 2025 8:34 am
karsotrade
Спасибо, буду разбираться. Только "железо" поменять не могу, уже собран достаточно сложный контроллер с тачскрином для теплицы, управляющий несколькими зонами полива, проветриванием, набором воды, датчиками температуры, влажности и т.д. В связи с обкаткой стали добавлятся функции, вот я и уперся в количество команд с мжд.

Re: Передача данных с МЖД в Arduino.

Добавлено: Пт авг 08, 2025 10:58 am
V.A.S.t
karsotrade писал(а):
Пт авг 08, 2025 8:34 am
Спасибо, буду разбираться. Только "железо" поменять не могу, уже собран достаточно сложный контроллер с тачскрином для теплицы, управляющий несколькими зонами полива, проветриванием, набором воды, датчиками температуры, влажности и т.д. В связи с обкаткой стали добавлятся функции, вот я и уперся в количество команд с мжд.
Не понимаю, зачем для контроллера добавлять ещё контроллер, если у существующего контроллера уже всё есть? (Это я к сообщению выше)
Но зерно истины в том сообщении всё-же есть. Воспользуйтесь библиотекой Pusubclient. MQTT - это идеальный протокол для умного дома. У меня все три ардуины через него управляются и отправляют свои данные.

Re: Передача данных с МЖД в Arduino.

Добавлено: Сб авг 09, 2025 12:12 am
karsotrade
V.A.S.t писал(а):
Пт авг 08, 2025 10:58 am
Не понимаю, зачем для контроллера добавлять ещё контроллер, если у существующего контроллера уже всё есть? (Это я к сообщению выше)
Но зерно истины в том сообщении всё-же есть. Воспользуйтесь библиотекой Pusubclient. MQTT - это идеальный протокол для умного дома. У меня все три ардуины через него управляются и отправляют свои данные.
Вероятно я не совсем понятно обьяснил, контроллер один, собран и работает. В процессе обкатки дополняются новые функции и команды с мжд, Вот я и уперся в количество символов передаваемых мжд в ардуину при таком раскладе. Менять протокол мне не имеет смысла т.к. скеч (длинной более 2000 строк) замечательно работает. Проблема мизерная, с мжд сейчас (допустим) отправляемое число 15 принимается ардуиной как 1 и 5, и каждое на своей строке. Мне это надо привести в нормальный вид "15", и далее использовать в командах ардуины.

Re: Передача данных с МЖД в Arduino.

Добавлено: Сб авг 09, 2025 3:23 am
V.A.S.t
karsotrade писал(а):
Сб авг 09, 2025 12:12 am
Вероятно я не совсем понятно обьяснил, контроллер один, собран и работает.
Я всё понял, я про совет, который был дан ZyaK » Пт авг 08, 2025 12:17 pm
Протокол имеет смысл поменять.
По факту, как я написал, ставьте библиотеку Pubsubclient и шлите что хотите, куда хотите, в каких хотите объемах через MQTT. Брокера только разверните на сервере с MDM.
Температуру, влажность, режимы полива в MDM. Команды из МДМ. Полный контроль.
НО! Если уж так лень менять протокол, хотя е ещё раз КРАЙНЕ рекомендую это сделать, то сделайте просто закрывающий символ в запросе и ориентируйтесь на него.

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

if (client){                                                                                                                                               
  if (client.connected()) {   
String res = '';  
newInfo = 0;
while (client.available()) {                                                                        
  char c = client.read();                                                                       
if (c == '$'){                                                                                  
  newInfo = 1;                                                                                   
  }
if (c == '|')        //Завершающий символ                                 
{break;} 
if (newInfo == 1){                                                                               
  Serial.println (c);
  res += c;
}
                                               
}}
delay (1);                                              
client. stop(); 
if (res == 'r' )                                                             
  {  выполнение команды  }
else if(res == '....')
	{  выполнение команды  }
.....
При этом запрос будет выглядеть как http://192.168.21.8/$r1df1t1|