Дальше начался творческий процесс…
Датчик препятствия на 3-х светодиодах
Признаюсь честно, в электронике я новичок и до этого только повторял чужие готовые конструкции. На глаза мне попалась статья (
Как говориться, долго думал… Шутка. Пришла в голову мысль, а почему только датчик освещенности? Почему не датчик препятствий? Вроде бы простая мысль – освещать один светодиод вторым (оба светодиода смотрят в одном направлении) и если свет отражается от препятствия, то время разряда светодиода-датчика значительно уменьшится. Есть только одна проблема. Такой датчик совершенно не защищен от внешней «засветки» (т.е. не учитывается освещенность «местности», ведь например днем и ночью она будет кардинально разная). Поэтому было решено добавить второй светодиот-датчик, который бы не засвечивался светодиодом-фарой, а «измерял» бы общую освещенность, зная которую можно корректно интерпретировать показания датчика препятствий. Для того, чтобы светодиод-датчик общей освещенности не засвечивался светодиодом-фарой было решено направить его вверх (обычно свет Солнца/лампочки для робота идет сверху).
Была нарисована плата, собрана конструкция. Программка управления супер простая: если время разряда светодиода-датчика направленного вперед меньше, чем того, что направлен вверх, то в наличие препятствие (иначе – препятствия нет).
Модуль управления двигателями (драйвер двигателей)
В самой машинке была платка, отвечающая за прием, перекодировку и последующее управление движением машинки. Собрана она была на китайской микросхеме SM6135W (это специализированная микросхема-приемник для радиоуправляемых машинок, аналог RX-2B, которая сама декодирует получаемые по радиоканалу команды в 4 команды: FORWARD, BACKWARD, LEFT и RIGHT). Каждой из команд соответствует вывод микросхемы (LEFT и RIGHT поворачивают передние колеса влево/вправо). Вначале загорелась мысль симулировать для это микросхемы команды по проводу, как будто они получены по радиоканалу, но тестовые попытки не увенчались успехом (во-первых в даташите на саму микросхему система команд не описана (я промолчу, как я читал дата шит на китайском в переводе гугла), был найден аналог – дата шит на RX-2B (аналог), но попытка симулировать систему команд от RX-2B результатов не дала (хотя в даташите на RX-2B они вроде толково описаны), может я недопонял чего-то, или RX-2B не полный аналог, ну да ладно)…
Ввиду провала попытки использовать родную микросхему SM6135W (достоинством была-бы возможность управлять двигателями по одному проводу, при некотором усложнении программы управления), я эту микруху выпаял и переделал управление на прямой контроль микроконтроллером команд FORWARD, BACKWARD, LEFT и RIGHT непосредственно с портов микроконтроллера (при этом стало задействовано 4 ножки микроконтроллера, но в целом мне ног хватило).
Управление двигателями ввиду этого получилось тоже простое – выставляем 1 на соответствующей ножке микроконтроллера (чтобы двигатся вперед на ножке FORWARD, чтобы назад на ножке BACKWARD, влево на ножке LEFT и вправо на ножке RIGHT).
Плата микроконтроллера ATtiny2313
То ли я не люблю излишеств, да и стояла задача сделать тестового робота как можно дешевле, выбор пал на микроконтроллер ATtiny2313 (подсчеты показали, что ножек хватит, хотя задействованы были буквально все ножки, кроме RESET и одного пина порта PORTD). Плата микроконтроллера была полностью взята с сайта RoboZone.su (
Сборка конструкции
Решено было использовать 4 датчика препятствий (по одному над каждым колесом). 4 датчика по два вывода на каждый (катод светодиода направленного вверх и светодиода направленного вперед) заняли 8 ножек (весь PORTB), 4 ножки порта PORTD заняли команды управления драйвером двигателей от радиоуправляемой машинки, 2 порта используются для отладки программы по COM-порту (PORTD.0 и PORTD.1), и даже задействовал PORTA (кнопки START и STOP). Так что почти все ножки микроконтроллера оказались при деле.
В процессе работы оказалось, что почему-то (я так точно и не знаю почему до сих пор) на ножке PORTB.5 (отвечающую за сигнал SCK при программировании) уровень сигнала никогда сам не падает до логического 0 (хотя если дотронуться щупом вольтметра, то все начинает работать), поэтому PORTB.5 был перенесен на PORTD.6 (единственную свободную ножку порта PORTD). Но это для тех кто решит посмотреть исход ник прошивки, чтобы не удивлялись.
Вопрос с питанием был решен использованием 4-х аккумуляторов по 1.2 вольта каждый (итого 4.8 вольта). Изначально машинка была рассчитана на 6 вольт (4 батарейки АА), но подавать 6 вольт на микроконтроллер мне как-то не хотелось (хотя я читал, что должен выдержать), да и идея возможности заряжать аккумуляторы многократно привлекает намного больше чем одноразовые батарейки (хотя покупка двух дополнительных аккумуляторов стоила столько-же сколько вся остальная машинка с механикой и электроникой вместе взятая, но, пожалуй, это говорит больше о дешевизне самого робота).
Вся конструкция собрана на кусочке прозрачного плексигласа, завалявшегося в квартике, который в последствии был дополнен бампером, сделанном из пластиковой крышки от банки с майонезом (потому как надоело в процессе отладки программы разгибать «помятые» светодиоды). Бампер из пластиковой крышки оказался на удивление отличным. Достаточно жестким и в то же время достаточно упругим. Одним словом, хоть и из того что было, но пожалуй лучше было бы и не сделать.
При включении-выключении двигателей наблюдались заметные просадки по питанию, вплоть до сброса микроконтроллера, так что по питанию был добавлен конденсатор 2200мкФ/16Вольт (я не знал как правильно рассчитать необходимую емкость, поэтому просто взял «наобум» достаточно емкий, небольной и не дорогой). Хватил за глаза (хотя создается впечатление, что питание от аккумуляторов более стабильно и меньше подвержено «проседанию» напряжения, чем тестовое питание через КР142ЕН5А, которой я подавал на робота пока занимался отладкой на столе в стационарных условиях (колеса в воздухе).
В дополнение к "родному" отсеку для батареет, находящемуся под днищем машинки, был добавлен еще один такой же сверху, включенный параллельно, для возможности установки 8 аккумуляторов (дающих в сумме больший ток), потому как практика показала, что жрет этот ненасытный малыш достаточно много (минут за 40 активной езды садит комплект аккумуляторов).
Программирование
В принципе задач у робота никаких не стояло. Пока что просто ездит не натыкаясь на препятствия. Так что и программа получилась простая. Датчики опрашиваются последовательно (вначале пробовал опрашивать параллельно, но видимо «земля» для всех ножек микроконтроллера общая, потому что для всех светодиодом время разряда было всегда строго одинаковое). Но последовательного опроса датчиков тоже вполне достаточно. Типично время разряда светодиода-датчика в пасмурную погоду – около 7-10 миллисекунд. Т.е. все 8 светодиодных датчики можно опросить за 80 милисекунд, это примерно 12.5 опросов в секунду. Роботу большый FPS и не нужен. Кроме того, приняты меры предотвращения «зависания» на опросе датчиков. (дело в том, что в полной темноте дветодиодные датчики могут разряжатся до 2-3 секунд, что конечно неприемлемо медленно для робота, но если датчик смотрящий вперед не разрядился за 7-10 миллисекунд, как в пасмурную погоду, то он уже наверняка не засвечивается от препятствия соседним светодиодом, а потому дальше ждать нет смысла да и общая «освещенность» нас в этом случае не волнует, т.к. препятствия заведомо нет).
Движение робота можно описать словами «где свободно туда и едем». Т.е. если оба передних датчика не показываю препятствий – едем вперед. Если препятствие спереди слева, то еде все еще вперед, но поворачиваем вправо (вдруг это ножка стула и мы ее успеем объехать?), и т.д. Аналогично действуем когда едем назад, а назад едем, если оба передних датчика показывают препятствия. Если препятствия показываю все 4 датчика (ну в угол какой-то между мебель заехали), то отключаем двигатели и ждем пока «разработчик» заботливо переставит на свободно пространство.
Испытания
Признаюсь честно, датчики на светодиодах всетаки не так защищены от засветки, как датчики на TSOP-ах, но наличие второго светодиода, измеряющего общую освещенность всеже заметно улучшает ситуацию. Единственный случай, когда датчик неправильно интерпретирует обстановку, когда например Солнце из окна утром/вечером под маленьким углом засвечивает светодиод направленный вперед больше чем направленный вверх, но и это бывает как правило с одним датчиком из 4-х (не может же Солнце засветить и датчики направленные вперед и направленные назад одновременно?). Решается путем направления всех 4-х датчиков в разные стороны (например передние под углом 120 градусов между собой и задние под углом 120 градусов между собой). Таким образом Солнце, даже находясь низко над горизонтом «ошибочно» засвечивает не более одного датчика, и когда машинка едет «на» Солнце, то она просто поочередно «петляет» поворачиваясь к Солнцу то одним передним датчиком то другим (змейкой ездит).
При комнатном освещении (лампочка на потолке), без света или при дневном свете аппарат ведет себя адекватно (нет такого, чтобы светодиод направленный вперед был освещен больше, чем тот, что направлен вверх при отсутствии препятствия). Хотя при ярком Солнце, конечно «дальность» обнаружения препятствия сильно падает (светодиот-фара дает слабую «добавку» к и без того сильной фоновой освещенности). Ночью или в темноте – вообще хорошо себя ведет. Если давать роботу название, то я бы его наверное назвал «The Bat!» (Летучая Мышь) за наиболее адекватную работу в сумерках и темноте и желание «смыться» с от прямых Солнечных лучей в тень.
Питания в 5 вольт для 6-ти вольтовых двигателей вполне достаточно. Хотя по мягкому ковру ездит с трудом. Подводный камень, на который я напоролся с драйвером двигателей был следующий: понятное дело, что нельзя одновременно подавать противоположные сигналы FORWARD и BACKWARD или LEFT и RIGHT, т.к. это приводит к КЗ в драйвере двигателей. И эта возможность была программно исключена. Но оказалось, что если быстро (а микроконтроллер работает на 8 мГц) менять сигналы, то КЗ все равно остается (видимо транзисторы в драйвере так быстро не переключаются), да и нужно «гасить» ток, протекающий в обмотках двигателя в обратном направлении. Так что перед каждой сменой направления двигателя контролер вначале делает паузу 0.7 секунды, и только потом меняет направление вращения двигателя. 0.7 секунды выбраны экспериментально (как их посчитать я тоже не знаю).