На официальном сайте ардуино натолкнулся на для работы с устройствами PS/2.
Это даёт шанс пообщаться с компьютерной мышкой напрямую :)
У меня как раз завалялась полудохлая мышка и я сразу решил проверить на ней работу библиотеки :)
Посмотрим, что собственно представляет из себя разъём PS/2 (Personal System)
Если посмотреть на разъём типа «мама» (female connector), выведенный на материнской плате ПК, то увидим шесть входов:
Распиновка (pinout) следующая:
Pin 1 +DATA Data
Pin 2 N/C Not connected
Pin 3 GND Ground
Pin 4 Vcc +5 V DC (до 275 mA)
Pin 5 +CLK Clock
Pin 6 N/C Not connected
Подробнее о протоколе обмена PS/2 можно .
Таким образом, у мышки, имеем шесть выводов, два из которых не используются :)
Т.к. на рисунке приведён пример распиновки «мамы» PS/2, то соответствующие выводы типа «папа» у разъёма компьютерной мышки можно получить зеркальным отображением разъёма :)
Я подпаял к кабелю мышки провода витой пары, которые так хорошо работают с макетной платой, и напрямую подключил их к соответствующим портам ардуины
, как показано на страничке ардуиновской библиотки PS/2 :)
Далее нужно скачать файл
, который содержит библиотеку для работы с PS/2.
Открыв архив, видим папку ps2, которую нужно поместить в библиотечную директорию Arduino IDE (\hardware\libraries\).
Перезапускаем IDE и видим, что у нас появилась не только новая библиотека ps2, но и новые примеры :)
компилируем скетч и загружаем в МК.
Теперь через монитор последовательного порта можем наблюдать, данные о перемещении мышки:
Здорово, правда? И так просто :)
Из документации известно, что X растёт слева-направо, а Y снизу-вверх.
Т.е. вполне обычная для урока математики система координат :)
Таким образом, о движении мышки вправо можно судить по положительной величине X, и наоборот – о движении мышки влево будет говорить отрицательная величина X. Аналогично и для Y.
Обязательно стоит внимательно изучить тестовый скетч ps2_mouse и обратить внимание, что работу с мышкой нужно инициализировать (команда 0xFF)
/*
* скетч для работы с ps/2-мышкой
*/
#include <ps2.h>
/*
* к Pin 5 - подключена линия Data, а к pin 6 – линия Clock
*/
PS2 mouse(6, 5);
/*
* Инициализация работы с мышкой.
* Посылается команда Сброса (Reset it)
* затем мышка переводится режим remote mode
* так, что мы получаем от неё данные по запросу
*/
void mouse_init()
{
mouse.write(0xff); // reset
mouse.read(); // ack byte
mouse.read(); // blank */
mouse.read(); // blank */
mouse.write(0xf0); // remote mode
mouse.read(); // ack
delayMicroseconds(100);
}
void setup()
{
Serial.begin(9600);
mouse_init();
}
/*
* считываем данные с мышки и выводим в COM-порт
*/
void loop()
{
char mstat;
char mx;
char my;
/* запрашиваем данные от мышки */
mouse.write(0xeb); // команда на чтение данных
mouse.read(); // игнорируем ack
mstat = mouse.read();
mx = mouse.read();
my = mouse.read();
/* выводим данные в COM-порт*/
Serial.print(mstat, BIN);
Serial.print("\tX=");
Serial.print(mx, DEC);
Serial.print("\tY=");
Serial.print(my, DEC);
Serial.println();
// delay(20);
}
Список команд, которые поддерживает мышка можно посмотреть в документации на конкретный контроллер, используемый в мышке.
Например, в данной мышке используется оптический сенсор PAW3401,
поддерживающий следующие команды:
а вот табличка — что за данные шлёт мышка в ответ на команду чтения данных (0xEB):
нулевой бит 1-го байта показывает нажата ли левая кнопка мышки, первый бит — правая;
второй байт содержит смещение по X: значение может быть от -127 (смещение влево) до 127 (вправо);
третий байт содержит смещение по Y: значение может быть от -127 (смещение вниз) до 127 (вверх).
Т.о. если мышку не трогать во втором и третьем байтах будут нули.
для мышки с колесом прокрутки будет 4-й байт — для оси Z
Для чего же мы можем использовать мышку?
Например, как датчик перемещения… ну или просто управлять с помощью мышки сервой или нашим роботом :)
А как можно узнать нажатые клавиши или использование колесика прокрутки?
И еще вопрос: мышь возвращает смещение относительно прошлого сеанса чтения или относительно некого «центра»?
обновил статью — после таблички команд добавил табличку данных от мышки.
данные о нажатых кнопках можно получить в переменной
mstat
, в которую считывается первый байт.
Данные о колёсике прокрутки содержатся в четвёртом байте (в скетче не используется).
Возвращаемую величину можно рассматривать как скорость смещения.
возвращаемые данные — это смещение относительно последнего положения. чтобы таким образом мерить пройденное расстояние их нужно просто накапливать в счётчике.
значение смещения передаётся в 1 байте, так что ваша скорость больше чем та, которую может обеспечить мышка и вам придётся искать другой вариант датчика перемещения.
для мышки с колесом прокрутки будет 4-й байт — для оси Z
Не похоже на это. Возможно, что при скролле и передаётся 4-й байт, а в остальных случаях — три, но как это определить? В первом байте в битах 4 и 5 есть информация какое перемещение послано — по X или по Y, но там ни байта про Z :)
Если пытаться тупо читать 4-байт, то система подвисает — я так понимаю уходит в бесконечный цикл в ожидании данных при вызове mouse.read().
У кого-нить получилось заюзать колёсико?)
Разобрался я со скроллом, о чём и спешу поделиться.
Источник информации (описание протокола на английском языке):
Итак. История колеса прокрутки ведёт свою историю с мышки Microsoft Intellimouse. Работает эта мышь (и подобные ей) по протоколу PS/2 с расширением Intellimouse (Intellimouse Extensions). По умолчанию мышь маскируется под обычную, расширение надо включить принудительно. Для этого необходимо послать несколько последовательных команд на изменение частоты дискретизации (sample rate).
У расширения Intellimouse есть два режима: мышка со скролом и мышка со скроллом и пятью кнопками. Для первого режима команды дискретизации будут: 200, 100, 80. Для второго: 200, 200, 80. После этого надо проверить как отреагировала мышь, запросив её ID командой «Get device ID» (0xF2), если ответит 0х00, то это обычная мышь, если 0х03 — то со скроллом, 0х04 — скролл и пять кнопок.
А теперь слайды код:
#include <ps2.h>
PS2 mouse(6, 5);
void mouse_init()
{
mouse.write(0xff); // reset
mouse.read(); // ack byte
mouse.read(); // blank */
mouse.read(); // blank */
mouse.write(0xf0); // remote mode
mouse.read(); // ack
delayMicroseconds(100);
}
char IM_mouse_flag = 0; // флаг, что у нас включено расширение Intellimouse
void setup()
{
Serial.begin(9600);
mouse_init();
// Посылаем 200, 100, 80
mouse.write(0xF3); // set sample rate to...
mouse.write(200); // 200
mouse.read(); // ignore ack
mouse.write(0xF3); // set sample rate to...
mouse.write(100); // 100
mouse.read(); // ignore ack
mouse.write(0xF3); // set sample rate to...
mouse.write(80); // 80
mouse.read(); // ignore ack
mouse.write(0xF2); // get device ID
mouse.read(); // ignore ack
IM_mouse_flag = (mouse.read() == 0x03); // check Intellimouse mode
}
void loop()
{
char mstat;
char mx;
char my;
char scroll;
/* get a reading from the mouse */
mouse.write(0xeb); // give me data!
mouse.read(); // ignore ack
mstat = mouse.read();
mx = mouse.read();
my = mouse.read();
if(IM_mouse_flag)
scroll = mouse.read();
/* send the data back up */
Serial.print(mstat, BIN);
Serial.print("\tX=");
Serial.print(mx, DEC);
Serial.print("\tY=");
Serial.print(my, DEC);
if(IM_mouse_flag){
Serial.print("\t");
Serial.print(scroll, DEC);
}
Serial.println();
}
С моей старой мышкой Logitech это сработало.
Нужно учесть, что на скролл отводится всего три бита в четвёртом байте. Соответственно диапазон значений для колёсика будет -7:+7, а не -127:+127, как для перемещения мышки.
PS: В данной статье есть маленькая неточность: ответ мышки на команду «Set sample rate» возвращает 0хFA один раз, а не два. Видимо опечатка.
Мышь — лучшая навигационная система для вашего робота! Непревзайденная точность позиционирования и простота использования! Сарказма насчет ЛСП (локальной системы позиционирования) нет. Так же можно использовать вместо датчика столкновения: на мотор сигнал есть а с мыши не меняются координаты — вы уперлись в стенку!
Один вопрос — почему у меня макс. значения досигают 63(по обоим осям). При это скорость черепашья. Как тогда в винде мышь работает шустро (не эта, а вообще все пс 2 мыши)?
Комментарии (12)
RSS свернуть / развернутьИ еще вопрос: мышь возвращает смещение относительно прошлого сеанса чтения или относительно некого «центра»?
SabMakc
данные о нажатых кнопках можно получить в переменной
, в которую считывается первый байт.
Данные о колёсике прокрутки содержатся в четвёртом байте (в скетче не используется).
Возвращаемую величину можно рассматривать как скорость смещения.
admin
chiibis
noonv
chiibis
noonv
Не похоже на это. Возможно, что при скролле и передаётся 4-й байт, а в остальных случаях — три, но как это определить? В первом байте в битах 4 и 5 есть информация какое перемещение послано — по X или по Y, но там ни байта про Z :)
Если пытаться тупо читать 4-байт, то система подвисает — я так понимаю уходит в бесконечный цикл в ожидании данных при вызове mouse.read().
У кого-нить получилось заюзать колёсико?)
dansamara
Источник информации (описание протокола на английском языке):
Итак. История колеса прокрутки ведёт свою историю с мышки Microsoft Intellimouse. Работает эта мышь (и подобные ей) по протоколу PS/2 с расширением Intellimouse (Intellimouse Extensions). По умолчанию мышь маскируется под обычную, расширение надо включить принудительно. Для этого необходимо послать несколько последовательных команд на изменение частоты дискретизации (sample rate).
У расширения Intellimouse есть два режима: мышка со скролом и мышка со скроллом и пятью кнопками. Для первого режима команды дискретизации будут: 200, 100, 80. Для второго: 200, 200, 80. После этого надо проверить как отреагировала мышь, запросив её ID командой «Get device ID» (0xF2), если ответит 0х00, то это обычная мышь, если 0х03 — то со скроллом, 0х04 — скролл и пять кнопок.
А теперь
слайдыкод:С моей старой мышкой Logitech это сработало.
Нужно учесть, что на скролл отводится всего три бита в четвёртом байте. Соответственно диапазон значений для колёсика будет -7:+7, а не -127:+127, как для перемещения мышки.
PS: В данной статье есть маленькая неточность: ответ мышки на команду «Set sample rate» возвращает 0хFA один раз, а не два. Видимо опечатка.
dansamara
noonv
MAFia
MAFia
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.