Очередной проводной «велосипед» для датчиков дома/квартиры

Озадачился малой домашней автоматизацией/управлением. Поиски что уже есть показали беспроводные (Zwave, и т.п.), проводные решения (Ethernet, 1-wire и подобное). Беспроводка — дорого, Ethernet — тоже неслабо стоит за каждое устройство. Ну, соответственно, захотелось изобрести собственные костыли.

Итак, задача:
1) Провод как базовый способ связи. Дешево, надежно, сердито.
2) Оконечные устройства предельно простые и дешевые, чтобы было проще ткнуть еще одного клиента, вместо изобретения методов как подключить что-то новое к неподалеку стоящему.
3) Независимость клиентов от центра сети.

Провод не пугал, в силу особенностей — проводка и так в коробах, добавить что-то новое несложно. Схема взята трехпроводная — общий, питание(сейчас +12в), данные. Уровень простоя линии данных +5В, подключение клиентов — как в 1-wire, подтяжка стоит у меня на центральном компьютере, можно поставить в любом месте сети в принципе. Активный уровень — зажимание клиентом линии данных на общий провод. Ну, ничего нового и революционного 🙂

Кодирование данных — манчестерское, скорость обмена примерно 12кбит/сек. Выглядит это примерно вот так:

protocol1Длина одного бита порядка 80мкс. Поскольку активный уровень в проводе — низкий, то наличие оного низкого уровня при передаче каким-либо клиентом в линию высокого уровня — налицо признак коллизии, в таких случаях передатчик бросает работу и ждет освобождения.
Пакет данных состоит из байта приоритета, двух байт адреса источника, двух байт адреса приемника, байта длины пакета, данных, байта контрольной суммы (рассчитывается как примитивная сумма всех байт данных). Байт приоритета введен в основном на всякий случай, чтобы коллизию передачи обнаружить побыстрее и менее важный передатчик побыстрее заткнулся. Сейчас пока все равноправные.

При выборе базового МК, учитывая желаемый фактор «подешевле» альтернатив STM8S003F3 не нашлось. Удивительно недорогой контроллер, причем с достаточно неплохой начинкой — железный I2C, SPI, UART. Все это приправлено 8КБ памяти программ, 1КБ оперативной, немного EEPROM и стоит менее 0,5$ в розницу в моей стране.  Прочая обвязка — линейный стабилизатор питания L7805, немного конденсаторов, стабилитрон, транзистор, кусочек текстолита — и базовое устройство(без учета стоимости труда по сборке) получается стоимостью буквально в доллар.
wire1-smallНа текущий момент для таких микроклиентов есть поддержка датчиков температуры DS18B20, температуры/влажности DHT22, температуры/давления BMP085. Опрос кнопок и управление оптореле и обычным реле можно не считать. А, еще на плате если нужно — ставлю полевик мелкий для управления кусочком светодиодной ленты, в качестве ночника. Также есть приемник IR кодов протокола NEC и передатчик для него.

Адаптер такой сети для большого брата — сделан тоже на STM8, поддерживающее ПО — C# (протокол адаптера примитивен, ПО можно реализовать на чем угодно, мне C# просто удобнее).

mwire-pcТестовая сеть, развернутая в доме — сейчас поставляет данные о температуре, давлении, влажности на улице (заодно делится ими с проектами narodmon.ru и openweathermap.org), температуре и влажности в спальной комнате и управляет увлажнителем воздуха в той же комнате,  поддерживая микроклимат. С помощью веб-интерфейса можно с телефона выключить/включить ночник (с управлением яркостью). Система управления всем этим на десктопе — Majordomo (www.smartliving.ru). Общая протяженность сегментов сети — около 40 метров.

В планах — поставить еще стопку датчиков движения, для управления автоматическим ночным освещением или для  любых прочих целей, что удастся придумать. Контроль освещения, контроль температуры в доме (управление отопительным котлом). Плюс контроль доступа бесконтактными картами на заборе 🙂

Исходные тексты прошивок, файлы печатных плат — доступны интересующимся по запросу (сразу не выкладываю — модернизируется постоянно, по мере тестовой эксплуатации). Сам протокол проверен на STM8S003 и STM32F100 серии.

15 thoughts on “Очередной проводной «велосипед» для датчиков дома/квартиры

  1. Если можно поделитесь кодом для 1Wire для STM32F100 серии. Я начинаю изучать stm32fvldiscover. пытаюсь разобраться с этим интерфейсом на примере датчика температуры.

    • У меня код есть для стм32 только под свой протокол, 1-wire — делал для стм8. Впрочем, вот вариант «тупого» опроса, там подобрать только задержку на конкретный мк. Код в архиве работал на STM8 с тактовой в 16мгц
      http://mgslab.com/samples/1wire.zip

  2. день добрый.
    Пришлите или выложите свой проект под STM8.
    перерыл кучу сайтов везде под 32 проекты а под 8 нету.
    заранее спасибо.

    • Архив со всеми текущими законченными датчиками. Беспроводные на nrf24l01 еще не доделал 🙂
      http://mgslab.com/soft/aih.zip

      Все для IAR. Печатные платы еще есть, нужны? (DipTrace)

  3. Спасибо.
    Давайте и печатки 🙂 будем на вашем проекте тренироваться. да и nrf24l01 тоже интересны (лежат 3 модуля таких)
    Вообще я только-только за stm (да и вообще за МК) взялся. Вспомнил школу и как паял приёмники, гирлянды 🙂 усилки на 27Мгц-е радиостанции. Попалась статья по ардуино. купил — там конструктор всё просто. потом MSP430 — мало примеров но тоже довольно всё понятно. потом атмеловские атмеги — примеров много и всё более унифицировано. а BASCOM бейсик так вообще всё просто.
    А вот с АРМ — сред программирование много, да ещё все наравят свой синтаксис и библиотеки всунуть. И только благодаря вашему проекту до меня только дошло что есть Standard Peripherals Library что в корне отличает курсы dcoder на изиэлектроникс.
    А так как по урокам dcoder я переписал вывод на LCD1602, а он явно не хочет с SPL стыковаться придется под них переписать. Может знаете где есть описание SPL на русском т.к. сказать вводный курс?

    • платы http://mgslab.com/soft/aih_pcb.zip

      nrf — пока в процессе, заткнулся на реализации самостоятельно маршрутизируемой сети, что наиболее интересно лично мне.

      А то что сред много — дело такое. Как и использовать или нет стандартные библиотеки. Кстати, предупреждение — они ОЧЕНЬ тормозные, через регистры напрямую сильно быстрее.

      А лучшее описание, имхо — читать заголовочные файлы и даташит. Там, в принципе, достаточно понятно все.

    • эээ… дык вся статья то про эту самую mgsWire? 🙂 Кратко — однопроводный двунаправленный протокол связи между кучей контроллеров с шинной топологией.

  4. по mgsWire тормознул 🙂 как всегда выдрал кусок статьи про датчики.
    по тормозам библиотек — так не систему реального времени внедрять. Да и примеры в сети в основном под них. я по этому и не догонял почему примеры есть, но не компилятся.
    сча обкорнаю ваши проекты чтоб разобраться для начала с каждым датчиком. потом уже и по mgsWire можно глянуть, хотя мне больше по беспроводке датчики интересуют.
    если будут вопросы буду задавать, надеюсь не откажите в ответе на очевидное 🙂

    • вопросы — всегда пожалуйста 🙂 Насчет реального времени — ну, когда как. Я когда делал этот свой протокол — пришлось без библиотек, иначе не укладывался код в разумное время реакции на прерывания.
      Беспроводка дело нужное, надеюсь добить протокол в ближайшее время, простейший линк точка-точка работает без проблем, а интересна сеть.

  5. для начала хочу LCD подключить 🙂
    есть такая функция
    void Lcd_write_cmd(unsigned char cmd )
    {

    delay(70);
    PC_ODR = (cmd & 0xF0); //отправляем старшие разряды
    PD_ODR_bit.ODR4 = 0; // RS
    PD_ODR_bit.ODR5 = 0; //RW
    PD_ODR_bit.ODR6 = 1; // E — строб
    delay(5);
    PD_ODR_bit.ODR6 = 0; // E — строб
    PC_ODR = ((cmd & 0x0F)<<4); // младшие 4 разряда шлём
    PD_ODR_bit.ODR4 = 0;
    PD_ODR_bit.ODR5 = 0;
    PD_ODR_bit.ODR6 = 1;
    delay(5);
    PD_ODR_bit.ODR6 = 0;
    delay(90);
    }
    как переделать на SPL? что-то не доганю (если поможете, будет проще вкурить)

    • вот примерно так:
      PC_ODR = (cmd & 0xF0); //отправляем старшие разряды
      это
      GPIO_Write(PORTC, cmd & 0xF0);

      PD_ODR_bit.ODR4 = 0; // RS
      это
      GPIO_WriteLow(PORTD, GPIO_Pin_4);

      PD_ODR_bit.ODR6 = 1;
      это
      GPIO_WriteHigh(PORTD, GPIO_Pin_6);

      где-то так. delay — сразу не скажу, не помню, есть ли в spl штатно

  6. ну не совсем так, через GPIO
    GPIO_Write(GPIOC, (dat & 0xF0));
    GPIO_WriteHigh(GPIOD, GPIO_PIN_4);

    как более точно вывести температуру от датчика ds18b20 ?
    просто не могу понять кто врёт, на градуснике 24.9, а датчик 26 показывает

  7. т.е. как у вас округление ?
    как вывести после 2 знака после запятой температуру?

    • если мой код, то в ds1820_readtemp два вариант — один целочисленное значение возвращает, второй с плавающей точкой. Там где целочисленное делал — точность страдает, надо код модифицировать.

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *

This site uses Akismet to reduce spam. Learn how your comment data is processed.