Создание собственной сети самодельных устройств на базе Arduino (Часть 1)
Добрый день, хабравчане! Сегодня расскажу вам про интеграцию Arduino с ПК на Windows и другими устройствами. Дело было уже в 2018 году, ко мне наконец-то приехали мои платы Arduino самых разных моделей.
Я давно хотел собрать умный дом, и решил использовать именно эту платформу. Почему? Ну я довольно хорошо знаю C# и немного C++, а как известно, прошивки под Arduino пишутся именно на изменённых плюсах. К тому же платформа имеет цифро-аналоговый преобразователь, что упрощает работу с аналоговыми датчиками. В придачу платформа весьма известна и имеет большую модульную базу.
При всей своей любви к микроконтроллерам, я предпочитаю всё вычислять на винде, а вся моя сила в .NET приложениях. Это и стало моей проблемой. Я просто не мог воспринять среду разработки Arduino IDE. Пришлось привыкать. Однако простые проекты для разминки всё же работали в основном на ПК. Кого заинтересовала тема, прошу под кат!
Моим первым экспериментом стал простой обмен информацией по USB (последовательный порт), через который я отправлял пакеты с простыми командами для выполнения действий на микроконтроллере. Для примера использовал модель Arduino UNO.
Это – интерфейс программы для Windows. «Писк» — подача сигнала на пин (вывод Arduino) под номером 10 постоянного электрического сигнала, который запитывает подключённый мною зуммер. «LED» — подача постоянного тока на пин 13, который по умолчанию на контроллере подключен к встроенному светодиоду, который служит для отладки скетчей (прошивок).
Однако весь этот функционал лежит именно на контроллере.
Что же делает программа? Просто отправляет цифры в порт! «0» — значит отключить
светодиод, «1» — включить светодиод, «2» — отключить зуммер, «3» — включить
зуммер. Делается всё с использованием базовых элементов Windows Forms. Если
кому интересно, для обмена данными используется скорость 115200 бод. Благодаря
этому я могу без проблем просмотреть содержание сообщений от микроконтроллера в
Arduino IDE.
Я думаю, что многим сейчас захотелось узнать, что в прошивке микроконтроллера. Так-как это было относительно давно, искать код прошивки Arduino было не просто, но нужный файл всё-таки нашёлся!
Ели что, это старая версия файла, без зуммера, только со светодиодом.
Однако это – только пример. Единственное – у данной системы должен быть хаб – то есть точка пересечения всех устройств. А это мгновенно разрушит всю децентрализацию системы.
Отсюда вывод – метод использования хаба подходит только для сбора информации и управления. Хаб нужен, например для выхода девайсов в интернет, но не как ключевая точка связи между ними.
Допустим связать все устройства сможем по I2C или по собственному протоколу. Но как скидывать данные в хаб? И вообще, что послужит хабом? Варианта 3:
- Хаб из роутера.
- Хаб из другой Arduino-платы.
- Хаб из Raspberry Pi.
Как видим, данный роутер обладает USB-разъёмом, а по характеристикам видно, что всё крутится на линуксе. Лично им не пользовался, но по характеристикам нам подойдёт. И это НЕ реклама.
В случае с роутером, скидывать данные можно по последовательному порту, как и на Windows, а на линуксе запустить скрипт – обработчик сообщений (простите, если что-то не так называю, просто почти не знаком с линуксом).
Рассмотрим вариант 2. Ещё одна плата Arduino. Здесь уже не подойдут модели Nano, Mini, Micro. Нужна Arduino модели либо UNO, либо MEGA. Но просто так плату не подключить к сети. Как вариант использовать Arduino UNO WI-FI, или что надёжнее Arduino Yun или Tian. Проблемы последних – относительно долгая загрузка и цена, а по функционалу они смахиваю на всё тот-же роутер, ибо работают по линуксом.
Здесь лучше всего использовать так званный «Ethernet Shield». Это плата расширения для Arduino, которая одевается сверху и позволяет поднять на устройстве простой WEB-сервер с простыми PHP-скриптами для обработки информации от других устройств в сети.
Некоторые модели данной платы расширения оборудованы слотом под micro-sd карту памяти, что позволяет помимо удалённого управления вести также локальное логирование.
Вариант 3. Почти аналогичный предыдущему и меньше всего мне нравящийся. Использование микрокомпьютера Raspberry Pi. Именно компьютера. Согласитесь, вешать под эту задачу целый компьютер, пусть и очень слабый – лишняя трата ресурсов. Как денежных, так и вычислительных. Лично я бы если и использовал Raspberry Pi, то только как сервер видеонаблюдения или под готовую программу управления умным домом по типу «Major DoMo» и подобных. Также можно отвести её по такие задачи, как боты в мессенджерах и сложные алгоритмы контроля микроклиматом, ну или в самом маловероятном случае можно поселить туда искусственный интеллект.
Как видим, Raspberry Pi 3 имеет:
- 4 USB-порта;
- 1 Ethernet-порт;
- 1 HDMI-порт;
- Wi-Fi;
- Интерфейс DSI для подключения дисплея Raspberry Pi с сенсорным экраном;
- Слот для micro-sd карт.
Вывод: лично для меня в качестве хаба больше подходит Arduino UNO + Ethernet Shield. Из всех рассмотренных вариантов этот самый дешёвый и простой в реализации.
В такой конфигурации от хаба не зависит работоспособность системы. И пусть даже хаб выйдет из строя, на работоспособность самой сети это не повлияет. Сеть только потеряет выход в интернет.
Работа с массивами и строками
Разберём пример отправки строк в случайном порядке. Любая строка уже является массивом символов. Поэтому вместо типа String, можно использовать массив char[]. Для примера создадим массив из четырёх имён и будем выводить их в случайном порядке через разные промежутки времени, используя функцию random().
Управляем Arduino через USB. Библиотека Serial.
Набор функций Serial служит для связи устройства Ардуино с ПК или другими устройствами, поддерживающими последовательный интерфейс обмена данными. Все платы Arduino имеют хотя бы один последовательный порт (UART). Для обмена данными Serial используют цифровые порты ввод/вывода 0 (RX) и 1 (TX) , а также USB порт. Важно учитывать, что если вы используете функции Serial, то нельзя одновременно с этим использовать пины 0 и 1 для других целей.
Среда разработки Arduino IDE имеет встроенный монитор порта. Для начала обмена данными необходимо запустить монитор нажатием кнопки « Монитор порта » и выставить ту же скорость связи, с которой вызвана функция begin().
Основные функции Serial
- begin()
- end()
- available()
- read()
- flush()
- print()
- println()
- write()
- peek()
В нашем примере мы рассмотрим только часть функция Serial.
Serial.write() – записывает в порт данные в двоичном виде.
Serial.print() — может иметь много значений, но все они служат для вывода информации в удобной для человека форме. Например, если информация, указанная как параметр для передачи, выделена кавычками – терминальная программа выведет ее без изменения. Если вы хотите вывести какое-либо значение в определенной системе исчисления, то необходимо добавить служебное слово: BIN-двоичная, OCT – восьмеричная, DEC – десятичная, HEX – шестнадцатеричная. Например: Serial.print(25,HEX).
Serial.println() делает то же, что и Serial.print(), но еще переводит строку после вывода информации.
SerialEvent() Автоматически вызывается при поступлении новых данных.
Serial.begin() Инициирует последовательное соединение и задает скорость передачи данных вбит/c (бод). Для обмена данными с компьютером используйте следующие значения: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 или 115200.
Первое что мы с вами сделаем это будем управлять встроенным светодиодом на плату Arduino который подключен к 13 пину.
В монитор порта ни какой информации не возвращается. Также можно вывести в монитор порта информацию полученную от Arduino.
При включении светодиода выведем: « Светодиод вкл .». И также выведем слово « Portal-Pk.ru», с переносом строки. Чтобы следующая запись выводилась строчкой ниже.
При выключении светодиода выведем: «Светодиод выкл.». И также выведем слово «Portal-Pk.ru» с переносом строки.
Данный инструмент помогает при отладки программы . В монитор порта модно вывести состояние оборудования, на коком этапе выводит ошибку и пр.
Функции библиотеки Serial
Описание
Инициирует последовательное соединение, а также задает скорость передачи данных. Скорость измеряется в бит/с (бод). Для обмена данных с компьютером через USB используются значения из следующего списка: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 и 115200. При подключении двух устройств через пины RX и TX, могут использоваться любые другие значения.
Синтаксис
Serial.begin(speed)
Serial.begin(speed, config)
Параметры
speed — скорость передачи данных
config — необязательный параметр, устанавливает данные, четность и стоповые биты
Возвращаемое значение
Пример
Отправка и парсинг Serial
Данный урок переехал из урока о мониторе порта, рекомендуется сначала изучить его. Стандартные инструменты “библиотеки” Serial позволяют отправлять и принимать данные по интерфейсу UART. Здесь мы рассмотрим некоторые алгоритмы и протоколы связи, чтобы наладить управление программой через монитор порта в ручном режиме, или использовать для этого специальные программы, а также приложение на смартфоне и Bluetooth-UART модули. Между двумя Ардуинами, или между Ардуино и другим МК (esp8266, STM32) можно общаться по Serial. Для этого нужно соединить их следующим образом:
- Соединить GND, ибо сигнал не ходит по одному проводу.
- Для односторонней связи соединить дата-пины у отправителя -> приёмника как TX -> RX.
- Сериал может быть как аппаратный (пины подписаны на плате), так и программный, например встроенная библиотека SoftwareSerial.h. У неё пины указываются вручную.
- Внимание! Если прошивка загружается через аппаратный юарт, например TX RX на Arduino Nano, то пин RX нужно освободить, иначе прошивка не загрузится.
Для передачи данных между платами можно использовать разобранные выше функции и разобранные ниже алгоритмы, но я хочу показать вам один особенно удобный способ передачи структур данных при помощи стандартных средств ядра Ардуино. Напомню, структура представляет собой набор данных из любых типов, что очень удобно для передачи разных данных. Отправка данных осуществляется при помощи Serial.write(байтовый буфер, размер) , а приём – при помощи Serial.readBytes(байтовый буфер, размер) . Минус readBytes заключается в том, что она блокирующая: выполнение кода не идёт дальше, пока функция не примет указанное количество байт или не завершит работу по таймауту, про таймаут написано выше в этом уроке. Обе функции принимают байтовый буфер, но мы с вами знаем про указатели и их типы, поэтому можем обманом (byte*) заманить структуру в отправку и чтение. Ниже показываю примеры как отправить и принять структуру с одной Ардуины на другую при помощи SoftwareSerial, таким же образом можно использовать обычный аппаратный Serial. Также поделюсь примером отправки и чтения с контролем целостности данных – CRC, который сильно повышает надёжность передачи: позволит распознать ошибку в пакете, если хоть один бит был передан или принят неправильно. Примеры будут работать на любых Ардуино-совместимых платах, в том числе на базе esp8266. С ней есть некоторые особенности, о них расскажу ниже.
При использовании описанного выше способа для отправки данных на esp или обратно нужно помнить о некоторых особенностях памяти в esp:
- Тип данных int занимает на esp 4 байта, то есть Ардуина должна принимать этот тип как long .
- Компилятор esp очень странно пакует байты в структуру, поэтому однобайтные типы данных нужно размещать в конце структуры. Например так:
Just for duino
В этой статье рассказывается о том, как написать простую программу реализующую обмен данными между компьютером и ардуино. Речь идет о программе для ПК. Конечно можно пользоваться готовыми программами. Однако своя программа может значительно лучше подходить для конкретного проекта. Схема и код для ардуино здесь
Программа будет писаться на python. Этот язык является open source проектом. Есть версии интерпретатора python для различных платформ. Если в программе написанной на python не используются специфические возможности конкретной платформы, то эта программа будет работать везде, где установлен интерпретатор python.
Начать нужно с установки интерпретатора. Для windows его можно найти перейдя по ссылке http://python.org/downloads/windows/ Я использую python 2.7 Вот только для работы с ардуино этого недостаточно. Еще необходимо установить модуль http://pyserial.sourceforge.net/ Есть несколько версий под разные платформы. Тут главное не перепутать 🙂
Привожу текст программы
Откройте «блокнот» (notepad), вставте текст программы, сохраните документ с расширением .py Всё. Но работать в специализированном редакторе намного приятнее.
Чтобы запустить программу, нужно кликнуть правой кнопкой мышки на файле. В открывшемся меню следует навести курсор мышки на пункт «открыть с помощью». И там уже кликнуть левой кнопкой мышки на «python».
Есть еще один вариант. Запускаете программу «командная строка» (cmd). И там пишите, что то вроде
Первой частью этой строки выполняется запуск интерпретатора. Вторая часть строки сообщает интерпретатору, где находится текст программы.
Теперь нажимаете enter и наслаждаетесь результатом.
Ардуино должна быть уже подключена к компьютеру. В противном случае программа завершит работу не сумев связаться с платой.
А так выглядит работа программы
Завершается работа программы нажатием Ctrl + C
Далее я постараюсь дать более подробные пояснения по программе. Если ничего не заработало, то прочтение оставшейся части статьи должно помочь найти и исправить неточности.
Сразу скажу о том, что отступы в python делают не для красоты. Это необходимые элементы языка. В python они выполняют ту же функцию, что и фигурные скобки в C/C++. Правда есть некоторые нюансы.
Эта строка кода нужна для того, чтобы программа выполнялась, например, в linux. В windows она не нужна, но она и не мешает.
Эта строка сообщает компилятору о том, в какой кодировке записана программа. У меня это windows1251.
Этой строчкой выполняется подключение к проекту модуля serial. Он необходим для работы с COM портами.
Здесь производится открытие порта COM14. Именно этот порт моя windows предоставила Arduino Uno. Номер порта можно узнать в Arduino IDE. Для обмена данными используется тот же порт, что и для загрузки скетча в ардуино. Только в программе на питоне используется один номер. Без COM. И нумерация начинается с ноля. Таким образом, COM1 соответствует номер 0. И так далее. Скорость обмена данными составляет 9600 bps. Данные передаются по восемь бит (один байт). Бит паритета не используется. Завершается передача данных одним стоп битом. Всё как в программе для ардуино. В противном случае компьютер и ардуино не поймут друг друга. Последний параметр определяет время в течении которого программа будет ждать поступления данных от ардуино. Я установил время ожидания в одну секунду.
Этот фрагмент программы является примером использования отступов в эстетических целях. Один из тех самых нюансов про которые я говорил чуть выше.
Этой строчкой на экран выводится информация об открытом порте. Она включена в программу с ознакомительными целями.
Элемент обработки исключений в python.
Этим кодом формируется строка запроса. Данные введенные пользователем помещаются в переменную data.
Здесь предусматривается обработка исключения возникающего при нажатии Ctrl + C
Выход из бесконечного цикла.
Этой строкой выполняется передача данных через COM порт.
Полученные от ардуино данные записываются в переменную data.
Переменная data выводится на монитор.
Здесь порт закрывается.
Еще нужно сказать, что комментарии в python начинаются с символа ‘#’ Это то же самое, что ‘//’ в C/C++.