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

Умный дом на шине CAN

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

  1. __AK__
    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407

    __AK__

    сноб

    __AK__

    сноб

    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407
    - Узкий выбор МК
    - Короткие сообщения, из-за чего большой оверхед, пересылка длинных сообщений занимает много траффика на шине
     
  2. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    Зачем этот выбор должен быть широким?
    Достаточно широко распространенной серии, STM32 таковой является.
    ARM Cortex-M3 с CAN есть и у других производителей, перенос кода, если что-то вдруг, не займет много времени, если использовать RTOS, например ту же Chibos.

    Оверхеда там при 11 бит ID где-то одна третья, учитывая что в любом другом протоколе вам так или иначе все равно придется передавать и адрес и CRC.
    Передавать больше чем 8 байт информации на практике не нужно никогда, разве для перезаливки кода модулей. Большой разницы не вижу если заливка вместо 9 секунд займет 8... Да и длинные пакеты в системе сильно увеличивают латентность.
     
  3. X13dev
    Регистрация:
    29.05.13
    Сообщения:
    277
    Благодарности:
    85

    X13dev

    Живу здесь

    X13dev

    Живу здесь

    Регистрация:
    29.05.13
    Сообщения:
    277
    Благодарности:
    85
    Адрес:
    Германия
    Нам пришлось увеличить буфер до 32 байт. Нужно в I2C и UART.
    I2C:
    BME280 - температура, влажность и давление. Чтение конфигурации - 30+11 байт, чтение данных - 12 байт.
    BH1750 - датчик освещённости, выдаёт сразу значение в люксах.
    UART:
    Т63182 Tellaire - датчик CO2.
    Телевизор LG. Команда 9 байт
     
  4. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    Не нужно передавать по сети весь обмен с датчиками.
    Пишется модуль HAL операционной системы, который и взаимодействует с датчиком.
    Модуль имеет методы, события и свойства.
     
  5. X13dev
    Регистрация:
    29.05.13
    Сообщения:
    277
    Благодарности:
    85

    X13dev

    Живу здесь

    X13dev

    Живу здесь

    Регистрация:
    29.05.13
    Сообщения:
    277
    Благодарности:
    85
    Адрес:
    Германия
    Это прекрасно работает если на нодах прошит booloader и есть менеджер прошивок. Это когда открыл нужный проект внёс изменения, нажал кнопочку и он сам подтянул актуальные библиотеки, откомпилировал, залил на правильную ноду и обновил все связи.
    Такой подход накладывает серьёзные ограничения, например должен быть установлен компилятор под нужную платформу. Про сервер на малине (голубая мечта многих) с веб интерфейсом можно забыть.
    Поскольку в гетерогенной сети такое невозможно, мы вынесли драйвера I2C устройств на сервер и это работает даже со спящими нодами.

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

    Извиняюсь за сумбурное изложение, просто когда-то то-же делал логику на устройствах и от воспоминаний о поддержании всего этого зоопарка до сих пор колотит.
     
  6. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    Мы так и поступили. GCC компилятор с тулчейном под ARM мультиплатформен.

    Именно на нем и планируем, пока не пробовал, гоняю на виртуалках, но проблем быть не должно тулчейн под него есть, а LINUX он и в Африке LINUX.

    Из-за простоты протокола эта операция занимает очень мало времени, кстати как и добавить многобайтовые сообщения в CAN. Дописать в CAN модуль для Chibios весом в пару килобайт кода еще немного несложно. Я вообще плохо понимаю тех кто не использует RTOS.
    Вот он
    Код:
    #include "ch.h"
    #include "hal.h"
    #include "sh_canbus.h"
    
    // CAN global variables
    extern can_global CAN;
    
    extern uint8_t UM_ID;
    
    
    static const CANConfig cancfg = {
      CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP,  0x403a0008 // 250 к√ц
      // CAN_BTR_LBKM | CAN_BTR_SJW(0) | CAN_BTR_TS2(1) | CAN_BTR_TS1(8) | CAN_BTR_BRP(6)
    };
    
    
    /*
     * Receiver thread.
     */
    static THD_WORKING_AREA(wa_can_rx, 128);
    static THD_FUNCTION(can_rx, arg) {
      event_listener_t el;
      CANRxFrame rxmsg;
    
      (void)arg;
      chRegSetThreadName("can_rx");
      chEvtRegister(&CAND1.rxfull_event, &el, 0);
      while(!chThdShouldTerminateX()) {
        if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0)
          continue;
        while (canReceive(&CAND1, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == MSG_OK) {
          if((rxmsg.SID < 256) && (rxmsg.DLC >=2) && (rxmsg.DLC <=5)){
            /* Process message lenght 2-5 data8 byte ad ID sender 0...255*/
            if(rxmsg.DLC == 2){
              uint8_t msg_arr[4];
              msg_arr[0] = rxmsg.DLC+1;
              msg_arr[1] = rxmsg.SID;
              msg_arr[2] = rxmsg.data8[0];
              msg_arr[3] = rxmsg.data8[1];
              chMBPost(&CAN.can_recieve_mailbox, (msg_t)msg_arr, TIME_INFINITE);
            } else if(rxmsg.DLC == 3){
              uint8_t msg_arr[5];
              msg_arr[0] = rxmsg.DLC+1;
              msg_arr[1] = rxmsg.SID;
              msg_arr[2] = rxmsg.data8[0];
              msg_arr[3] = rxmsg.data8[1];
              msg_arr[4] = rxmsg.data8[2];
              chMBPost(&CAN.can_recieve_mailbox, (msg_t)msg_arr, TIME_INFINITE);
            } else if(rxmsg.DLC == 4){
              uint8_t msg_arr[6];
              msg_arr[0] = rxmsg.DLC+1;
              msg_arr[1] = rxmsg.SID;
              msg_arr[2] = rxmsg.data8[0];
              msg_arr[3] = rxmsg.data8[1];
              msg_arr[4] = rxmsg.data8[2];
              msg_arr[5] = rxmsg.data8[3];
              chMBPost(&CAN.can_recieve_mailbox, (msg_t)msg_arr, TIME_INFINITE);
            } else if(rxmsg.DLC == 5){
              uint8_t msg_arr[7];
              msg_arr[0] = rxmsg.DLC+1;
              msg_arr[1] = rxmsg.SID;
              msg_arr[2] = rxmsg.data8[0];
              msg_arr[3] = rxmsg.data8[1];
              msg_arr[4] = rxmsg.data8[2];
              msg_arr[5] = rxmsg.data8[3];
              msg_arr[6] = rxmsg.data8[4];
              chMBPost(&CAN.can_recieve_mailbox, (msg_t)msg_arr, TIME_INFINITE);
            }
          }
        }
      }
      chEvtUnregister(&CAND1.rxfull_event, &el);
    }
    
    
    /*
     * Transmitter thread.
     */
    static THD_WORKING_AREA(wa_can_tx, 128);
    static THD_FUNCTION(can_tx, arg) {
      (void)arg;
      //can_global arg;
      uint8_t *pbuf;
      CANTxFrame txmsg;
      uint8_t i;
    
      chRegSetThreadName("can_tx");
      while (true) {
    
        // вот здесь тред останавливаетс¤ и ждет пока не по¤в¤тс¤ в майлбоксе сообщени¤
        chMBFetch(&CAN.can_send_mailbox, (msg_t *)&pbuf, TIME_INFINITE);
        txmsg.IDE = CAN_IDE_STD;
        txmsg.EID = UM_ID;
        txmsg.RTR = CAN_RTR_DATA;
        txmsg.DLC = pbuf[0];
        for(i=0;i<txmsg.DLC;i++){
          txmsg.data8[i] = pbuf[i+1];
        }
        canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, MS2ST(100));
        chThdSleepMilliseconds(5);
      }
    
    }
    
    
    void CAN_init(){
     // create CAN send mailbox
     chMBObjectInit(&CAN.can_send_mailbox, CAN.can_buffer, CAN_BUFFER_SIZE);
     // create CAN send thread
     chThdCreateStatic(wa_can_tx, sizeof(wa_can_tx), NORMALPRIO+7, can_tx, NULL);
     // create CAN recieve mailbox
     chMBObjectInit(&CAN.can_recieve_mailbox, CAN.can_recieve_buffer, CAN_BUFFER_SIZE);
     // create CAN recieve thread
     chThdCreateStatic(wa_can_rx, sizeof(wa_can_rx), NORMALPRIO+7, can_rx, NULL);
    
     canStart(&CAND1, &cancfg);
    }
    
    void CAN_send(uint8_t *send_array){
      chMBPost(&CAN.can_send_mailbox, (msg_t)send_array, TIME_INFINITE);
    }
    
    Согласен, но это только оттого, что вы придерживаетесь зоопарка микроконтроллеров. В случае Cortex-M и хорошей OS все только упрощается.
     
    Последнее редактирование: 27.12.15
  7. __AK__
    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407

    __AK__

    сноб

    __AK__

    сноб

    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407
    Далеко не все STM32 имеют на борту CAN. Да и на STM32 свет клином не сошелся. Упомянутый выше дешевый XMC1100 имеет контроль Хэмминга на памяти программ и контроль четности на памяти данных. Отличный камень для автоматизации. Но CAN-а в нем нет, есть UART.

    Топик и CRC передаются в пакете один раз. При длине сообщения более 8 байт в CAN этот оверхед передается снова и снова. Кроме того, от 8 байт данных будет отъеден как минимум 1 байт для того, чтобы обеспечить связность частей сообщения.

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

    "Никогда не говори никогда" (с)
     
  8. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    Не все, половина :)
    Выше я писал, что можно использовать любой Cortex микроконтроллер, не обязательно от ST.

    Гибкость гораздо выше чем в вашем решении. Есть и минусы, но они несущественны.

    Все события на шине логируются сервером.

    Опять неполное понимание или нежелание слышать. Это только в случае переконфигурации только через OpenHAB.
    Я думаю ваша система через OpenHAB тоже не конфигурируется. :)
    В нормальном режиме есть групповые команды и скрипты в контроллере, все гибко.
     
  9. yushkin
    Регистрация:
    18.05.09
    Сообщения:
    3.726
    Благодарности:
    1.787

    yushkin

    Живу здесь

    yushkin

    Живу здесь

    Регистрация:
    18.05.09
    Сообщения:
    3.726
    Благодарности:
    1.787
    Адрес:
    Москва
    Камрады, никто не думал делать общение по Ethernet? Как сетевик могу утверждать, что этот протокол удовлетворяет всем требованиям УД, к тому-же он аппаратно встроен в большое количество МК.
    У него есть отличная штука - мультикаст/броадкаст.
     
  10. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    У Ethernet есть несколько минусов:
    • минимум два провода
    • ограниченная дальность
    • топология только звезда, тянуть придется кучу проводов, про УД в уже эксплуатирующихся помещениях можно забыть
    • большое потребление, связка хаб-контроллер потребляет только по ethernet около двух ватт...
     
  11. __AK__
    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407

    __AK__

    сноб

    __AK__

    сноб

    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407
    Особенно "приятно" будет вносить изменения, которые затронут сразу десяток уже установленных модулей. Каждый из них придется править вручную, потом, возможно, отлаживать правки, и затем перегружать.

    Я не про логи шины, я про логи датчиков. Например, датчик температуры может публиковать среднюю и мин/макс температуры раз в полчаса, но при этом вести внутренний лог с периодом измерения раз в минуту. Или датчик потребляемой мощности всего дома, он может публиковать усредненную мощность раз в минуту, но вести подробный лог с периодом раз в секунду. И так далее. Этм логи выкачивается или изредка и регулярно (например, ежедневно), или лежат в EEPROM модулей до востребования.

    Он жрет много электричества и требует прокладки огромного количества проводов. Вот поставлю я три датчика рядом, и придется там же и хаб ставить, и сетевое питание туда тянуть.
     
  12. yushkin
    Регистрация:
    18.05.09
    Сообщения:
    3.726
    Благодарности:
    1.787

    yushkin

    Живу здесь

    yushkin

    Живу здесь

    Регистрация:
    18.05.09
    Сообщения:
    3.726
    Благодарности:
    1.787
    Адрес:
    Москва
    Огромное количество - это сколько? Если отказаться от FullDuplex - можно все на одной шине сделать (CSMA/CD встроен в протокол)
     
  13. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    Можно, при желании, но тогда длина такой шины будет смехотворной...

    Никто не мешает, если данная информация необходима, гнать ее на шину, ведь так или иначе вы ее через эту шину будете сгружать, не бегать же к каждому контроллеру. Если текущее значение нужно изредка получить в данный момент, то идет запрос к данному датчику и ответ с его значением. Чтобы не забить шину если что, у нас например контроллер, не может отправлять датаграммы чаще чем через определенное время.
     
  14. __AK__
    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407

    __AK__

    сноб

    __AK__

    сноб

    Регистрация:
    19.10.15
    Сообщения:
    951
    Благодарности:
    407
    При выгрузке логов сравнительно длинными сообщениями за счет малого оверхеда будет сэкономлено от 1/3 до 1/2 траффика. А если логи хранятся в сжатом виде, то это еще в несколько раз уменьшит суммарный траффик. Кроме того, логи передаются не в реальном времени и потому могут иметь очень низкий приоритет, не мешая основному траффику. Тогда как пропущенное измерение - криминал, поэтому измерения третируются как высокоприоритетные сообщения реального времени. Это большая разница в нагрузке шины.
     
  15. asasl
    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10

    asasl

    Живу здесь

    asasl

    Живу здесь

    Регистрация:
    04.04.09
    Сообщения:
    104
    Благодарности:
    10
    Адрес:
    Москва
    Готовы выложить исходники своей реализации CSMA/CD?
    Я смогу обернуть их в модули для ОС.