Компактный DIY Zigbee датчик температуры с e-ink дисплеем

xjz1yb95c-pckuamv2stcrotqgc.jpeg


В сегодняшней статье хочу рассказать о новой версии миниатюрного датчика температуры и влажности с e-ink дисплеем. Этот проект является продолжением моего старого открытого ардуино проекта миниатюрного датчика температуры c e-paper дисплеем, который работал на nrf52810.
Основной целью этой версии датчика был переход на протокол Zigbee. По пути к ней был также доработан и оптимизирован дизайн платы, дизайн корпуса и добавлены очень полезные Zigbee фишки :).

Ну и это первое устройство с e-inkом работающее на сс2530 под протокол Zigbee, и о котором я рассказываю на Хабре. Это тоже интересная история, потому что многие говорили, что не получится, но на самом деле — получается, и не только на монохромных дисплеях, но и на полноцветных TFT.

ys0u01tojji73jnqatfmo_mchda.jpeg

Летом 2021 года я решил попробовать свои силы в разработке работающих на Zigbee DIY устройств. Начал с простого устройства. Это был zigbee датчик влажности почвы на основе проекта DIYRUZ. Основной задачей я для себя ставил не разработку своего дизайна платы под проект DIYRUZ, а изучение кода того проекта, попутно тренируясь на своей железке. Как только я немного освоился со средой разработки IAR, и понял, что Си — не очень страшный, то начал писать драйвера под самые разные сенсоры, так как этого очень сильно не хватало, да и сейчас не хватает при разработке под сс2530.

gfhspd2zu6_abqpxsaxswr1fvws.jpeg

Естественно, в процессе погружения я часто думал о том, чтобы на основе какого-то из своих старых ардуино проектов с e-ink дисплеями сделать zigbee версию. Присутствуя в чатах разработчиков zigbee устройств, я видел попытки подружить cc2530 и e-ink дисплеи, но в целом посыл был такой, что cc2530 не очень хорошо подходят под эти задачи из-за недостаточного объёма памяти.

Но мне повезло познакомиться в одном из телеграм чатов с одним замечательным человеком @koptserg и с его классным zigbee проектом e-monitor (обязательно поставить звёздочку). К тому моменту Сергей успешно добавил в свой проект на сс2530 поддержку монохромного e-ink дисплея от компании Waveshare c диагональю 2.9 дюйма. Так, в процессе нашего общения и у Сергея, и у меня в проектах сейчас поддерживается практически весь модельный ряд небольших дисплеев компании Waveshare и Gooddisplay с диагональю до 3.7 дюйма, на остальные дисплеи просто пока не хватило времени :).

n3au5kkzremguuojud-9afp4wwa.jpeg

Теперь, после небольшого, но очень важного отступления в историю, вернёмся к рассказу об этом проекте. Железная часть проекта базируется на двух платах. Одна — базовая плата, на которой располагается МК, сенсоры, питание, и вторая плата, на которой располагается обвязка дисплея, разъём дисплея и сам дисплей. Платы между собой соединяются штыревыми разъёмами с шагом 2 мм.

r38xfuliu5oarhcsocjx7t6ihfq.jpeg

Основная работа на базовой плате заключалась в замене радиомодуля. Модуль E18-MS1-PCB оказался существенно больше используемого мною модуля на MINEW nRF52810, поэтому пришлось очень много и существенно двигать компоненты. Также был заменён сенсор температуры и влажности. Ранее на плате устанавливался сенсор HTU21D, а в zigbee версии он был заменён сенсором SHTC3, так как ранее, работая над одним из проектов, для него был написан легковесный драйвер, без всего лишнего. Также данный сенсор удачно пришёлся ко двору, так как он намного компактнее HTU21D и чуть дешевле по стоимости. И завершающий небольшой штрих — это транзисторная защита от переполюсовки батарейки.

z1mu9arzubrlmqyxsmcttyjfd9e.jpeg

Использование радиомодуля E18-MS1-PCB также повлияло и на вторую плату в проекте. Из-за большого металлического экрана расположенные на плате дисплея конденсаторы упирались в этот металлический экран. Но я оказался даже рад этому факту, потому что дизайн этой платы теперь выглядит куда приятнее. Также на этой плате была устранена одна небольшая старая болячка, про которую я постоянно забывал. Были добавлены вырезы под кнопки, повторяющие границы на базовой плате. Ранее эта болячка вылезала в процессе использования готовых устройств. Иногда кнопка могла начать упираться в край платы с дисплеем и ей не хватало хода, чтобы переключить кнопку.

ybxgf2f-g92netipsjtvpudmsig.jpeg

Корпус в проекте тоже подвергся доработке. Была уменьшена толщина боковых стенок, существенно тоньше стала верхняя панель с вырезом под экран, были скруглены все углы. Основное, но внешне незаметное изменение связанно со сцепкой двух половинок корпуса. Скоба зацепа была перенесена с одной половинки корпуса на другую, что существенно улучшило соединение и также увеличило внутренний свободный объём корпуса. Сейчас на момент написания этой статьи на сервисе JLCPCB заказаны корпуса, которые будут напечатаны по технологии MJF. Ранее я уже заказывал напечатанные по этой технологии корпуса для других своих проектов, результатом остался доволен.

qsijarqpjs2b4c2jgllguvhugg4.jpeg

Программная часть проекта, естественно, была самой сложной. Начиная с написания драйвера под e-ink экран и заканчивая написанием конвертора. Интеграция именно этого экрана далась наиболее тяжело, если сравнивать с другими e-ink дисплеями. Связанно это с немного другой логикой работы этого дисплея относительно остальных и всяких моментов с железной частью, например, инвертированным состоянием пина busy относительно остальных экранов. В предыдущем проекте на ардуино эти все моменты обошли меня стороной, так как там просто использовалась готовая библиотека.

Экран не очень большой, поэтому в этом проекте я просто формирую будущую картинку целиком в памяти и перезаписываю сразу весь экран. Объём изображения получается 1024 байта. Так как пришлось разбираться с регистрами экрана при написании драйвера, то по пути была существенно увеличена скорость обновления экрана в отличие от версии проекта на ардуино :). Увеличена скорость работы SPI, также данные передаются не побайтово, а сразу всем массивом, что позволило существенно быстрее их передавать и, соответственно, меньше времени находиться устройству в рабочем режиме.

void сonfigSPI(void)
{
   uint8 baud_exponent;
   uint8 baud_mantissa;

  PERCFG |= 0x02;

  HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_CLK_PORT,  HAL_LCD_CLK_PIN);
  HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_MOSI_PORT, HAL_LCD_MOSI_PIN);
  HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_MISO_PORT, HAL_LCD_MISO_PIN);

  baud_exponent = 17;
  baud_mantissa =  0;

  U1UCR  = 0x00;
  U1CSR  = 0x00;
  U1GCR  = HAL_SPI_TRANSFER_MSB_FIRST | HAL_SPI_CLOCK_PHA_0 | HAL_SPI_CLOCK_POL_LO | baud_exponent;
  U1BAUD = baud_mantissa;
}
  EpdSendCommand(0x30);  //Set the clock frequency
  EpdSendData(0x27); //100Hz for full mode

  EpdSendData(0x0A);; //27.5Hz for partial mode
void EpdSetFrameMemoryXY(const unsigned char* image_buffer, int x, int y, int image_width, int image_height, uint8 part) {
    int x_end;
    int y_end;
    if (
        image_buffer == NULL ||
        x < 0 || image_width < 0 ||
        y < 0 || image_height < 0
    ) {
        return;
    }
    x &= 0xF8;
    image_width &= 0xF8;
    if (x + image_width >= epd_width) {
        x_end = epd_width - 1;
    } else {
        x_end = x + image_width - 1;
    }
    if (y + image_height >= epd_height) {
        y_end = epd_height - 1;
    } else {
        y_end = y + image_height - 1;
    }
    
    if (part == 0){
    EpdSendCommand(0x91);
    EpdSendCommand(0x90);
    EpdSendData(x);
    EpdSendData(x_end);

    EpdSendData(y);
    EpdSendData(y_end);
    EpdSendData(0x00);

    EpdSendCommand(0x10);
    HalEpd_HW_WriteStart();
    for (int j = 0; j < y_end - y + 1; j++) {
        for (int i = 0; i < (x_end - x + 1) / 8; i++) {
            HalEpd_HW_Write(image_buffer[i + j * (image_width / 8)]);
        }
    }
    HalEpd_HW_WriteStop();
    }
    if (part == 1){
    EpdSendCommand(0x13);
    HalEpd_HW_WriteStart();
    for (int j = 0; j < y_end - y + 1; j++) {
        for (int i = 0; i < (x_end - x + 1) / 8; i++) {
            HalEpd_HW_Write(image_buffer[i + j * (image_width / 8)]);
        }
    }
    HalEpd_HW_WriteStop();
}
}

Стандартный вариант полного обновления экрана:

3eymstokhk59o9abmck6hum7_98.gif

Мой вариант стабильного частичного полноэкранного обновления:

zoicdh2ky0yj8i2w6vwnlyvvaq8.gif

Помимо основного функционала для такого типа датчиков (передача данных о температуре и влажности воздуха по протоколу zigbee в систему Умного дома) этот датчик может управлять другим устройством в zigbee сети напрямую (binding), например, таким как реле. Это позволяет без написания сценариев на стороне УД управлять работой отопительных приборов, вентиляторов.

Чтобы привязать устройство, на примере работы через frontend сервиса zigbee2mqtt нужно перейти на страницу устройства, открыть вкладку binding и выбрать из списка устройство, к которому нужно привязать датчик и поставить «птичку» на кластере On-Off.

szhycatnill5oo_zd_85ciuvwfe.jpeg

Для того чтобы управлять другими устройствами, датчику необходим дополнительный функционал. Он должен уметь отправлять команды на включение и отключение, ориентируясь на данные о каких-то пороговых значениях. И он это умеет. Конфигурацию датчика можно осуществлять через УД или через frontend сервиса zigbee2mqtt. Опять же, на примере frontend-a zigbee2mqtt достаточно зайти на вкладку Exsposes и там включить контроль управления по температуре, или по влажности воздуха или сразу по обоим (например, привязав к двум разным устройствам: нагреватель с контролем по температуре и вентилятор с контролем по влажности). Далее необходимо будет выставить минимальные и максимальные пороги для команд включения и отключения.

ngnc9osc8ezngndt7kvjrqhlfhk.jpeg

vpbntrj7rvlexctyqipjwip38po.jpeg

Благодаря такому расширенному функционалу, у обычного сенсора температуры и влажности появляются новые и очень удобные варианты его использования, например, мой новый zigbee датчик скоро заменит старый аналогичный, который работает на протоколе mysensors и будет управлять вентиляцией в ванной комнате.

uz87499lyjyqcqsjicq9vhrmqlo.jpeg

Видео:


Гербер файлы проекта размещены в моём каталоге проектов на сервисе по заказу плат pсbway.com.

Ссылка на гитхаб этого проекта

В следующих статьях я расскажу и о других своих zigbee проектах: датчике влажности почвы с e-ink экраном на 2.13 дюйма, с выводом графиков влажности почвы, освещённости, даты и времени последнего полива; об очень интересном датчике детектирования CO2 c IPS дисплеем; о zigbee часах с e-ink дисплеем на 3.7 дюйма и о том, как можно не переплачивать за датчики WB-MSW-ZIGBEE v. 3.

m1y_paqfwqquoc3rf_ljspyyrrg.jpeg

Чтобы не пропустить информации о других моих zigbee проектов, рекомендую подписатся на мой профиль на Habr и на Youtube канал, а также телеграм чат DIYDEV, где раньше всего публикуется информация о проектах, о процессе разработки, о завершающихся и только начинающихся проектах.

oug5kh6sjydt9llengsiebnp40w.png

© Habrahabr.ru