Сверхдешёвая камера с управлением — своими руками


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

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

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

    О том какова стоимость моей поделки: читаем ниже.

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

    Пройдём по ценам*


    * все цены даны со скидками. О скидках — отдельно, пожже.

    Необходимый набор:
    • Arduino Uno (или nano) — 15.29$
    • Сервопривод (рулевая машинка) SG90 2х2.37$ = 4.74$
    • Вебкамера 3.01$
    Итого: 23.04$ (примерно 750р, на данный момент)

    Дополнительный набор (ленивости + плюшки):
    • Экран от Nokia 5110 — 250р (в комплекте с самой Нокией и блоком питания, куплено пару лет назад, будем считать, что именно для этой цели, реально можно найти уже вдвое дешевле, или вообще на халяву)
    • MegaShield v4 к Arduino — 5.86$
    • Проводки-коннекторы — 2.86$ (40 штук за эту цену, реально использовано 7)
    • Сверхяркий сверхсиний сверхтодиод для подсветки экрана — 5р/шт (лучше 4шт., у меня сделано неправильно)
    Итого: примерно 550р

    Всего: 1300р

    О реализации


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

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

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

    О решениях
    • Решено использовать в качестве отображения — картинки
    • Для исключения жёсткого диска из процесса выдачи картинок установлен RamDisk, на который дважды в секунду «ложится» изображение с вебкамеры
    • Для выдачи картинки решено использовать php и gdlib
    • Обновление картинки инициируется клиентом посредством javascript и ajax, и происходит без обновления самой странички


    Довольно лирики!


    Как выглядит

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

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


    Ардуина, если кто не видел


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


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


    «Сэндвич» анфас


    LCDшка


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


    В сборе


    В сборе 2


    Колхоз — система проводков и верёвочек (крепление камеры)





    Куда же без него


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

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

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

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

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

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


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

    Будьте внимательны к мелочам


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


    Оставшиеся недоработки


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


    О скидках


    Общеизвестно, что в Китае — дешевле. Главное знать места, где именно дешевле, и как добыть дополнительную скидку.
    Тут смысла писать нет — слишком большой объём текста с картинками, к тому же известный большинству.
    Поэтому дабы не провоцировать ярых противников борьбы со спамом и прочим «реферальством», отмечу необходимый минимум — это скидка 15% на BiC, складывающаяся из одноразового купона на 10% и скидки за первую покупку 5% при вводе рекомендателя + хинт, как использовать эту систему неоднократно.
    Все заинтересовавшиеся, могут ознакомиться с полной информацией по ссылке на страничке с, собственно, самой камерой.

    Ссылки


    Камера, работающий экземпляр, для тех кто ещё не видел и не наигрался
    Топик, в котором ссылку на камеру слили на хабр раньше времени
    RAMDisk
    juction
    Исходники (упрощённые, во избежание) клиентской части, серверной (php) и программы web-arduino-прокси (VB 6.0)

    Apache, php, либо какие-то комбинированые сборки и т.д. — на свой вкус.
    Поделиться публикацией
    Комментарии 42
      0
      Небольшая подсказка: линки на файлы/папки можно создавать без утилит типа Junction, в FAR'е для этого Alt+F6
        0
        А можно ссылку) Интересно посмотреть, как реализовано одновременное использование одной камеры кучей юзеров.
          0
          ncux.sytes.net:8888/webcam.php
            0
            О, сча подсмотрим что он там на клавиатуре набирает
            давайте смотреть на клаву и экран :)
            0
            А всё, увидел ссылку) Думал там по первой ссылке ещё фотографии рабочего варианта)
          • НЛО прилетело и опубликовало эту надпись здесь
              0
              Я выпилил некоторые сочетания :)
              За них не банит, но и не пропускаются.
              В частности сочетания с тремя символами # подряд.
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  На самом деле это команды управления :)))
                  Это баг из-за того что если активно спамить или жать кнопки буфер ком-порта не успевает прочитаться полностью и последующие сообщения валятся в конец буфера.
                  По идее так может и два сообщения сплюсовать если активно спамить. Но кнопки давят всётаки чаще.

                  Я давно придумал как убрать это дело — команды должны быть из непечатаемых символов — например с начала таблицы — до 30го. Но в последний момент перед публикацией, уморился вычитывать косяки в статье и просто-напросто уже поленился отключать всё и перешивать :)
                0
                оффтопик:
                > Чтобы не прописывать в php прямых локальных путей, папка с картинкой смонтирована в www папку с помощью juction (бесплатная утилита Марка Руссиновича)

                В новой винде для этого есть встроенная утилита mklink, а в официальных админ-паках для старых раньше была linkd
                  –1
                  Я в линухе привык что всё просто :)
                  А тут погуглил — mklink не обнаружил, поэтому хапнул первое что яндекс выдал по этому поводу.
                    0
                    far manager — Alt+F6 изкоробки
                    +1
                    Проблема, что buyincoins иногда отправляется полежать, да и ардуины нет на складе :( Про экран кстати тоже не все так просто — тот что можно купить в Москве — без контактов и плат а как обычный дисплей — с контактными площадками прямо на стекле. Не подскажете как к нему подключаться?
                      0
                      Очень просто. Как и в телефоне — резинка-гармошка с металлическими вставками (или какие они там? прорезиненный метал? металлизированная резина?).
                      Или можно нарвать пинчиков из шлейфа от флопика — они на конце раздвоенные как прищепки — как раз надеть на край экрана. Добиться контакта чтоб экран работал и залить всю эту систему соплями китайских девственниц (термоклеем).
                        0
                        А байкон периодически ДДОСят активно все кому не лень.
                        К тому же они ещё любят что-то править у себя и обновления накатывать в этот момент.
                        А Ардуины, походу, смели после статьи на муське :)
                        На Алиэкспрессе есть, но там 18$ и без скидок.
                          0
                          UPD: только что заходил на BiC — нормально работает, даже не лагает как обычно.
                          UNO и nano — всё в наличии.
                            0
                            Я заказал 4 дня назад пачку всячины на BiC и msp430 от TI. msp430 уже приехал (FedEx. 3 дня), а вот на BiC отписали что отправили все кроме UNO потому что он «out of stock»:
                            Sorry to bother you. You may find your order on BuyinCoins.com is still waiting to be shipped. Because we get a notice from our warehouses that we temporarily run out of stock of this item. We have been making every attempt to maintain stock of every item we offer on BuyinCoins.com, but we meet the inventory management problem on rare occasion.


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

                        // правильно — должно onchange работать ;)
                          0
                          Ну вот так и сделал.
                          OnClick, кстати, тоже вполне себе работает :)) Но только в опере и в хроме, я потому на этот счёт даже не заморачивался пока на работе с убунты не заглянул в камеру. Паника ваще была…
                          0
                          Камера крутится только на 360 градусов?
                          Еще бы сделать два небольших лога картинок, когда экранчик и кот попадает в кадр.
                            0
                            Камера не крутится на 360 градусов. Что вообще значит только на360? :)

                            Эти сервы только 180 могут (без вскрытия) + ещё урезаны углы, т.к. там смотреть нечего в комнате :))
                            0
                            Думаю, не помешала бы кнопка: «Перейти к дисплею». А то уже минут 5 не могу до него докликать.
                              0
                              Если честно, эта функция есть, и не только про дисплей, там ещё про кота было и про меня, но я её закомментировал в итоге, т.к. в этом случае покою не дадут камере, она будет мотыляться по всем трём точкам по два раза каждую секунду :)))
                              0
                              Вот спасибо за идею! Думал чем заняться на выходных, а тут такое!
                                0
                                У тебя крутые обои на стене!
                                  0
                                  Прошу прощения за повтор с предыдущим топиком, но каков смысл с 0 собирать управляемую камеру за 5тр, если уже готовая и с бесплатной доставкой с DX стоит примерно 2тр(аналог Foscam FI8908W). У нее есть возможность управления не только позиционированием в т.ч. и пользовательскими cgi, но и доп.выходы имеются, останется только дисплейчик добавить для вывода комментов с Хабра(если оно конгечно надо ибо камера и без него работать будет).
                                    0
                                    Зачем мне что-то покупать, если я могу сделать это сам? Особенно если мне это интересно :)
                                    Ну и, вообще говоря, смысл был не в камере. Камера была чисто как контроль.
                                    К тому же я в 750р уложился а не в 5000р :)

                                    Управление нагрузкой 220в было успешно отработано.
                                    А камера осталась отдельно, просто как наглядный пример.
                                    И кроме того, я не думаю, что камера с ДХ потянет онлайн в 100+ юзеров :)

                                    Готовое не всегда лучшее. По крайней мере для меня.
                                      0
                                      Что-ж вы так привязались к этим «5000»? Прошлый автор слепил из того что было под рукой. Можно юзать любую камеру, любые сервы. Однако, при реализации мгновенного пропорционального управления мышкой (с клавы — отстой) ваши HXT900 быстро сдохнут. Так что за дешевизной гнаться оправданно надо. В общем, не надо таким образом цену рассчитывать. Да, ардуина с ethernet-шылдом была, кою вы тоже посчитали. Однако, в вашем случае роль шылда играет целый комп, а его вы забыли к стоимости приплюсовать :-) А автономность дорогого стоит — сейчас та камера у автора стоит себе тихонечко на балконе, крутит ip-камеру (вообще без участия компа).
                                      0
                                      5000? Ну надо же от чего-то отталкиваться :)))

                                      По поводу компа — он у каждого есть. Для того чтоб просто побаловаться, показать друзьям и положить на полку — этого более чем достаточно.

                                      А IP камера, шилды + роутер (а он тоже не у всех, его считали?) — это уже серьёзно. Скажем так — не игрушечный уровень, а серьёзное увлечение.

                                      На IP камеру, кстати, я уже вовсю заглядываюсь :) Езернетовский шилд тоже заказан.

                                      Сервы за 2 доллара — не жалко. Пусть себе сдохнут. Месяц крутят и вроде не помирают. 4 бакса за то чтоб проверить сколько в принципе они могут выдержать — вполне себе адекватная цена.

                                      Ну и до кучи — ну не осилит IP камера 100+ пользователей. Надо внешние сервисы задействовать будет. А лично для себя — да, решение оправданное.

                                      Если бы я написал про камеру за 160$ с моторизованным зумом, крутые шаговые движки, запитку всего этого дела от 12в — много кто повторил бы вот так для себя и ради интереса?
                                      Да врядли… А так пишут — интересуются, вопросы задают, не просто общие, а вполне конкретные.

                                      Можно напугать, а можно и привлечь простотой.
                                      А дальше если втянутся — сами сообразят и докупят. А если нет — то и невелика потеря, под другие дела приспособить можно.
                                        0
                                        Не совсем в тему: а не кажется ли Вам, что при одновременном подключении 1000 клиентов и управлении всеми киентами камерой, вы не сможете получить нужный результат ибо пока изображение сохранилось на диске, камера будет уже не там. Тут наверное нужно переместить камеру, тогда передать изображение клиенту. Опять же нет реалтайма. И Еще, у вас IP внешний и статический?
                                          0
                                          1000 я не осилю. На такое количество я и не расчитывал. Но для IP камеры уже и 20 — предел выше некуда.
                                          IP — внешка и статик, да.
                                            0
                                            напрямую с камеры видео раздавать — нафиг, нафиг. Для такого нужен видеосервер (тот же erlyvideo, к примеру). Ну или сторонний сервис, это удобнее если задержка некритична (у меня yatv задействован).
                                            0
                                            Камера с 360* покрытием была бы надёжнее, избавиться от хрупкой механики. Это можно сделать с использованием параболических зеркал или с помощью нескольких камер. А программно можно реализовать мгновенное перемещение по сфере.
                                              0
                                              1000 пользователей и система зеркал — это уже мастеркласс :)
                                              Никак не за тыщу рублей и не при помощи домашнего компа :)
                                              0
                                              А каких образом идет выбор качества картинки? Каждие полсекунды сохраняется 6 одинаковых изображений разного качества?
                                                0
                                                Нет же! Нафига?
                                                PHP генерит gd-либой.
                                                Исходники же по ссылке. Я там всё лишнее, все навороты выкинул — всё предельно просто.
                                                0
                                                Початился от души, напомнило старый мобильник с СМСками на монохромном дисплее :) Спасибо автору!
                                                  0
                                                  Камера показывает: Котэ лежит под елкой с шаром. Может, прикрутить к девайсу «будилку» для Котэ с кнопкой на веб-морде?
                                                    0
                                                    Шокер штоль? :))))
                                                      0
                                                      Предлагаю пушку гауса и небольшие стальные шарики. Чтоб от полученного дамага котэ не погиб на месте.
                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                      0
                                                      Как же быстро всё устаревает. Уже можно сделать на основе Arduino Due + OV7670 приемлемую реализацию
                                                      http://privateblog.info/peredacha-kartinki-s-ov7670-cherez-arduino-uno-na-android-telefon/

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

                                                      Самое читаемое