Руководство по сборке камеры

Вступление

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

Тем не менее всё описанное ниже вполне работоспособно и может быть применено на практике.

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

Позже я написал о ней пару статей на разных ресурсах, ссылки на которые приведу в конце этой статьи.

Впервые публично я использовал камеру как наглядный пример, сопровождающий обзор, на другом ресурсе (а фактически, в качестве чита что-бы подтянуть голоса). Это был настоящий бета-тест, который выявил кучу недоработок. За это огромное спасибо всем неравнодушным, помогавшим кто советом, а кто и куском кода.

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

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

Начало

Сперва о стоимости/бюджетности такого решения.

Все ингредиенты покупаются в Китае (Aliexpress, BuyInCoins, Ebay - кому что роднее)

Необходимый набор:

  • Arduino Uno (или nano) - $9-10
  • сервопривод (рулевая машинка) SG90 - около $2 = итого $4 за две
  • вебкамера - около $3
  • Итого: $17

    Много это или мало решать Вам, по состоянию на январь 2015 года (когда я решил обновить статью и немного подзаняться сайтом) это составляет 1100-1200 рублей.

    На момент сборки камеры в 2011м году Arduino UNO стоила дороже, и общая цена этого комплекта выходила примерно в 750 рублей.

    Дополнительный набор (ленивости + плюшки):

  • экран от Nokia 5110 - 250р (изначальный самодельный вариант - экран достался в комплекте с самой Нокией и блоком питания, будем считать, что именно для этой цели, реально можно найти вообще на халяву). В настоящий момент готовый экран легко купить за $3-5
  • MegaShield v4 к Arduino - $6
  • проводки-коннекторы - $3 за пучок (40 штук за эту цену, реально использовано 7)
  • сверхяркий сверхсиний сверхсветодиод для подсветки экрана - 5р/шт (лучше 4шт., у меня сделано неправильно). Не актуально в случае покупки готового шилда с экраном.
  • Итого: примерно $13 (исходя из покупки готового экрана)

    О реализации

    Всё делалось с нуля. Повторять то, что уже было - я не стал, во-первых из соображений тренировки, а во-вторых Ethernet-модуля у меня на тот момент не было, и я решил что это всё пока что для меня слишком сложно (т.к. там был завязан MySQL) и это решение мне однозначно не подойдёт.

    О задачах

    Задачи я себе обозначил следующие:

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

    В ходе реализации возникли вопросы вот такого плана:

  • видео либо грузит процессор в случает показа на несколько пользователей, либо даёт задержку 5-10 секунд, т.е. не обеспечивает "реалтаймовость", из-за чего нельзя сразу определить адекватность и вообще работоспособность управления
  • использование сервиса трансляций, хотя и сильно разгружает сервер в случае большого онлайна, не обеспечивает необходимую надёжность, и, опять же, даёт задержку
  • специальный сервер для трансляции видеопотока требует определённых навыков, которых у меня пока что нет
  • использование отображения путём смены картинок не обеспечивает высокий fps, а также постоянно обращается к жёсткому диску, что, при большом количестве пользователей, может вызывать лаги картинки не из-за загрузки процессора, а именно из-за обращения к диску
  • О решениях

    Решено:

  • использовать в качестве отображения - картинки.
  • для исключения жёсткого диска из процесса выдачи картинок установлен RamDisk, на который дважды в секунду "ложится" изображение с вебкамеры
  • для выдачи картинки решено использовать php и gdlib
  • обновление картинки инициируется клиентом посредством javascript и ajax, и происходит без обновления самой странички
  • Как всё это выглядит в реальности

    А выглядит всё более чем скромно

    Работает примерно так

    (тут ссылка на ютуб)

    Arduino

    Ардуино

    Мегашилд с проводками

    Мегашилд

    "Сэндвич" в профиль

    Ардуино и Мегашилд

    "Сэндвич" анфас

    Ардуино и Мегашилд

    LCDшка

    Экранчик

    Она же вид сзади (пины и кондёр)

    Экранчик

    В сборе

    Всё в сборе

    Всё в сборе

    Колхоз - система проводков и верёвочек

    Крепление камеры

    Крепление камеры

    Крепление камеры

    Крепление камеры

    А вот так всё выглядит в жизни

    Место установки камеры

    Как устроено аппаратно

    Вебкамера подлючена по USB к компьютеру (он же сервер).

    Arduino тоже подключена к компьютеру по USB.

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

    До переделки всё это работало круглосуточно более года, со средним онлайном 4-5 пользователей. В самом начале при набегах с хабра и других сайтов онлайн был 50-100, по питанию система справлялась.

    Как работает программно

    На стороне клиента

  • чистый веб-интерфейс, без всяких плагинов и примочек на стороне пользователя. Только браузер (html, css, и javascript/ajax)
  • На стороне сервера

  • сам сервер - Apache
  • обработчик скриптов - php
  • приём картинок с камеры - любая самая простая доступная, бесплатная или самопальная программа для сохранения картинок с вебкамеры
  • хранение картинки - RamDisk, утилита для создания дискового раздела в оперативной памяти (русскоязычная версия RAMDisk "Enterprise" бесплатна для локализованных систем)
  • чтобы не прописывать в php прямых локальных путей, папка с картинкой смонтирована в www папку с помощью juction (бесплатная утилита Марка Руссиновича)
  • передача управления из интернета к Arduino реализована с помощью программы-прокси, следующим образом: php скрипт создаёт UDP сокет и отправляет датаграмму на определённый порт, далее программа-прокси слушает этот этот порт и принимает приходящие на него сообщения и отправляет их на COM-порт Arduino (можно даже без обработки). Выбор UDP вызван исключительно для упрощения системы, UDP не требует никаких подтверждений и проверок о доставке-отправке ни со стороны клиента, ни со стороны сервера.
  • На стороне Arduino

  • собственно Arduino
  • скетч внутри Arduino - стандартные примеры из штатного набора arduino-0022 servo и serial + найденная на просторах интернета библиотека для дисплея, доработанная до приемлемого вида (в плане кириллицы и латиницы одновременно)
  • на момент сборки плюсом стоял мегашилд, чисто из-за удобства и культурного вида - в этом варианте я не спаял ни одного проводка (за исключением платы к дисплею)
  • Живучесть

    Система выдержала все нашествия и рейды, а так же онлайн более 120 пользователей.

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

    Внимание к мелочам

    Хочу отметить проблемы с программной частью которые случались из-за собственной невнимательности/неосведомлённости/ненаблюдательности:

  • первое с чем я серьёзно мучался: Arduino принимает из отправленной на её виртуальный COM-порт строки отдельно первый байт и отдельно всё остальное. Какие изощрения я только не пробовал - и с массивами и с кучей проверок... Хоть ты убейся. Решение проблемы? Пришло неожиданно и внезапно, в момент когда я об этом и не думал: задержка! Sleep 2 после чтения каждого байта. ВСЁ!
  • вторая проблема - серьёзная нагрузка на сервер, казалось бы, из ничего, возникла потому, что обновление картинки было сделано по таймеру, не дожидаясь собственно факта загрузки картинки (или ошибки загрузки). Таком образом отсылалась куча "лишних" запросов.
  • третье: FireFox оказался самым правильным и капризным браузером, и заставил меня учиться писать валидный код. Так например, событие OnClick по элементу Option работать не должно. А оно работало. Везде, кроме огнелиса.
  • четвёртая, совершенно не явная и редко всплывающая: периодически картинка "ломалась". Как выяснилось, это происходило в момент когда файл был занят при записи. Т.е. проверка file_exists() проходила, а файл оставался залоченным. Не помогла и проверка is_writable(). Пришлось организовывать цикл по наличию ошибки и внутри него отрабатывать чтение файла "до победного конца".
  • Оставшиеся недоработки

  • во-первых, это "левые" символы иногда появляющиеся в конце сообщения на экране. На самом деле это команды управления. Уши этого бага растут из того что если активно спамить или жать кнопки, буфер ком-порта не успевает полностью прочитаться Ардуиной и последующие сообщения валятся в конец буфера. Решение есть, но пока не сделано.
  • во-вторых, это периодическое падение UDP-сокета в программе прокси при большом онлайне. В чём причина - не знаю. Проявляется не сразу. Умирает и не "откисает". Помогает закрытие сокета и бинд по-новой. Возможно, виноват кривой видовский winsock.ocx. Переписывать это дело на API в бейсике, как-то лень. Пока одним из "топорных" решений вижу сброс и ребинд сокета по таймеру, каждые, скажем, полчаса.
  • В настоящий момент камера лишена этих недостатков, ввиду того что я отказался от подключения Arduino по USB - исчез и виртуальный COM-порт, и "костыль" в виде UDP-COM прокси.

    О скидках

    Как было написано выше - в Китае - дешевле. Главное знать места/продавцов, где именно дешевле, и как получить скидку.

    Ссылки

  • статья на хабре (уже на гиктаймсе)
  • статья на MySku
  • исходники клиентской части (html), серверной (php) и программы web-arduino-прокси (VB 6.0)

    twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru rutvit.ru myspace.com technorati.com digg.com friendfeed.com pikabu.ru blogger.com liveinternet.ru livejournal.ru memori.ru google.com bobrdobr.ru mister-wong.ru yahoo.com yandex.ru del.icio.us
  • Оставьте комментарий!

    Вы можете войти под своим логином или зарегистрироваться на сайте.

    (обязательно)