Как сделать кликер в ардуино
Перейти к содержимому

Как сделать кликер в ардуино

  • автор:

Arduino.ru

Добрый день господа, я знаю таких проектов полно, но мне лень искать искать и править.

Arduino 1.6.5 так как страшие версии не правильно понимают экран

FLProg на всякий случай

Arduino Nano Atmega 328

Экран 2х16 1602A подключенный через I2C, адрес 0х27

Хочу сделать кликер/счетчик нажатия на кнопку. Работа легкая, но повторюсь лень

  • Войдите на сайт для отправки комментариев

Втр, 08/03/2016 — 08:22
Зарегистрирован: 07.03.2016

Написал скетч с помощью FLProg, но счетчик сичатает нажата кнопка или нет, а мне нужно чтобы общее количество нажатий было.

bool _count1I = 0; unsigned long _count1P = 0UL; bool _bounseInputD12S = 0; bool _bounseInputD12O = 0; unsigned long _bounseInputD12P = 0UL; bool _bounseInputD13S = 0; bool _bounseInputD13O = 0; unsigned long _bounseInputD13P = 0UL; void setup() < Serial.begin(9600); pinMode(13, INPUT); //кликать суды pinMode(12, INPUT); //сброс _bounseInputD12O = digitalRead(12); _bounseInputD13O = digitalRead(13); >void loop() < bool _bounceInputTmpD12 = (digitalRead (12)); if (_bounseInputD12S) < if (millis() >= (_bounseInputD12P + 40)) > else < if (_bounceInputTmpD12 != _bounseInputD12O ) > bool _bounceInputTmpD13 = (digitalRead (13)); if (_bounseInputD13S) < if (millis() >= (_bounseInputD13P + 40)) > else < if (_bounceInputTmpD13 != _bounseInputD13O ) > if (_bounseInputD13O) < if (! _count1I) < _count1P = _count1P+1; _count1I = 1; >> else < _count1I=0; >if (_bounseInputD12O) _count1P = 0; Serial.print(_count1I);; delay (100); >

P.S. Пока пишу на сериал порт, дабы не нагибаться постоянно

  • Войдите на сайт для отправки комментариев

Как сделать кликер в ардуино

При подключении платы Digispark к USB компьютера, она определяется как компьютерная мышь.

Принцип работы заключается в том, что при нажатии на кнопку эмитируется нажатие левой кнопки мыши в бесконечном цикле с рандомной задержкой между кликами. За задержку отвечает переменная “j” и она имеет два параметра, это значения 200 и 3000. В нашем случае величина задержки будет генерироваться в пределах от 200 миллисекунд до 3000 миллисекунд.

Остановить цикл можно повторным нажатием на кнопку, или отсоединением платы от компьютера.

Переменная “j” помечена комментарием //НАСТРОЙКА! Настройте её на свое усмотрение и загрузите скетч на плату.

Как прошить плату Digispark на базе микроконтроллера ATtiny 85 смотрите по этой ссылке www.kolotushkin.com/Как прошить плату Digispark на базе микроконтроллера ATtiny 85

//Начало скетча

#include "DigiMouse.h" const int buttonPin = 1; int buttonState = 0; int i = 0;//переменная для цикла while int j = random (200, 3000);//НАСТРОЙКА! void setup()  pinMode(buttonPin, INPUT);//определяем переменную buttonPin как вход DigiMouse.begin(); > void loop()  buttonState = digitalRead(buttonPin);//проверка состояния кнопки if (buttonState == HIGH)  delay(500); //если кнопка нажата, то сделать паузу на 500 мс и перейти к while while (i  1)  unsigned long currentTime; //Переменная текущего времени if (millis() - currentTime > j)  currentTime = millis(); j = random (200, 3000);//НАСТРОЙКА! DigiMouse.setButtons(1  <0); //нажать на левую кнопку мыши //DigiMouse.setButtons(2 <<0);//нажать на правую кнопку мышиDigiMouse.delay(50);//Задержка 50 миллисекунд DigiMouse.setButtons(0);//отпустить все кнопки DigiMouse.delay(50);//Задержка 50 миллисекунд > buttonState = digitalRead(buttonPin); //проверка состояния кнопки if (buttonState == HIGH)  delay(500); // Если кнопка нажата, то сделать паузу на 500 мс и выйти из цикла break; > > > > 

//Конец скетча

//Дополнительные команды

DigiMouse.moveX(20); //переместить курсор вправо на 20 пикселей DigiMouse.moveX(-20); //переместить курсор влево на 20 пикселей DigiMouse.moveY(20); //переместить курсор вниз на 20 пикселей DigiMouse.moveY(-20); //переместить курсор вверх на 20 пикселей DigiMouse.scroll(10); //крутить колесико вперед на 10 DigiMouse.scroll(10); //крутить колесико назад на 10 

В конце скетча имеются Дополнительные команды! На тот случай если вы захотите добавить функции к устройству.

После загрузки припаяйте кнопку к контактам P1 и 5V, как показано на этой схеме.

Кликер своими руками

Попросил меня на днях товарищ помочь с одной задачкой: управлять компом с аудиопроигрывателем, установленном на ноутбуке с Windows, с помощью маленького аппаратного пультика. Просил всякие ИК пульты не предлагать. И сделать AVR-е, коих у него осталось некоторое немалое количество, пристраивать потихоньку надо.

Постановка задачи

Задача, очевидно, делится на две части:

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

Раз уж работаем с AVR, то почему бы не Arduino?

Поставим задачу.
Аппаратная платформа:
HW1. Управление ведётся кнопками без фиксации;
HW2. Обслуживаем 3 кнопки (в общем случае сколько не жалко);
HW3. Нажатием считается удерживание кнопки не менее 100 миллисекунд;
HW4. Более длинные нажатия игнорируются. Обработка более 1 кнопки за раз не выполняется;
HW5. При нажатии кнопки запускается некоторое действие на компьютере;
HW6. Обеспечить интерфейс связи с компьютером через встроенный Serial/USB-преобразователь;
Программная платформа:
SW1. Обеспечить интерфейс связи с компьютером через выбираемый последовательный порт;
SW2. Преобразовывать приходящие по интерфейсу связи команды в события операционной системы, доставляемые до нужного аудиоплеера.
SW3. Приостановка обработки команд. В том числе по команде с пульта.

Ну и дополнительное требование: если это не вносит серьёзных затрат времени, сделать решения максимально универсальными.

Проектирование и решение

HW1

Схема подключения кнопки

Кнопки кнопки пребывают в положении «нажато» непродолжительное время. Кроме того, кнопки могут дребезжать (то есть формировать множество срабатываний за короткий промежуток времени из-за нестабильного контакта).
К прерываниям их подключать нет смысла — не те времена отклика нужны, чтобы этим заморачиваться. Будем читать их состояния с цифровых пинов. Для обеспечения стабильного чтения кнопки в ненажатом состоянии необходимо подключить входной пин к земле (pull-down) или к питанию (pull-up) через подтягивающий резистор. Воспользуемся встроенным pull-up резистором не будем делать дополнительный дискретный элемент на схеме. С одной стороны кнопку подключим к нашему входу, другой — к земле. Вот что получается:

И так — для каждой кнопки.

HW2

Кнопок надо несколько, поэтому нам нужно некоторое количество однородных записей о том, как кнопки опрашивать и что надо делать, если она нажата. Смотрим в сторону инкапсуляции и делаем класс кнопки Button , который содержит в себе номер пина, с которого ведётся опрос (и сам же его инициализирует), и команду, которую надо послать в порт. С тем, что из себя представляет команда, разберёмся позже.

Класс кнопки будет выглядеть примерно так:

Код класса Button

class Button < public: Button(uint8_t pin, ::Command command) : pin(pin), command(command) <>void Begin() < pinMode(pin, INPUT); digitalWrite(pin, 1); >bool IsPressed() < return !digitalRead(pin); >::Command Command() const < return command; >private: uint8_t pin; ::Command command; >;

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

Соберём кнопки воедино и назначим им пины:

Button buttons[] = < Button(A0, Command::Previous), Button(A1, Command::PauseResume), Button(A2, Command::Next), >;

Инициализация всех кнопок делается вызовом метода Begin() для каждой кнопки:

for (auto &button : buttons)

Для того, чтобы определить, какая кнопка нажата, будем перебирать кнопки и проверять, нажато ли что-нибудь. Возвращаем индекс кнопки, либо одно из спецзначений: «не нажато ничего» и «нажато более одной кнопки». Спецзначения, разумеется, не могут пересекаться с допустимыми значениями номеров кнопок.

GetPressed()

int GetPressed() < int index = PressedNothing; for (byte i = 0; i < ButtonsCount; ++i) < if (buttons[i].IsPressed()) < if (index == PressedNothing) < index = i; >else < return PressedMultiple; >> > return index; >

HW3

Кнопки будем опрашивать с некоторым периодом (скажем, 10 мс), и будем считать, что нажатие произошло, если одна и та же кнопка (и ровно одна) удерживалась заданное количество циклов опроса. Делим время фиксации (100 мс) на период опроса (10 мс), получаем 10.
Заведём декрементный счётчик, в который записываем 10 при первой фиксации нажатия, и декрементируем на каждом периоде. Как только он переходит из 1 в 0, запускаем обработку (см HW5)

HW4

Если счётчик уже равен 0, никаких действий не выполняется.

HW5

Как было сказано выше, с каждой кнопкой ассоциирована выполняемая команда. Она должна быть передана через коммуникационный интерфейс.

На этом этапе можно реализовать стратегию работы клавиатурой.

Реализация главного цикла

void HandleButtons() < static int CurrentButton = PressedNothing; static byte counter; int button = GetPressed(); if (button == PressedMultiple || button == PressedNothing) < CurrentButton = button; counter = -1; return; >if (button == CurrentButton) < if (counter >0) < if (--counter == 0) < InvokeCommand(buttons[button]); return; >> > else < CurrentButton = button; counter = PressInterval / TickPeriod; >> void loop()

HW6

Интерфейс связи должен быть понятным и отправителю, и получателю. Поскольку последовательный интерфейс имеет единицу передачи данных в 1 байт и имеет байтовую синхронизацию, то нет особого смысла городить что-то сложное и ограничимся передачей одного байта на команду. Для удобства отладки сделаем передачу одного ASCII-символа на команду.

Реализация на Arduino

Теперь собираем. Полный код реализации показан ниже под спойлером. Для его расширения достаточно указать ASCII-код новой команды и привязать к ней кнопку.
Можно, конечно, было бы просто для каждой кнопки явно указать код символа, но мы так делать не будем: именование команд нам пригодится при реализации клиента для ПК.

Полная реализация

const int TickPeriod = 10; //ms const int PressInterval = 100; //ms enum class Command : char < None = 0, Previous = 'P', Next = 'N', PauseResume = 'C', SuspendResumeCommands = '/', >; class Button < public: Button(uint8_t pin, Command command) : pin(pin), command(command) <>void Begin() < pinMode(pin, INPUT); digitalWrite(pin, 1); >bool IsPressed() < return !digitalRead(pin); >Command GetCommand() const < return command; >private: uint8_t pin; Command command; >; Button buttons[] = < Button(A0, Command::Previous), Button(A1, Command::PauseResume), Button(A2, Command::Next), Button(12, Command::SuspendResumeCommands), >; const byte ButtonsCount = sizeof(buttons) / sizeof(buttons[0]); void setup() < for (auto &button : buttons) < button.Begin(); >Serial.begin(9600); > enum < PressedNothing = -1, PressedMultiple = -2, >; int GetPressed() < int index = PressedNothing; for (byte i = 0; i < ButtonsCount; ++i) < if (buttons[i].IsPressed()) < if (index == PressedNothing) < index = i; >else < return PressedMultiple; >> > return index; > void InvokeCommand(const class Button& button) < Serial.write((char)button.GetCommand()); >void HandleButtons() < static int CurrentButton = PressedNothing; static byte counter; int button = GetPressed(); if (button == PressedMultiple || button == PressedNothing) < CurrentButton = button; counter = -1; return; >if (button == CurrentButton) < if (counter >0) < if (--counter == 0) < InvokeCommand(buttons[button]); return; >> > else < CurrentButton = button; counter = PressInterval / TickPeriod; >> void loop()

И да, я сделал ещё одну кнопку, чтобы иметь возможность приостановки передачи команд на клиента.

Клиент для ПК

Переходим ко второй части.
Поскольку сложного интерфейса нам не надо, и привязка к Windows, то можно пойти разными путями, кому как нравится: WinAPI, MFC, Delphi, .NET (Windows Forms, WPF и т.д.), или же консольки на тех же платформах (ну, кроме MFC).

SW1

Данное требование закрывается через коммуникацию с последовательным портом на выбранной программной платформе: подключаемся к порту, читаем байты, обрабатываем байты.

SW2

Пожалуй, все видели клавиатуры с мультимедийными клавишами. Каждая клавиша на клавиатуре, в том числе мультимедийная, имеет свой код. Самое простое решение нашей задачи — это имитация нажатий мультимедийных клавиш на клавиатуре. С кодами клавиш можно ознакомиться в первоисточнике — MSDN. Осталось научиться их посылать в систему. Это тоже не сложно: есть в WinAPI функция SendInput.
Каждое нажатие клавиши — это два события: нажатие и отпускание.
Если мы пользуемся C/C++, то можно просто подключить заголовочные файлы. На других языках надо сделать проброс вызовов. Так, например, при разработке на .NET придётся импортировать указанную функцию и описать аргументы. Я выбрал .NET за удобство разработки интерфейса.
Я выделил из проекта только содержательную часть, которая сводится к одному классу: Internals .
Вот его код:

Код класса Internals

 internal class Internals < [StructLayout(LayoutKind.Sequential)] [DebuggerDisplay("")] private struct INPUT < public uint Type; public KEYBDINPUT Data; public const uint Keyboard = 1; public static readonly int Size = Marshal.SizeOf(typeof(INPUT)); >[StructLayout(LayoutKind.Sequential)] [DebuggerDisplay("Vk= Scan= Flags= Time= ExtraInfo=")] private struct KEYBDINPUT < public ushort Vk; public ushort Scan; public uint Flags; public uint Time; public IntPtr ExtraInfo; private long spare; >[DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure); private static INPUT[] inputs = < new INPUT < Type = INPUT.Keyboard, Data = < Flags = 0 // Push >>, new INPUT < Type = INPUT.Keyboard, Data = < Flags = 2 // Release >> >; public static void SendKey(Keys key) < inputs[0].Data.Vk = (ushort) key; inputs[1].Data.Vk = (ushort) key; SendInput(2, inputs, INPUT.Size); >>

В нём сначала идёт описание структур данных (отрезано только то, что касается клавиатурного ввода, поскольку мы его имитируем), и собственно импорт SendInput .
Поле inputs — массив из двух элементов, будет использоваться для генерации событий клавиатуры. Нет смысла выделять его динамически, если архитектура приложения предполагает, что вызова SendKey в несколько потоков не будет выполняться.
Собственно, дальше дело техники: заполняем соответствующие поля структур виртуальным кодом клавиши и отправляем в очередь ввода операционной системы.

SW3

Требование закрывается очень просто. Заводится флаг и ещё одна команда, которая обрабатывается особым образом: флаг переключается в противоположное логическое состояние. Если он установлен, то остальные команды игнорируются.

Вместо заключения

Улучшайзингом можно заниматься бесконечно, но это уже совсем другая история. Я не привожу здесь проект Windows-клиента, потому как он предоставляет широкий полёт фантазии.
Для управления медиаплеером посылаем один набор «нажатий» клавиш, если надо управлять презентациями — другой. Можно сделать модули управления, собирать их либо статически, либо в виде подключаемых плагинов. Вообще много чего можно. Главное — желание.

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

Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно.
Вам необходимо обновить браузер или попробовать использовать другой.

SET

21 Авг 2019 2 0

Всем доброго время суток!
Есть идея для компьютерной игры.
Нужно нажимать на компьютерной мышке одну кнопку каждые 25-30 мин, по 3 раза подряд с паузой в 2 секунды и с задержкой в 1 секунду.
Саму кнопку подключить к Реле+Ардуино и питать его от USB .
Сам я не селен в элементной базе, нужно все уместить в корпусе мышки, прошу помочь.

DIM_OST

21 Авг 2019 1 0

Всем доброго время суток!
Есть идея для компьютерной игры.
Нужно нажимать на компьютерной мышке одну кнопку каждые 25-30 мин, по 3 раза подряд с паузой в 2 секунды и с задержкой в 1 секунду.
Саму кнопку подключить к Реле+Ардуино и питать его от USB .
Сам я не селен в элементной базе, нужно все уместить в корпусе мышки, прошу помочь.

Добрый день, реализовать можно несколькими способами: 1.Arduino leonardo — это копия Arduino uno но она может эмулировать нажатия кнопок на клавиатуре или мышке а так же передвигать курсор. 2.bs Micro— arduino leonardo размером с монету и стоимостью как флешка https://ru.aliexpress.com/item/32778104714.html. Не вижу смысла заморачиваться с реле и большой ардуино.

SET

21 Авг 2019 2 0

Добрый день, реализовать можно несколькими способами: 1.Arduino leonardo — это копия Arduino uno но она может эмулировать нажатия кнопок на клавиатуре или мышке а так же передвигать курсор. 2.bs Micro— arduino leonardo размером с монету и стоимостью как флешка https://ru.aliexpress.com/item/32778104714.html. Не вижу смысла заморачиваться с реле и большой ардуино.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *