Управляем платой на расстоянии с Arduino Ethernet Shield

Буквально на днях со статьи  «Украинцы в Вегасе: 7 украинских продуктов, которые засветились на CES 2016» узнал об очень интересном стартапе Blynk — платформа, созданная украинцами для iOS и Android-устройств, позволяет контролировать Arduino, Raspberry Pi и другие похожие микроконтроллерные гаджеты удаленно.imageОписанный функционал сервиса вызвал огромное желание попробовать его в действии и начну пока с ARDUINO. В документации к проекту детально описана настройка и пошагово «первый старт». Страница проекта в Facebook. (ниже перевод и практика использования). Быстрый старт: Arduino + Ethernet shield Скачиваем мобильное приложение Blynk (App Store, Google Play) В приложении получаем ключ авторизации (Auth Token)Загружаем в библиотеку в Arduino IDE. Инструкция по установке библиотек здесь. В Arduino IDE, выбираем File -> Examples -> Blynk -> BoardsAndShields -> Arduino_Ethernet В скетче необходимо внести ключ с мобильного приложения (Auth Token) и выгружаем в нашу Arduino. Подключаем Arduino с Ethernet shield к сети Интернет.

image
Принцип работы Blynk

Попробуем включить светодиод подключенный к Arduino используя Blynk App на телефоне. Подключаем светодиод как указано изображении ниже: Мобильное приложения Blynk 1. Создаем Blynk аккаунт После установки приложения на телефон необходимо создать новый аккаунт. Используйте реальный мейл, он еще понадобится. Зачем создавать аккаунт? Аккаунт необходим для предоставления доступа к устройствам, при управлении проектами с нескольких устройств, а также в целях безопасности. Есть возможность настроить свой сервер Private Blynk Server и держать все под личным контролем. 2. Создаем новый проект. После успешного входа в аккаунт, создаем новый проект дав ему имя. 3. Укажите ваше оборудование. Выберите оборудование которое вы будете использовать. Просмотрите список поддерживаемого оборудования. 4. Ключ авторизации (Auth Token) Auth Token — это уникальный идентификатор который необходим для соединения устройства со смартфоном. Каждый новый проект который вы будете создавать будет иметь свой уникальный ключ. ПРЕДУПРЕЖДЕНИЕ: не передавайте никому ключ авторизации, за исключением намеренного предоставления доступа к вашему оборудованию. Ключ удобно высылать по почте. Нажмите E-mail и ключ будет отправлен на адрес указанный при регистрации. Если нажать на ключ в приложении, он будет скопирован в буфер обмена. Теперь жмите «Create» 5. Добавление виджетов. Сейчас ваш проект чист, давайте добавим кнопку для управления светодиодом. Нажмите где-либо по пустой области проекта для отображения панели с виджетами. Все доступные виджеты (элементы управления) размещены здесь. Вибирайте кнопку (Button). Widget Box Drag-n-Drop — нажмите и удерживайте необходимый елемент управления, чтобы перетащить на новое место. Настройки виджетов — каждый виджет имеет свои настройки. Нажмите на виджет, чтобы открыть их. Наиболее важный параметр для настройки это PIN . Список пинов соответствует физическим контактам на устройстве. Если ваш светодиод подключен к цифровому контакту 8 — выберите D8 (D — означает цифровой). 6. Запускаем проект. Когда вы закончите с настройками — жмите кнопку PLAY. Это переключит вас с режима редактирования в режим выполнения, в котором вы сможете взаимодействовать с вашими устройствами. В данном режиме вы не сможете перемещать или настраивать элементы управления, нажмите STOP чтобы вернуться в режим редактирования. После запуска выполнения, вы получите сообщение “Arduino UNO is offline”. Исправим это в следующем разделе. Начинаем работу с устройством Как использовать скетч примера. На вашем компьютере должна быть установлена библиотека Blynk Library. Если еще нет — жмем здесь. Скетч в примере поможет вам быстро получить онлайн доступ к устройству, библиотека содержит несколько примеров для изучения. Откройте пример скетча, соответствующий вашему устройству или шилду. Давайте разберем скетч для Arduino UNO + Ethernet shield

#define BLYNK_PRINT Serial #include  #include  #include   char auth[] = "YourAuthToken";  void setup() {   Serial.begin(9600); // See the connection status in Serial Monitor   Blynk.begin(auth);  // Here your Arduino connects to the Blynk Cloud. }  void loop() {   Blynk.run(); // All the Blynk Magic happens here... }  Ключ авторизации (Auth Token) В скетче-примере вы можете найти его в следующей строке:
char auth[] = "YourAuthToken";

Это ключ который вы отправили себе в письме ранее. Проверьте вашу почту и скопируйте ключ, вставьте его вместо текста YourAuthToken. Должно выглядеть подобно этому:

char auth[] = "f45626c103a94983b469637978b0c78a";

Выгрузите скетч в ваше устройство и откройте монитор порта, вы должны увидеть следующее:

Blynk v.1.0.3 Your IP is 192.168.0.11 Connecting... Blynk connected!

Если это так — мои поздравления — вы все настроили правильно и ваше устройство подключилось к облаку Blynk! Зажигаем светодиод! (Blynking) Возвращаемся к установленному мобильному приложению Blynk и нажимаем кнопку для включения и выключения светодиода. Посмотрите другие примеры скетчей.. Будьте свободны в ваших экспериментах, объединяйте разные примеры и создайте свой невероятный проект! Сделав все согласно инструкции — чуда не произошло и с первого раза все не завелось Почему-то не получает IP-адрес с роутера, будем копать…. Копать пришлось не долго, проблема решилась непосредственным подключением платы ARDUINO к роутеру (до этого подключение шло через промежуточный свич, который скорее всего и создавал проблему). Подключились! Активность в мобильном приложении вызывает мерцание диодов передачи данных на Ethernet-шилде, значит все работает, новое поле для экспериментов готово!

Следующие несколько уроков будут посвящены организации сети Ethernet. В этом уроке я изложу минимум информации, необходимой для практической работы с сетью. Немного расскажу об Ethernet модуле ENC28J60 и приведу схему подключения его к плате Ардуино.

Предыдущий урок     Список уроков     Следующий урок

Локальная сеть Ethernet.

Ethernet – самый распространенный в мире сетевой интерфейс. Когда говорят об объединении компьютеров в локальную сеть, как правило, имеют в виду именно его. Ethernet контроллер стал штатным устройством для каждого компьютера.

Первый вариант стандарта Ethernet появился еще в 70х годах. Первоначально средой передачи был коаксиальный кабель, топология сети – шина, скорость передачи 10 мегабит/сек. Со временем появилось множество разновидностей Ethernet со скоростью передачи до 100 гигабит/сек, изменилась архитектура сети, стала другой среда передачи. Об этом существует много подробной информации: протоколы, форматы данных, алгоритмы обмена и т.п. Я буду рассказывать о сети Ethernet чисто с практической стороны.

Нам интересны стандарты Ethernet  (10 Мбит/сек) и  Fast Ethernet (100 Мбит/сек). Они совместимы и отличаются только скоростью передачи данных. Для подключения к сети плат Ардуино мы будем использовать контроллеры первого стандарта (10 Мбит/сек), а штатные сетевые контроллеры компьютеров поддерживают второй  стандарт (100 Мбит/сек). Но это не помешает подключить компьютер к той же сети. Стандарты обозначаются соответственно 10BASE-T и 100BASE-TX.

Топология сети.

Два Ethernet устройства могут быть соединены между собой непосредственно. Никакие дополнительные блоки не требуются, достаточно одного кабеля.

Если используется более двух устройств, то соединение происходит по радиальной топологии с помощью хабов (HUB).

Хаб или сетевой концентратор — это электронный прибор для соединения нескольких сетевых устройств в один сегмент сети. Он содержит несколько портов ввода/вывода.

По сути это повторитель. Все сигналы, которые подаются на один из его портов, повторяются на остальных. Несмотря на то, что физически топология сети выглядит как радиальная, логически с использованием хабов она превращается в “общую шину”. Любые пакеты данных в сети попадают на все сетевые устройства, в том числе и на устройства, которым они не предназначены. Благодаря этому возможны конфликты данных, увеличивается нагрузка на сеть. В настоящее время хабы практически вытеснены более совершенными устройствами — сетевыми коммутаторами.

Хабы можно соединять между собой, но только в древовидные структуры.

При этом недостатки, связанные с логической топологией ”общая шина” усугубляются за счет увеличения количества сетевых устройств.

Гораздо больше возможностей имеет сеть, созданная на базе коммутаторов (switch).

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

Коммутатор это прибор для соединения нескольких устройств сети в пределах одного или нескольких сегментов.

Подобно хабу коммутатор имеет несколько портов ввода/вывода. Но в отличие от хаба коммутатор передает пакеты данных не всем подключенным к нему устройствам, а только непосредственно получателю.  Благодаря этому увеличивается производительность сети, повышается надежность.

  • Хаб — это “тупой” аппаратный повторитель сигналов.
  • Коммутатор – интеллектуальное устройство, которое анализирует заголовки пакетов и передает данные только на нужные порты.

Обычно сетевой коммутатор поддерживает различные скорости передачи данных одновременно.

К портам коммутаторов могут быть подключены другие коммутаторы или хабы. Это позволяет почти бесконечно расширять сеть.

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

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

Среда передачи данных Ethernet (кабель).

В качестве среды передачи нужные нам стандарты требуют применения кабеля категории 3 или категории 5. Используются только две неэкранированные витые пары (4 провода).

Одна витая пара предназначена  для передачи данных, другая для приема.

  • Волновое сопротивление линий — 100 Ом.

Кабель обозначается UTP —  Unshielded twisted pair (неэкранированная витая пара). Часто на нем написано ”ETHERNET LAN CABLE”.

Стандартный кабель содержит 4 витые пары.

Мы будем использовать только две из них.

Для подключения к портам Ethernet используются 8 контактные разъемы RJ-45.

Есть два варианта распиновки разъемов: T568A и T568B. Часто просто называются варианты A и B.

Распиновка T568A.

Номер контакта Назначение сигнала
1 TX+
2 TX-
3 RX+
6 RX-

Распиновка T568B.

Номер контакта Назначение сигнала
1 RX+
2 RX-
3 TX+
6 TX-
  • На сетевой карте компьютера и Ethernet модуле Ардуино  применяется вариант A.
  • Порты ввода/вывода коммутатора или роутера используют вариант B.

Понятно, что выходные сигналы одного устройства должны подключаться к входам другого, и наоборот. Поэтому существует 2 варианта кабелей: прямой и перекрестный. Прямой используется для соединения между устройствами с разъемами типов A и B, а перекрестный – для соединения портов с одинаковой распиновкой.

Для нас это означает:

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

Прямой кабель предполагает, что соединяются контакты с одинаковыми номерами. Соответствие сигналов вход – выходу обеспечивается распиновкой разъемов сетевых портов.

В перекрестном кабеле провода соединяются таким образом, чтобы у связанных кабелем портов входные сигналы были подключены к выходам, а выходные к входам.

На рисунках показаны общепринятые цвета жил кабеля. Лучше их придерживаться.

  • Максимальная длина сегмента кабеля – 100 м.

В сетевом интерфейсе Ethernet существует полная гальваническая развязка каждого устройства от среды передачи (кабеля). Развязка осуществляется за счет применения импульсных трансформаторов.

Это значительно повышает помехозащищенность сети и обеспечивает электрическую безопасность сетевых устройств.

Модуль ENC28J60.

Платы Ардуино будем подключать к сети Ethernet с помощью модуля ENC28J60. Физически он представляет собой плату размерами 51 x 18 мм.

Это самый дешевый сетевой Ethernet контроллер. По моей партнерской ссылке на момент написания статья его цена составляет всего 250 руб.

Моя цель не сделать обзор возможностей и технических характеристик модуля. Возможно, я напишу отдельную статью о нем в рубрике ”Электронные компоненты”. А сейчас я приведу информацию необходимую для работы модуля совместно с платами Ардуино.

Модуль выполнен на базе микросхемы ENC28J60 фирмы Microchip. Практически это микросхема ENC28J60 в стандартном включении.

Техническую информацию фирмы-производителя можно посмотреть по этой ссылке ENC28J60.pdf.

Вот принципиальная схема модуля.

Основные характеристики модуля ENC28J60.

  • Совместимость с Ethernet сетями 10/100/1000 Base-T. Скорость передачи данных 10 мбит/сек, реализация TCP/IP стека.
  • Интерфейс связи с микроконтроллером – SPI, частота до 20 мГц.
  • Напряжение питания 3,1 – 3,6 В. Типовое 3,3 В.
  • Интерфейсные входы модуля позволяют непосредственное подключение к сигналам с 5 вольтовыми уровнями. Максимально-допустимое напряжение на входах интерфейса SPI — 6 В. В половине статей о подключении ENC28J60 к Ардуино написано, что необходимо подключать входные сигналы через согласующие резисторные делители. Это не так. Сомневающееся могут посмотреть документацию на микросхему ENC28J60.
  • Ток потребления от источника питания 3,3 В:
    • в момент передачи может достигать 180 мА;
    • в активном состоянии, но без передачи 120 мА;
    • в режиме ожидания (сигнал CS в неактивном уровне) не более 2 мА.
  • В модуле обеспечивается гальваническая развязка от линии связи.

Это характеристики, которые я решил выделить. Главное:

  • для питания модуля необходимо использовать источник напряжением 3,3 В и выходным током до 180 мА;
  • выводы интерфейса модуля допускается подключать к 5 вольтовым сигналам.

Интерфейс связи с микроконтроллером.

К микроконтроллеру модуль подключается через 10 контактный разъем типа PLHD, расположенный на печатной плате устройства.

Назначение контактов (распиновка) модуля ENC28J60.

Контакт Обозначение Направление Назначение
1 CLK выход Выход тактового сигнала
2 INT выход Сигнал прерывания
3 WOL Зарезервирован
4 SO выход Сигнал SO интерфейса SPI
5 SI вход Сигнал SI интерфейса SPI
6 SCK вход Сигнал SCK интерфейса SPI
7 CS вход Сигнал CS интерфейса SPI (выбор контроллера)
8 RST вход Сброс
9 VCC Питание модуля 3,3 В 180 мА
10 GND Общий вывод

Подключение модуля ENC28J60 к плате Ардуино.

Для питания модуля необходим источник напряжения 3,3 В. Такое напряжение есть на плате Arduino UNO. Поэтому я решил подключить модуль к ней. Для других плат пришлось бы добавлять стабилизатор напряжения 3,3 В.

В характеристиках на плату Arduino UNO указано, что ток потребления на выводе 3,3 В должен быть не более 50 мА. А нам необходимо 180 мА. Но на моей плате Arduino UNO в качестве стабилизатора 3,3 В используется микросхема XC6206P332MR. На плате это корпус SOT-23 с обозначением 662K. Допустимый выходной ток для этого стабилизатора 200 мА (технические характеристики можно посмотреть по ссылке XC6206.pdf). Т.е. модуль можно смело запитывать от Arduino UNO.

Для управления модулем мы будем использовать аппаратный интерфейс SPI микроконтроллера. Поэтому выбора выводов платы Ардуино для подключения модуля у нас нет.

Таблица соединения выводов платы Arduino UNO и модуля ENC28J60 выглядит так.

Плата Arduino UNO Модуль ENC28J60
Вывод № вывода Обозначение
12 4 SO
11 5 SI
13 6 SCK
10 7 CS
RES 8 RST
3.3 V 9 VCC
GND 10 GND

Кому-то удобнее будет работать со схемой.

У меня все это выглядит так.

К роутеру я подключил модуль прямым кабелем.

В следующем уроке изучим библиотеку для управления модулем ENC28J60, научимся писать программы для передачи данных через сеть Ethernet.

Предыдущий урок     Список уроков     Следующий урок

Поддержать проект Хочу разобраться с Ethernet Shield для Arduino. Поскольку тема достаточно обширная и уложиться в одну статью будет не просто.Не пытаясь ухватиться за все и сразу, в этот раз:

  • создадим простой «сервер» на базе Arduino и Ethernet Shield; 
  • подключим его к домашней сети;
  • получим данные через обычный браузер.

Для того, чтобы добавить некоторой «пикантности» и научиться комбинировать проекты — будем на «сервере» измерять температуру используя датчик DS18S20 из другой моей статьи.

История HTTP

Перед тем, как разобраться с Ethernet Shield неплохо было бы подтянуть мат. часть и разобраться с протоколом HTTP. Итак, HTTP — это сокращение от HyperText Transfer Prоtocоl. Рекомендую хотя бы почитать статью на википедии, так как я буду описывать все очень кратко.В общем, протокол благодарно базируется на другом протоколе более низкого уровня TCP (Transmission Control Protocol). Нужен TCP для того, чтобы передавать данные от одного устройства подключенного в сеть, к другому. Из всего протокола нам интересны только два параметра. 

  • IP-адрес — так как TCP создан для TCP/IP сетей, то каждый хост (далее я буду так именовать устройства), будет иметь свой собственный адрес IP-адресс. Такой адрес состоит из 4-х чисел от 0 до 255 разделенных точками (пример: 192.168.0.100);
  • Порт (port) — число от 0 до 65535 (как по мне, проще запомнить 216)

Итак, мы практически готовы к осознанию протокола HTTP. HTTP — это протокол еще более высокого уровня, чем TCP. В оригинале, он разрабатывался (как следует из название) для передачи гипертекста. Стоит признаться — порой меня поражают осознание того, насколько светлые головы придумывали все эти протоколы, они просто загляденье. Итак, HTTP. По сути, это набор правил для сообщений между разными хостами. Другими словами, это некоторый набор условностей, которые позволяют понять одному хосту, что он него хочет другой, и ответить ему в соответствующей манере. Нам придется составлять сообщения в соответствии с этими правилами, так что их понимание сильно упростит процесс.

Постановка задачи

Мне бы хотелось отойти от очень простых примеров которые в сущности повторяют проделанные в сети тысячи раз опыты. В этом эксперименте:

  • Подключим Arduino с помощью Ethernet Shield к сети
  • Создадим простой web-интерфейс через который будем управлять Arduino
  • Подключим к Arduino датчик температуры DS18S20 из этой статьи
  • Подключим к Arduino простой светодиод

Вывод данных с датчика и управление светодиодом должно осуществляться через web-интерфейс. Используются: Arduino, Ethernet Shield, DS18S20, Светодиод и пара резисторов (100 Ом для светодиода и 4,7 КОм для DS18S20).

Пишем простой и крутой код

Задача в этот раз посложнее и кода, соответственно, вышло немного больше. Главное без паники, сейчас во все разберемся. Перед тем как лезть в главные функции любой Arduino программы loop и setup разберемся со всеми вспомогательными, и пойдем снизу вверх разбирать одну за одной.

  • void connectToSensor() эта функция, как и следующая являются кусочком разбитой на две части прошивки сделанной в статье о температурном датчике, для понимания процесса её придется прочитать. Конкретно этот кусочек кода ищет полный адрес подходящего нам сенсора на 1-wire шине, и как только находит первый — записывает его адрес в переменную addr. В дальнейшем этот адрес будет использоваться для вызова нашего датчика. 
  • float getTemperature(). Вторая часть в работе с датчиком температуры после поиска его адреса — это получение данных и вычисление температуры. Именно этим и занимается функция getTemperature. Следует отметить, что этот код претерпел некоторые изменения после публикации статьи о датчике. Дело в том, что и код на странице используемой для общения с датчиком библиотеки OneWire, тоже был изменен, и я решил последовать их примеру. Изменения не значительны, а идею я уже описывал — не буду повторяться.
  • void updateTemperature() — обновление данных с датчика на каждом цикле работы нашего контроллера будет слишком накладно, так как это достаточно «дорогостоящая» операция, ведь общение по шине 1-wire занимает некоторое время (главные недостаток протокола). Поэтому я обернул обновление данных в функцию и делаю это не чаще раза в 5 секунд. Функция millis() возвращает количество миллисекунд прошедших после запуска контроллера, именно с помощью нее здесь и вычисляется время последнего обновления. Функцию эту можно будет спокойно вызывать в каждом цикле loop.
  • String floatToString(float value, byte precision) — сервисная функция. Все что она делает — это преобразует float значение в строчку. Первый параметр — это само float значение, вторым можно регулировать количество знаков после запятой. Функция работает совсем просто — в начале берем целочисленную часть нашего value, а потом умножаем все значение на precesion и отнимаем вычисленную ранее целочисленную часть. В конце «собирается» строчка, в которой в начале идет целая часть, потом точка, а за ней разность вычисленная на предыдущем шаге. Пример: floatToString(12.258, 100) вернет «12.25» строчку. 
  • void generatePage(EthernetClient client). Вот мы и добрались до HTML странички. Функция generatePage записывает в переданный в качестве единственного параметра объект EthernetClient нашу html страничку. Я не буду расписывать HTML, предполагая, что у вас есть базовые знания этого языка разметки. На сгенерированной странице у нас будет отображаться текущее состояние нашего светодиода, температура полученная с нашего датчика и две ссылки одна для включения, вторая для выключения светодиода.
  • void redirectHeader(EthernetClient client, String path) — любой ответ от сервера передаваемый по http (как и сам запрос собственно) обязательно начинается с header’а. Так вот, метод redirectHeader, как можно догадаться из названия, оправляет пользователю ответ с кодом 302, который означает перенаправление. Получив такой заголовок браузер отправит следующий запрос на адрес указанным в заголовке Location. Наша функция получает этот самый путь в виде строки (второго параметра).
  • void successHeader(EthernetClient client) — эта функция тоже генерирует заголовок http ответа, только в этот раз с кодом 200. Код 200 обозначает успешное выполнение запроса и подразумевает, что после заголовка будут так же отправлены данные (в нашем случае html страница). Функция не принимает никаких строк в качестве параметров, так как всегда генерирует одинаковый ответ.

Теперь можно сказать, что со всеми вспомогательными функциями мы разобрались. Самое время взглянуть не переменные объявленные нами в самом начале кода, сразу после объявления библиотек. О каждой из них по порядку:

  • byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; — MAC адрес нашего устройства. Должен быть уникальным для каждого устройства в сети. Вроде бы на новых сериях Ethernet Shield этот адрес будет написан на самом shield, но сам не видел — так что точно не скажу
  • IPAddress ip(192,168, ,33); — создаем объект IPAddress для нашего устройства. Этот адрес будет изменяться в зависимости от настроек вашей сети, но в моем случае это 192.168.0.33
  • EthernetServer server(80); — создается объект server который предоставляет нам интерфейс для реализации собственно сервера. Единственные параметр передаваемый в конструктор — это номер порта, по которому следует ждать запросов от пользователей. 80-й порт выбран не с проста. Дело в том, что это порт по умолчанию для http запросов, и браузер будет обращаться именно к нему, если не указать ему другой специально
  • byte wirePin = 8; OneWire ds(wirePin); byte addr[8]; — собственно объявляем на каком pin у нас будет наш датчик температуры, затем создаем объект класса OneWire, который предоставляет API для работы с этим протоколом, и в конце концов — объявляем переменную которая будет хранить адрес нашего датчика, чтобы его не приходилось каждый раз искать снова
  • byte ledPin = 7; boolean isLedOn = false; — объявляем переменную которая будет хранить в себе номер порта на которой находится наш светодиод, и создаем еще одну boolean переменную которая содержит в себе сведения о текущем состоянии светодиода (false — выключен, true — включен)
  • unsigned long lastUpdate = ; — переменная куда мы будем записывать время последнего обновления нашего датчика в миллисекунда. Начало отсчета — старт нашего микроконтроллера.
  • float temperature = 100.0; — текущая температура датчика. В качестве значения по-умолчанию я поставил -100, просто потому, что такое значение легко запомнить и его не может выдать наш датчик (физические ограничения), а значит сверив значение переменной temperature с -100 всегда можно сказать установлено это значение датчиком или он просто еще не успел обновить показания.

Осталось разобрать как это все связывается вместе в setup и loop функциях. Самые очевидные места я буду пропускать. Начнем с void setup(void):

  • Ethernet.begin(mac,ip); — передаем объявленные и инициализированные ранее mac и ip метод begin. Это еще не создает соединения, но инициализирует нас как host в сети.
  • server.begin(); — «включает» наш сервер если так можно выразиться. После вызова этой команды, наш сервер получит возможность прослушивать 80-й порт указанный нами при инициализации объекта.
  • connectToSensor(); — вызывает нашу функцию которая должна найти адрес нашего датчика и записать его в переменную addr;

Ну, осталось самое сложное — вникнуть в void loop(void):

  • updateTemperature(); — наша функция, которая обновляет температуру полученную от сенсора, о ней я уже писал, здесь её просто вызываем
  • EthernetClient client = server.available(); — получаем от сервера объект класса EthernetClient, который содержит в себе методы для работы с подключившемся к нашему серверу клиентом (в нашем случае клиентом будет браузер)
  • if(client) { — проверяем, получили ли мы что либо от метода available(). На самом деле, это нормально не получить ничего и просто снова вернуться в начало функции loop. Так будет происходить все время, пока никто не подсоединиться к нашему серверу. В таком случае сервер будет «в холостую» гонять цикл loop в ожидании клиента.
  • String request; boolean currentLineIsBlank = true; boolean requestLineReceived = false; — если клиент все же нашелся, мы объявляем несколько переменных. Строка request будет содержать в себе первую строчку HTTP запроса — именно она содержит относительный путь ресурса, к которому клиент пытается получить доступ. Исходя их этого относительного пути мы и будем в последствии выполнять те или иные действия. Две других переменных вспомогательные. currentLineIsBlank — помогает нам отловить случай, когда приходит пустая строка запроса — это обозначает окончание запроса и момент времени, когда самое время отправлять ответ клиенту. Вторая переменная requestLineReceived — является флагом, который выставляется в значение true после того, как первая строчка будет получена и записана в упомянутую уже переменную request. Этот флаг обозначает, что последующие строчки запроса можно пропускать, так как они у нас никак не обрабатываются.
  • while(client.connected()){ — цикл, который остановится если клиент отсоединиться так и не дождавшись ответа от нашего сервера. В этом цикле мы будем получать запрос от клиента, а так же формировать ответ.
  • if (client.available()) { — проверяет доступны ли еще данные от клиента. Так как запрос поступает по сети, то может быть и такое, что мы уже обработали все данные которые были доступны, но это еще не является окончание запроса. Тогда описанный ранее цикл while будет крутиться до тех пор, пока новая порция данных не будет получена
  • char c = client.read(); — считываем символ из потока данных доступных от клиента. Далее идет обработка этого символа. 

Описание дальнейших строчек не представляется мне такой уж хорошей идеей, так там переплетается сразу несколько действий и придется часто перепрыгивать с одного куска кода на другой — это ухудшает восприятия. Если описывать суть, то я бы её формулировал следующим образом:В начале в строку request по одному добавляются символы до тех пор, пока мы не встретим символ окончания строки. В результате строка request будет содержать первую строчку полученную нами от клиента. Все остальные строчки запроса клиента пропускаются и мы лишь ожидаем окончание запроса. Напомню, если кто-то так и не читал про http — окончанием запроса является пустая строка. Сразу после окончания запроса клиента мы начинаем разбирать первую строку его запроса помещенную ранее в переменную request. В этой строке нас будет интересовать значение path которое находится между двумя пробелами, после декларации HTTP метода и до обозначения версии протокола.После того, как строка получена, мы начинаем сравнивать её с тремя возможными значениями. Если строка ссылается к корню (иными словами равна «/»), то мы вызываем функцию которая генерирует нам header с 200-м кодом, а потом другой функцией передаем клиенту нашу html страницу. Если же строка равна /switch-on или /switch-off  включаем или выключаем светодиод соответственно, изменяем сведения о его состоянии и перенаправляем пользователя в корень нашего сервера.После этого мы ожидаем одну миллисекунду, чтобы клиент успел получить все данные от нашего сервера с помощью функции delay, и последним шагом закрываем соединение с этим клиентом client.stop();.Вот собственно и весь код. Я даю себе слово, что больше не буду так подробно разбирать код построчно, так как это занимает ну очень много времени. Ладно, продолжим.

Собираем схему

В принципе, эта схема будет практически идентична той, которую мы используем в примере с датчиком, только в этот раз к Arduino будет сверху нахлабучен еще и shield, ну и конечно же добавиться светодиод — куда же без него.

Видео, куда без него

Ничего особенного, поморгали светодиодом, посмотрели температуру. Вот собственно и все, что хотелось рассказать.

С каждым годом платы Arduino применяется во все более сложных проектах, и это связано не с самими платами, а в значительной степени с модулями и чипами, совместимыми с 8-битными процессорами.

Сегодня мы более подробно рассмотрим шилд (shield), то есть плату расширение для Arduino Nano. Этот шилд оснащен чипом ENC28J60, который занимается обработкой данных отправляемых в сеть. При правильном использовании он станет настоящим сетевым комбайном, который будет способен предоставлять данные с датчиков или собирать и выполнять пользовательские рекомендации для всех пользователей целевой сети

Подключение модуля ENC28J60 к плате Ардуино и сети

Подключить шилд ENC28J60 к Arduino чрезвычайно просто. Мы должны установить нашу Arduino Nano в разъем шилда. На фото ниже показано правильное подключение модуля ENC28J60 к плате Arduino Nano.

image

Библиотеки и необходимые материалы

Для запуска модуля ENC28J60 и начала успешного сотрудничества с платой нам понадобится библиотека. Воспользуемся библиотекой EtherCard. Помимо EtherCard, мы можем найти в сети еще несколько библиотек, но, на наш взгляд, эта самая простая в использовании. Предлагаемых в ней функций достаточно для большинства задач.

image Блок питания 0…30 В / 3A Набор для сборки регулируемого блока питания… Подробнее

Библиотеку можно скачать по этой ссылке. Конечно, скаченную библиотеку в IDE Arduino придется установить вручную.

Поэтому проще будет использовать программу установки. Для этого в Arduino IDE перейдите по пути Эскиз/Include Library/Manage libraries, в поле поиска введите EtherCard и нажмите Install для установки библиотеки.

Мы начнем тестировать модуль с загрузки примера backSoon, измененного под наши требования. Данный пример предназначен для подключения к сети и настройки простого веб-сайта, который будет отображать текст. Скетч представлен ​​ниже:

#include   #define STATIC 1  #if STATIC  static byte myip[] = { 192,168,1,200 };// IP-адрес, мы можем выбрать его произвольно  static byte gwip[] = { 192,168,1,1 };// адрес по умолчанию, в нашем случае маршрутизатор  #endif  static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; //indywidualny adres mac płytki  byte Ethernet::buffer[500]; // tcp/ip буфер отправки и приема    const char page[] PROGMEM =  "HTTP/1.0 503 Service Unavailablern"  "Content-Type: text/htmlrn"  "Retry-After: 600rn"  "rn"  ""   ""   " Добро пожаловать на вашу первую страницу "   ""   ""   " На основе этой страницы мы можем создать сайт в локальной сети "   " Ввод текста очень прост, достаточно знать основы HTML "   ""  "";// здесь мы определяем, какая страница будет отображаться    void setup(){   Serial.begin(57600);   Serial.println("n[backSoon]");   if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)   Serial.println( "Failed to access Ethernet controller");  #if STATIC   ether.staticSetup(myip, gwip);  #else   if (!ether.dhcpSetup())   Serial.println("DHCP failed");  #endif   ether.printIp("IP: ", ether.myip);   ether.printIp("GW: ", ether.gwip);   ether.printIp("DNS: ", ether.dnsip);  }  void loop(){   if (ether.packetLoop(ether.packetReceive())) {   memcpy_P(ether.tcpOffset(), page, sizeof page);   ether.httpServerReply(sizeof page - 1);   }  }

Большинство элементов скетча объяснено с помощью комментариев к исходному коду, но стоит сосредоточиться не на самой программе, а на сетевых аспектах. Это может быть неочевидно для людей, которые не имеют ежедневного контакта с настройкой компьютерных сетей.

IP-адрес — это идентификационный номер устройства в сети. IP-адрес используется для правильной связи между другими устройствами. Каждое устройство в сети должно иметь свой индивидуальный IP-адрес, чтобы пересылка пакетов не мешала друг другу.

Если для Вас это совершенно новая тема, то вам нужно сначала определить адреса, используемые в сети. Самый простой способ — подключить компьютер к тому же маршрутизатору, к которому вы подключаете Arduino.

Даже если компьютер подключен к Wi-Fi, домашние маршрутизаторы обычно используют общую адресацию. Поэтому в Windows запустите команду cmd и введите команду ipconfig. Найдите среди результатов IPv4-адрес. Он, как правило, обычно имеет вид 192.168.1.100. Первые три числа обычно представляют собой сетевой адрес, а последнее — адрес устройства.

Мы использовали адрес 192.168.1.200, чтобы получить безопасное расстояние до других устройств в сети, но если у нас есть одно устройство, подключенное к сети, модуль Ethernet может иметь IP 192.168.1.3.

Здесь может возникнуть резонный вопрос, так как в сети всего два устройства, почему бы не дать модулю Ethernet адрес 192.168.1.2?

По одной очень простой причине — адрес 192.168.1.1 является адресом шлюза по умолчанию и назначается маршрутизатору, и этот адрес шлюза по умолчанию отмечен в программе как «gwip».

Последний элемент — это MAC-адрес, помеченный как «mymac», MAC-адрес — это индивидуальный адрес устройства, аналогично IP. Два одинаковых MAC-адреса в сети могут вызвать конфликт пакетов. Так-как у нас в сети только один модуль Ethernet, то нам не о чем беспокоиться.

После загрузки скетча в Arduino, стоит включить Serial Monitor, он будет отображать введенные нами данные. Скорость передачи данных в Serial Monitor должна быть изменена с 9600 на 57600 бод.

image

Когда модуль настроен в соответствии с предоставленными нами адресами, мы должны подключить кабель с разъемом RJ45 к нашему модулю, а другой разъем — к свободному разъему RJ45 в маршрутизаторе. После подключения подождите несколько секунд, затем вернитесь к компьютеру и введите IP-адрес нашего модуля в строке браузера, затем нажмите Enter. Мы должны увидеть страницу, которая выглядит так, как показано ниже:

image

Отображение показаний датчика DS18B20

Для проверки скорости работы программы подключим датчик температуры DS18B20 к контакту 4, благодаря чему мы сможем проверить, как работает отображение данных с датчиков. Датчик подключается к контакту 4. Не забудьте соединить контакт данных и VCC подтягивающим резистором 4,7 кОм. Макет должен быть построен согласно фото ниже:

image

После сборки системы мы можем перейти к программной части. Нам понадобятся библиотеки OneWire, DallasTemperature для поддержки датчика DS18B20 и пакет библиотеки ETHER_28J60 для упрощения работы с датчиком на нашем веб-сайте.

Почему мы используем две разные библиотеки? По одной простой причине — не имеет смысла усложнять себе работу. EtherCard гораздо лучше для использования в типичных сетевых приложениях, однако ETHER_28J60 — гораздо более удобный инструмент для записи разных типов данных на страницу, при этом код будет легче и понятнее.

Установив новый пакет библиотек, мы можем перейти к написанию программы, которая должна выглядеть, как показано ниже:

#include "etherShield.h"  #include "ETHER_28J60.h"  #include   #include   #define ONE_WIRE_BUS 4 // определяем подключение датчика DS18B20  OneWire oneWire(ONE_WIRE_BUS); // запускаем OneWire  static uint8_t mac[6] = {0x74, 0x69, 0x69, 0x2D, 0x30, 0x31}; //adres MAC  static uint8_t ip[4] = {192, 168, 1, 200}; // адрес шлюза по умолчанию  static uint16_t port = 80; // порт данных, для HTML значение должно быть 80  ETHER_28J60 e;  DallasTemperature sensors(&oneWire); // назначаем датчик DS18B20 OneWire  void setup()  {   sensors.begin();   e.setup(mac, ip, port);  }  void loop()  {   sensors.requestTemperatures(); // получаем данные о температуре от DS18B20   float temp = sensors.getTempCByIndex(0); // создаем переменные для значений датчика   if (e.serviceRequest())   {   e.print(" Вот ваш первый сетевой датчик температуры!  ");   e.print("Температура ");   e.print(temp);   e.print(" *C");   e.respond();   }   delay(100);  }

После загрузки программы мы должны увидеть следующее:

image

Мы уже ознакомились с основами этого модуля. Как видите, использование Arduino в сети не так сложно, как может показаться. Кстати, чип ENC28J60 считается самым сложным в программировании и адаптации для правильной работы, поскольку он официально не поддерживается Arduino. Но немного практики и использование соответствующих библиотек даст вам желаемый результат!

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
А как считаете Вы?
Напишите в комментариях, что вы думаете – согласны
ли со статьей или есть что добавить?
Добавить комментарий