Практическое программирование Arduino/CraftDuino — подключаем мышку PS/2


0. Начало
1. Цифровой ввод — кнопка
2. Аналоговый вывод — Fading
3. Аналоговый ввод – потенциометр
4. Аналоговый ввод – осциллограф
5. Генерация звука – пьезоизлучатель.
6. Фоторезистор
7. Сенсор на светодиоде
8. Общение с Arduino — программирование работы с COM-портом.
9. Аналоговый датчик температуры – LM335

10. Подключаем к Arduino мышку PS/2

На официальном сайте ардуино натолкнулся на библиотеку для работы с устройствами 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 🙂

Далее нужно скачать файл ps2.zip
, который содержит библиотеку для работы с 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

Для чего же мы можем использовать мышку?
Например, как датчик перемещения… ну или просто управлять с помощью мышки сервой или нашим роботом 🙂

Ссылки
1. http://www.arduino.cc/playground/ComponentLib/Ps2mouse
2. http://en.wikipedia.org/wiki/PS/2_connector
3. http://pinouts.ru/Inputs/PS2Mouse_pinout.shtml
4. http://www.ixbt.com/peripheral/mice-sensor.shtml

По теме
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)


14 комментариев на «“Практическое программирование Arduino/CraftDuino — подключаем мышку PS/2”»

  1. А как можно узнать нажатые клавиши или использование колесика прокрутки?
    И еще вопрос: мышь возвращает смещение относительно прошлого сеанса чтения или относительно некого «центра»?

    • обновил статью — после таблички команд добавил табличку данных от мышки.
      данные о нажатых кнопках можно получить в переменной

      mstat

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

    • возвращаемые данные — это смещение относительно последнего положения. чтобы таким образом мерить пройденное расстояние их нужно просто накапливать в счётчике.

    • Да, но порог достигается слишком быстро. Если я двигаю мышку с нужной мне скоростью там всегда 127. Это явно из-за переполнения.

    • значение смещения передаётся в 1 байте, так что ваша скорость больше чем та, которую может обеспечить мышка и вам придётся искать другой вариант датчика перемещения.

  2. для мышки с колесом прокрутки будет 4-й байт — для оси Z

    Не похоже на это. Возможно, что при скролле и передаётся 4-й байт, а в остальных случаях — три, но как это определить? В первом байте в битах 4 и 5 есть информация какое перемещение послано — по X или по Y, но там ни байта про Z 🙂
    Если пытаться тупо читать 4-байт, то система подвисает — я так понимаю уходит в бесконечный цикл в ожидании данных при вызове mouse.read().
    У кого-нить получилось заюзать колёсико?)

    • Разобрался я со скроллом, о чём и спешу поделиться.
      Источник информации (описание протокола на английском языке): http://www.computer-engineering.org/ps2mouse/

      Итак. История колеса прокрутки ведёт свою историю с мышки 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 один раз, а не два. Видимо опечатка.

    • В данной статье есть маленькая неточность: ответ мышки на команду «Set sample rate» возвращает 0хFA один раз, а не два. Видимо опечатка.

      Не совсем соглашусь с данным утверждением. Вероятно, играет роль модель грызуна или что-то еще. Имел дело с Джениусовской мышкой. К слову, она USB’шная, но, несмотря на все вопли об абсолютно разных протоколах, работает совершенно так же, как пспополамная, с теми же пинами.
      Так вот, долго не мог понять, почему не удается включить режим со скроллом. Сегодня наконец вымучил. Дело было в том, что не производилось считывание после отсылки 0xF3. После самой команды также возвращалось 0хFA, после получения чего и удалось включить скролл.
      Хотя в итоге он все равно не так обрадовал. Суть в том, что, в отличие от координат x-y, для скролла не производится накопление, и выдается то число оборотов, которое сделано в сам момент считывания. Таким образом, нужно очень постараться, чтобы получить результат 2 (-2), а больше — совсем никак. Это у всех так, есть способ поменять режим, или же специфика модели?

  3. Мышь — лучшая навигационная система для вашего робота! Непревзайденная точность позиционирования и простота использования! Сарказма насчет ЛСП (локальной системы позиционирования) нет. Так же можно использовать вместо датчика столкновения: на мотор сигнал есть а с мыши не меняются координаты — вы уперлись в стенку!

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

    • Там все дело в фокусе. Под сенсором линза стоит. Можно, конечно, побаловаться с ней, но, боюсь, тогда грызун снова будет работать на очень малом диапазоне расстояний, и вряд ли на поверхности сработает (не в фокусе будет).

  4. Один вопрос — почему у меня макс. значения досигают 63(по обоим осям). При это скорость черепашья. Как тогда в винде мышь работает шустро (не эта, а вообще все пс 2 мыши)?

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

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака телеприсутствие управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение