Все началось с маленькой игры из “темных веков” под названием "Марио", в которой крошечный маленький парень прыгал на утках, чтобы спасти мою принцессу, пока не стал мужественным красивым принцем, бродящим в Персии (Prince of Persia), борющимся против темноты, чтобы спасти мой мир. Я думаю многие из посетителей нашего сайта выросли, играя в эти игры. Но рано или поздно игры надоедают какими увлекательными бы они не были. Но сейчас передовые игровые консоли предлагают игры виртуальной реальности, и это значительно улучшает эффект присутствия в игре по сравнению с управлением игрой с помощью обычной клавиатуры или мышки. И эти новые технологии часто позволяют вдохнуть вторую жизнь в старые игры.
Этот проект предназначен для тех, кто устал играть в популярную компьютерную игру "Angry Birds" с помощью клавиатуры и мыши и хочет попробовать в ней что-нибудь новое. В нем рассмотрим совершенно новый способ управления в этой игре, основанный на использовании платы Arduino, гибкого датчика и потенциометра. Когда гибкий датчик будет изгибаться, птица на катапульте будет также изгибаться, а с помощью потенциометра вы сможете указывать направление, в котором она должна будет запускаться. Описанную в этой статье систему можно также использовать для управления курсором мыши с помощью потенциометра (вдруг это кому-нибудь пригодится). Более подробно про работу с гибким датчиком можно прочитать в этой статье.
Необходимые компоненты
Программное обеспечение
- Arduino IDE.
- Processing IDE.
- Игра Angry Birds на компьютере.
Аппаратное обеспечение
- Плата Arduino (любой версии) (купить на AliExpress).
- Гибкий датчик (Flex Sensor) (купить на AliExpress).
- Потенциометр (купить на AliExpress).
- Резистор 47 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
- Концепция проекта.
Плата Arduino будет считывать значения с потенциометра и гибкого датчика и передавать их на ноутбук/ПК через USB COM порт при помощи стандартной функции Serial.write(). Затем мы будем считывать эту информацию с помощью программной среды Processing и управлять курсором мыши, используя класс Robot в Java, который поддерживается средой разработки Processing IDE. Мы написали программу в Processing IDE, которая при изгибании (оттягивании) гибкого датчика будет делать клик левой кнопкой мыши и курсор мыши будет перемещаться в направлении X в зависимости от того, насколько оттянут гибкий датчик. Затем на основе значения с потенциометра мы будем перемещать курсор мыши в направлении Y, таким образом, мы сможем установить направление, в котором будет запускаться птица.
Работа схемы
Схема устройства представлена на следующем рисунке.
Как можно видеть, мы просто подключили гибкий датчик и потенциометр к аналоговым входам (A0,A1) платы Arduino. Для подключения выхода гибкого датчика к Arduino мы использовали подтягивающий резистор на 47 кОм.
Вы можете соединить все эти компоненты схемы на макетной плате или спаять их на перфорированной плате и разместить все это, к примеру, на перчатках чтобы сделать проект более креативным. Но мы просто использовали макетную плату.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же объяснены наиболее важные его фрагменты.
В программе мы инициализировали последовательный порт для работы на скорости 9600 бод/с и начали считывание значений с выхода гибкого датчика и потенциометра. Как мы знаем, функция serial.write() может передавать только один байт данных в один момент времени. В одном байте 8 бит, следовательно, получаем 2^8 = 256. То есть мы сможем передавать значения от 0 до 256. Значит мы должны сжать (упаковать) значения с выхода гибкого датчика и потенциометра в число от 0 до 256.
Для этого мы будем использовать функцию map() в Arduino. Значения с выхода гибкого датчика конвертируются в диапазон от 5 до 100. То есть когда мы будем изгибать датчик, мы будем иметь инкремент значений начиная с 5 (до 100 при полном изгибе датчика), а когда мы будем отпускать его, то его значение снова будет возвращаться к 5. Для отслеживания кликов мыши мы будем использовать значения 0 и 1. 1 будет соответствовать нажатой кнопке мыши, а 0 – отпущенной кнопке мыши.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if (FlexValue>=65 && FlexValue<=120) //значения с выхода нашего гибкого датчика изменяются от 65 до 120, у используемого вами гибкого датчика могут быть немного другие значения { FlexValue = map (FlexValue,120,65,0,100); //конвертируем эти значения в диапазон от 0 до 100 if (FlexValue>=5) // 1 и 0 используются для указания кликов мышки, поэтому начнем с 5 { Mclick=true; Serial.write(1); //1 передается чтобы сделать клик левой кнопкой мыши Serial.write(FlexValue); //значение с выхода гибкого датчика – это дистанция, на которую нужно передвинуть указатель мыши в направлении X } else { Mclick=false; Serial.write(0);} } |
Аналогичным образом значения с выхода потенциометра конвертируются в диапазон от 101 до 200, используя функцию map(), и затем передаются в компьютер/ноутбук с помощью функции Serial.write().
1 2 3 4 5 |
if (potValue<=200) { potValue = map(potValue,0,200,101,201); //конвертируем значения с выхода потенциометра в диапазон от 101 до 201 Serial.write(potValue); //значение с выхода потенциометра – это дистанция на которую нужно передвинуть указатель мыши в направлении Y } |
Программа в Processing
Processing - это приложение для разработки с открытым исходным кодом, которое можно легко загрузить и использовать для разработки интересных проектов с использованием Arduino или других микроконтроллеров. На нашем сайте вы можете посмотреть все проекты, в которых была использована программная среда Processing.
В этом проекте мы использовали среду processing IDE чтобы считывать данные с COM порта и управлять указателем мыши основываясь на данных полученных по COM порту. Полный код программы в Processing для этого проекта можно загрузить по этой ссылке - Processing Code for Angry Bird Game Controller (клик правой кнопкой мыши и выберите 'Сохранить как').
Данные, поступающие по COM порту, необходимо считывать с той же самой скоростью, с которой они передаются платой Arduino. Удостоверьтесь с помощью диспетчера устройств, что Arduino подсоединена к COM порту. В нашем случае Arduino подключена к порту COM3 (у вас это может быть другой порт – внесите соответствующие изменения в программу), это 0-й порт в нашем компьютере, поэтому для настройки COM порта используем следующую команду:
port = new Serial(this,Serial.list()[0],9600);
Как правильно определить порт в подобных ситуациях описано в данной статье.
Поскольку данные от Arduino поступают к нам в запакованном виде, то здесь (в Processing) мы их должны снова распаковать и использовать для задания положения указателя мыши.
if (port.available()>0)
{
data=port.read();
println(data); // считываем данные с COM порта и сохраняем их в переменной data
}
if (data>=101 && data<=201) //если значение data находится в диапазоне от 101 до 201, то значит в нем присутствуют значения с выхода потенциометра
{
Turn = int (map (data,101,201,0,100)); //используем эти значения чтобы повернуть катапульту
}
if (data>=5 && data <=100) // если значение data находится в диапазоне от 5 до 100, то значит в нем присутствуют значения с выхода гибкого датчика
{ Pull = int (map(data,5,100,0,100));} //используем эти значения чтобы повернуть катапульту
if (data == 1)
click = true; //используем это значение чтобы нажать кнопку мыши
if (data == 0)
click = false; // используем это значение чтобы отпустить кнопку мыши
Теперь, поскольку мы разграничили данные, получаемые по COM порту, мы можем контролировать мышку используя Robot Java Class в программной среде Processing. Команда robot.mouseMove(crntX-Pull, crntY+Turn); может быть использована для перемещения указателя мыши в любую позицию, а команды robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); и robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); можно использовать для нажатия и отпускания кнопки мыши соответственно.
if (click == false) //когда гибкий датчик не изогнут
{
crntX = (int)p.getX() ; crntY = (int)p.getY() ;
if (Pull>50)
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); //отпускаем кнопку мыши
}
if (click == true) //когда гибкий датчик изогнут
{
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); //нажимаем кнопку мыши
robot.mouseMove(crntX-Pull, crntY+Turn); // передвигаем указатель мыши в позицию, зависящую от значений с выходов гибкого датчика и потенциометра
}
}
Когда наша программа будет запущена в processing IDE, она покажет на экране компьютера небольшое диалоговое окно, в котором можно увидеть текущие значения указателя мыши, значения с выходов гибкого датчика и потенциометра, а также нажата ли кнопка мыши или нет.
Эти значения можно использовать для отладки программы (при необходимости).
Работа проекта
Соберите аппаратную часть проекта и загрузите код программы (приведенный в конце статьи) в плату Arduino. Затем определите к какому COM порту в вашем компьютере подключена плата Arduino и внесите соответствующие изменения в код программы в Processing. Скомпилируйте и запустите программу в Processing.
После этого запустите игру Angry Birds, поместите ваш курсор рядом с катапультой и согните гибкий датчик чтобы птица на катапульте также изогнулась. Затем дополнительно задайте направление полета птицы с помощью потенциометра. После этого отпустите гибкий датчик.
EEEEWWWWWEEEEEEEEEE!!!!!!!!!!...............
Ваша птица полетит в воздух и приземлится. Прямо на поросят. Более подробно весь этот процесс показан на видео в конце статьи.
Исходный код программы
Большинство комментариев к данной программе переведено в разделе “Объяснение программы для Arduino” данной статьи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
void setup() { Serial.begin(9600); //инициализация последовательного порта на скорость работы 9600 бод/с } boolean Mclick = false; void loop() { int potValue = analogRead(A0); //переменная чтобы хранить значение с выхода потенциометра int FlexValue = analogRead(A1); // переменная чтобы хранить значение с выхода гибкого датчика // Serial.println(FlexValue); // Serial.print("POT: "); // Serial.println(potValue); // Serial.print("Flex: "); if (FlexValue>=65 && FlexValue<=115) //my flex sensor varies from 65 to 120, your might be different { FlexValue = map (FlexValue,120,65,0,100); //based on bending convert to 0 to 100 if (FlexValue>=5) // 1 and 0 is used for mouse click so start from 5 { Mclick=true; Serial.write(1); //1 is sent to make mouse left click Serial.write(FlexValue); //Flex value is the distance to move mouse in X direction } else { Mclick=false; Serial.write(0);} } else { Mclick=false; Serial.write(0);} if (potValue<=200) { potValue = map(potValue,0,200,101,201); //Based in turn convert to 101 to 201 Serial.write(potValue); //Pot value is the distance to move mouse in Y direction } delay(500); //задержка для стабильности } |