1 2 3 4 5 6 7 8 9 10 9/10 8,94оценок: 17

Smarthome - самому и бюджетно?

Тема в разделе "Умный дом", создана пользователем vores8, 31.10.09.

  1. belovictor
    Регистрация:
    04.11.11
    Сообщения:
    9
    Благодарности:
    2

    belovictor

    Участник

    belovictor

    Участник

    Регистрация:
    04.11.11
    Сообщения:
    9
    Благодарности:
    2
    Адрес:
    Москва
    Я вообще дизайнером не пользуюсь. Просто захожу sshем на Raspberry на которой крутится openHAB и правлю конфиги текстовым редактором :)


    Vores8, заэкспортировал данные из openHAB, которые он получает из KNX в cosm.
    https://cosm.com/feeds/95677
     
  2. SergeyIzDerevni
    Регистрация:
    01.09.13
    Сообщения:
    20
    Благодарности:
    2

    SergeyIzDerevni

    Участник

    SergeyIzDerevni

    Участник

    Регистрация:
    01.09.13
    Сообщения:
    20
    Благодарности:
    2
    Адрес:
    Санкт-Петербург
    А как Вы к Raspberry периферию прикручивали ? И что именно из периферии, реле, датчики ну и вообще ?
     
  3. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    Как я провел летом?

    Летом все свободное время ессно сжирал огород, подвал, гараж и прочая хрень вокруг дома. Но лето слава богу кончилось, узбеки улетели в теплые края, посему строительство бюджетного смартхоума продолжилось.

    Что нового.

    Сначала из старого. OpenHAB по прежнему рулит. Опробовал его на куче разных доставшихся нахаляву девайсов (в качестве "серверных" платформ)
    [​IMG]
    upload_2013-11-5_15-58-9.png

    ну и на недоноуте SONY VAIO (атом + 1гб мозгов)

    Вкратце - работает везде. Наверное так и остался бы на одной из этих железяк, но тут зачесалось у меня заменить домашнюю файлопомойку (netgear stora) на что-то более существенное и в результате был приобретен HP Microserver N54L, на который был водружен дебиан, ну а где дебиан, там и опенхаб. Так что теперь у меня все смартхоумное растет на HP, надо туда еще имплантировать asterisk до кучи. Да, и сетку предварительно проапгрейдил, отправив в отставку TRENDNET BFG-114 (оч хороший роутер кстати, только IGMP не поддерживает) и поменяв его на Mikrotik 2011-LS (ваще зверь).
    Да, и еще достался мне по случаю RasPI, на котором крутится OpenELEC, качая телевидение c torrent-tv.ru.

    Ну это все так - макро-изменения. Из микро.
    Решал задачу как организовать связь между ардуинами без проводов. В результате связал их по радио через NRF24L01 (190 руб)
    [​IMG]
    Придумал свой протокол, спаял ноду на пробу. Идея такая - есть ардуино-гейт, одним концом смотрит в ком-порт на НР через usb, другим концом в RF. Есть ноды - максимум 5 штук, поскольку NRF поддерживает 5 параллельных каналов на прием-передачу (можно больше нод, хоть целое дерево, но мне заморачиваться не хотелось, хотя готовые библиотеки для ардуины есть). К каждой ноде цепляются датчики и исполнительные устройства. Ноды по радио общаются с гейтом, причем гейт может сам опрашивать состояние нод или же ноды оповещают гейт о свой внутренней жизни.
    Технически реализовано просто и (ессно) дешево. Гейт - ардуино уно + NRF24L01. Ноду я сваял несколько монструозную. 5 датчиков температуры 1-wire, 3 датчика температуры влажности DHT11, 2 реле и один самопальный детектор 220 вольт. И все на одной ардуине нано. Ну и ессно NRF24L01. Неделю работает, разделены бетонным перекрытием, "ниодного разрыва". Как следствие наблюдаю температуры в котельной, температуру и влажность в подвале, и управляю вентиляторам в подвале для поддержания нужного микроклимата (ну то есть опенхаб управляет). Да, самопальный детектор 220в наконец-то показывает, включен у меня в данный момент котел или нет. (у меня на котле приделан дымосос, такой вентилятор чтобы дымоход не класть. Получается что-то вроде коаксиального дымохода. Так вот - дымосос работает - значит котел включился. И наоборот. Датчик подключен паралельно мотору дымососа и выдает 0 или +5в на ногу ардуины. Ардуина на свой ногеопределяет 0 или 1 ну и соответственно шлет сигнал гейту, а тот все это в опенхаб)
    Прикрутил опенхаб к xively. com, теперь могу смотреть показания датчиков в интернете - вот тут

    Из мелочей, раскурочил радиомодуль управления китайскими радиолампочками. Вайфайка там совершенно ни к чему - отлично управляется напрямую через усб-порт.

    В планах. Еще одна нода на пару датчиков температуры и 8 реле на улицу (вентиляция теплицы и управление клапанами полива). OpenSprinkler на ардуине. Но это все на весну.

    Вобщем как обычно, делюсь кодами, знаниями, просто советами. Если что интересно - спрашиваете.
     
    Последнее редактирование: 05.11.13
  4. Ed777
    Регистрация:
    11.07.10
    Сообщения:
    372
    Благодарности:
    451

    Ed777

    Продолжайте, я заинтригован...

    Ed777

    Продолжайте, я заинтригован...

    Регистрация:
    11.07.10
    Сообщения:
    372
    Благодарности:
    451
    Адрес:
    Киров
    Приветствую, vores8! Как всегда очень познавательное продолжение иcтории про Smarthome:super:
    А не рассматривали вариант на Synology, например DS213? Там Debian и asterisk прикручивается. См. здесь. На нем же WEB сервер поднять и масса всего прочего возможна. См. здесь.
     
  5. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    Как вариант. Но...
    Я же жадный - мне 2 диска мало (у меня нетгир была на двух дисках), а в НР их 4, плюс памяти 2 гига плюс проц Турион двухъядерный.
    Астериск у меня кстати летал просто на LX800, а вот фрискейловскую приблуду грузил просто на 100% (да и вообще, как то разачаровался я в армах, одна радость - расбери :))

    Кстати, если интересно - ниже код радио-гейта для ардуины (непричесанный, но вполне себе рабочий)

    Код:
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    
    #include "defs.h"
    
    // Set up nRF24L01 radio on SPI bus plus pins 9 & 10
    
    RF24 radio(9,10);
    
    #define SEND_INTERVAL 5000
    int interval = 0;
    
    byte getVal(char c)
    {
      if(c >= '0' && c <= '9')
        return (byte)(c - '0');
      else
        return (byte)(c-'A'+10);
    }
    
    void setup(void)
    {
    
      Serial.begin(9600);
    
      //
      // Setup and configure rf radio
      //
    
    
      radio.begin();
    
      radio.openReadingPipe(1,talking_pipes[0]);
      radio.openReadingPipe(2,talking_pipes[1]);
      radio.openReadingPipe(3,talking_pipes[2]);
      radio.openReadingPipe(4,talking_pipes[3]);
      radio.openReadingPipe(5,talking_pipes[4]);
    
      radio.startListening();
    
      //  radio.printDetails();
    
    
    //  Serial.println("server started");
    }
    
    void loop(void)
    {
      rf_message message;
    
      // if there is data ready
      uint8_t pipe_num;
      if ( radio.available(&pipe_num) )
      {
        // Dump the payloads until we've gotten everything
        bool done = false;
        while (!done)
        {
          // Fetch the payload, and see if this was the last one.
          done = radio.read( &message, sizeof(message) );
    
          // Spew it
          //        printf("Got payload %lu from node %i...",sizeof(message),pipe_num+1);
        }
        if (message.type != 0xFF) {
          Serial.print(pipe_num, HEX);
          Serial.print(":");
          Serial.print(message.pin, HEX);
          Serial.print(":");
          Serial.print(message.function, HEX);
          Serial.print(":");
          if (message.sensor[0] < 0x10)
            Serial.print(0, HEX);
          Serial.print(message.sensor[0], HEX);
          if (message.sensor[1] < 0x10)
            Serial.print(0, HEX);
          Serial.print(message.sensor[1], HEX);
          Serial.print(":");
          Serial.print(message.type, HEX);
          Serial.print(":");
          if (message.type == 1) {
            Serial.print(*(int*)&(message.data[0]));
          }
          if (message.type == 2) {
            Serial.print(*(float*)&(message.data[0]));
          }
          Serial.println();
        } else {
          Serial.print ("error message from node ");
          Serial.print (pipe_num);
        }
    
      }
    
      byte pipe = -1;
      String content = "";
      char character;
    
      while(Serial.available()) {
        character = Serial.read();
        content.concat(character);
        delay(10);
      }
    
      if (content != "") {
        content.toUpperCase();
        //    Serial.println(content);
        int from = 0;
        int to = 0;
        to = content.indexOf(':', from);
        pipe = content.substring(from, to).toInt();
        //    Serial.println(pipe);
        from = to + 1;
        to = content.indexOf(':', from);
        message.pin = getVal(content.substring(from, to).charAt(0));
        //    Serial.println(message.pin);
        from = to + 1;
        to = content.indexOf(':', from);
        message.function = content.substring(from, to).toInt();
        //    Serial.println(message.function);
        from = to + 1;
        to = content.indexOf(':', from);
        //    message.function = content.substring(from, to).toInt();
        //    Serial.println(content.substring(from, to));
        message.sensor[0] = getVal(content.substring(from, to)[0])* 16 + getVal(content.substring(from, to)[1]);
        message.sensor[1] = getVal(content.substring(from, to)[2])* 16 + getVal(content.substring(from, to)[3]);
        //    Serial.print(message.sensor[0], HEX);
        //    Serial.print(message.sensor[1], HEX);
        //    Serial.println();
        from = to + 1;
        to = content.indexOf(':', from);
        message.type = content.substring(from, to).toInt();
        //    Serial.println(message.type);
        if (message.type == 2) {
          char buf[20];
          content.substring(to + 1).toCharArray(buf, content.substring(to + 1).length());
          //    Serial.println(content.substring(to + 1).length());
          float data = atof(buf);
          *(float*)&(message.data[0]) = atof(buf);
          //    Serial.println(data,4);
        }
        if (message.type == 1) {
          int data = content.substring(to + 1).toInt();
          *(int*)&(message.data[0]) = content.substring(to + 1).toInt();
          //    Serial.println(data);
        }
        radio.stopListening();
        radio.openWritingPipe(listening_pipes[pipe-1]);
        radio.write( &message, sizeof(message) );
        radio.startListening();
    
    /*
    Serial.print("message sent to pipe ");
        Serial.println(pipe);
        Serial.print(message.pin);
        Serial.print(":");
        Serial.print(message.function);
        Serial.print(":");
        Serial.print(message.sensor[0], HEX);
        Serial.print(message.sensor[1], HEX);
        Serial.print(":");
        Serial.print(message.type);
        Serial.println();
    */
      }
    }
    
     
  6. Ed777
    Регистрация:
    11.07.10
    Сообщения:
    372
    Благодарности:
    451

    Ed777

    Продолжайте, я заинтригован...

    Ed777

    Продолжайте, я заинтригован...

    Регистрация:
    11.07.10
    Сообщения:
    372
    Благодарности:
    451
    Адрес:
    Киров
    Поправил ссылку. См ссылку строкой выше.
    На 4 винта См.здесь
     
  7. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    А цена? Мне сервер обошелся в 8 тыр, судя по тому что 2-х дисковая синолоджи стоит примерно 16, то 4-х дисковая вообще золотая будет
     
  8. Ed777
    Регистрация:
    11.07.10
    Сообщения:
    372
    Благодарности:
    451

    Ed777

    Продолжайте, я заинтригован...

    Ed777

    Продолжайте, я заинтригован...

    Регистрация:
    11.07.10
    Сообщения:
    372
    Благодарности:
    451
    Адрес:
    Киров
    Дороговато за двухдисковую 16 т. р., брал почти 2 года назад Synology DiskStation DS212j за 152евро.
    Если интересно, можно посмотреть цены и на 4х дисковые
     
  9. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    Меня попросили рассказать, как сопрячь опенхаб и овен. Не вопрос.
    Итак, сопрягаем опенхаб с овеном. Сопрягаем их по протоколу Modbus. Поскольку по модбасу работает много всяких устройств, сначала немного теории.
    Модбас - это такой протокол. Он предназначен для передачи байтов и битов между двумя устройствами (как впрочем и любой протокол передачи данных). Существует два вида модбаса: Modbus serial и Modbus TCP. Сериал нам не интересен (хотя опенхаб поддерживает и то и то). Передача данных по протоколу модбас происходит между мастером и слейвом. При этом мастер может быть только один, а слейвов - много (прямо бдсм какой-то!).Мастер может опрашивать слейвов на предмет состояния данных в них. Мастер может менять данные на слейвах. Слейвы сам ничего не могут, только откидываются своими данными в ответ на запросы мастера (на то они и слейвы).

    Очень рекомендую вот прямо сейчас сходить на сайт https://www.modbustools.com/ и скачать оттуда ModbusPoll (это мастер) и ModbusSlave (угадайте что это). Бесплатно можно скачать триальные версии, но нам этого хватит.

    Запускаете ModbusPoll и ModbusSlave.

    ModbusPoll: Connection->Connect...
    Устанавливаем
    Connection=ModbusTCP/IP
    IP Address=127.0.0.1
    Port=502
    Жмем OK
    теперь в это же проге
    Setup->Read/Write Definition
    Slave ID = 1
    Function = 01 Read Coils
    и снова OK

    Теперь в ModbusSlave и делаем абсолютно то же самое, только пункт Read/Write Definition теперь называется Slave Definition.

    Если вы все настроили правильно: адрес везде 127.0.0.1, порт 502, ид слейва 1 и функция 01, то у вас должна получиться работающая сладкая парочка мастер-слейв. Меняя значения в ячейках на мастере, вы увидите их изменения на слейве. И наоборот. (наоборот тоже работает, потому что мастер опрашивает состояние ячеек слейвов раз в 1000мс)
    upload_2013-11-6_19-6-46.png
    upload_2013-11-6_19-7-25.png

    Последнее замечание. Значения в ячейках могут быть только 0 или 1, потому что это coil. Поскольку дальше мы будем настраивать опенхаб чтобы он мог включать-выключать лампочки через овен, нам больше чем 1 и 0 не надо (1 - вкл, 0 - выкл)

    Едем дальше. Теперь настраиваем опенхаб. Опенхаб у нас будет почетным мастером. Копируем модбасовский байндинг в папку addons и курим вики. Вот тут https://code.google.com/p/openhab/wiki/ModbusTcpBinding (обратите внимание на слог - сам писал :)). Если вики курить лень - делаем вот что.
    Открывает файл openhab. cfg (или если уж совсем влом, правим openhab_default.cfg). Пишем там следующее
    Код:
    modbus:myslave.host=127.0.0.1
    modbus:myslave.length=1
    modbus:myslave.type=coil
    фсе. Что мы такого понаписали? Опрашивать слейва раз в секунду, читать койлы, количеством один.
    Теперь пишем в айтемс.
    Код:
    Switch MySwitch "My Modbus Switch"  {modbus="myslave:0"}
    ну и в сайтмапе этот свитч тоже нарисуйте.

    Убеждаемся что ModbusPoll не запущен, а ModbusSlave наоборот. Запускаем опенхаб. В вашем сайтмапе должен появиться свитч. Понажимайте на него и посмотрите как меняется значение в ячейке 0 ModbusSlave. Если оно не меняется - пишите сюда симптомы, будем разбираться

    Что делать дальше со все этим богатством? Прибиваем ModbusPoll и ModbusSlave. В openhab. cfg вместо 127.0.0.1 прописываем реальный айпишник овена. Ну собственно и все. Щелкаем в сайтмапе свитчем и слушаем, как щелкает реле в овене.
    На вопрос, зачем вам это надо, отвечайте сами :) А если серьезно, теперь вы можете в овене написать свою собственную прогу и рулить ею из опенхаба. Или навесить на овен аналоговые датчики и передавать их значения в опенхаб. Ну и так далее, на что хватит вашей воспаленной фантазии :)

    Как водится, задавайте вопросы прямо тут

    вот тут соврал. по умолчанию опрос слейвов каждые 200мс

    Теперь собственно овен. Он у нас будет жалким слейвом (судьба у него такая, это ж не сименс и не бекофф. Впрочем если бы был сименс или бекофф - тоже были бы жалкими слейвами)

    Открываем Codesys. Идем в закладку "Ресурсы", тыкаем в "Конфигурация ПЛК".
    Наблюдаем дерево, корнем которого является ваш ПЛК. Тычем правой кнопкой мыши в него, выбираем "Добавить подэлемент" и в открывшемся меню выбираем "Modbus (slave)".
    Видим в дереве добавленный элемент "Modbus (slave) [VAR]". Тыкаем на него правой же кнопкой и добавляем подэлемент "8 bit". Это мы сразу добавляем 8 койлов. (поскольку единица данных в данном случае байт, а койл - это бит, ну вобщем вы поняли).
    Теперь пишем простую прогу. Для начала посмотрим какие адреса имеют наши койлы. Раскрываем наши 8 бит - появляется описание байта. Раскрываем описание байта - и вот она смерть Кощеева! Аж в 8 экземплярах. Поскольку нам нужен койл с адресом 0 - смотрим на (* Bit 0 *). В моем случае это выглядит как
    Код:
    AT %QX8.1.0.0:BOOL
    и еще нам потребуется адрес реле, которым мы собсно и будем управлять. Возьмем например самое первое с адресом
    Код:
    AT %QX1.0: BOOL
    upload_2013-11-6_20-7-56.png
    вот эти адреса мы и будем использовать в нашей овновской проге (на языке ST)
    Прога будет максимально простая
    Объявим данные
    Код:
    PROGRAM PLC_PRG
    VAR
        relay1 AT %QX1.0 : BOOL;
        switch1 AT %QX8.1.0.0 : BOOL;
    END_VAR
    ну а весь код будет такой
    Код:
    relay1 := switch1;
    Вот собсно и все. Для проверки стартуем прогу в кодесисе в режиме эмуляции (конкретно не забудье нажать старт) и запускаем ModusPoll (предварительно для чистоты эксперимента прибейте опенхаб, если он у вас запущен, чтоб не путался под ногами), в свойствах соединения указываем реальный IP овена, меняем на ModbusPoll значение в ячейке 0. На овене должно щелкать реле.

    Если реле не щелкает, значит у вас что-то не так - пишите симптомы сюда, будем вместе разбираться
     
    Последнее редактирование модератором: 07.11.13
  10. sly2k
    Регистрация:
    22.02.08
    Сообщения:
    528
    Благодарности:
    122

    sly2k

    Живу здесь

    sly2k

    Живу здесь

    Регистрация:
    22.02.08
    Сообщения:
    528
    Благодарности:
    122
    Адрес:
    деревня Мякинино
    Добрый вечер,
    vores8. Хотелось бы спросить, как на ваш взгляд можно ли будет через ардуину прикрутить к опенхабу управление освещением через вот такие девайсы радиоуправляемые выключатели nooLite.
    Что мне в них понравилось - родные выключатели вполне прилично выглядят. но хочется часть функций навесить на умный дом - например отработка сценариев по датчикам движения, т. е. необходимость стороннего управления в обход родных кнопок. Спасибо.
     
  11. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    Вот с этим наверное можно https://www.noo.com.by/adapter-noolite-pc.html
    ардуина тут не нужна. Вот к опенхабу придется простенький байндинг написать. У меня примерно похожая конструкция работает вот с этими лампочками http://www.limitlessled.com/product-category/limitlessled-smart-light-bulbs/

    В вашем случае скорее всего вот такой вот приемник http://www.noo.com.by/adapter-dlya-kompyutera-rx1164.html прямо в усб порт компа и опенхабом опрашивать этот порт. Тоже в некотором роде слейв дял опенхаба-мастера. В порт будут приходить команды, формат их описан в мануале на девайс. Остается только преобразовывать в команды опенхаба.

    Ну и опять наврал, за полгода оказывается жизнь поменялась в плане опенхабовского плагина. Правильные строчки в openhab. cfg такие

    Код:
    modbus:tcp.myslave.connection=127.0.0.1:502
    modbus:tcp.myslave.length=1
    modbus:tcp.myslave.type=coil
    сорри что ввел в заблуждение
     
    Последнее редактирование модератором: 07.11.13
  12. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    Рассказываю про радио. Сам модуль NRF24L01 весьма подробно описан в интернете, например тут https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
    [​IMG]
    К ардуине цепляется 7 проводами
    nRF24L01+ Arduino Arduino Mega
    VCC 3,3V 3,3V
    GND GND GND
    MISO 12 50
    MOSI 11 51
    SCK 13 52
    CE 8 8
    CSN 7 7

    в результате должно получиться что-то вроде вот такого
    [​IMG]
    существует масса готовых библиотек, наиболее известные RF24 (http://maniacbug.github.io/RF24/) и MIRF(http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01)

    Что будем передавать? Передавать будем данные с ноды. Нода состоит из ардуины, на ноги коей прицеплены разные датчики, релюшки и т. д. В простейшем случае одна нога = один датчик (релюшка и т. д.).
    • Поскольку нод может быть несколько, каждая нода должна иметь свой номер.
    • Поскольку у ноды несколько ног, каждая нога ноды тоже имеет свой номер.
    • Поскольку висящий на ноге ноды датчик может выполнять несколько функций (например DHT11 может выдавать температуру и влажность), то у каждой ноги ноды должно быть поле "функция"
    • Поскольку на одной ноге может висеть несколько датчиков (например в случает 1 wire), эти датчики тоде нужно как-то различать
    • Поскольку датчик может передавать данные как двоичные (0/1) так и вещественные (23.58 например), то нужно различать тип передаваемых данных
    • Ну и наконец, нужно передавать сами данные.

    Вот. Все вышеизложенное описываем следующей структурой
    Код:
    typedef struct {
      byte pin;
      byte function;
      byte sensor[2];
      byte type;
      byte data[4];
    } rf_message;
    
    pin - это собственно номер ноги
    function - это функция датчика
    sensor - два байта чтобы различать датчики, висящие на одной ноге
    type - тип данных (1 - int, 2 - float)
    data - собственно 4 байта для данных, чтобы влез обычный float

    А где номер ноды? А он нам в явном виде не нужен. Поскольку мы используем 5 параллельных каналов NRF24L01, то у нас будет максимум 5 нод. Каждая нода вещает на своем канале. И наш гейт, получив данные с канала N, сможет всегда определить что это данные с ноды номером N.

    Но тем не менее, нам надо каналы как-то поименовать. Например вот так

    Код:
    const  uint64_t server_talking_pipe = 0xF0F0F0F000LL;
    const  uint64_t server_listening_pipe = 0x3A3A3A3A00LL;
    const uint64_t talking_pipes[5] = { 0xF0F0F0F001LL, 0xF0F0F0F002LL, 0xF0F0F0F003LL, 0xF0F0F0F004LL, 0xF0F0F0F005LL };
    const uint64_t listening_pipes[5] = { 0x3A3A3A3A01LL, 0x3A3A3A3A02LL, 0x3A3A3A3A03LL, 0x3A3A3A3A04LL, 0x3A3A3A3A05LL };
    вот собственно и весь протокол

    Как этим всем пользоваться? Ну естественно каждая нода должна сформировать сообщение о своем состоянии.

    Например. У меня есть единственный датчик DS18B20, который висит на ноге... да на любой. Я буду называть это "нога 1".
    Кстати, номером 0 ничего нумеровать не будем, это у нас будет зарезервированный особый случай. Если в каком-то поле стоит 0 это будет означать - игнорируй это поле.
    Итак. датчик вещает температуру - вещественное число. Например 28.56. То переведенное на человеческий язык есть сообщение должно иметь вид
    1:0:0000:2:28.56
    Расшифровываем:
    pin = 1 - первая нога
    function = 0 - пофиг
    sensor = 0000 - пофиг
    type = 2 - ага, вещественное число
    data = 28.56 - собственно данные

    Другой пример. Датчик DHT11 на ноге 2 вещает температуру
    2:1:0000:2:28.56
    и влажность
    2:2:0000:2:28.56

    Тут мы используем поле function, чтобы различать, когда мы передаем температуру (function = 1) а когда влажность (function = 2)

    Ну и напоследок - состояние ноги 8 ардуины (HIGH это 1, LOW естественно 0)
    8:0:0000:1:1
    как можно заметить, разница в поле type. Поскольку мы передаем целое число то type = 1

    Ну вот мы договорились, что будет передавать нам нода. Естественно, передавать она будет это в упакованном виде, а гейт должен будет все это распаковывать в человеческий вид и передавать это на ком порт.

    Теперь собственно гейт. Гейт у нас на ардуине, поэтому начинаем с функции setup()
    Код:
    void setup(void)
    {
      Serial.begin(9600);
      //
      // Setup and configure rf radio
      //
      radio.begin();
    
      radio.openReadingPipe(1,talking_pipes[0]);
      radio.openReadingPipe(2,talking_pipes[1]);
      radio.openReadingPipe(3,talking_pipes[2]);
      radio.openReadingPipe(4,talking_pipes[3]);
      radio.openReadingPipe(5,talking_pipes[4]);
    
      radio.startListening();
    
    //  Serial.println("server started");
    }
    
    Никаких изысков. Используем библиотеку RF24, открываем 5 каналов на чтение, ну и за одно в ком-порт будем писать на скорости 9600

    Опять же, поскольку у нас ардуина, пишем функцию loop(). Начнем собственно с чтения сообщений с нод и перевода их на человеческий язык.
    Код:
    void loop(void)
    {
      rf_message message;
    
      uint8_t pipe_num;
      if ( radio.available(&pipe_num) )
      {
        bool done = false;
        while (!done)
        {
          done = radio.read( &message, sizeof(message) );
        }
    
    Вот мы и прочитали сообщение. Теперь переводим его из байтов в читабельный вид.

    Одно замечание. Если у ноды что-то не так с конкретным датчиком, она тип данных ставит не 1 или 2, а 0xFF - мол все плохо

    И еще одно замечание - номер ноды мы как раз определяем по номеру канала pipe_num, из которого прочитано сообщение

    Код:
    
        if (message.type != 0xFF) {
          Serial.print(pipe_num, HEX);
          Serial.print(":");
          Serial.print(message.pin, HEX);
          Serial.print(":");
          Serial.print(message.function, HEX);
          Serial.print(":");
          if (message.sensor[0] < 0x10)
            Serial.print(0, HEX);
          Serial.print(message.sensor[0], HEX);
          if (message.sensor[1] < 0x10)
            Serial.print(0, HEX);
          Serial.print(message.sensor[1], HEX);
          Serial.print(":");
          Serial.print(message.type, HEX);
          Serial.print(":");
          if (message.type == 1) {
            Serial.print(*(int*)&(message.data[0]));
          }
          if (message.type == 2) {
            Serial.print(*(float*)&(message.data[0]));
          }
          Serial.println();
        } else {
          Serial.print ("error message from node ");
          Serial.print (pipe_num);
        }
    
      }
    
    И вот теперь, когда радио получит сообщение в виде последовательности байт, это сообщение волшебным образом будет выплюнуто в ком-порт как раз в приятном для глаза виде, например

    2:1:0000:2:28.56

    Что нам еще надо уметь? Читать из ком-порта команды для нод и отправлять их нодам. Команды будут двух типов
    • запросить данные у ноды
    • передать данные в ноду
    Запрашивать данные у ноды будем специальным сообщением, в котором message. type = 0ю То есть чтобы например запросить значение датчика температуры на ноге 1 будем отправлять соответствующей ноде сообщение

    1:0:0000:0

    и даже поле data заполнять не будем.
    Или читаем показания влажности с датчика на ноге 8
    8:2:0000:0

    С отправкой данных ноде тоже все просто. Указываем тип данных в поле type и собственно значение. Например, установить в 1 (HIGH) ногу 6
    6:0:0000:1:1

    ну и так далее. Код простой, но весьма занудный, поэтому здесь его не привожу, а все прикрепляю в аттаче
     

    Вложения:

    Последнее редактирование модератором: 08.11.13
  13. Shemnik69
    Регистрация:
    10.04.13
    Сообщения:
    119
    Благодарности:
    78

    Shemnik69

    Это Я

    Shemnik69

    Это Я

    Регистрация:
    10.04.13
    Сообщения:
    119
    Благодарности:
    78
    Адрес:
    Саратов
    Схему и информацию приготовил. Готов в скайпе обсудить детали.
     
  14. vores8
    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238

    vores8

    Живу здесь

    vores8

    Живу здесь

    Регистрация:
    26.12.07
    Сообщения:
    367
    Благодарности:
    238
    Адрес:
    Нижний Новгород
    А может сюда? Другим наверное тоже интересно будет
     
  15. Shemnik69
    Регистрация:
    10.04.13
    Сообщения:
    119
    Благодарности:
    78

    Shemnik69

    Это Я

    Shemnik69

    Это Я

    Регистрация:
    10.04.13
    Сообщения:
    119
    Благодарности:
    78
    Адрес:
    Саратов
    Согласен. Вот схема..набросал вечером..исходя из размещенных (и работающих) элементов. Задача состоит в следующем. Команда на открытие должна поступать от кнопок, от центрального модуля (ОпенНАВ) или другой (Бенукс. прочие программы). Соответственно это как команда (запрос от сервера) так и опрос входных портов (присоединение кнопок). Опрос датчиков (контактные). Вывод сигналов в сервер. 1. Текущее состояние. 2. Состояние кнопок (вкл./ выкл).3. Состояние датчиков (вкл/выкл). 4. Вывод сигнала на внешние порты (реле). Логика работы следующая. по сигналу, от сервера на открытие (по времени. по команде на открытие через WEB мордочку (кнопка/переключатель), нажатая кнопка (брелок, через реле и радиосигналку) Ардуино выдает сигнал 1 на выходной порт (любой удобный) к которому присоединено реле включающее двигатель.

    Двигатель переключаеться (реверс) двумя реле одно открытие второе закрытие. Остановка створы по сигналам от контактных датчиков с переключающими контактами в обеих положениях и индикацией (светодиоды) на панели. Светодиоды показывают текущее положение визуально. При открытии ворот система анализирует состояние датчиков и датчика пресечения проема (ИК луч) и по пересечению луча более 4-5 сек понимает что автомобиль проехал и спустя 5-6 сек. дает команду на закрытие. Человек пресекает луч 1-2 сек и это не должно выдавать команду на закрытие. Приоретет команд это кнопки (брелок) или сигнал ОпенНАВ (человек) или система по времени. Например открытие 6.50 закрытие 7.05 (иди по пересечению) ..открытие 17.25 закрытие 17.40 (или по пересечению).

    Да сорри на схеме пропустил контактный датчик пресечения створы. :|: Сами датчики нарисовал а вот выходной сигнал пропустил. это контакт реле на разрыв по пресечению (можно переделать на замыкание это без разницы) также этот сигнал должен остановить створу при закрытии и пресечении луча. Кроме того проем видит камера и при открывании/закрывании идет видеосъемка (видеорегистратор) с отправкой кадра в случае пересечении луча... на мобильную почту (смартфон).. Ну вот в вкратце так.
     

    Вложения:

    • Схема 001.jpg
    Последнее редактирование модератором: 12.11.13