Добрый день, уважаемый читатель!
Представляю вашему вниманию небольшой обзор еще одной китайской платы контроллера на базе ESP32 для реализации различных идей автоматизации всего и вся: KC868-A16 ESP32 home automation relay module.
На этот раз мне попал в лапы один из контроллеров, выпускаемых довольно известным производителем – KinCony Electronics Co., Ltd.. В одной из своих статей я уже как-то упоминал его, но мельком и вскользь. Выпускают они довольно большой спектр продукции для интернета вещей и с интересными возможностями. Но как всегда – не бывает идеальных вещей, а тем более контроллеров домашней автоматизации из Китая.
Дабы было понятно, почему “ещё одной“, приведу ссылки на похожие обзоры на моем сайте: ESP32_Relay_X4 и ESP32_Relay_X8 и ESP32R3 v4 + IO expander. Забегая вперед скажу: лично мне данный модуль понравился гораздо больше двух предыдущих вариантов, хотя и он не без недостатков. И, если бы я приобрел такой модуль год назад, вероятнее всего, моя “теплица с зачатками разума” строилась бы на нем.
Дисклеймер. Данная статья – не реклама в исходном смысле этого слова. Я никак не связан с производителем и не получал от него образцы продукции. Рассматриваемую плату я временно получил от одного из своих читателей для того, чтобы написать для неё немного другой вариант прошивки для теплицы с удаленным управлением и зачатками разума. Пользуясь случаем и с разрешения владельца платы, я решил написать данный обзор – в первую очередь для того, чтобы заранее можно было понять, для чего такую плату можно применить и каких подводных камней от неё ожидать.
Общие сведения
Данный модуль можно заказать как в виде отдельной платы, так и вместе с корпусом на DIN-рейку. Корпус далеко не герметичен, но позволяет худо-бедно защитить электронику от внешних механических воздействий. Клеммники хоть и винтовые, но разъемные, что позволяет быстро отключить периферию в случае необходимости – например для перепрошивки модуля.
Открутив 4 болта по краям, получаем доступ к плате. Кстати, сама плата к корпусу никак не прикреплена, хотя посадочные места под саморезы предусмотрены. Китайцы, такие китайцы, экономят на спичках. Мне попалась плата с уже распаянными разъемами I2C и RF 433 Mhz, хотя на фото попадаются и без них.
Сердцем платы является модуль ESP32-WROOM-32E классической линейки. Стандартный, с печатной антенной. Хотелось бы, конечно, иметь возможность подключить внешнюю антенну, особенно при установке платы в металлический бокс, но увы – в данном случае ничего не выйдет.
Все “разрешенные” GPIO микроконтроллера использованы полностью, хотя, на мой взгляд, можно было сделать чуть-чуть лучше. Точнее так – можно сделать печатные перемычки, дабы один и тот же GPIO можно было бы использовать разными способами, в случае необходимости. Но, в целом, обвязка микроконтроллера выполнена на высоком уровне – гораздо лучше, чем, скажем в ESP32R3 v4. Все требования технического паспорта ESP32 соблюдены.
Интерфейсы и карта GPIO
Плата имеет довольно обширный набор интерфейсов, которые наиболее часто востребованы среди “умнодомостроителей”. Плата имеет практически всё, что требуется от подобного устройства:
- Питание от внешнего источника 12В постоянного тока
- 16 цифровых входов «сухой контакт» с опторазвязкой
- 16 MOSFET выходов 12/24 В 10А MAX для управления реле, клапанами, моторами и прочими исполнительными механизмами
- 4 аналоговых входа 0–5 В (ну это наверняка не совсем так, надо бы проверить)
- 3 GPIO микроконтроллера просто выведены “наружу” для подключения датчиков 1Wire (DS18B20), SingleBus (DHT22) и прочего оборудования.
- Разъемы для подключения стандартных модулей приёмника и передатчика 433 МГц
- Интерфейс RS485
- Ethernet интерфейс на базе чипа LAN8720A
- Разъём USB Type-C для программирования и отладки
Внутри платы расположены три дополнительных разъема:
- Разъемы для подключения стандартных модулей приёмника и передатчика 433 МГц
- Разъем I2C – шины для подключения датчиков или например, дисплея;
Карта GPIO выглядит так:
- Львиную долю GPIO отожрал интерфейс Ethernet: 17, 18, 19, 21, 22, 23, 25, 26, 27. Ну ок.
- Аналоговые входы через счетверенный ОУ выведены на выводы 34, 25, 26, 39 – они как раз для этого и предназначены. Отлично.
- GPIO 14, 32, 33 просто выведены на внешний разъем для датчиков. Принимается.
- Шина I2C выведена на GPIO 4 и 5. Кстати, вторую шину I2C можно получить, задействовав “прямые” GPIO 14, 32, 33.
- Шина RS485 использует GPIO 13 и 16. Аппаратное управление потоком не используется.
- К GPIO 2 теоретически должен подключаться приемник 433 МГц. А если вы не планируете его использовать, его можно пустить в дело другим способом.
- К GPIO 15 может быть подключен передатчик 433 МГц. А если вы не планируете его использовать, его можно пустить в дело другим способом.
- GPIO0 используется только как кнопка для прошивки (её также можно использовать и в программе)
- GPIO12 не используется совсем. Этот вывод просто подтянут к земле через резистор. И совершенно правильно не используется – это один из strapping pins. Ибо если на нем в момент старта ESP будет +3В – микроконтроллер просто не сможет запуститься.
В целом весьма неплохо.
А как же цифровые входы и выходы – спросите вы? А они реализованы через квази-двунаправленные расширители GPIO – PCF8574, про которые я уже писал однажды. К выходам нет никаких претензий, а вот входы реализованы “не очень”… Подробнее об этом будет рассказано ниже.
Что мы имеем в итоге:
// EN: Pins DS18B20/DHT11/DHT21/LED // RU: Выводы DS18B20/DHT11/DHT21/LED #define CONFIG_GPIO_1WIRE_HT1 32 #define CONFIG_GPIO_1WIRE_HT2 33 #define CONFIG_GPIO_1WIRE_HT3 14 // EN: Analog inputs // RU: Аналоговые входы #define CONFIG_GPIO_ANALOG_A1 36 #define CONFIG_GPIO_ANALOG_A2 34 #define CONFIG_GPIO_ANALOG_A3 35 #define CONFIG_GPIO_ANALOG_A4 39 // EN: RF433 MHz // RU: RF433 МГц #define CONFIG_GPIO_RF433_RX 2 #define CONFIG_GPIO_RF433_TX 15 // EN: RS485 bus // RU: Шина RS485 #define CONFIG_GPIO_RS485_RX 16 #define CONFIG_GPIO_RS485_TX 13 #define CONFIG_GPIO_RS485_RTS -1 // EN: I2C bus #0: pins, pullup, frequency // RU: Шина I2C #0: выводы, подтяжка, частота #define CONFIG_I2C_PORT0_SDA 4 #define CONFIG_I2C_PORT0_SCL 5 #define CONFIG_I2C_PORT0_PULLUP false #define CONFIG_I2C_PORT0_FREQ_HZ 100000 #define CONFIG_I2C_PORT0_STATIC 3 // EN: I2C bus #1: pins, pullup, frequency // RU: Шина I2C #1: выводы, подтяжка, частота // #define CONFIG_I2C_PORT1_SDA 16 // #define CONFIG_I2C_PORT1_SCL 17 // #define CONFIG_I2C_PORT1_PULLUP false // #define CONFIG_I2C_PORT1_FREQ_HZ 100000 // #define CONFIG_I2C_PORT1_STATIC 2 // EN: GPIO expanders PCF8574 // RU: Расширители GPIO PCF8574 #define CONFIG_I2C_INPUTS1_ADDRESS 0x22 // pcf8574_hub_in_1 # for input channel 1-8 #define CONFIG_I2C_INPUTS2_ADDRESS 0x21 // pcf8574_hub_in_2 # for input channel 9-16 #define CONFIG_I2C_RELAYS1_ADDRESS 0x24 // pcf8574_hub_out_1 # for output channel 1-8 #define CONFIG_I2C_RELAYS2_ADDRESS 0x25 // pcf8574_hub_out_2 # for output channel 9-16 // EN: Ethernet (LAN8720) // RU: Ethernet (LAN8720) #define CONFIG_GPIO_ETH_ADDR 0 #define CONFIG_GPIO_ETH_POWER_PIN -1 #define CONFIG_GPIO_ETH_CLK_NET 17 #define CONFIG_GPIO_ETH_MDIO 18 #define CONFIG_GPIO_ETH_TXD0 19 #define CONFIG_GPIO_ETH_TX_EN 21 #define CONFIG_GPIO_ETH_TXD1 22 #define CONFIG_GPIO_ETH_MDC 23 #define CONFIG_GPIO_ETH_RXD0 25 #define CONFIG_GPIO_ETH_RXD1 26 #define CONFIG_GPIO_ETH_RX_DI 27 #define CONFIG_GPIO_ETH_TYPE ETH_PHY_LAN8720 #define CONFIG_GPIO_ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
Описание выводов от разработчиков вы можете найти здесь: kincony.com/forum/showthread.php?tid=1666
Подсистема питания
Плата рассчитана на внешний источник питания напряжением 12В. Исполнительные устройства могут быть запитаны от напряжения 12 ~ 24 В, так как для этого предусмотрены отдельные клеммы.
Система внутреннего питания платы двухступенчатая:
- вначале напряжение питания 12В понижается с помощью DC-DC преобразователя XL1509-5.0 до 5В,
- затем уже “стандартным” линейным стабилизатором LM1117-3V3 понижается до необходимых микроконтроллеру 3,3В.
Схема подсистемы питания:
При этом:
- Операционные усилители аналоговых входов питаются от шины +12В через дополнительный фильтр.
- Непосредственно от линии питания +5В питается только преобразователь интерфейса RS485 (и стабилизатор 3,3В, разумеется) и приемник 433 МГц
- Все остальные микросхемы и модули подключены к линии питания +3V3.
Что вполне соответствует техническому паспорту на ESP32 – никаких +5В на линиях SDA и SCL тут нет, что безусловно, радует.
Интерфейс программирования
Для программирования предусмотрен USB-интерфейс на микросхеме CH340C и с разъемом Type C:
Для перевода контроллера в режим программирования рядом с разъемом предусмотрены две кнопки: RESET и DOWNLOAD – последняя подключена к GPIO 0. Для перевода МК в режим загрузки прошивки удерживайте кнопку DOWNLOAD в момент сброса кнопкой RESET. Но, на самом деле, вам это вряд ли понадобится, так как плата снабжена схемой автоматического перевода МК в режим прошивки по сигналу с CH340C. Но, это так, на всякий случай, потому что всегда полезно знать – как перевести ESP32 в режим прошивки вручную.
В run-time вы можете использовать кнопку DOWNLOAD по своему усмотрению. Главное не забывайте – в момент любого сброса ESP32 она должна быть отпущена, иначе чип перейдет в режим прошивки.
Ethernet
Плата снабжена ethernet-интерфейсом на базе чипа LAN8720A. Например если вы захотите интегрировать данное чудо китайской техники в металлический коммутационный шкаф, то данный интерфейс вам должен очень пригодится. Чип расположен в непосредственной близости от ESP32.
Данный чип поддерживается ESP-IDF по умолчанию, что позволяет достаточно легко интегрировать проводные сетевые подключения в вашу прошивку.
// ESP-IDF officially supports several different Ethernet PHY chip driver esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config); esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config); esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config); esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
Ссылка на документацию: docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/network/esp_eth.html. В ближайшее время собираюсь более плотно изучить данный вопрос.
Насчет поддержки данного интерфейса в Arduino я сильно не уверен, но исследования не проводил.
Шина I2С
Шина IIC ( I2C ) используется “внутри” платы для обмена данными с квазидвунаправленными расширителями GPIO PCF8574. Шина I2C использует следующие сигнальные GPIO:
// EN: I2C bus #0: pins, pullup, frequency // RU: Шина I2C #0: выводы, подтяжка, частота #define CONFIG_I2C_PORT0_SDA 4 #define CONFIG_I2C_PORT0_SCL 5
На “внешние” разъемы контакты шины не выведены, да они и не особо там нужны. Вместо этого разъем I2C расположен внутри корпуса почти по центру платы:
К данному разъему, теоретически, можно подключать различные LCD-экраны и датчики с I2C – интерфейсом.
Но я бы не рекомендовал подключать к нему датчики, особенно длинными соединительными проводами. Дело в том, что на этой же шине подключены PCF8574, а они очень “не любят” помех на шине – могут запросто уйти в недокументированное и неуправляемое состояние, вывести их из которого можно только через отключение питания всей платы. Именно поэтому, скорее всего, разработчики и не стали выводить данный интерфейс “наружу”.
Кроме того, если вы решите контролировать входы по прерываниям, вам потребуется максимально быстро прочитать данные с PCF8574, а различные ошенно-тормознутые устройства вроде экранов, могут приводить к конфликтам и сильным задержкам. Однако “по умолчанию” прерывания для PCF8574 разработчиками вообще не предусмотрены! Но об этом подробнее ниже.
Шина RS485
Что меня особо радует в данной плате – так это наличие встроенного интерфейса RS485. Это предоставляет разработчику возможность использования огромного количества готовых к применению датчиков и исполнительных устройств, и при этом не особо заботится о длине проводов и помехах на шине. Датчики I2C – это “детский сад” по сравнению с RS485 и Modbus, хотя протоколы в чем-то и похожи друг на друга. Я настоятельно рекомендую вам использовать именно данный интерфейс в серьезных проектах.
На данном устройстве приемопередатчик RS485 реализован на микросхеме MAX13487E:
Это полудуплексный приемопередатчик RS-485/RS-422 с защитой от электростатического разряда до ±15 кВ. MAX13487E/MAX13488E оснащены системой управления потоком данных в шине AutoDirection, поэтому вывод управления потоком данных не используется.
На микросхеме шинного буфера 74LVC1G125, судя по всему, собрана схема согласования логических уровней MAX13487E ( 5.0 В) с уровнями ESP32 (3,3В). Рядом установлены минимально необходимые элементы защиты от повышенного напряжения в линии передачи.
К линиям A и B сидели на трубе наглухо припаян согласующий резистор 120 Ом (R79 – см фото выше). На китайских модулях он обычно установлен через перемычку, которая по умолчанию разомкнута. Здесь же производитель решил не заморачиваться с перемычками. Вообще. Даже под припой. В этом смысле ESP32R3 v4 мне нравиться немного больше – на ней сделаны печатные перемычки, которые можно перерезать и с помощью капли припоя переключить в другое положение.
Работа RS485 “на короткой дистанции” (на столе) проверена, проблем не наблюдается. Все датчики читаются корректно. Правда, тестировал я на весьма небольшой скорости – 9600, так как китайские датчики такие китайские.
Цифровые дискретные выходы
Как я уже написал, плата имеет 16 выходов с открытым стоком на MOSFET-транзисторах c P-каналом: NCE60P10E. Этот транзистор по паспорту допускает ток до 10А при максимальном напряжении до 60В. Но я бы не стал нагружать его током 10А, да ещё на длительное время по двум причинам: во-первых китайские 10А можно смело делить на два, а во вторых транзисторы не имеют радиатора (хотя как бы они на это и рассчитаны). Производитель поступил ещё проще – рекомендованный им ток через ключи – всего 500 мА ( 0,5 А ).
Каждый ключ снабжен защитным диодом, поэтому Вы можете легко управлять этими ключами любой низковольтной нагрузкой, в том числе индуктивной, вроде катушек реле, ламп, актуаторов, клапанов, вентиляторов, насосов и т.д. В этом плане описываемая плата идеально подходит для моего проекта безумной теплицы, так как почти все исполнительное оборудование у меня как раз 12-вольтовое. А если требуется включить что-то на 220в или более мощное, то вам придется использовать любое удобное реле на DIN-рейку или контактор. Производитель предлагает свой набор реле в корпусе на туже самую рейку.
Все это добро управляется двумя микросхемами PCF8574 с адресами 0x24 и 0x25. Схема управления транзисторами включения приведена ниже. Собственно выход на нагрузку – это контакт Y1, контакт LO0 – это вывод напряжения питания нагрузки (общий для группы). Все выходы снабжены индикацией включения.
На вывод LO0 через колодку вы можете подать любое необходимое напряжение: 12В, 24В или даже 5 или 36 при необходимости. Выходы объединены в две группы, таким образом одну половину можно задействовать на включение устройств с одним напряжением питания, а другую – с другим.
Оптрон включается при низком напряжении на выводе PCF8574, таким образом для включения нагрузки нам необходимо записать 0
в соответствующий вывод, а для выключения – 1
. Собственно, такое поведение (высокий уровень на выходах) предусмотрено для PCF8574 по умолчанию, поэтому включения нагрузки при запуске платы не происходит. Но это не помешает нам при запуске платы записать 0xFF в микросхему еще раз для гарантии.
Мой код управления выглядит примерно так:
#define PCF8574_TIMEOUT -1 // EN: GPIO expanders PCF8574 // RU: Расширители GPIO PCF8574 #define CONFIG_I2C_INPUTS1_ADDRESS 0x22 // pcf8574_hub_in_1 # for input channel 1-8 #define CONFIG_I2C_INPUTS2_ADDRESS 0x21 // pcf8574_hub_in_2 # for input channel 9-16 #define CONFIG_I2C_RELAYS1_ADDRESS 0x24 // pcf8574_hub_out_1 # for output channel 1-8 #define CONFIG_I2C_RELAYS2_ADDRESS 0x25 // pcf8574_hub_out_2 # for output channel 9-16 static uint16_t pcfOutputs = UINT16_MAX; bool pcfRead8(uint8_t address, uint8_t* data) { esp_err_t err = readI2C(I2C_NUM_0, address, nullptr, 0, data, 1, 0, PCF8574_TIMEOUT); if (err != ESP_OK) { rlog_e(logTAG, "Failed to read PCF8574 0.0x%2x: %d (%s)", address, err, esp_err_to_name(err)); return false; }; return true; } bool pcfWrite8(uint8_t address, uint8_t data) { esp_err_t err = writeI2C(I2C_NUM_0, address, nullptr, 0, &data, 1, PCF8574_TIMEOUT); if (err != ESP_OK) { rlog_e(logTAG, "Failed to write PCF8574 0.0x%2x: %d (%s)", address, err, esp_err_to_name(err)); return false; }; return true; } void pcfInit() { ... // Отключаем все выходы pcfOutputs = UINT16_MAX; pcfWrite8(CONFIG_I2C_RELAYS1_ADDRESS, (uint8_t)((pcfOutputs >> 0) & 0xFF)); pcfWrite8(CONFIG_I2C_RELAYS2_ADDRESS, (uint8_t)((pcfOutputs >> 8) & 0xFF)); } bool pcfOutputsWrite(const uint8_t out_num, const bool value) { if (value) { pcfOutputs &= ~(0x1 << out_num); } else { pcfOutputs |= 0x1 << out_num; }; if (out_num < 8) { return pcfWrite8(CONFIG_I2C_RELAYS1_ADDRESS, (uint8_t)((pcfOutputs >> 0) & 0xFF)); } else { return pcfWrite8(CONFIG_I2C_RELAYS2_ADDRESS, (uint8_t)((pcfOutputs >> 8) & 0xFF)); }; }
Цифровые дискретные входы
Ещё две PCF8574 заняты под получение данных с 16 дискретных входов. Они объединены в две группы и выведены на два разъема. Для изменения состояния любого дискретного входа необходимо замкнуть цепь с соответствующего контакта разъема на “землю”, которая выведена на тот же самый разъем. Напряжение на входе 0 ~ 1.8 В соответствует логическому нулю на входе PCF, напряжение выше 8В – единице. Промежуточные напряжения 2 ~ 8 В могут дать неожиданные значения, поэтому их следует избегать.
При этом полной гальванической развязки нет, как таковой, так как внешняя сторона оптопары все равно соединена либо с общим проводом платы, либо с линией питания + 12В. Фактически оптрон используется тут только как устройство согласования уровня 12в до 3.3В.
Ещё мне очень непонятно назначение резисторов, подтягивающих аноды светодиодов оптронов к питанию. Светодиод не транзистор, и оптопара не сможет сработать, даже если один из выводов светодиода “болтается в воздухе”. Как по мне – так это бесполезный расход деталей, места на плате и 2 мА тока на нагрев воздуха.
Но главная проблема подстерегает нас не в этом!!! Главная проблема – ни одна из микросхем, обрабатывающих дискретные входы, не имеет подключения своего выхода прерывания с ESP32. То есть фактически вы не сможете обрабатывать дискретные входы по прерыванию! При таком включении вы сможете опрашивать входы только периодически, например один раз в секунду. Соответственно замутить в таком режиме какой-нибудь счетчик (например от датчика скорости ветра) будет крайне затруднительно.
Что мешало вывести тот же вход приемника и (или) передатчика 433 МГц через перемычки на выходы прерывания PCF – не понимаю!? Приходится применять метод колхозинга и делать это самостоятельно:
После такой доработки можно работать с дискретными входами уже нормально. Входы 9-16 у меня пока остались подключены по прежнему, опрашивать их можно только периодически.
Но и такая доработка не гарантирует реализацию полноценных счетчиков импульсов по дискретным входам. Дело в том, что для опроса состояний входов приходится читать шину I2C, а делать это можно только вне обработчика прерываний. Поэтому приходится мудрить с кодом.
Я делаю это так: по прерыванию только выставляю соответствующий бит в группе событий:
static void IRAM_ATTR gpioInputs1IsrHandler(void* arg) { BaseType_t xResult, xTaskWoken; xResult = xEventGroupSetBitsFromISR(_ioexpFlags, FLG_INPUTS1_ISR, &xTaskWoken); if (xResult == pdPASS) portYIELD_FROM_ISR(xTaskWoken); } void gpioInputsInit() { gpio_install_isr_service(0); gpio_reset_pin(CONFIG_GPIO_PCF_INPUTS1_INTR); RE_OK_CHECK(gpio_set_direction(CONFIG_GPIO_PCF_INPUTS1_INTR, GPIO_MODE_INPUT), return); RE_OK_CHECK(gpio_set_pull_mode(CONFIG_GPIO_PCF_INPUTS1_INTR, GPIO_FLOATING), return); RE_OK_CHECK(gpio_set_intr_type(CONFIG_GPIO_PCF_INPUTS1_INTR, GPIO_INTR_NEGEDGE), return); RE_OK_CHECK(gpio_isr_handler_add(CONFIG_GPIO_PCF_INPUTS1_INTR, gpioInputs1IsrHandler, nullptr), return); RE_OK_CHECK(gpio_intr_enable(CONFIG_GPIO_PCF_INPUTS1_INTR), return); rlog_i(logTAG, "GPIO%d configured", CONFIG_GPIO_PCF_INPUTS1_INTR); }
Затем, уже в основном цикле задачи читаю микросхему и выполняю все необходимые действия:
static EventBits_t bits; while (1) { bits = xEventGroupWaitBits(_ioexpFlags, FLGS_WAIT_BITS, pdTRUE, pdFALSE, portMAX_DELAY); // Обработка прерываний по входам if ((bits & FLG_INPUTS1_ISR) > 0) { pcfInputs1Process(); }; // Обработка команд на управления выходами if ((bits & FLG_QUEUE_SIGNAL) > 0) { pcfOutputsProcess(); }; };
void pcfInputs1Process() { static uint8_t buffer = 0; static uint8_t inputs = 0; static uint8_t changes = 0; if (!pcfRead8(CONFIG_I2C_INPUTS1_ADDRESS, &buffer)) return; // Проверяем наличие изменений в данных на входах changes = inputs ^ buffer; if (changes) { inputs = buffer; // Считаем импульсы на входа счетчиков только по активному уровню if ((buffer & changes) == 0) { if (changes & CONFIG_IOEXP_WIND_SPEED) { _cntWindSpeed++; } else if (changes & CONFIG_IOEXP_WATER_VOLUME) { _cntWaterVolume++; }; }; }; }
Конечно, супербыстрых счетчиков через PCF8574 получить не удастся, но для счетчика литров воды или скорости ветра – вполне сгодится.
Аналоговые входы
Для измерения напряжения используются выводы 34, 25, 26, 39. В текущей ревизии платы входы HT1 и HT2 предназначены для измерения тока 4 ~ 20 мА, в входы HT3 и HT4 – для измерения напряжения от 0 до 5В. Как это возможно?
Указанные выше выводы ESP32 “ущербные”, не имеют внутренней подтяжки, и могут работать только “на вход”. Зато они могут работать в режиме ADC даже когда включен WiFi – приемопередатчик. При этом микросхема ESP32 не может нормально измерять напряжение выше 3В. Поэтому для заявленного диапазона измерений 0 ~ 5В необходимо предварительное преобразование уровня – в простейшем случае для этого достаточно делителя напряжения. Для измерения тока обычно применяется резистор, с помощью которого ток превращается в напряжение, которое затем и измеряется ADC.
Для входов напряжения (HT3 и HT4) входной сигнал втискивается в заданные рамки с помощь упомянутого делится напряжения. На схеме вроде как обозначены резисторы 5,1кОм и 10кОм. А на деле стоят 510 Ом ± 5% / 12.4 kОм ± 1%, то есть фактический коэффициент деления около 0,96 ( ???нафига??? ). В результате, подав на вход 5В на выходе делителя мы получим что-то около 4,8В, а никак не 3В!
На токовых входах (HT1 и HT2) вместо резистора верхнего плеча делителя впаяна перемычка, а сопротивление нижнего плеча – 124 Ом ± 1%. Таким образом мы имеем самый простой преобразователь ток – напряжение.
Кстати, приведенная ниже схема явно устаревшая, так как не соответствует тому, что фактически установлено на плате. Видимо схема осталась от первых ревизий плат.
Фотография данного участка платы приведена ниже – можете сравнить со схемой производителя. Нажмите на картинку для увеличения.
Затем эти сигналы подаются на соответствующий вход счетверенного операционного усилителя LM224 или LM324, включенного в режиме повторителя со 100% обратной связью. Это дает коэффициент усиления равный 1, но зато такой повторитель имеет очень высокое входное сопротивление каскада, что исключает какое либо влияние входа ESP32 на измеряемый сигнал. Сигнал с выхода ОУ уже подается на вход ESP32. Там же, на выходах ОУ, стоят диоды Шоттки BAT54S для защиты ESP32 от повышенного и пониженного напряжения.
Операционный усилитель запитан от 12В через дополнительный фильтр на дросселе и конденсаторах для уменьшения помех по линии питания.
Прямые входы/выходы
Три вывода: GPIO 14, 32, 33 просто выведены “наружу” на ту же колодку, что и ADC (Header 5 / P9). Их вы можете использовать по своему усмотрению, но при этом следует учитывать, что они уже подтянуты к линии питания +3,3В через резисторы 4,7 кОм. К ним идеальным способом можно подключить “народные” датчики типа DS18B20 или DHT11, DHT21, DHT22 (AM2302) и т.д.
А можно задействовать сразу два вывода, и организовать через них вторую шину I2C для подключения датчиков типа SHT2x / SHT3x / SHT4x и аналогичных. С готовой подтяжкой.
Или организовать “быстрый” счетчик импульсов по прерываниям, если потребуется.
Разъемы для приемника и передатчика 433 Мгц
Ну и наконец, на плате внутри корпуса присутствуют еще два разъема – для подключения приемника и передатчика сигналов 433 МГц.
К ним, при необходимости, можно подключить вот такие модули приемника и передатчика:
Разъем P7 предназначен для подключения передатчика и соединен с выводом GPIO 15 напрямую и без какой либо подтяжки. Если вы не собираетесь его использовать, его вполне можно использовать в других целях – например как это сделал я выше, в разделе про дискретные входы.
Разъем P2 предназначен для подключения приемника. Приемник питается от +5В и для понижения логического уровня до 3.3В, необходимого для подачи на вход ESP32, применена еще одна микросхема шинного буфера 74LVC1G125. Соответственно, этот вход легко можно использовать для подключения любых внешних модулей с напряжением логической единицы равным 5В.
Выводы
Да, данная плата получилась гораздо дороже своих собратьев, про которые я писал ранее, но зато на ней предлагается весь набор необходимых интерфейсов, который может потребоваться в домашней автоматизации. На мой взгляд, в данном случае у производителя получился довольно неплохой контроллер для домашнего применения, но и его можно немного улучшить. Просто добавить перемычек, дабы можно было без “колхоза” переключить некоторые выводы в другой режим истолькования. Вряд ли производитель прочтет сей опус, конечно, но вдруг… Вдруг мы увидим следующую версию платы, где это реализовано?
Программировать его можно с помощью фреймворков ESP-IDF, Arduino32, а также для него существует несколько вариантов готовых прошивок, например Tasmota. Ссылки на готовые прошивки можно найти на странице продукта.
Ссылки
- Страница продукта: kincony.com/arduino-esp32-16-channel-relay-module-2.html
- Схема: kincony.com/download/KC868-A16-schematic.pdf
- Описание выводов: kincony.com/forum/showthread.php?tid=1666
- Обзор на Хабре: habr.com/ru/companies/ruvds/articles/665492/
💠 Полный архив статей вы найдете здесь
Пожалуйста, оцените статью:
Имею такую плату. Выпаяв резисторы на входе оптопар можно эти входы “отвязать”. А вот выходы привязаны к земле жестко. Тут отвязать не получится. Это косяк данной платы.
В интернете (в т.ч. на гитхабе) есть коды для простого подключения Ethernet к ESP32 на ардуиновском фрамеверке. Но я не нашел примера, как к Ethernet привязать протокол modbus. Вроде это не должно быть сложно, т.к. есть примеры привязки modbus к WIFI. Если у кого есть примеры, поделитесь плз.