Автомобиль с видеокамерой. Управление через WiFi. Создаем Android-приложение для управления домашним роботом через Bluetooth

Вайбер на компьютер 10.07.2019
Вайбер на компьютер

В этой статье информация о том как собрать свой танк, оснащенный Web Камерой и управляемый посредством Wifi роутера.

Необходимые материалы:

  1. Web Camera
  2. Роутер TP-Link TL-MR3020
  3. Сервоприводы SG90 - 2шт
  4. Camera Platform Anti-Vibration
  5. Аккумулятор 7.2V 5000mah
  6. Аккумулятор 5V 2000mah
  7. Nano 3.0 Atmel ATmega328
  8. L298N motor driver
  9. Провода, термотрубки, USB хаб, диоды и другое.
  10. Платформа на ваш вкус, я выбрал DD1-1

Сборка нашего монстра
Настройка Роутера MR3020.
Первым делом начнем с роутера. Я долго думал что выбрать OR-WRT или CyberWRT. OR-WRT гибок в настройках, но все редактирование и внесения своих настроек осуществляется через терминал с помощи программы Putty. А так как Я боялся на тот момет работать через терминал, Я выбрал где есть графический интерфейс это CyberWRT, плюс возможно подключение через USB порт.
Для того что бы изменить прошивку нашего роутера, нужно скачать прошивку CyberWrt MR3020.

Как мы скачали, делаем следующее:

1) Включить роутер и подождать загрузки.
2) Зайти и залогиниться на 192.168.0.254 (по умолчанию admin\admin)
3) Найти в меню слева System Tools, там пункт System Upgrade и залить прошивку через веб-форму
4) Дождаться перезагрузки (порядка 4х минут)
Роутер готов к настройке.

Можно выбрать один из режимов: «Точка доступа» и «Клиент Wi-Fi сети». Для настройки режима Клиента:
- выберите режим «Клиент Wi-Fi сети»
- IP адрес Вашего устройства (по этому адресу будет доступно Ваше устройство. Постарайтесь выбрать незанятый IP. Например: 192.168.1.100)
- Маска подсети (255.255.255.0)
- Шлюз (например, IP Вашего домашнего роутера или шлюза - 192.168.1.1)
- Тип шифрования (тип шифрования, используемый в Вашей домашней сети)
- Пароль (пароль, для доступа к Вашей домашней сети)

Если сделали все правильно, то у вас пойдет RSS строка в нижней части экрана.

Когда все заработала, у вас появятся раздел модули, там вы находите модуль "РОБОТ". Устанавливайте. Готово.

Подключение L298N, Arduino Nano, MR3020, Камера и другое

На картинке все наглядно показано, но на всякий случай напишу.

Вывод Arduino DIGITAL 4 - к IN1 пину модуля.
Вывод Arduino DIGITAL 5 - к IN2 пину модуля.
Вывод Arduino DIGITAL 6 - к IN3 пину модуля.
Вывод Arduino DIGITAL 7 - к IN4 пину модуля.
Вывод Arduino GND - к GND клеме модуля.
GND клема модуля - Минус аккумулятора.
7.2V клема модуля - Плюс аккумулятора.
RM клема модуля - Правый моторчик.
LM клема модуля - Левый моторчик.
USB порт Arduino - Подключаем к USB хаб
Web Камера - Подключаем к USB хаб
USB хаб - Подключаем к USB роутера

Питание так скажем логистики, осуществляется вторым аккумулятором. Емкость 2000 mA/h 5v, дабы не спалить роутер. Да и с двумя аккумуляторами робот стабильней работает. Так вот, его мы подключаем просто в разъем микро USB. Через USB хаб который подключен к роутету питанию уже получает и камера и наша ардуинка.

Скетч для Arduino Nano
Вам необходима скачать библиотеку CyberLib , она предназначена только для Atmega 328.

/* Версия 1.5 WIFI Tanka на DD1-1 Реализовано: 1) Движение камеры по X и Y 2) Гудок 3) Фары 4) Звук при включении */ #include // Подключаем библиотеку #include // Подключаем библиотеку сервоприводов Servo myservo1; Servo myservo2; long previousMillis; // Нужно для таймера int LedStep = 0; // Счетчик для LED int i; #define robot_go {D4_High; D5_Low; D6_Low; D7_High;} #define robot_back {D4_Low; D5_High; D6_High; D7_Low;} #define robot_stop {D4_Low; D5_Low; D6_Low; D7_Low;} #define robot_rotation_right {D4_High; D5_Low; D6_High; D7_Low;} #define robot_rotation_left {D4_Low; D5_High; D6_Low; D7_High;} #define LED_ON {D13_High;} #define LED_OFF {D13_Low;} #define Headlamp_ON {D8_Low;} #define Headlamp_OFF {D8_High;} #define Buzzer {tone(11, 494, 500);} #define init {D4_Out; D5_Out; D6_Out; D7_Out; D8_Out; D13_Out;} uint8_t inByte; void setup() { myservo1.attach(9); // Подключение сервоприводов к порту myservo2.attach(10); // Подключение сервоприводов к порту D11_Out; D11_Low; // Динамик Headlamp_OFF; // Фары выкл по умолчанию for(uint8_t i=0; i<12; i++) beep(80, random(100, 2000)); //звуковое оповещение готовности робота init; // Инициализация портов //Buzzer; // Инициализация портов динамика UART_Init(57600);// Инициализация порта для связи с роутером wdt_enable (WDTO_500MS); } void loop() { unsigned long currentMillis = millis(); // Обновление таймера if (LedStep == 0 && currentMillis - previousMillis > 500){ // Задержка 0,5 сек. previousMillis = currentMillis; // обновление таймер LED_ON; // Включить LedStep = 1; // Счетчик шагов } if (LedStep == 1 && currentMillis - previousMillis > 500){ // Задержка 0,5 сек. previousMillis = currentMillis; // обновление таймер LED_OFF; // Выключить LedStep = 2; // Счетчик шагов } if (LedStep == 2 && currentMillis - previousMillis > 500){ // Задержка 0,5 сек. LedStep = 0; // Счетчик шагов } if (UART_ReadByte(inByte)) //Еесли что то пришло { switch (inByte) // Смотрим какая команда пришла { case "x": // Остоновка робота robot_stop; break; case "W": // Движение вперед robot_go; break; case "D": // Повопорт влево robot_rotation_left; break; case "A": // Поворот вправо robot_rotation_right; break; case "S": // Движение назад robot_back; break; case "U": // Серво поднимается myservo1.write(i -= 20); break; case "J": // Серво опускается myservo1.write(i += 20); break; case "H": // Серво поворачивается влево myservo2.write(i += 20); break; case "K": // Серво поворачивается вправо myservo2.write(i -= 20); break; case "Y": // Серво поворачивается 85 myservo1.write(85); myservo2.write(85); break; case "F": // Включить фары Headlamp_ON; break; case "V": // Выключить фары Headlamp_OFF; break; case "I": // Гудок Buzzer; break; } } wdt_reset(); }

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

Машинка на arduino и Bluetooth без редактирования кода. Мы будем использовать специализированный бесплатный софт для составления скетча. Кроме того не надо покупать шасси для нашей поделки, подойдет практически любая неисправная радиоуправляемая модель автомобиля или танка.

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

Итак, давайте разберем на живом примере как сделать своими руками дистанционно управляемую по bluetooth c android планшета или смартфона машинку. Статья, как ни странно, рассчитана на начальный уровень знаний. Здесь нет руководства по редактированию кода в Arduino IDE, да и мы использовать его будем только для заливки нашего кода. А составлять алгоритм управления будем в программе под названием FLProg. Программа управления со смартфона — HmiKaskada_free. Но сначала о железе, которое нам понадобится.

Машинка на arduino и Bluetooth — аппаратная часть.

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

Для управления электродвигателями нашего будущего творения понадобится Н-мост на микросхеме L298N Ссылка на Али, я брал у именно этот. Картинка кликабельна.

Н-мост для arduino

Может управлять двумя двигателями в диапазоне напряжений 5 — 35 вольт. Поддерживает ШИМ, то есть можно регулировать обороты двигателей. На плате есть вывод стабилизированного напряжения 5 вольт для питания ардуино.

Схема подключения проста и незатейлива:

Следующей неотъемлемой частью электронной начинки нашего проекта является bluetooth модуль HC-06 . Самый обычный модуль для ардуино, настолько популярен что в дополнительном описании не нуждается.

HC-06 bluetooth for arduino

Основным элементом и мозгом в моем случае выступает arduino nano , тут даже фото выкладывать не буду ибо все о ней знают и умеют с ней работать. Кстати подойдет любая плата ардуино, лишь бы в корпус поместилась 😀

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

Машинка на arduino и Bluetooth — составление скетча.

Повторюсь — никакого копания в коде тут не будет. Мы будем использовать популярную программу FLProg. Скачать ее последнюю версию можно на официальном сайте . Интерфейс проги прост и незатейлив, но имеется огромный функционал и поддержка практически всех популярных модулей. Как ей пользоваться писать не буду так как это потянет на пару статей. Скажу только что я не встречал более удобной и доступной программы для составления скетчей для arduino и ее клонов. Скрин интерфейса:

Интерфейс FLProg

На сайте полно текстовых и видео мануалов, думаю разберетесь.

Мой проект для дистанционно-управляемой машины можно скачать с яндекс-диска через сервис сокращения ссылок.

Машинка на arduino и Bluetooth — интерфейс управления на планшете android.

По многочисленным просьбам написал подробную инструкцию по разработке интерфейса управления на базе HmiKaskada android в статье . Ссылка кликабельна.

Для устройств под управлением android существует программа HmiKaskada (ссылка на ЯндексДиск) . Изначально она разрабатывалась как альтернатива дорогим промышленным HMI панелям. Но пытливые умы быстро смекнули что управлять она может чем угодно. В нашем случае машинкой. Поддерживает беспроводные интерфейсы Wi-Fi и Bluetooth, кроме того можно девайс подключить напрямую через USB.

Есть платная и бесплатная версии программы. У меня есть обе но я принципиально сделал проект в бесплатной версии что бы показать вам и в очередной раз убедиться в абсолютной работоспособности free версии. Основное отличие free от PRO версий это работа только по блютуз.

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

Как и многие другие самоделкины, я регулярно использую микроконтроллеры AVR для всяких разных любительских поделок. А благодаря концепции «Arduino» эти поделки теперь приобретают еще и элегантный вид. Действительно, за какие-то 300-400 рублей мы получаем миниатюрную многослойную плату с маской, шелкографией и с полностью разведенной на ней периферией для микроконтроллера (причем в SMD исполнении!). Я уже не говорю о всевозможных подключаемых модулях этой же «Arduino» серии: датчиках, контролерах, дисплеях и целых наборов, так нужной нам дополнительной периферии. И опять же всё также недорогих и в прекрасном исполнении. Практически уже нет необходимости, что-то разводить и допаивать на «коленке».­­­­­­­­­

Но все эти разнообразные любительские поделки, требуют естественно, предварительного программирования. Да и в последующем при разных усовершенствованиях, постоянно приходится эти поделки перепрошивать . Понятное дело, что удобнее делать это дистанционно, чем постоянно таскать их к обычному программатору. Вообще, благодаря той же платформе «Arduino», вариантов и здесь много: Bluetooth, ZigBee, радиоканал с вашим личным протоколом, IR, и даже Wi-Fi. Все они позволяют наладить беспроводной контакт с вашим микроконтроллером. Но мы же остановимся на последнем варианте. Основных причин здесь четыре:

1: современно, интернет вещей же!

2: беспроводной роутер есть в каждой квартире, регистрируй в домашней сети свои устройства и вуаля!

3: ваши поделки осуществляют революционный скачок в своём развитии; мало того, что их можно программировать на расстоянии, они теперь ещё и сами могут общаться с окружающим их миром: электронные часы самостоятельно берут точное время с часовых NTP-серверов, исполнительные устройства управляются с другого конца города или страны, регистрирующие девайсы сохраняют накопленные данные в облако и т.д. и т.п.

4: есть замечательная серия микросхем ESP8266 на которой не очень легко всё это реализовать.

Далее, в этой статье на примере механической руки на сервоприводах - будет разобрано и продемонстрировано удаленное программирование и обмен данными с ПК (или чего угодно) с устройствами на базе AVR микроконтроллеров. Сразу же хочу отметить, что все программы приведенные в дальнейшем являются чисто демонстрационными и никакой коммерческой ценности не имеют. Поэтому претензии, типа, почему программатор такой кастрированный и мало функциональный или почему нет дополнительных сервисов, которые есть везде, не принимаются. Поскольку коды открытые, любой желающий может допилить их по своему усмотрению, мне же для работы, пока хватает и таких.

Предполагается, что читатель уже знаком и с «Arduino» модулями (шилдами) и с подключением и прошивкой ESP8266. На самом деле в Сети выложено огромное количество материалов разъясняющих азы работы с этими девайсами и мне не хотелось бы здесь повторяться. Для новичков в конце статьи есть перечень полезных ссылок по этим вопросам, где можно найти кучу информации, почему это всё у вас не работает. По своему опыту бывшего инженера электронщика могу ответственно заявить, что 99 % неполадок сводится к следующему:

1. Плохие контакты. Поскольку «Arduino» шилды, подразумевают коммутацию с друг другом через провода вида «папа-мама», а не через пайку, то очень часто что-нибудь, где-нибудь, да отходит. Проверяйте. Да и вообще, как говорится, электроника это наука о контактах.

2. Проблемы с питанием. Не подавайте 5 вольт питания туда, где требуется 3.3. Иногда из ESP8266 от этого идёт дым. Хотя с другой стороны логические сигналы от пятивольтовых устройств она переваривает без проблем.

3. Проблемы с достаточной мощностью питания. ESP8266 имеет подлую натуру и иногда может потреблять чуть ли не триста миллиампер, хотя до этого могла удовлетворяться и тридцатью. Соответственно хилый стабилизатор 3.3 вольт платы «Arduino», к которому вы ничтоже сумняшеся, её подключили, тут же просаживается до микроскопических значений. А вы не можете понять, почему оно, то работает, то нет.

4. Путаница с выводами. Всегда проверяйте, какие сигналы куда идут. Приемник RXD должен соединяться с передатчиком TXD, также как и TXD с RXD, но MOSI должно соединяться с MOSI, а MISO с MISO и так далее.

5. Не рассчитывайте на внутрисхемные подтягивающие резисторы в ESP8266, всегда подтягивайте выводы к нулю или питанию, через 5-10 килоомные внешние резисторы, а не просто перемычкой. Иначе можете в лучшем случае получить невиданный доселе ток потребления, а потом обонять неприятный запах горелого пластика.

6. Косяки программного обеспечения. Поскольку ПО для индивидуальных юзеров пишется таким же энтузиастами, то периодически вылазят глюки самих прошивок и баги при обновлении версий этих же прошивок. Лечится ползанием по соответствующим форумам, иногда даже англоязычным. Некоторые товарищи даже утверждали, что и сама микросхема ESP сырая как погода в Питере, но с другой стороны существует также мнение что с 2014 (года её первого выпуска) ситуация с этим кардинально улучшилась (в отличие от погоды).

7. Загадочные глюки. Это редкое, но нервопотребляющее явление. У меня к примеру, не шилось удалённо одно «Arduino»устройство. Вернее шилось но с ошибками. Но шилось без ошибок, если на нем висел шлейф от программатора (но без самого программатора). «АГА», сказал я себе и припаял конденсатор 15 пФ, между выводом передачи данных и выводом синхронизации. Всё заработало. Но день убил.

Итак, давайте начнем с самого простого. У нас есть механическая конечность MechArm (но не такая какую собрал Говард Воловитс) сделанная в Китае и персональный компьютер с Windows. Задача - удаленная прошивка программы и управление ея с компьютера.


Для управляющего контроллера возьмем симпатичную миниатюрную платку Arduino Nano c камнем ATmega328P. Эта плата прекрасно впихивается внутрь механической руки.


Теперь определимся каким образом мы её будем программировать. Существуют три основных способа наиболее подходящих для удаленной прошивки: через интерфейс SPI, через встроенный загрузчик, через порт JTAG.

Самый простой вариант, это конечно встроенный загрузчик (бутлоадер). Это заранее прописанная во FLASH память, программа, которая по определенному протоколу получает код, (допустим по самому простому UART) и специальными командами записывает его в место расположения загружаемой программы. Так работает, например, сам загрузчик ARDUINO IDE. После сброса или старта, загрузчик ждет какое-то время данные на приём и если не дожидается начинает исполнение программы с нулевого адреса. Если данные приходят, он пишет их в программную секцию. После следующего сброса загруженная программа начинает исполняться. В деталях, возможно, я описал неточно, но суть именно такая. В итоге нам требуется всего три вывода для программирования: приемник RTD, сброс RESET и земля GND. Вообще, используется еще и передатчик TRD, для верификации записанной программы, но для простых демонстрационных приложений (не для атомной электростанции), проверку можно опустить.

Сам загрузчик пишется на языке ассемблера, есть примеры простых загрузчиков в даташитах на AVR. Можно раскопать существующий уже загрузчик, если он в открытом доступе и просто использовать его в готовом виде, если известен протокол по которому он работает. Единственный нюанс, что для этого требуется настроить AVR в специальный режим, путем прошивки специальных фьюз-битов, что делается обычным программатором, а потом им же зашить сам загрузчик в память микроконтроллера (то есть без программатора один раз все равно не обойтись).

Второй вариант, это программирование по последовательному интерфейсу SPI. Тут уж внутреннего загрузчика нет, а программируем мы, посылая специальные команды и затем данные, по вышеупомянутому интерфейсу. Здесь у нас загрузчик уже внешний, но его все равно писать надо. При передаче используются в добавление к RESET и GND уже четыре дополнительных вывода MOSI, MISO - данные, SLK синхронизация, СS - выбор кристалла. Но вообще также можно убрать MISO и СS. Данные будут только приниматься (верификации программы тогда не будет), а кристалл у нас и так всего один.

У каждого подхода есть свои плюсы и минусы (а JTAG я вообще не рассматривал, поскольку жизнь человеческая коротка). Но в итоге я склонился к SPI поскольку на ассемблере писать было лень, а открытых готовых загрузчиков я не нашел (просто хорошо не искал).

Для построения беспроводного канала я, как уже говорилось, выбрал крайне широко известную в настоящее время микросхему ESP8266 - микроконтроллер, а точнее целый SoC (System-on-Chip) китайского производителя Espressif с интерфейсом Wi-Fi. Помимо Wi-Fi он отличается возможностью исполнять программы из внешней флэш-памяти. А конкретно для своего проекта я взял ESP8266-07 с 512 Кб памяти на борту.


Вообще годится любая ESP8266, где есть лишние ноги для реализации SPI. Поэтому самая простая ESP8266-01 нам не подойдет, так как у неё разведено совсем мало ножек для портов ввода-вывода. Но с другой стороны разница в цене на них меньше ста рублей, а доступны они одинаково. Ну и большие отладочные платы с ESP, где для удобства разведена куча периферии, нам тоже не годятся, так как не влазят, туда куда мы их хотим впихнуть, в нашу механическую руку.

Глобальная суть идеи в общем была такова. С компьютера на ESP без проводов по WI-FI (в рамках вашей домашней сети) передается тело загружаемой в микроконтроллер программы. А ESP уже по проводам с использованием интерфейса SPI записывает эту программу непосредственно во FLASH память микроконтроллера. Потом естественно сбрасывает его и дает возможность загруженной программе выполняться. Кроме того в ESP должен быть независимый блок, который заведует еще и обменом данными с микроконтроллером, так как мы хотим не только программировать, ни и еще обмениваться с ним данными. В частности для проекта с MechArm, после записи программы, мы ещё передаем сигналы управления сервоприводами, дабы привесть эту руку в движение. Поэтому на самой ESP нам желательно поднять TCP сервер для передачи программы и UDP сервер для управления MechArm. Соответственно эти серверы присоединяются к домашней сети и внимательно слушают, нет ли там желающих загрузить новый код в MechaArm или помахать кому-нибудь ею.

Так-то, я нашел в Сети, прошивки уже позволяющие производить программирование AVR по воздуху, но там главная проблема в том, что для чего другого эту прошивку использовать уже нельзя. А нам хотелось бы после программирования и общаться с AVR также удаленно.

Какое ПО мы будем использовать:

Для ПК, я писал всё на JAVA, среда IntelliJ IDEA . Но в принципе, можно на чём угодно, нам там главное написать клиент, который будет отправлять программу для прошивки AVR на ESP8266.

Сами программки для AVR я пишу в ATMEL STUDIO , на языке С, редко на ассемблере. Скетчи Arduino не использую принципиально, практически любая нужная библиотека пишется за час другой, причем с полным пониманием её работы. Я пробовал скетчи, но пока у вас нет на AVR операционной системы, скетчи так и будут отбирать у друга периферию и регулярно глючить. Да сама IDE Arduino по сравнению с ATMEL STUDIO, конечно вещь весьма примитивная. Но тут вопрос, конечно, спорный, гуманитариям и школьникам веселее и проще будет, наверное, со скетчами.

Для программирования ESP8266 я использовал прошивку NodeMCU, а программы писал на языке Lua. Нет, я бы с удовольствием писал бы на Java и на С, но их же на ESP нет. Luа язык в применении к нашей задаче не сложный, освоить его пара пустяков. А собственно для загрузки программ и их отладки на ESP, я взял IDE ESPlorer . Отечественный бесплатный продукт (но можете сделать автору donation), который конечно не сравнить со средами упомянутыми выше, но как говорится дарёному коню… Но чтобы пользоваться ESPlorer и писать на LUA, нам сначала необходимо сменить в микросхеме ESP8266 базовую прошивку (поставляемую от производителя) на новую. В этом предприятии нам поможет программа NODE MCU PyFlasher. В смысле, поможет её перепрошить. А саму прошивку мы сами создадим и получим в руки на сайте создателей: NodeMCU .А более подробно об этом процессе вы можете прочесть

Всё очень доступно и понятно. К базовым библиотекам добавляем поддержку SPI и битовые операции (в LUA в нашем случае битовые операции перегружены и от них мало толку). Много в прошивку библиотек пихать не следует, так как из-за наличия всякого разнообразного софта на ESP8266 остается совсем мало памяти, какие-то жалкие 20 кБ.

Конечно, вы можете просто взять готовую прошивку, коих много уже болтается в Интернете, но не рекомендую. Хотя бы потому, что на некоторых нет поддержки битовых операции (а они нам нужны) и нет регулирования скорости передачи данных по SPI.
Соответственно, они передаются по умолчанию со скоростью 40 Мгц делённые на какой-то небольшой коэффициент и поэтому AVR их переваривать не успевает.

Кому лень создавать прошивку можете скачать мою из облака .

Теперь у нас есть прошивка и нам надо загрузить её в ESP8266 вместо базовой. Для этого нам пригодится простейший адаптер USB - UART.


Присоединяем ножки TXD к RXD, а RXD к TXD, делаем общей землю, но не используем, как казалось, удобный вывод питания 3.3 В на адаптере. В большинстве случаев ESP8266 просадит его напрочь. Поэтому запитываем ёё отдельно. Потом переводим ESP в режим программирования (GP0 на землю, если кто забыл) и запускаем NODE MCU PyFlasher .

Главное, не забудьте стереть флэш-память (yes, wipes all data), иначе в зависимости от версии прошивки после программирования в памяти может остаться ненужный мусор, который в свою очередь будет сыпать мусор в консоль при дальнейшей работе. До этого я использовал софт, где не было опции стереть предварительно память, намучался жутко, так как ничего не работало. А ларчик просто открывался, только правда на англоязычном форуме создателей NODE MCU.

Заимев же нужную прошивку мы теперь можем писать и отлаживать программы на языке LUA (там еще MicroPython, но я им не пользовался) используя при этом очень удобные API от NODE MCU. Запускаем уже упомянутый ранее ESPlorer.

Также настраиваем его для работы с ESP8266, устанавливаем параметры последовательного соединения. Всё достаточно просто и многократно изложено в Интернете.

Теперь пишем программульку на LUA, кою потом загрузим в ESP8266:

Загрузчик Lua для AVR, записываемый в ESP8266

function InstrProgrammingEnable () -- instruction for MC "enable programming" p=0 while p<31 do p=p+1 pin=8 gpio.write(pin, gpio.LOW) spi.send(1, 0xAC,0x53) read = spi.recv(1, 8) spi.send(1,0,0) gpio.write(pin, gpio.HIGH) if (string.byte(read)== 83) then print("connection established") p=33 if(p==31) then print("no connection") end end end end function ProgrammingDisable () pin=2--END OF ESET FOR MK gpio.mode(pin, gpio.INPUT) pin=8 gpio.mode(pin, gpio.INPUT) pin=5--CLK MASTER for SPI gpio.mode(pin, gpio.INPUT) pin=6--MISO MASTER for SPI gpio.mode(pin, gpio.INPUT) pin=7--MOSI MASTER for SPI gpio.mode(pin, gpio.INPUT) end function ProgrammingEnable () pin=2-- RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) pin=2--POZITIV FOR 4MSEC RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) tmr.delay(4) gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) tmr.delay(25000) end function InstrFlashErase() pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0xAC,0x80,0,0) gpio.write(pin, gpio.HIGH) tmr.delay(15000) pin=2--RESET FOR MK gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) tmr.delay(20000) gpio.write(pin, gpio.LOW) print("FLASH is erased") InstrProgrammingEnable () end function InstrStorePAGE(H, address, data) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,H,0,address,data) gpio.write(pin, gpio.HIGH) tmr.delay(500) end function InstrWriteFLASH(page_address_low,page_address_high) pin=8 gpio.write(pin, gpio.LOW) spi.send(1,0x4C,page_address_high,page_address_low,0) gpio.write(pin, gpio.HIGH) tmr.delay(5000)-- иногда не прописываются флэш при малых задержках end function Programming (payload) pin=8--CS MASTER for SPI gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP) pin=4--LED LIGHTS ON LOW gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.LOW) print(string.len(payload)) page_count = 7 -- пишем 1 килобайт for k =0 ,page_count ,1 do--quantity of pages for i=0 , 127, 2 do-- -1 address = i/2 data=payload:byte(i+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x40,address,data) -- tmr.delay(100)-- otherwise not in time write data =payload:byte(i+1+1+128*k) if data == nil then data = 0xff end InstrStorePAGE(0x48,address,data) -- tmr.delay(100) end page_address_low=bit.band(k ,3)*64 -- 3 это двоичное 11 page_address_high=k/4+frame1024*2 tmr.delay(1000) InstrWriteFLASH(page_address_low,page_address_high) tmr.wdclr() end pin=4--LED gpio.mode(pin, gpio.OUTPUT) gpio.write(pin, gpio.HIGH) end --MAIN BLOCK wifi.setmode(wifi.STATION) --wifi.sta.config("имя сети","пароль") -- set SSID and password of your access point station_cfg={} tmr.delay(30000) station_cfg.ssid="имя сети" tmr.delay(30000) station_cfg.pwd="пароль" tmr.delay(30000) wifi.sta.config(station_cfg) tmr.delay(30000) wifi.sta.connect() tmr.delay(1000000) print(wifi.sta.status()) print(wifi.sta.getip()) while (wifi.sta.status()~=1) do if(wifi.sta.status()==5) then break end end sv=net.createServer(net.TCP,30) tmr.delay(100) print("SERVER READY") sv:listen(4000,function(c) c:on("receive", function(c, payload) print(payload) if (payload =="program\r\n") then c:send("ready\r\n") print("ready for program\r\n") spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8,320,spi.FULLDUPLEX) ProgrammingEnable () tmr.delay(100) InstrProgrammingEnable () tmr.delay(100) InstrFlashErase() tmr.delay(100) frame1024=0--номер переданого фрей мов st=net.createServer(net.TCP,30) st:listen(4001,function(c) c:on("receive", function(c, payload) tmr.wdclr() Programming (payload) frame1024=frame1024+1 end) end) end if (payload =="data\r\n") then c:send("ready\r\n") print("ready for data\r\n") srv=net.createServer(net.UDP) tmr.delay(1000) pin=10 gpio.write(pin, gpio.HIGH) uart.setup(0,9600,8,0,1,0) srv:listen(5000) srv:on("receive", function(srv, pl) pl=pl*1 --print(pl) uart.write(0,pl) tmr.wdclr() end) end if (payload =="stop\r\n") then if(st~=nil) then st:close() frame1024=0 ProgrammingDisable () print("stop program") end if(srv~=nil) then srv:close() print("stop data") end end end) end) end)


Где соответствующие функции выполняют следующие действия:

function InstrProgrammingEnable () – переводит микроконтроллер в режим программирования специальной командой отправляемой по SPI.

function ProgrammingEnable () – просто ресетим AVR на 25 мс перед началом программирования

function ProgrammingDisable () – после окончания программирования, переводим выводы SPI в ESP8266 в неактивное состояние, чтобы они не мешались нам при выполнения кода на микроконтроллере (вдруг они там используются)

function InstrFlashErase() – затираем флэш-память на микроконтроллере перед началом программирования. Зачем это нужно объяснять не нужно.

function InstrStorePAGE(H, address, data) – по этой команде во внутренний буфер микроконтроллера записывается байт программы. Но это ещё не сама флэш запись, так как флэш пишется здесь постранично по 128 байт.

function InstrWriteFLASH(page_address_low,page_address_high) – а вот это уже запись флэш и она требует времени, обратите внимание на временную задержку 5 000 мкс.

function Programming (payload) – самая большая и важная функция использующая и вышеперечисленные функции. Она берет передаваемую программу кусками по 1024 байт, делит их на байтики и формирует для них адреса, а затем отправляет в микроконтроллер во внутренний буфер и через каждый 128 байт инициализирует запись флэш. Потом берет следующий килобайт кода и повторяет операцию, естественно со смещением в адресах, чтобы писать дальше а не затирать записанное. Вначале, я пробовал пересылать программы целиком, но при превышении 6 килобайт в ESP8266 элементарно кончается доступная память и она вылетает. Один килобайт оказался самой удобной единицей, ибо аккуратно делится на части и удобно передается по TCP (нам же надо его с компьютера ещё получить). Больший размер тоже не нужен, TCP, сами знаете, в текущей версии ограничивает передаваемый пакет, в 1500 что ли байт (но у меня передавался почему-то 1440, вроде).

Как бы ничего сложного, но несколько подводных камней пришлось преодолеть.

Регистрируемся в беспроводной сети.

Создаем вначале TCP сервер, который слушает три команды:

1. “program” (будем программировать),

2. “data” (будем меняться данными),

3. ”stop” (всё прекращаем).

Если мы программируем, то сначала инициализируем SPI и создаем еще один TCP сервер, который хапает данные (код прошиваемой программы) покилобайтно и вызывает под них функции программирования микроконтроллера. Я понимаю, что выглядит глупо создавать второй сервер, но это необходимость, ибо местное API поддерживает создание только одного сокета, а нам необходимо разделять команды ”program” и “data” собственно с передаваемыми данными, ибо на глаз они не различаются, там байты и тут байты.

Если же мы хотим не программировать, а обмениваться данными, посылая их в нашем случае в микроконтроллер, то мы сначала отправляем по TCP строку ”data”. В ответ на это будет создан уже UDP сервер (я напомню, что мы управляем динамически механической рукой и нам задержки с формированием TCP пакетов не нужны, да и вообще отправлять один байт целым TCP кадром моветон). А UDP дейтаграммы у нас будут маленькими и формироваться будут быстро.

После инициализируется UART, и каждый принимаемый в беспроводном виде байт, отправляется уже по проводу TXD на микроконтроллер, который обязан, буде там прошита соответствующая программа, его принять. Обмен данными в другом направлении организовать также не сложно, но я пока его не реализовывал.

Ну и по команде ”stop” вышеупомянутые сервера (кроме самого первого) закрывают соединения и самый главный сервер вновь переходит в состояние ожидания команд ”program” и “data”.

Поскольку SPI интерфейс программно эмулируется в ESP8266, то порты ввода-вывода для сигналов CS, CLK, MISO,MOSI, RESET (для AVR), можете использовать любые доступные, а не те, что указаны у меня в загрузчике. Кроме того оказалось, что CS и MISO в принципе тоже можно в данном случае оборвать, будет работать и без них. Ну и один вывод задействуется на встроенный в плату ESP8266 светодиод, чтобы мигал иногда и показывал, что программа ещё живая.

Проверок на ошибки записи не делается (за исключением первого запроса к AVR, но эта информация просто выводится на консоль), EEPROM не программируется, больше 32 Кб не шьется – короче есть ещё над чем поработать. Скорость обмена по SPI примерно 115 Кбит, за несколько секунд всё прошивается, примерно, как у обычного последовательного программатора типа ISP500).

Берите код, вписывайте свои сети и пароли, компилируйте на ESplorer, обзывайте его “init” (чтобы запускался при рестарте) и отправляйте на ESP8266. Должно работать. В смысле работать беспроводным программатором, как минимум.

Мы же теперь займемся управляющей стороной – персональным компьютером.

По сути, нам нужно взять файл формата HEX, в который превращаются ваши программы, написанные в среде ATMEL STUDIO и отправить его по WI-FI на известный нам порт сокета (в данном случае 4000). Маленькая загвоздка в том, что нам нужен двоичный файл BIN для пересылки, а ATMEL STUDIO радует нас только HEXом. Выхода здесь два; или перевести его в формат BIN специальной программой конвертером, типа WinHex или сделать это самим в своей программе. Я пока не сделал, но вроде это не сложно, там надо отрезать заголовок и сделать что-то ещё.

В итоге программу-загрузчик я написал на JAVA (в основном потому, что больше ни на чем не умею), работая в просто прекрасной и бесплатной среде IntelliJ IDEA. В ней создается TCP клиент, который ищет сервер запущенный на ESP8266. Если находит, то связывается с ним и отправляет ему файл расположенный по такому-то адресу. Код ниже.

Загрузчик файлов на JAVA, работающий на стороне ПК

import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.List; public class Net { public static void main(String args) { new Http_client(4000); } } class Http_client extends Thread { int port; String s; String Greetings_from_S; Http_client(int port){ this.port = port; start(); } public void run() { //192.168.1.113 -это адрес ESP8266 в моей сети. Но вообще, узнается из общения с роутером // лучше сделать его статическим, роутеры это умеют try (Socket socket = new Socket("192.168.1.113", port)) { PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true); pw.println("program");// Greetings with SERVER System.out.println("program"); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); Greetings_from_S = br.readLine(); System.out.println(Greetings_from_S); if(Greetings_from_S.equals("ready")) { try { File file = new File("d:BlinkOUT.bin");// адрес выгружаемого файла BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); byte data = new byte; bis.read(data); byte data_buffer = new byte; int frames = data.length/1024; System.out.println(frames); int residy = data.length%1024; for (int i = 0; i < frames;i++) { for (int k = 0; k< (1024); k++) { data_buffer[k] = data; } sendingChunk(data_buffer); } byte data_buffer2= new byte; for (int i = 0; i < residy;i++) { data_buffer2[i] = data; } sendingChunk(data_buffer2); pw.println("stop");// System.out.println("stop program"); } catch (Exception e) { System.out.println(e); } } } catch (Exception e) { System.out.println(e); } } public void sendingChunk (byte data_buffer){ try (Socket socket = new Socket("192.168.1.113", 4001)){ BufferedOutputStream bos = new BufferedOutputStream((socket.getOutputStream())); bos.write(data_buffer); bos.flush(); System.out.println(data_buffer.length); } catch (Exception e) { System.out.println(e); } } }


Тут конечно накручено лишнего, всякие ready, в принципе не нужны. Если уж TCP соединение установлено, то оно установлено. Единственная проблема была в том, что файл никак не хотел отправляться ровными кусками по 1024 байт, как мне очень требовалось, хотя я и явно указывал размер. Видимо там какой-то финальный буфер недоступный из JAVA, и он отправляет пакеты размером, каким ему хочется, что для приемной стороны совершенно неприёмлемо. Сначала я пробовал сделать задержку, чтобы буфер уставал ждать следующие куски и отправлял как есть. Но задержка стала работать, когда достигла 10 секунд, что мне как-то показалось многовато на один передаваемый килобайт.

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

Единственное, для запуска необходимо поставить на компьютер среду выполнения JAVA. Но я обычно запускаю сразу из IntelliJ IDEA ибо там в консоли всегда видно, что происходит (но и здесь среда JAVA нужна). Хотя, конечно, по-умному надо сделать GUI. То есть окошко, где выпадает путь к файлу, возможность менять там же в окне номера портов и ну и прочие нужные вещи. И все это собрать в виде исполняемого файла.

А таперича, как говаривал Коровьев, вернемся граждане, собственно к механической конечности MechArm, что была упомянута в самом начале. У нас теперь есть возможность удаленно её запрограммировать, а затем ею поуправлять. Перейдём к программе управления на стороне микроконтроллера.

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


Такой привод управляется прямоугольными импульсами, периода 20 мс (50Гц) с коэффициентом заполнения от 2 до 4 процентов. То есть 2% это полный поворот в одну сторону, 4% в другую. Задача как раз для встроенного в AVR ШИМ.

Один сервопривод используется для движения вправо-влево; второй на себя – от себя; третий вверх-вниз; четвертый – сама клешня, которая должна сжиматься и разжиматься. Всё написано на С и откомпилировано до HEX файла в ATMEL STUDIO. Немного странный вид программы связан с тем, что изначально рука управлялась с клавиатуры привязанной проводами к микроконтроллеру. Но провода вчерашний день, надо эволюционировать дальше.

Можно конечно использовать скетчи для сервоприводов от ”ARDUINO”, но мне они не понравились. Самому писать интересней. К тому же все четыре сервопривода должны работать одновременно, а не в мультиплексированном режиме, когда ШИМ переключается на каждый сервопривод поочередно. Ибо гравитацию никто не отменял и поднятая вверх конечность, моментально опустится, если на соответствующий сервопривод перестанут поступать управляющие импульсы. Я не уверен, что ”ARDUINO” скетч обеспечивает одновременный режим работы для четырех серво. А вот сами мы вполне можем написать программку отвечающую нужным требованиям. Да и вообще при отсутствии операционной системы, которая отделяет агнцев от козлищ, применение скетчей конкурирующих за периферийные устройства микроконтроллера (а мы даже и не знаем заранее какие) дело слишком багопроизводительное.

Вот сам код, который мы записываем в Arduino Nano посредством ESP8266-07.

Программа для управление MechArm для микроконтроллера AVRmega328P

#define F_CPU 16000000 #include #include // стандартные целые числа #include #include // математика #include //стандартный ввод-вывод #include #include #include //стандартные возможности #define UART_BAUD_RATE 115200 // счетчик Т1 задает временной интервал 20мс #define COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - отключен; 001 без делителя; 010 c делителем 8; 011 -64; 100 -256; 101 -1024 #define COUNTER1_ON TCCR1B=0b00000011 // счетчик Т0 задает ширину управляющего импульса для серво РВ0 и РВ1 #define COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 000 - отключен; 001 без делителя; 010 c делителем 8; 011 -64; 100 -256; 101 -1024 #define COUNTER0_ON TCCR0B=0b00000100 // счетчик Т2 задает ширину управляющего импульса для серво РB2(PD6) и РВ3(PD7) #define COUNTER2_OFF TCCR2B=0b00000000 // CS02 CS01 CS00 - 000 - отключен; 001 без делителя; 010 c делителем 8; 011 -64; 100 -256; 101 -1024 #define COUNTER2_ON TCCR2B=0b00000110 volatile uint16_t period_20ms; volatile uint8_t State_of_keyboard; volatile uint8_t start_position ; volatile int8_t number_servo; ISR(USART_RX_vect)// прерывание для UART { State_of_keyboard=UDR0; return; } ISR(TIMER0_COMPA_vect)// серво РВ0 ширина управляющего импульса { PORTB &=~(1<<0); TIMSK0&=~(1<
Суть программы ясна из текста и комментариев. Мы используем счетчик Т1 для образцового периода 20 мс и счетчики Т0, Т2 для выдачи ШИМ сигналов на четыре линии порта ввода-вывода, благо каждый из этих двух счетчиков, может работать на два устройства.
В программе устанавливаются начальные положения сервоприводов, через загрузку счетных регистров OCR0A, OCR0B, OCR2A,OCR2B. Также вводятся константы ограничители, поскольку нам не всегда нужен размах в 180 градусов. Ну и дальше, по прерыванию от UART, программа ловит число отправленное ESP8266 (от 1 до 8) и переводит его в команду для соответствующего сервопривода. Приводов четыре, каждый работает в двух направлениях, поэтому целых чисел от одного до восьми вполне хватает. Как только число выбрано, содержимое вышеупомянутых регистров счетчиков либо инкрементируется либо декрементируется, соответственно изменяя скважность управляющего импульса и угол поворота выбранного сервопривода. Те приводы, которые мы не выбирали, сохраняют старое значение угла поворота, (поскольку содержимое соответствующих регистров хоть и обновлялось, но не менялось) и продолжают удерживать механическую руку в прежнем положении.

Теперь нам осталось лишь написать управляющую программу, простите за тавталогию, для управления механической рукой уже непосредственно с компьютера по WI-FI.
Код также написан на JAVA, но немного облагорожен. Появился GUI и возможность редактировать номера портов и сетевой адрес ESP8266.

Что там происходит понятно из окошка. Текст программы я здесь не привожу (он доступен на

RC машинка может быть WiFi машинкой...?

RC машинка это хорошо, но дешевые RC машинки имеют ограниченный диапазон и управляются только определённым пультом поставляемым в комплекте.

Я купил RC джип 4х4 с гибкой подвеской и внедорожными шинами примерно за 30 долларов. Поигравшись с машинкой я решил, что её можно улучшить при помощи Wi-Fi и Android. Потратив немного времени, я полностью удалил плату из машинки. Я замерял напряжения на этой плате и разработал систему управления двигателем при помощи Arduino. Оригинальная система управления не использует ШИМ для контроля скорости. Машинка рассчитана на переезд через препятствия на очень низкой передаче, и как следствие очень медленно. В моей же схеме используется ШИМ.

Я использую Arduino уже несколько месяцев. Я также приобрел asynclabs WiFi Sheild для Duemilanoe Arduino, чтобы экспериментировать с WiFI. Он поставляется с библиотекой, устанавливаемой в Arduino IDE. Я смог сделать программу, которая позволяет управлять двигателями и направлением движения при помощи WiFi.

При помощи Visual Studio я разработал окно программы, которая подключается к серверу автомобиля и дает ему команды. Затем после нескольких попыток я написал приложение для Android, которое использует акселерометр для управления машинкой.

Инструменты и элементы

Это общий список инструментов и элементов, которые использовались в этом проекте. В документации Eagle указаны точные технические характеристики используемых компонентов.

Мультиметр
Паяльник
Припой
Отвертки
Раствор для травления плат
Фольгированый стеклотекстолит
Плоскогубцы
Arduino
AsyncLabs WiFi Sheild
Разъёмы RJ45
Драйвер двигателя с H-мостом
Конденсаторы

Драйвер двигателей

Используя Eagle, я разработал эту схему и сделал печатную плату для неё. Она функционирует как драйвер двигателей и регулятор их мощности для Arduino.
Это позволяет использовать стандартный 7.2В аккумулятор для питания основных и рулевых двигателей и Arduino.

В этой схеме используется двойной интегральный драйвер с Н-мостом SN754410 для управления двигателями. Выводы управления драйвера подсоединены к кабелю RJ45, который подключается к AsyncLabs WiFi Sheild.

Arduino Shield

Используя библиотеку SparkFun в Eagle я разработал Arduino Shield, через который будут проходить контакты с WiFi Shield и подключаться к драйверу двигателя через разъем RJ45 и 2 винтовые клеммы.

Цоколевка контактов RJ45 очень важна. Ошибка в подключении может привести к непредсказуемым результатам и придётся переделывать плату.

Травление печатных плат

Эта тема была раскрыта много раз, и я не буду подробно описывать её.
Я использую , и он меня устраивает, а с опытом дает прекрасные результаты.

Для крепления платы к корпусу использовались липучки. Мне повезло, т.к. в моей машинке было много места для электроники под трубчатым каркасом.
Я забыл сфотографировать соединение платы драйвера двигателя с остальными платами, однако он хорошо стал и не занял много места в корпусе.

Программа

Мой код может быть не достаточно эффективен, но он работает.

Машинка

Мне удалось собрать CarServer на основе примера SocketServer, который я получил вместе с Wifi Sheild AsynLabs.
Вам необходимо будет ввести информацию о своей беспроводной сети в код Arduino. Когда машина включилась, дайте ей 15-45 секунд, чтобы установить соединение с маршрутизатором. Красный светодиод на WiFi Shield означает, что соединение установлено.

Я сделал эту программу при помощи C # и MS Visual Studio 2008. Я сделал хорошее окно, и автомобилем можно управлять стрелочками.

Почему бы не управлять машинкой с телефона?

Такая мысль появилась у меня примерно через неделю после покупки DroidX. Я начал экспериментировать и в конечном итоге использовал Android SDK. Я нашел аналогичные приложения, где для управления используется акселерометр. Смотря на эти приложения написал свое.

Вставить IP и порт, указанные в коде Arduino. Держите телефон горизонтально. Затем наклоните его от себя, чтобы ехать вперед и на себя, чтобы ехать назад. Используйте телефон как руль.
Это мое первое крупное приложение для Android. В нем до сих пор есть некоторые ошибки, но в основном оно работает нормально.

Рулите во дворе машинкой 4x4 с WiFi!

Я отлично провел время, создавая этот проект. Я получил много знаний и новых навыков, и теперь у меня есть машинка 4х4, которой можно управлять с телефона.

Мне нужна камера для установки за лобовым стеклом, чтобы смотреть куда ехать. Она должна быть с низким энергопотреблением, а также передавать видео сама по себе. (Я думаю, что Arduino справится с этим).

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Драйвер двигателей
IC1 Микросхема SN754410 1 В блокнот
Линейный регулятор 5 В 1 В блокнот
Биполярный транзистор

2N3904

1 В блокнот
C1, C2 Электролитический конденсатор 2 В блокнот
Разьем 2 вывода 7 В блокнот
Разьем 8 выводов 1 В блокнот
Arduino Shield
U1 Плата Arduino 1 В блокнот
Т1 Биполярный транзистор

2N3904

1 В блокнот
R1 Резистор 1 В блокнот
U$3 Подстроечный резистор 1 В блокнот
Разьем 2 вывода 2

И HTC Desire с прошивкой cyanogen 7.1.0 RC1 (Android 2.3.4). На всякий случай напомню, что все что будет описываться дальше - работает только начиная с Android 2.3.4 для телефонов и Android 3.1 для планшетов.

Тут стоит отметить что данный USB Host Shield не совсем удачный, особенно в сочетании с Arduino Mega 2560. Первая проблема заключалась в том что данная плата расширения сделана для Arduino UNO, а она отличается от Mega положениями контактов SPI, поэтому пришлось кидать перемычки (см. фото). Второй проблемой, хотя и вполне ожидаемой, стала потребность во внешнем источнике питания для работы этой платы расширения. Более удачной считается USB Host Shield 2.0 от Circuits@Home, но она и дороже.

Плата с перекинутыми SPI контактами

Настройка Arduino ПО

1. Если еще не установлено, то скачать и установить ПО для Arduino .
2. Скачать и распаковать пакет ADK (содержит DemoKit приложение). Должны появится папки app , firmware , и hardware .
3. Скачать библиотеку CapSense
4. Скопировать firmware/arduino_libs/AndroidAccessory и firmware/arduino_libs/USB_Host_Shield в /libraries/ .
5. Создать директорию CapSense в /libraries/ и скопировать в нее CapSense.cpp и CapSense.h из архива CapSense.

Загрузка прошивки

Google любезно предоставляет свой DemoKit скетч для Arduino. Все что нужно - это открыть его из firmware/demokit/demokit.pde , скомпилировать и залить на плату.

Тестовое Android приложение

В DemoKit пакете также находятся исходники Android приложения для демонстрации возможностей. Google предлагает нам самостоятельно создать Android проект и собрать это приложение. Для начала нам надо будет установить API Level 10 . Дальше все просто - создаем Android проект и указываем путь к папке app , в Build Target указываем Google APIs (Platform 2.3.3 , API Level 10). Собираем приложение и устанавливаем на телефон. Кто не хочет возится со сборкой - может скачать готовый APK .

Запуск

Просто подключаем наш телефон к USB Host Shield. Если мы все сделали правильно, то на экране появится запрос запуска DemoKit приложения.

Само приложение содержит две вкладки - In (кнопки, джойстик и сенсоры) и Out (светодиоды, реле и сервоприводы).

Я решил что для демонстрации вполне достаточно пары светодиодов и кнопки. Как это все чудо работает можно пронаблюдать на видео.

Немного кода

В рассматриваемом примере сообщения, передающиеся по USB, состоят из трех байтов:
1-й байт определяет команду или группу устройств, например светодиоды - 0x2
2-й байт указывает на конкретное устройство, например зеленый светодиод - 0x1
3-й байт содержит значение, передаваемое устройству, например максимальная яркость - 0xff

Arduino

... /* инициализация */ AndroidAccessory acc("Google, Inc.", "DemoKit", "DemoKit Arduino Board", "1.0", "http://www.android.com", "0000000012345678"); void setup() { .... acc.powerOn(); } void loop() { byte msg; /* проверка подключения */ if (acc.isConnected()) { /* получение сообщения от Android устройства */ int len = acc.read(msg, sizeof(msg), 1); if (len > 0) { /* сообщение для светодиодов */ if (msg == 0x2) { if (msg == 0x0) analogWrite(LED3_RED, msg); else if (msg == 0x1) analogWrite(LED3_GREEN, msg); else if (msg == 0x2) analogWrite(LED3_BLUE, msg); } } msg = 0x1; b = digitalRead(BUTTON1); if (b != b1) { msg = 0; msg = b ? 1: 0; /* отправка состояния кнопки */ acc.write(msg, 3); b1 = b; } } }

Android

import com.android.future.usb.UsbAccessory; import com.android.future.usb.UsbManager; ... public class DemoKitActivity extends Activity implements Runnable { private UsbManager mUsbManager; UsbAccessory mAccessory; FileInputStream mInputStream; FileOutputStream mOutputStream; ... private void openAccessory(UsbAccessory accessory) { mFileDescriptor = mUsbManager.openAccessory(accessory); if (mFileDescriptor != null) { mAccessory = accessory; FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); mOutputStream = new FileOutputStream(fd); Thread thread = new Thread(null, this, "AccessoryThread"); thread.start(); } } public void run() { int ret = 0; byte buffer = new byte; int i; while (ret >= 0) { // получение входящих сообщений ret = mInputStream.read(buffer); i = 0; while (i < ret) { int len = ret - i; switch (buffer[i]) { case 0x1: // сообщение от кнопки if (len >= 3) { Message m = Message.obtain(mHandler, MESSAGE_SWITCH); m.obj = new SwitchMsg(buffer, buffer); mHandler.sendMessage(m); } i += 3; break; } } } } // пример использования - включить красный светодиод на полную яркость: // mActivity.sendCommand((byte)2, (byte)0, (byte)255) public void sendCommand(byte command, byte target, int value) { byte buffer = new byte; if (value > 255) value = 255; buffer = command; buffer = target; buffer = (byte) value; if (mOutputStream != null && buffer != -1) { try { mOutputStream.write(buffer); } catch (IOException e) { ... } } } }

Выводы

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

Также нельзя забывать о том, что Android устройство для Arduino может выполнять роль платы расширения, в которой есть GPS, Bluetooth, WiFi, акселерометр и многое другое.



Рекомендуем почитать

Наверх