Подключение usb мышки к ардуино

Обновлено: 16.05.2024

КПДВ, 111.3 KB

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

Подготовка и немного теории

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

Погуглив информацию по этой теме и разобрав старую PS/2 мышку Logitech, я увидел знакомую по статьям из интернета картину.

Не очень сложная схема «мышей первого поколения», оптический сенсор по центру и чип интерфейса PS/2 чуть выше. Попавшийся мне оптический сенсор является аналогом «популярных» моделей ADNS2610/ADNS2620/PAN3101. Я думаю, они и их аналоги были массово произведены на одном и том же китайском заводе, получив на выходе разную маркировку. Документация на него нашлась очень легко, даже вместе с различными примерами кода.

Документация гласит, что этот сенсор до 1500 раз в секунду получает изображение поверхности размером 18x18 точек (разрешение 400cpi), запоминает его и с помощью алгоритмов сравнения изображений вычисляет смещение по координатам Х и Y, относительно предыдущей позиции.

Реализация

Для «общения с сенсором» я использовал популярную вычислительную платформу Arduino, а припаяться решил прямо к ножкам чипа.

Подключаем 5V и GND к соответствующим выходам Arduino, а ножки сенсора SDIO и SCLK к цифровым пинам 8 и 9.

Для получения смещения по координатам нужно прочитать значение регистра чипа по адресу 0x02 (X) и 0x03 (Y), а для дампа картинки нужно, сначала записать значение 0x2A по адресу 0x08, а потом 18x18 раз его прочитать оттуда же. Это и будет последнее «запомненное» значение матрицы яркости изображения с оптического сенсора.

А для получения и отображения картинки была написана программа на Processing.

Результат

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

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

Если начать приподнимать мышку над поверхностью даже на пару миллиметров, четкость сразу пропадает.

Если вы вдруг захотите повторить это дома, для нахождения мышки с аналогичным сенсором рекомендую искать старые девайсы с интерфейсом PS/2.

Заключение


Хотя получаемое изображение и не очень большое, этого вполне хватило для решения моей задачи (сканнер штрих кода). Получилось очень даже экономично и быстро (мышка за

100р + Arduino + пару дней на написание кода).

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

Теория
Аналогичные работы
Документация
Исходники

UPD от 23.09: добавил немного информации про линзу и номера пинов для ардуины.

Широкую популярность интерфейс PS/2 (Personal System/2) приобрел благодаря использованию для взаимодействия с манипулятором типа мышь в компьютерах Apple Macintosh и позднее, в конце 1980-х годов, в ОС Windows для IBM PC. Однако сегодня PS/2 практически полностью заменен интерфейсом USB. Тем не менее, протокол PS/2 представляет собой интересную платформу для различных экспериментов. Например, можно с помощью клавиатуры, подключенной через этот интерфейс, осуществлять ввод фраз для бегущей строки из светодиодных матриц, подключенных к Arduino.

Схема выводов разъема PS/2 (в просторечии распиновка) представлена на рисунеку


Разъем PS/2

Обмен данными по протоколу PS/2

Обмен данными через PS/2 осуществляется асинхронно по последовательному протоколу. Для обмена информацией используются 2 линии:

1 — DATA (по этой линии передаются сами данные);

5 — CLOCK (по этой линии передаются тактовые сигналы).

При передаче от устройства (клавиатуры или мыши), подключенного через интерфейс PS/2 к компьютеру (или, в нашем случае, к контроллеру), используется протокол, суть которого иллюстрирует схема, показанная на рис. 9.2. Устройство не начинает передачу, если линия Clock не находилась в "1" по крайней мере 50 микросекунд.

Устройство передает последовательно:

стартовый бит — всегда ноль;

стоп-бит — всегда единица.

Таким образом, данные передаются по одному байту за раз, при этом байт данных передается побитно. Первым, как можно видеть, идет стартовый бит (Start bit) — он всегда передается низким уровнем (логический "0"). Далее передается сам байт данных, начиная от младшего бита к старшему. То есть, если нужно передать байт 0xF0, который в двоичной системе записывается так: 11110000, то передаваться его биты будут в следующем порядке: "0","0","0","0","1","1","1","1". После данных идет бит четности (Parity bit): если число четное — будет передана "1", а если нечет- ное — "0". Бит четности — это контрольный бит, принимающий значения "0" или "1" и служащий для проверки общей четности двоичного числа (четности количества единичных битов в числе). Стоп-бит (Stop bit) — всегда логическая "1".

Устройство устанавливает/меняет сигнал Data, когда линия Clock находится в логической единице. Контроллер читает данные, когда линия Clock находится в логиче- ском нуле.

Частота сигнала Clock примерно 10–16,7 кГц. Время от фронта сигнала Clock до момента изменения сигнала Data — не менее 5 микросекунд.


Передача данных от PS/2-клавиатуры (мыши) к контроллеру

При передаче команд в обратную сторону — от контроллера к клавиатуре или мыши — протокол отличается от ранее описанного. Последовательность передаваемых битов здесь будет такая

Хост-контроллер опускает сигнал Clock в ноль на время примерно 100 микросекунд.

Хост-контроллер опускает сигнал Data в ноль, формируя стартовый бит.

Хост-контроллер отпускает сигнал Clock в логическую единицу, клавиатура фиксирует стартовый бит.

Далее клавиатура генерирует сигнал Clock, а хост-контроллер подает передаваемые биты.

После того, как хост-контроллер передаст все свои биты, включая бит четности и стоп-бит, клавиатура посылает последний бит "0", который является подтверждением приема.


Отправка данных по протоколу PS/2 от контроллера к клавиатуре (мыши)

Библиотека ps2dev

Библиотека PS/2 представляет собой класс C++:

PS2dev(int clk, int data); int write(unsigned char data);

int read(unsigned char * data);

int _ps2clk; int _ps2data;

void golo(int pin); void gohi(int pin);

Конструктор класса принимает два параметра типа int — номера портов устройства Arduino, к которым подключены линии Clock и Data, например:

PS2dev mouse(6, 5);

Здесь к Pin5 подключена линия Data, а к pin6 — линия Clock.

Функция golo переводит порт в режим вывода и устанавливает на нем логический "0", функция же gohi переводит порт в режим ввода и подключает на нем подтягивающий резистор. Обе функции имеют тип private и используются только внутри класса. Нам же доступны всего две функции:

write — записывает байт в линию PS/2;

read — считывает байт из линии PS/2.

Подключение клавиатуры

На каждую принятую от контроллера команду (или — проще сказать — на каждый принятый байт) клавиатура должна обязательно ответить одним из следующих байтов:

0xFA — подтверждение об успешном приеме;

0xFE — команда принята с ошибкой — вероятно, это ошибка циклической контрольной суммы (CRC).

При получении от контроллера команды 0xFF (начальная установка) клавиатура отвечает 0xFA, а затем сбрасывается и посылает в ответ байт 0xAA.

В клавиатуру контроллер может послать следующие команды:

0xF3 —– это тоже двухбайтовая команда. После этой команды следует параметр, определяющий частоту повтора кодов при нажатой клавише и интервал времени между нажатием и началом повторов.

После подачи напряжения питания клавиатура посылает код 0xAA и немедленно готова к работе. Она сразу, без дополнительного программирования, готова посылать коды нажатых клавиш. По умолчанию клавиатура посылает на нажатие клавиши один байт-код, а на отпускание клавиши два байта. Первый байт в кодах отпуска ния клавиши — это префикс отпускания 0xF0. Например, если нажать и отпустить клавишу <1>, то клавиатура пошлет последовательность кодов 0x16, 0xF0, 0x16. Существует еще так называемый дополнительный код — это префикс 0хE0. Он посылается вместе с кодами дополнительных клавиш. Например, при нажатии клавиши <Insert> (нецифрового блока) отправляется последовательность 0хE0, 0x70, 0хE0, а при ее отпускании 0xF0, 0x70.

До сих пор все более или менее понятно, но, как оказалось позже (при написании редактора текста — см. разд. 9.4), это еще не все. Получив от контроллера команду зажечь светодиод — например, Num_Lock, клавиатура зажигает соответствующий светодиод, но теперь при нажатии клавиш основной панели клавиатуры, которые продублированы на цифровой панели (<Del>, <Home>, <Insert> и пр.), отправ- ляется иная последовательность байтов, например:

клавиша <Home> основной панели при потушенном Num_Lock:

клавиша <Home> основной панели при включенном Num_Lock:

Это все необходимо учитывать при приеме кодов с клавиатуры. В следующем разделе мы создадим редактор текста. Текст, получаемый с клавиатуры, будет выводиться на дисплей WINSTAR WH1604. При этом вводимый текст мы сможем редактировать.

// будем еще добавлять служебные клавиши

При нажатии обычных клавиш их визуальное представление будет выводиться в текущую позицию дисплея с заменой текущего символа (режим Insert) или со сдвигом курсора вправо. Линию Clock клавиатуры подсоединим к pin3 и запустим обработчик прерывания 1 для отслеживания момента передачи данных с клавиатуры. Схема подключения клавиатуры и дисплея представлена на рисунке


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

В функции начальной установки необходимо инициализировать клавиатуру и дисплей и запустить обработчик прерывания по событию начала отправки кода с клавиатуры. Содержимое функции setup() представлено в примере.

// инициализация клавиатуры kbd_init(); Serial.println("keyboard-ok");

// инициализация дисплея lcd.begin(16, 4);

// ожидание передачи от клавиатуры по прерыванию 1 attachInterrupt(1, get_char, FALLING);

Коды, поступающие с клавиатуры PS/2, не соответствуют кодам ASCII. Если отсечь все служебные коды, из клавиатуры выдаются коды в интервале 0 — 0x7f. Для перевода поступающих кодов в коды ASCII создадим массив размером 1024 байта. Массив памяти условно разделен на 8 блоков. Карта распределения памяти в массиве для разных режимов приведена в таблице. Код нажатия неслужебной клавиши клавиатуры будет являться адресом нахождения соответствующего кода ASCII для нажатой клавиши. Отпускание клавиши отсечем программно. Переключение между языками станем осуществлять по нажатии клавиши <Alt>. В скетче предусмотрим возможность перехода и по нажатии клавиши <Scroll> — этот вариант более удобен, т. к. при этом будет осуществляться индикация на светодиоде Scroll клавиатуры выбранного языка. Выбор нужного символа для режима Num_Lock будем подготавливать программно.

Карта распределения памяти для перевода кодов клавиатуры в коды ASCII

Создадим проект управления курсором мыши с помощью простого джойстика на основе платы Arduino Uno.

Комплектующие

В качестве альтернативы для отслеживания компьютерной мыши с помощью трекпада мы сделаем проект управления мышью с помощью джойстика. Джойстик может перемещать курсор в любом направлении (ось x и y), а также выполняет функцию клика с помощью встроенного переключателя.

Для нашего проекта нам понадобится немного комплектующих.

Аппаратное обеспечение

  1. Arduino UNO × 1
  2. Двухосный джойстик × 1

Программное обеспечение

Основы проекта

Джойстик состоит из двух потенциометров, выровненных в направлении x и y. Arduino считывает аналоговые значения с джойстика в диапазоне от 0 до 1023.

Таким образом, когда джойстик находится в своем положении по умолчанию (в центре), аналоговое значение также становится близким к 500 (между 0 и 1023).


Эскиз Arduino запрограммирован таким образом, что, когда джойстик находится в центральном положении, выводится значение 0 на последовательный монитор, а когда джойстик отведен от центра, выводится значение в диапазоне от -80 до 80.

Таким образом, когда джойстик перемещается в крайнее положение Arduino выводит значение 80, а если джойстик перемещается в другое крайнее положение, то выводится -80.

Чтобы вывести отдельные значения для направления x и y, мы будем использовать «:» между значениями направления x и y. Пример:


Состояние кнопки джойстика (SW) выводится как значение 1 или 0 на последовательном мониторе после значений x и y.

Чтобы ноутбук / компьютер распознал значения, нам понадобится pyautogui на Python.

Схема соединения

Соедините Arduino и джойстик согласно схеме ниже:


Программирование на Python

У пользователя должен быть установлен Python на ноутбуке / компьютере. Его можно скачать здесь.

Для Windows pyautogui можно установить из командной строки, введя 3 следующих команды:

Программа python предназначена для чтения текста, напечатанного Arduino, и распознавания значений направления x и y, а также состояния кнопки (SW).

Текущие координаты курсора получают из функции pyautogui pyautogui.position(), которая предоставляет координаты X и Y курсора в виде пикселей.

Когда джойстик перемещается, аналоговые значения (от -80 до 80), предоставленные Arduino добавляются с текущей позицией курсора для перемещения курсора в нужном направлении.

Чтобы переместить курсор в заданном направлении, функция pyautogui.moveTo(X + x, Y + y) удовлетворяет этой цели.

В функции X и Y - текущая позиция курсора, а x и y - позиции увеличения / уменьшения, предоставляемые Arduino.

Пример:

В этом примере функция перемещает курсор на 200 пикселей по оси x и 150 пикселей по оси y.

Для выполнения операции клика на основе состояния ПО используется pyautogui.click (x, y).

Программы

Запуск проекта

Загрузите эскиз Arduino (приведенный выше) в свой Arduino Uno и подключите джойстик к контактам Arduino, как показано на схеме выше.

Убедившись, что pyautogui установлен на вашем компьютере / ноутбуке, выполните следующие действия.

1. Скопируйте программу для питона в файл блокнота. Укажите правильный COM-порт Arduino.


В диспетчере устройств вы можете посмотреть COM-порт к которому подключена плата Arduino (см. изображение выше). Сохраните файл после внесения изменений.


2. Откройте приложение Python IDLE (python GUI).


Откройте из него файл блокнота.


2. Запустите (run) модуль.


Затем нужно снова вернуться на шаг назад.

В случае если вы видите какие-либо ошибки, перезапустите приложение и проверьте, правильно ли вы указали COM-порт Arduino.

Если ошибок нет, переместите джойстик, и вы увидите движение курсора на экране.

В этой статье мы рассмотрим создание на основе платы Arduino и гироскопа MPU-6050 специального "наперстка" (наконечника, одеваемого на палец), с помощью которого можно будет управлять движениями указателя мыши на экране компьютера.

Внешний вид проекта управления мышкой компьютера с помощью пальцев и Arduino

В некотором плане данный проект похож на проект виртуальной реальности на основе платы Arduino, рассмотренный ранее на нашем сайте. Также на нашем сайте вы можете посмотреть другие проекты, в которых был использован гироскоп MPU-6050:

Необходимые компоненты

  1. Плата Arduino Micro (купить на AliExpress).
  2. Гироскоп MPU-6050 (купить на AliExpress).
  3. Джампер (для соединения Arduino и MPU-6050).
  4. Эластичная лента (если хотите более плотно закрепить устройство на пальце).

Схема проекта

Схема "наперстка" на основе платы Arduino для управления мышкой компьютера представлена на следующем рисунке.

Схема "наперстка" на основе платы Arduino для управления мышкой компьютера

В схеме необходимо сделать следующие соединения между гироскопом MPU-6050 и платой Arduino:
- контакт VCC платы Arduino – к контакту VCC гироскопа;
- контакт GND платы Arduino – к контакту GND гироскопа;
- контакт 2 платы Arduino – к контакту SDA гироскопа;
- контакт 3 платы Arduino – к контакту SCL гироскопа.

Печать на 3D принтере компонентов проекта

Автор данного проекта изготовил две версии рассматриваемого наконечника на пальцы: одна из них изготовлена без использования 3D принтере и она получилась более громоздкой, а вторая, с использованием 3D принтера, получилась менее громоздкой и изготовлена в стиле стимпанка.

Сборка проекта

В стиле стимпанка

В этом случае аккуратно вставьте гироскоп MPU-6050 внутрь верхнего выступа изготовленного корпуса наконечника на палец, а соединительные провода уложите в нижний выступ.

Внешний вид наконечника на палец в стиле стимпанка

Обычная версия

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

Внешний вид обычной версии наконечника на палец

Объяснение программы для Arduino и настройка проекта

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Первым делом в программе нам необходимо подключить библиотеки, которые мы будем использовать в программе – Wire.h, I2Cdev.h, MPU6050.h и Mouse.h.

После этого вам необходимо загрузить в плату Arduino калибровочную программу, код которой приведен в конце данной статьи, одеть наше устройство на палец и открыть окно монитора последовательной связи (Ctrl + Shift + M).

После этого вы в окне монитора последовательной связи должны увидеть примерно следующую картину:

Читайте также: