Простое удалённое управление с компьютера роботом

Предисловие или зачем извращаться? Здравствуй, Хабрахабр! Я сидел вечером 11 июня, смотрел фильм. Неожиданно для себя я обнаружил, что мне написала незнакомая мне ранее женщина с предложением сделать робота для их нового квеста. Суть заключается в том, что нужно разгадывать головоломки, исследовать тайники, правильно применять подсказки, использовать доступные вещи и в итоге добывать ключи и открывать двери… От меня требовалось сделать робота, управляемого с компьютера с помощью отдельной программы. У мебя были сомнения по поводу 2 вещей: успею ли я и как именно сделать беспроводную передачу данных (беспроводной передачей данных я занимался до этого только на NXT)? Взвесив все за и против я согласился. После этого я стал думать над передачей данных. Поскольку требовалось сделать робота быстро, то вспоминать и доосваевать, например, дельфи не было времени, поэтому возникла идея сделать модуль который будет заниматься отправкой команд. От компьютера требуется просто посылать данные в СОМ-порт. Этот способ странный, но наиболее быстрый. Его я и хочу описать здесь. Так же я приложу 3 программы которые помогут сделать радиоуправляемую машинку.Сборка передатчика и его программа. Я сделал модуль для компьютера из FTDI Basic Breakout 5/3.3V от DFrobot, довольно распространённого микроконтролера ATMEGA 328P-PU с загрузчиком Arduino и радиомодуля на основе микросхемы nRF24L01. По-сути это просто Arduino Uno с радиомодулем. Что есть, то есть. У радиомодуля есть особенность, которую я не сразу заметил: входное напряжение должно быть в диапазоне от 3 до 3.6 вольт (хотя подача на него 5 вольт его не убьёт, но работать не будет), верхняя граница логической единицы составляет 5В. Это означает то, что для подключения радиомодуля к меге не нужен преобразователь уровней между 3.3В и 5В, а вот стабилизатор на 3.3В установить нужно. У FTDI есть встроенный стабилизатор, от него я и подпитал радиомодуль.Так выглядит сам модуль (внутри и в сборке) : cb539b214d4bd9ae9ee068d31ca6f55e.png

Программа состоит из инициализации, стартового сообщения и обработки команд из программы управления. Так было в моём случае. Основные команды библиотеки Mirf:

#include #include #include #include #include Эти библиотеки нужны для работы радиомодуля

Mirf.csnPin = 4 — задаёт номер пина, отвечающего за «разрешение общаться» радиомодуля и МКMirf.cePin = 6 — задаёт номер пина, отвечающего за режим работы радиомодуля (приёмник/передатчик)Mirf.spi = &MirfHardwareSpi — настраивает линию SPIMirf.init () — инициализирует радиомодульMirf.payload = 1 — размер в байтах одного сообщения (поумолчанию 16, максимум 32)Mirf.channel = 19 — задаёт канал (0 — 127, по умолчанию 0)Mirf.config () — задаёт параметры передачи

Mirf.setTADDR ((byte *)«serv1») — переводит радиомодуль в режим передатчикаMirf.setRADDR ((byte *)«serv1») — переводит радиомодуль в режим приёмника

Mirf.send (data) — отправляет массив типа byteMirf.dataReady () — сообщает об окончании обработки принятых данныхMirf.getData (data) — записать принятые данные в массив data

Mirf.setTADDR ((byte *)«serv1») — переводит радиомодуль в режим передатчикаMirf.setRADDR ((byte *)«serv1») — переводит радиомодуль в режим приёмника

Mirf.send (data) — отправляет массив типа byteMirf.dataReady () — сообщает об окончании обработки принятых данныхMirf.getData (data) — записать принятые данные в массив data

Прилагаю код программы передатчика.

Программа передатчика #include #include #include #include #include char active; byte data[1];

void setup (){Serial.begin (19200);

Mirf.csnPin = 4; Mirf.cePin = 6; Mirf.spi = &MirfHardwareSpi; Mirf.init (); Mirf.payload = 1; Mirf.channel = 19; Mirf.config ();

Mirf.setTADDR ((byte *)«serv1»);

//сигнальное сообщение о начале работыdata[0]=7; Mirf.send (data); delay (200);}

void loop (){if (Serial.available ()) //Если данные готовы к считыванию{active=Serial.read (); // Запись данных в переменную}

if (active=='2'){data[0]=2;}

if (active=='3'){data[0]=3;}

if (active=='4'){data[0]=4;}

if (active=='5'){data[0]=5;}

if (active=='6'){data[0]=6;}

Mirf.send (data); //Отсылаем данныеwhile (Mirf.isSending ()); // Ждём пока данные отсылаются}

Программа управления. Есть одна интересная штука — Processing. Синтаксис такой же как в Arduino, только вместо void loop () там расположился void draw (). Но она становилась ещё более интересной в моей ситуации с библиотекой processing Serial, которая позволяет работать с сериал-портом. Прочитав уроки на сайте Spurkfun`а, я поигрался с миганием светодиода на подключенной к компьютеру ардуинке по клику мышки. После этого я написал программу управления роботом с клавиатуры. Прилагаю код управления с помощью стрелок. В нём, в принципе, ничего необычного нет.

Программа управления машинкой import processing.serial.*; import cc.arduino.*; Serial myPort; PFont f=createFont («LetterGothicStd-32.vlw», 24);

void setup (){size (360, 160); stroke (255); background (0); textFont (f);

noCursor ();

String portName = «XXXX»; // Сюда нужно написать имя вашего портаmyPort = new Serial (this, portName, 19200);}

void draw () {if (keyPressed == false){clear (); myPort.write ('6'); println (»6»);}}

void keyPressed (){// 10 — enter// 32 — probel// 37/38/39/40 — keysclear ();

fill (255); textAlign (CENTER);//text (keyCode, 180, 80);

switch (keyCode){case 37: text («Edem vlevo», 180, 80); myPort.write ('1'); break;

case 38: text («Edem pryamo», 180, 80); myPort.write ('2'); break;

case 39: text («Edem vpravo», 180, 80); myPort.write ('3'); break;

case 40: text («Edem nazad», 180, 80); myPort.write ('4'); break;

default: text («Takoy kommandi net», 180, 80); myPort.write ('6'); break;}}

Программа приёмника. Инициализация этой программы отличается от инициализации программы передатчика буквально одной строчкой. Ключевая команда в бесконечном цикле Mirf.getData (data). Дальше полученная команда сравнивается с числами, которым соответствуют какие-либо действия робота. Ну, а дальше робот действует точно по командам. Прилагаю код программы приёмника машинки.

Программ машинки #include #include #include #include #include void setup (){Serial.begin (9600);

pinMode (13, OUTPUT); //LED

Mirf.csnPin = 10; Mirf.cePin = 9; Mirf.spi = &MirfHardwareSpi; Mirf.init (); Mirf.payload = 1; Mirf.channel = 19; Mirf.config (); Mirf.setRADDR ((byte *)«serv1»);}

void loop (){byte data[1];

if (! Mirf.isSending () && Mirf.dataReady ()){Mirf.getData (data); Serial.println (data[0]);}

switch (data[0]){case 1: motors (-100, 100); // поворачиваем влевоbreak;

case 2: motors (100, 100); // едем прямоbreak;

case 3: motors (100, -100); // поворачиваем вправоbreak;

case 4: motors (-100, -100); // едем назадbreak;

default: motors (0, 0); // стоимbreak;}

delay (50);}

Заключение. Что из этого всего вышло: www.youtube.com/watch? v=K5ekFyph82U

Этого робота я сделал для «Клаустрофобии». Они проводят квесты в реальности в разных городах, и как раз для одного из таких квестов организаторам понадобился радиоуправляемый робот-сапер. Мне понравилось. Это, конечно, ущербно, т.к. на фоне управления с помощью встроенных в ноутбук средств связи, но зато своё, сделанное весьма быстро и без особых проблем. Надеюсь эта статья поможет сделать нечто подобное, а, может, даже сложнее. Тут уж кому что захочется.

© Habrahabr.ru