ENC28J60 и REST-управление реле

ENC28J60 — почему-то, именно с этим Ethernet-модулем возникают проблемы у всех, кто пытался его использовать, отойдя в сторону от одно-двухстраничного WEB-сервера. Ответ в принципе работы ENC28J60; его работа с TCP/IP организована программно, а не аппаратно. Оттого, ожидать совместимости с другими похожими Ethernet-модулями несколько необдуманно.

ENC28J60 и REST-управление реле

Кратко. Нужно реализовать Web-сервер на Arduino, в качестве Ethernet-модуля которого будет использоваться ENC28J60. Сервер должен получать REST-команды с клиента и возвращать JSON-строку в качестве ответа. Также, в качестве управляемого устройства должен выступать реле-модуль.

Клиентом же может выступать некий абстрактный скрипт, написанный на NodeJS.

План решения этой задачи можно разбить на следующие этапы:

  1. Подключение модуля ENC28J60 к Arduino,
  2. Подключение реле-модуля на 2 реле,
  3. Реализация обработки запросов модулем ENC28J60,
  4. Соединение всего вместе,
  5. Написание „клиента“ на NodeJS.

Примечание: Рассматривается только Arduino UNO. Arduino Nano нельзя использовать с модулем ENC28J60. Проблема кроется где-то в особенности работы 13-го GPIO-разъёма. Выглядеть это будет как вечно зависший Arduino. Про остальные платы Arduino не знаю. Может, в чём-то я и не прав, так как видел такие вот девайсы в продаже: Arduino NANO v3 Ethernet Shield.

Подключение модуля ENC28J60 к Arduino

ENC28J60 и REST-управление реле

Есть 3 способа подключения Ethernet-модуля 28J60.

  1. Используя библиотеку UIPEthernet,
  2. Используя библиотеку ETHER_28j60,
  3. Используя библиотеку EtherCard.

Долгий поиск по интернету и опыты приводят к следующим выводам:

  1. ETHER_28J60 не работает как полагается и даже не „собирается“;
  2. Из оставшихся двух (Arduino_UIP и EtherCard), наиболее удобной в использовании является UIP. Однако, он жрёт просто чудовищный объём свободной памяти (сравнивая с Arduino UNO и её 2 килобайтами).
  3. EtherCard является довольно сложным в обращении — никаких print() прямо в качестве ответа „сервера“ и т.п.

Получается, что наиболее грамотным вариантом (не „простым“, не „удобным“ а именно „грамотным“) является EtherCard.

Внимание! EtherCard использует 8-ой GPIO-разъём, а не 10-ый при подключении контакта „Chip Select“. В EtherCard можно использовать и десятый разъём, но для этого нужно явно указать в void setup() {}:

Таким образом, GPIO-разъёмы, необходимые для корректного подключения следующие:

ENC28J60 pinArduino pin
VCC3,3V
GNDGND (самоочевидно)
SCKPin 13
SOPin 12
SIPin 11
CSPin 8 (или 10-ый, см. выше)

Характеристики модуля ENC28J60:

Напряжение3,3В
Ток в режиме передачи180мА
Ток в режиме простоя120мА

Имейте это в виду при использовании нескольких разных модулей с этим. Согласно „Arduino current limitations“, Arduino сможет отдавать только 200мА тока для питания (или 400мА, если у неё 2 GND-разъёма). После этого порога наступает его неисправность.

Подключение реле-модуля на 2 реле

ENC28J60 и REST-управление реле

С документацией на эти релюшки туго. Очень.

ENC28J60 и REST-управление реле

Беглый осмотр дорожек на плате позволяет заключить, что имеется 2 способа соединения Arduino и этого модуля: используя питания только от Arduino (используя перемычку VCC—JD-VCC) и убрав перемычку и запитав катушки реле отдельно. Замер тока показывает, что обе включенные реле используют для катушки около 100мА. Итого, нужна следующая схема подключения, где перемычку VCC—JD-VCC нужно снять:

Контакты модуля релеКонтакты других устройств
JD-VCC+5V DC (Блок питания 5В)
GNDGND (Блок питания)
In1Любой GPIO (Arduino)
In2Любой GPIO (Arduino)
VCC+5V (Arduino)

Примечание: Для управления реле можно использовать и 3,3-вольтовую логику. К примеру, Wi-Fi-модуль ESP8266 вполне может управлять этим реле напрямую. Но это не относится к обсуждаемой теме.

В данном случае получается, что, для того, чтобы добиться разности фаз на управлении реле, нужно не подавать логический сигнал с Arduino на соответствующий GPIO. Иными словами, digitalWrite(2, LOW); включит реле, если тот висит на GPIO2, а digitalWrite(2, HIGH); отключит реле.

Т.о., в этом реле-модуле всё наоборот, по сравнению с банальным светодиодом. Это следует иметь в виду при использовании реле.

Реализация обработки запросов модулем ENC28J60

Для удалённого управления Arduino удобнее всего использовать библиотеку „Arduino REST“. В замечательных Wi-Fi модулях ESP-8266 (которые сами себе „Arduino“) и для Serial-соединения вида „Arduino-компьютер“ эта библиотека проявила себя просто потрясающе, и поэтому сложилось заблуждение, что в случае Ethernet будет аналогично. Сразу следуют разочарования:

  1. aREST не поддерживает EtherCard,
  2. aREST вообще не поддерживает вышеописанные модули в целом.

Есть два способа решения этой проблемы:

  1. Изменить поведение aREST, из них:
    1. Реализовать rest.handle() вручную прямо в void loop() {};
    2. Расширить aREST.h из скетча Arduino;
    3. Исправить aREST.h, дописав нужное.
  2. Написать свою собственную реализацию аналогичной библиотеки.

Сперва я кинулся писать собственную реализацию, но, непосредственно перед выкладкой на GitHub при написаний примеров использования я наткнулся на ошибку (где-то ошибки с указателем и поведение вывода программы стало зависеть от фазы луны), поэтому проще было приручить надёжную aREST, чем пользоваться своей нестабильной поделкой (автор aREST пошёл по правильному пути, он резервирует буфер вывода программы в 350 байт заранее, чего я не делал, пытаясь объегорить контроллер с помощью „ехал указатель через указатель…“). I.e. пошёл по варианту 1.1.

Однако, и тут были грабли. Связка двух библиотек (aREST и EtherCard) оставляет около 200 байт памяти для работы Arduino из её двух килобайт.

Пришлось чуть-чуть подумать и максимально ужать взаимодействие между этими библиотеками. Код получился следующим (под результат оставляет около 500 байт свободными, а это четверть памяти Arduino, что неплохо):

Итого, при запросе к нашему серверу http://192.168.0.200/relay1 или http://192.168.0.200/relay2 мы получим значение реле (1 или 0 в ключе return_value JSON-ответа); а при запросе http://192.168.0.200/relay1?params=1 мы включим первое реле, запросив http://192.168.0.200/relay1?params=0 — выключим.

Соединяем всё воедино (ток)

Итак, у нас есть ардуина, способная выдать на любой свой GPIO до 40 мА и на два VCC-разъёма до 200 мА. При превышении этих значений наступит деградация микроконтроллера.

Релюшки жрут около 100 мА во включенном состоянии, модуль Ethernet — 180 мА. Отсюда следует, что питать что-то из этого нужно отдельно. Проще всего разделить JD-VCC и GND реле.

Запитать их можно через блок питания. Используя — например — такую вот плату с регуляторами напряжения:

ENC28J60 и REST-управление реле

Сам блок питания должен выдавать: 500мА (Arduino и ENC28J60, который питается через Arduino) + 100мА (питание реле) + 25% (от суммы) = 600мА + 25% = 750мА. Чаще всего в продаже встречаются блоки питания на 1А, скорее всего, именно он и нужен.

Написание „клиента“ на NodeJS

Всё просто. Пишем обычный web-клиент:

Проверяем его работу:

Вместо заключения

Осталось только спаять всё вместе и подобрать для результата подходящий корпус, просверлив в нём необходимые отверстия. Также нужно написать нормальную программу-клиент вместо теста из предыдущего пункта. Всего-навсего.

Для NodeJS уже есть модуль aRest (также на гитхабе). Беглый просмотр его кода позволяет сделать вывод о том, что эту библиотеку удобно использовать при наличии более одного-двух устройств (Arduino/ESP8266) прошитых с aREST.h.

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

Комментарии: