Система автоматизации на базе Arduino (умный дом, умная теплица, охранная сигнализация)

Тема в разделе "Arduino & Shields", создана пользователем SmartRnd, 6 дек 2016.

  1. SmartRnd

    SmartRnd Нерд

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

    В данном случае необходимо разработать устройства с интерфейсом RS-485 и написать протокол обмена данными между ними. С этой задачей уже сталкивался или еще столкнется любой разработчик оборудования. Каждый проходит этот путь самостоятельно, наступая на грабли, набившие шишки сотням предшественников.

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

    Протокол предназначен для построения централизованных систем с одним контроллером, который управляет всеми подчиненными модулями.

    Какие плюсы дает это вам:

    • протокол уже написан, его не требуется сочинять;

    • уже есть базовый скетч, который работает на данном протоколе. Хотите сделать адресный датчик температуры? Возьмите Arduino, привяжите к нему датчик температуры и немного допишите код. Все готово!!!;

    • протокол уже проверен и отлажен, т. е. уже реально используется много лет. В нем есть всё необходимое;

    • в свободном доступе находится программа-контроллер, которая позволяет управлять этими модулями по любому алгоритму, который вы сами захотите написать;

    • если вы еще не разработали какие-то модули с нужным функционалам, вы можете покупать их у производителей, которые уже давно занимаются устройствами на протоколе ADNet. Разработали свое устройство, используйте его.
     
    arkadyf и 9xA59kK нравится это.
  2. SmartRnd

    SmartRnd Нерд

    Описание протокола:

    http://smart-elec.ru/manuals/alpha/ADNetProtocol.pdf

    Базовый счетч для модуля, работающего на протоколе ADNet

    Код (C++):
    /*
      Пример модуля, работающего по протоколу ADNet

      Этот пример является шаблоном для разработки новых модулей, работающих по протоколу ADNet

      Описание PIN
      0 - RX RS485 RO
      1 - TX RS485 DI
      2 - управление приёмом и передачей по RS485. На этой же ноге висит Led индикации передачи
      3 - Led индикации работы. Мигает 1 раз в секунду, если всё хорошо, иначе - ошибка
      4 - задание адреса модуля по шине ADNet
      5 - задание адреса модуля по шине ADNet
      6 - задание адреса модуля по шине ADNet
      7 - задание адреса модуля по шине ADNet
      8 - задание адреса модуля по шине ADNet
      9 - задание адреса модуля по шине ADNet

      Created 14 сентября 2016г
      Быков Виктор Сергеевич

    */

    #include <EEPROM.h>
    unsigned char buff_in[8]; // буфер входящих символов
    unsigned char rbit_num=0; // количество байт во входящем буфере

    unsigned char RS485out = 2; // Порт управления прием/передача RS485
    unsigned char ledWork = 3;  // Светодиод индикации
    unsigned char jmp0 = 4;  // Джампер 0
    unsigned char jmp1 = 5;  // Джампер 1
    unsigned char jmp2 = 6;  // Джампер 2
    unsigned char jmp3 = 7;  // Джампер 3
    unsigned char jmp4 = 8;  // Джампер 4
    unsigned char jmp5 = 9;  // Джампер 5
    unsigned char addr; // Адрес модуля в шине
    unsigned char temp_uch;
    int temp_i;
    int ledWork_freq; //время между переключениями светодиода: 1000 все хорошо, иначе плохо
    unsigned long last_ledWork; //время последнего переключения светодиода

    // Массив для загрузки
    #define eeprom_size 64 // Размерность массива eeprom
    unsigned char ee_params[eeprom_size]={ 2,251,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    /*                                    00  01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    00 - версия модуля
    01 - номер модуля
    02 - тип модуля
    Остальные параметры программист может использовать для нужд устройства
    */


    #define read_only_params_count 3 // Количество параметров только для чтения
    unsigned char read_only_params[read_only_params_count]={0,1,2};

    void setup() {
      delay(3000);
      // initialize serial:
      Serial.begin(9600);
      ledWork_freq=1000; // Частот переключения LED работы 1000 - 1 переключение в секунду
      pinMode(RS485out,OUTPUT);
      pinMode(ledWork,OUTPUT);
      pinMode(jmp0,INPUT);
      pinMode(jmp1,INPUT);
      pinMode(jmp2,INPUT);
      pinMode(jmp3,INPUT);
      pinMode(jmp4,INPUT);
      pinMode(jmp5,INPUT);  
     
      digitalWrite(jmp0,HIGH); // Включили подтягивающий резистор 20кОм на +
      digitalWrite(jmp1,HIGH); // Включили подтягивающий резистор 20кОм на +
      digitalWrite(jmp2,HIGH); // Включили подтягивающий резистор 20кОм на +
      digitalWrite(jmp3,HIGH); // Включили подтягивающий резистор 20кОм на +
      digitalWrite(jmp4,HIGH); // Включили подтягивающий резистор 20кОм на +
      digitalWrite(jmp5,HIGH); // Включили подтягивающий резистор 20кОм на +
     
      if (EEPROMread(0)!=ee_params[0]) // Если EEPROM не задан
      {
        //присваиваем начальные значения
        for (temp_i=0; temp_i<eeprom_size; temp_i++)
        {
          if (temp_i!=1)
            EEPROMwrite(temp_i,ee_params[temp_i]);
        };
      };
      EEPROMfix(); // Проверяем правильность значений в eeprom
      digitalWrite(RS485out,LOW);  // Переходим в прием сообщений
    }
    // ------------------Чтение EEPROM-----------------------
    unsigned char EEPROMread(unsigned char num)
    {
      // В EEPROM могут храниться данные только unsigned char
      unsigned char res_0, res_1, res_2, total_res;
      if (num>eeprom_size) return 255;
      res_0=EEPROM.read(num);
      res_1=EEPROM.read(eeprom_size+num);
      res_2=EEPROM.read(eeprom_size*2+num);
      if (res_0==res_1) return res_0;
      if (res_0==res_2) return res_0;
      if (res_1==res_2) return res_1;
      return 255;
    };
    // ------------------Запись EEPROM-----------------------
    void EEPROMwrite(unsigned char num, unsigned char value)
    {
      // В EEPROM могут храниться данные только unsigned char
      if (num>eeprom_size) return;
      if (EEPROMread(num)==value) return;
      EEPROM.write(num,value);
      EEPROM.write(eeprom_size+num,value);
      EEPROM.write(eeprom_size*2+num,value);
    };
    // ------------------Ремонт EEPROM-----------------------
    void EEPROMfix()
    {
      int num;
      unsigned char res_0, res_1, res_2, total_res;
      for (int num=0;num<eeprom_size;num++)
      {
        res_0=EEPROM.read(num);
        res_1=EEPROM.read(eeprom_size+num);
        res_2=EEPROM.read(eeprom_size*2+num);
        if ((res_0==res_1) && (res_1==res_2)) continue;
        if (res_0==res_1) {EEPROM.write(eeprom_size*2+num,res_0);continue;}
        if (res_0==res_2) {EEPROM.write(eeprom_size+num,res_0);continue;}
        if (res_1==res_2) {EEPROM.write(num,res_1);continue;}
        // Если все 3 значения разные
        EEPROM.write(num,0);
        EEPROM.write(eeprom_size+num,0);
        EEPROM.write(eeprom_size*2+num,0);
      }
    };
    // ------------------Основной цикл программы-----------------------
    void loop() {
      addr=GetAddr();
     
      if (millis()-last_ledWork>ledWork_freq) // Мигание светодиода работы
      {
        last_ledWork=millis();
        digitalWrite(ledWork,!digitalRead(ledWork)); // Включаем светодиод
      };
    }

    // ------------------Функция передачи сообщений по RS-485-----------------------
    void transmit()
    {
      digitalWrite(RS485out,HIGH); // Переключаемся в передачу
      Serial.write(buff_in, 8); // Передаем ответ
      Serial.flush(); // Ожидаем отправку всей посылки
      digitalWrite(RS485out,LOW); // Переключаемся в приём
    }

    // ------------------Вычисление адреса модуля--------------------------
    unsigned char GetAddr()
    {
      unsigned char addr=0;
      if (digitalRead(jmp0)==LOW)
        addr+=1;
      if (digitalRead(jmp1)==LOW)
        addr+=2;
      if (digitalRead(jmp2)==LOW)
        addr+=4;
      if (digitalRead(jmp3)==LOW)
        addr+=8;
      if (digitalRead(jmp4)==LOW)
        addr+=16;
      if (digitalRead(jmp5)==LOW)
        addr+=32;  
      if (addr==0) return 255;
      return addr;    
    }

    // ------------------ Вычисление контрольной суммы для модуля-----------
    unsigned char  calc_ad_crc() // Вычисление crc для ADNet
    {
      unsigned char i, crc[3];
      crc[1]=0;
      for(i=2;i<7;i++)
        crc[1]=crc[1]+buff_in[i];
      return crc[1];
    }

    // ------------------Приём данных-----------------------
    /*
      SerialEvent occurs whenever a new data comes in the
    hardware serial RX.  This routine is run between each
    time loop() runs, so using delay inside loop can delay
    response.  Multiple bytes of data may be available.
    */

    void serialEvent() {

      while (Serial.available()) {
        // get the new byte:
        if (rbit_num<8)
        {
          buff_in[rbit_num]=(char)Serial.read();
          rbit_num++;
        };
        if (rbit_num==8) // Если в буфере 8 символов
        {
          if ((buff_in[0]==255)&&(buff_in[1]==255)) // Если есть 2 стартовых байта 255 и 255
          {
            temp_uch=calc_ad_crc();
            if (buff_in[7]==temp_uch) //Если crc совпадает
            {
              if (buff_in[3]==addr) // Если адрес модуля совпадает
              {
                func(); // выполняем команду, которую прислали на выполение
                rbit_num=0;
              };
            };
          };
          if (rbit_num==8) // Если во вхоящем буфере всё еще 8 симовлов
          {
            // смещаем во входящем буфере все на один символ влево
            for (int i=0;i<7;i++)
            {
              buff_in[i]=buff_in[i+1];
              rbit_num=7;
            };
          };
        };
      };
    };

    // Функция обработка сообщений RS-485
    void func()
    {
      unsigned char i;
      buff_in[3]=0;
     
      switch (buff_in[2])
      {

      case 0: // тип, версия моудля
        buff_in[4]=EEPROMread(0);
        buff_in[5]=EEPROMread(2);
        buff_in[6]=30; //для SE6i5o
        //msg[6]=33; для secu 16
        buff_in[7]=calc_ad_crc();
        transmit();
        break;
       
      case 5: // вернуть значение параметра
        switch (buff_in[5])
        {
          case 1:
            buff_in[4]=addr;
            break;
          case 9:
            buff_in[4]=0;//curr_hum;
            break;
          case 10:
            buff_in[4]=0;//curr_temp;
            break;
          default:
            buff_in[4]=(buff_in[5]<eeprom_size)?EEPROMread(buff_in[5]):0;
        }
        buff_in[7]=calc_ad_crc();
        transmit();
        break;

      case 6: // изменить значение параметра
        if(buff_in[5]>=eeprom_size) return;
        for (i=0;i<read_only_params_count;i++) //проверяем read only параметры
          if (buff_in[5]==read_only_params[i]) goto a;
        EEPROMwrite(buff_in[5],buff_in[4]);
        a:
        buff_in[7]=calc_ad_crc();
        transmit();
        break;

      case 10: // изменение выходов
      case 51:
        //msg[4]=SetOutput(msg[5],msg[4]);
        buff_in[7]=calc_ad_crc();  
        transmit();
        break;
      case 11: // запрос выходов
      case 50:
        buff_in[4]=0;//curr_hum;
        buff_in[6]=0;//curr_temp;
        buff_in[7]=calc_ad_crc();  
        transmit();
        break;
      default:
      break;
      }
    }
     
     
    arkadyf нравится это.
  3. SmartRnd

    SmartRnd Нерд

    Скачать бесплатную программу-контроллер, управляющую модулями по протоколу ADNet можно здесь:

    http://alpha-se.ru/alpha.php?page1=406&page2=42&razdel=3&info=114

    Посмотреть видео с обзором протокола и использованием программы контроллера можно здесь:

    http://alpha-se.ru/alpha.php?page1=403&page2=124

    На данный момент мне известны следующие производители оборудования для протокола ADNet:

    Умная электроника http://alpha-se.ru
    Разумный дом http://www.razumdom.ru
    Умный дом http://ydom.ru/
     
    Последнее редактирование: 7 дек 2016
    arkadyf нравится это.
  4. Vad33

    Vad33 Капитан-оригинал

    Протокол для радиолюбительских поделок?
     
  5. SmartRnd

    SmartRnd Нерд

    Можно сказать и так. :)
    Протокол простой, но на нём работает достаточно большое кол-во оборудования, есть бесплатный софт для управления им по требуемой логике.
    Если у Вас есть задача, которая требует скоординированной работы нескольких модулей, то проще взять за основу предложенный вариант, чем думать с нуля о чем-то своем.
    У нас сейчас есть проекты в которых 1 контроллер (ноутбук) управляет примерно 60 модулями по протоколу ADNet.

    [​IMG]
     
  6. SmartRnd

    SmartRnd Нерд

  7. Vad33

    Vad33 Капитан-оригинал

    По проводам- может быть. Под реальную задачу его нужно еще допиливать, много чего изменить, так что на выходе получится "каша из топора" - от протокола одно название. ну и совместимости ес-сно не будет, потому что формат тоже придется "рихтовать".
     
  8. SmartRnd

    SmartRnd Нерд

    Можно чуть подробнее? Что изменить? Что рихтовать?

    На этом протоколе только в Ростове-на-Дону нами реализованы системы автоматики более 30 квартир, 15 домов и 5 офисных зданий. Функционала везде хватало. Некоторым объектам более 7 лет и всё работает
     
  9. Vad33

    Vad33 Капитан-оригинал

    Я же не против, по проводам все вполне может работать годами.
    Из того что рихтовать:
    - Оставив посылку 8 байт, выкинуть за ненужностью стартовые байты,
    один или оба, вместо этого добавить еще один байт к данным и один к
    контрольной сумме.
    - Переделать расчет контрольной суммы на улучшенный алгоритм (не CRC16).
    - Включить контроль четности.
    - Перенести адрес на первое место.
    - Изменить принцип считывания и использования адреса устройства
    - Добавить ответы с признаком ошибки
    и т.д. и т.п.
    Ес-сно Это Будет уже другой протокол.
     
    MESS нравится это.
  10. Onkel

    Onkel Гуру

    Ну да, американская Applied Digital, реализовавшая протокол AdNet, неоднократный победитель CES по умным домам и домашней автоматизации, забыли спросить одного безработного бедолагу из глубокой провинции лидера в области электроники - РФ, как им сделать протокол. Вот наверное волосы на себе рвут...
     
  11. Vad33

    Vad33 Капитан-оригинал

    Ну если по существу сказать нечего, остается только хамить?! :D
    Как же вы под такой убогий протокол пишете код на "чистом С" без костылей?
    Теперь то понятно какой уровень. "Не фонтан..." :D
     
  12. Onkel

    Onkel Гуру

    Ага, это ведь вы рекомендовали новичкам делать связь модулей в умном доме с помощью RS-232 (точка- точка, с дальностью надежной связи единицы метров), и даже с помощью i2c (а это вообще по определению Inter-Integrated Circuit - протокол связи между чипами на плате)? И Вы с таким уровнем знаний называете один из самых известных протоколов "Умного Дома" "протоколом для любительских поделок"? А вообще тот же самый AdNet (логический уровень, с кодированием конечно) используется в половине американских тюрем в системах безопасности - их делает та же самая Applied Digital. Если кто-то организацию систем сигнализации в американских тюрьмах считает "радиолюбительской поделкой", так может это у критика протокола проблемы, а не у систем сигнализации американских тюрем?
    Виктор, как бы я лично к нему не относился, сделал несколько десятков умных домов и квартир, а вы сколько умных домов сделали, что так походя ему нравоучения читаете? Ноль, не так ли? Может , есть у вас другие какие заслуги, чтобы к вам люди, реально делающие умные дома, прислушались? Да вроде нет никаких? Протокол вам не нравится? А десяткам брендов, начиная с ведущих брендов в "Умных Домах", он нравится, и он есть во всех базах данных Crestron, AMX , Кeware и прочих и прочих и прочих, а у нас и в бывшей Вост. Европе Uniel продает десятки тысяч модулей в год с этим протоколом - вы просто не в курсе? А если вы не в курсе что вы можете умного сказать по этому поводу? А если не можете сказать то зачем несете тут чепуху?
     
    Последнее редактирование: 25 фев 2017
  13. Onkel

    Onkel Гуру

    Еще Uniel http://uniel.ru/catalog/1225
     
  14. Onkel

    Onkel Гуру

    Фото одного из оборудованных мною фонтанов опубликовано в National Geography. Вы много чего понаделали, что NG удостоил бы своим вниманием? А тогда что за наезды на фонтаны?
     
    Последнее редактирование: 25 фев 2017
  15. Vad33

    Vad33 Капитан-оригинал

    Да ладно, врать то и передергивать. Вы как старуха, только и можете вспоминать старые обиды и молится на оставшиеся три волосины. С одной стороны докапываетесь до возможностей передачи по RS232 и i2c, но так ничего и не опровергли по факту, с другой молитесь на древний ADNet, который создавался во времена, когда "контроллеры" делались на рассыпной логике. Поэтому он и во многих штатовских тюрьмах и в Восточной Европе. За столько то лет, наделали запасов...
    Я уважительно отношусь к старине и технической в том числе, но только не в случае, когда это впаривается под видом "надежного решения, проверенное временем". И некогда закрытый протокол, раздается всем желающим.
    Как я понял по скудному описанию, этот протокол даже длинное целое за один пакет не может передать, что говорит само за себя. Ес-сно, зачем при управлении парой-тройкой десятков релюшек были большие числа!?
    Поэтому и ниша этого протокола сейчас - радиолюбительские поделки, примитивные системы "умного дома" с десятком не сложных устройств, ...ах, ну да, и фонтаны, как же без них.. :D
     
    Последнее редактирование: 26 фев 2017
  16. Onkel

    Onkel Гуру

    Какие факты? Вы привели хотя бы одну систему Умного Дома со связью модулей друг с другом или с контроллером по RS232 или по i2c? Нет, потому что таких систем нет. А их нет потому что эти протоколы не предназначены для такого рода задач, и главное- в такого рода задачах не работают.

    опять наглое вранье. Z180 - это не рассыпуха.
    Ну а "древность" протокола - не всегда минус. AdNet есть во всех брендах Умного дома, есть в motorola premise, в eib - практически везде. А то что безвестный безработный аноним про этот протокол не слышал - наверное , беда этого безработного анонима.
    Ну отвечать на дальнейший треш нет смысла, а читали пусть сделают вывод- верить человеку, который сделал десятки умных домов и предлагает бесллатную программу контроля "Умного дома", или безработному необразованному бедолаге, который ни сделал ни одного умного дома, предлагает использовать для связи модулей i2c а потом называет свою некомпетентность "старыми обидами".
    То ли дело у вас, cv - чистый лист, есть чем гордиться?
     
    Последнее редактирование: 26 фев 2017
  17. Onkel

    Onkel Гуру

    а что вы в управлении светом будете делать с длинным целым? Или в управлении релейным модулем? Если бы нужно было бы часто (и вообще) их передавать, умные люди уж реализовали бы, не ждали бы от вас ценного указания. И еще нельзя передать float за один пакет. И еще много чего нельзя. Ну и что?
    То ли дело ваш "вредный совет" - RS232, да? А то, что RS232- точка- точка, ничего? Это по - вашему больше, чем десяток?
     
    Последнее редактирование: 26 фев 2017
  18. Unixon

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

    А как в системе на ADNet устройствам назначаются адреса? Что делать в случае коллизии?
     
  19. Onkel

    Onkel Гуру

    Система с одним мастером, коллизий не бывает. Мастер опрашивает слейва, слейв отвечает. На броадкасты модули слейвы не отвечают. Есть специальная процедура назначения адресов через броадкаст сообщения. Адреса либо вшиты, либо назначаются нажатием кнопки на модуле. Посылается бродкаст "адресация 1", нажимаете кнопку на модуле - в него прописывается его адрес "1", модуль отвечает о получении адреса , переход к следующему (или любому) адресу и т.д. Можно прописать 127 адресов, с 0x01 до 0x7F, нулевой адрес у мастера. Если интересно, могу послать протокол.
    Не знаю, в каком виде его обнародовал Виктор, но у меня все кроме ascii bobcat команд, и немного модифицировано, но без нарушения преемственности. В частности, при запросе параметров можно передавать целые, используя 6ой байт для младшего байта целого, а при запросе 0x0B по этому же байту посылать состояния. У меня целые цеха, включая МАХПы на этом протоколе работают и не сбоят. И без коллизий. Потому что , ясное дело , коллизия в МАХП - ну это очень хорошо слышно, а зачастую и видно, иногда за сотни километров. Так вот у меня коллизий при реализации на этом протоколе нет. Собственно когда делаешь систему уровня цеха или больше выбор невелик- modbus или вот один из SH протоколов, adnet мне исторически понравился больше других, я на нем и делаю, тем более историческая преемственность.
     
    Последнее редактирование: 26 фев 2017
  20. Vad33

    Vad33 Капитан-оригинал

    Больше чем вашему хамству, я поражаюсь вашей зашоренности.

    Вот то чего нет, потому что не может быть никогда. :D

    http://hi-tech-house.com/catalog/Domintell/equipment/DRS23201/

    [​IMG]

    http://chinaspbtop.ru/item/4-channe...uter-connected-control-relay/32783355462.html
    upload_2017-2-26_21-34-41.png

    Насчет i2c почитайте ранее
    http://forum.amperka.ru/threads/15-...5-реле-один-или-несколько-ардуино.7254/page-3
    1.5 метра i2c передает вполне без ошибок на обычном без ухищрений монтажном кабеле, при желании длину можно можно увеличить. Просто некогда искать


    Вранье еще более наглое. Z180 - это микропроцессор, Карл, МИКРОПРОЦЕССОР !
    Чтобы он стал КОНТРОЛЛЕРОМ нужно еще добавить память и периферию.
    Выглядит это примерно так:
    [​IMG]
    https://www.kickstarter.com/projects/2057605091/p112-single-board-computer-kit?ref=discovery
    Совсем не рассыпуха вокруг? :D
    Если кто еще помнит, у Zilog еще был легендарный брат - Z80, который на ZX Spectrum .
    Эх, молодость, когда же это было? Больше 20 лет назад. По компьютерным меркам-каменный век.

    Да-да. Даешь ручные мясорубки! Потому, что они надежные и были в свое время у всех брендов. :D

    Что же моя работа то вас так колбасит? Или это, как по Фрейду, кто на чем зациклен ?
    А насчет протокола - да, лучше бы я его не видел, был бы лучшего мнения о вашем СУПЕР ФОНТАНЕ,
    и прочих Умных домах.
    Последнее время по работе (сюрпрайз) приходится разбираться и переписывать для себя под телеметрию
    кучу протоколов для разных приборов. Так вот такого убогого старья не встречал. Ну может только в очень старых приборах.

    Бесплатным как известно знаете что бывает. Особенно у вас, такого бескорыстного. :)
    Видать продажи совсем упали ?! Не?

    По вашему, тот кто в своей жизни не сделал умного дома или фонтана тот прожил жизнь зря! :D
    Так для этого не нужно было Бауманку заканчивать, достаточно было бы профильного ПТУ!:)
     
    Последнее редактирование: 26 фев 2017