library for connecting Synaptics TouchPad to arduino
Протокол PS/2 включает два сигнальных провода, а также питание +5v и землю. Сигнальные провода, CLK и DATA, представляют собой двунаправленные сигналы с открытым стоком. Они удерживаются на высоком уровне (+5v) подтягивающим резистором 5–10 кОм на хосте. Хост или сенсорная панель могут в любой момент снизить уровень CLK или DATA. Когда порт бездействует, оба сигнальных провода находятся на высоком уровне. Хост может заблокировать устройство в любое время, удерживая CLK на низком уровне. Линии CLK и DATA должны иметь общую емкость не более 500pf, чтобы подтягивающий резистор 5–10 кОм мог вывести их на высокий уровень напряжения за разумное время.
Стандартная мышь PS/2 отправляет информацию о движении (и кнопках) на хост, используя следующий 3-байтовый пакет
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
Byte 1 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn |
Byte 2 | X Movement 7...0 | |||||||
Byte 3 | Y Movement 7...0 |
Счетчики движения представляют собой 9-битные целые числа с дополнением до 2, где самый старший бит появляется как знаковый бит в байте 1 пакета данных движения. Эти счетчики обновляются, когда мышь считывает ввод и обнаруживает, что произошло движение. Их значение - это количество перемещений, которое произошло с момента отправки последнего пакета данных о перемещении на хост (т.е. После того, как пакет отправлен на хост, счетчики перемещений сбрасываются). Диапазон значений, который может быть выражен с помощью счетчиков движения от -255 до +255. Если этот диапазон превышен, устанавливается соответствующий бит переполнения, и счетчик не увеличивается/уменьшается до тех пор, пока он не будет сброшен. Сброс происходит всякий раз, когда пакет данных движения успешно отправляется на хост. Они также сбрасываются после того, как мышь получает любую команду от хоста, кроме команды "Отправить повторно" (0xFE).
Каждый байт, передаваемый между устройством и хостом, включает в себя стартовый бит (логический 0), восемь бит данных (сначала младший бит), бит четности (нечетная четность) и стоповый бит (логическая 1).
Нечетность означает, что восемь битов данных и бит четности вместе содержат нечетное количество единиц.
Каждый байт команды создает по крайней мере один байт ответа от сенсорной панели. Для каждой команды, кроме команды "Отправить повторно" (0xFE), ответ всегда начинается с байта "Подтверждение" ACK (0xFA).
Пример инициализации microsoft scrolling mouse от Adam Chapweske
Power-on Reset : Включение питания
Mouse: AA Self-test passed : Мышь отправляет 0xAA Успешная самодиагностика
Mouse: 00 Mouse ID : Мышь отправляет свой DI 0x00
Host: FF Reset command : Хост отправляет команду перезагрузки 0xFF
Mouse: FA Acknowledge : ACK подтверждение от мыши о том что команда принята 0xFA
Mouse: AA Self-test passed : При инициализации 3 раза хост отправляет команду 0xFF (перезагрузка)
Mouse: 00 Mouse ID
Host: FF Reset command
Mouse: FA Acknowledge
Mouse: AA Self-test passed
Mouse: 00 Mouse ID
Host: FF Reset command
Mouse: FA Acknowledge
Mouse: AA Self-test passed
Mouse: 00 Mouse ID
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: C8 decimal 200
Mouse: FA Acknowledge
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: 64 decimal 100
Mouse: FA Acknowledge
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: 50 decimal 80
Mouse: FA Acknowledge
Host: F2 Read Device Type
Mouse: FA Acknowledge
Mouse: 00 Mouse ID
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: 0A decimal 10
Mouse: FA Acknowledge
Host: F2 Read Device Type
Mouse: FA Acknowledge
Mouse: 00 Mouse ID
Host: E8 Set resolution
Mouse: FA Acknowledge
Host: 03 8 Counts/mm
Mouse: FA Acknowledge
Host: E6 Set Scaling 1:1
Mouse: FA Acknowledge
Host: F3 Set Sample Rate
Mouse: FA Acknowledge
Host: 28 decimal 40
Mouse: FA Acknowledge
Host: F4 Enable
Mouse: FA Acknowledge
Initialization complete...
В потоковом режиме мышь отправляет данные о движении, когда обнаруживает движение или изменение состояния одной или нескольких кнопок мыши. Максимальная частота, с которой может происходить этот отчет, известна как частота дискретизации. Этот параметр находится в диапазоне от 10 выборок/сек до 200 выборок/сек. Его значение по умолчанию составляет 100 выборок в секунду, и хост может изменить это значение с помощью команды "Установить частоту дискретизации" (0xF3). Потоковый режим - это режим работы по умолчанию и этот режим реализован в библиотеке PS2Mouse.
В этом режиме мышь считывает свои входы и обновляет свои счетчики/флаги с текущей частотой дискретизации, но она только уведомляет хост о движении (и изменении состояния кнопки), когда эта информация запрашивается хостом. Хост делает это, выдавая команду "Прочитать данные" (0xEB). После получения этой команды мышь отправит пакет данных о движении и сбросит свои счетчики движения.
Относительный режим является режимом по умолчанию для большинства сенсорных панелей Synaptics. При подаче питания сенсорная панель идентифицируется для главного компьютера как обычная мышь. Это позволяет использовать сенсорную панель со стандартными драйверами мыши. Этот режим, совместимый с мышью, называется относительным режимом, потому что действия пальца передаются хосту в виде относительных движений мыши по поверхности сенсора. TouchPad сообщает об этом относительном движении хосту в пакетах, совместимых с мышью. Каждый пакет сообщает о количестве движения в направлениях X (по горизонтали) и Y (по вертикали), которое произошло с момента предыдущего пакета. Эти количества движения называются дельтами и обозначаются "∆X" и "∆Y". Движение слева направо сообщается с положительным значением ∆X, а движение справа налево - с отрицательным значением ∆X. О восходящем движении сообщается положительное значение ∆Y, а о нисходящем движении - отрицательное значение ∆Y. Пакет также сообщает информацию о кнопках «мыши». Поскольку относительный пакет разработан для совместимости с существующим протоколом мыши, точное содержимое относительного пакета варьируется от одного протокола к другому. По умолчанию используется двухкнопочная мышь.
Сенсорные панели Synaptics поддерживают абсолютный режим работы, при котором сенсорная панель передает расширенный пакет, который сообщает об абсолютном положении пальца на панели (X, Y), давлении пальца (Z) и другой информации, включая состояние кнопки. Cенсорная панель Synaptics начинает отправлять пакеты, когда Z равно 8 или больше. Сенсорная панель также начинает отправлять пакеты при каждом нажатии или отпускании любой кнопки. Как только сенсорная панель начинает передачу, она продолжает отправлять пакеты в течение одной секунды после того, как Z упадет ниже 8 и кнопки перестанут нажиматься. TouchPad делает это отчасти для того, чтобы программное обеспечение хоста могло использовать поток пакетов в качестве временной базы для декодирования жестов.
Когда включен абсолютный режим, каждый отчет о движении состоит из шести байт. Эти байты кодируют абсолютное положение пальца по осям X, Y на поверхности датчика, а также значение Z (давление) и различные другие измерения и биты состояния.
Для Synaptics touchPad этот режим включается при инициализации путем отправки последовательности команд. Например, чтобы установить байт режим на 0xC1 (абсолютный режим, высокая скорость передачи пакетов, включен режим Wmode), можно использовать последовательность команд,
0xE8, 0x03, 0xE8, 0x00, 0xE8, 0x00, 0xE8, 0x01, 0xF3, 0x14
где аргумент 0xC1 кодируется следующим образом: (0x03 × 64) + (0x00 × 16) + (0x00 × 4) + 0x01 = $C1
bit 7 |
bit 6 |
bit 5 |
bit 4 |
bit 3 | bit 2 | bit 1 | bit 0 |
|
byte 1 |
1 | 0 | w value 3..2 |
0 | w val 1 | right | left |
|
byte 2 |
y position 11..8 | x position 11..8 |
||||||
byte 3 |
z pressure 7..0 | |||||||
byte 4 |
1 | 1 | y pos 12 | x pos 12 | 0 | w val 0 |
r/d | l/u |
byte 5 |
x position 7..0 | |||||||
byte 6 |
y position 7..0 |
absolute X/Y/Z/W motion packet (Wmode = 1)
На типичных сенсорных панелях бит L/U идентичен биту левой кнопки, а бит R/D идентичен биту Right. На пэдах MultiSwitch с установленным битом возможностей capFourButtons и включенным Wmode биты L/U и R/D также сообщают о положениях кнопок Up и Down соответственно. Бит L/U сообщает о логическом исключающем ИЛИ для состояний кнопок "Влево" и "Вверх". С другой стороны, L/U - это то же самое, что и левый бит, если только не нажата кнопка Up, и в этом случае L/U является дополнением к левому биту. Бит R/D аналогичным образом выполняет XOR кнопок вправо и вниз. Это кодирование гарантирует, что пакет будет обратно совместим (и устойчив к вмешательству со стороны "слишком умных" контроллеров клавиатуры) всякий раз, когда не нажимаются кнопки "Вверх" и "Вниз". Некоторые сенсорные панели MultiSwitch используют другой формат, в котором можно разместить до 11 кнопок. Пакет абсолютного режима, как и пакет относительного режима, содержит несколько бит, которые сообщают о состоянии кнопок. Важно отметить, что в абсолютном режиме физические кнопки сообщаются отдельно от жестов касания и скольжения. В относительном режиме, совместимом с мышью, жесты и кнопки смешиваются, и хост не может их различить. Сенсорные панели Synaptics поддерживают дополнительное значение в пакете Absolute, называемое W mode. Значение W сообщается только тогда, когда хост включает специальный режим W. Значение W предоставляет дополнительную информацию о характере контакта с датчиком. Хост может использовать W, чтобы различать нормальные пальцы, случайный контакт ладони и несколько пальцев.
Подключение к nodemcu V3 (esp8266)
touchpad | nodemcu V3 | |
---|---|---|
T22 | (3.3v) | 3V |
T10 | (SCL) | GPIO5 (D1) |
T11 | (SDA/DATA) | GPIO4 (D2) |
T23 | (GND) | GROUND |
При успешной инициализации Synaptics touchpad в консоль будет выведен текст
TouchPad: Synaptics, id: 1000111, minor rev.: 1001, major: 10101, state: init completed
При этом активируется расширенный, 6 байтовый режим обмена данными. absolute X/Y/Z/W motion packet (Wmode = 1) и как только будут получены данные от touthpad они через функцию прерывания handleInterrupt запишутся в массив raw и в loop выведутся сырые данные.
#include <ESP8266WiFi.h>
#include <PS2Mouse.h>
PS2Mouse mouse(SCL, SDA);
void IRAM_ATTR handleInterrupt();
void setup() {
Serial.begin(115200);
mouse.begin();
attachInterrupt(digitalPinToInterrupt(SCL), handleInterrupt, FALLING);
}
byte raw[6];
void handleInterrupt() {
noInterrupts();
for(int i = 0; i < 6; i++){
raw[i] = mouse.get(true);
}
interrupts();
}
void loop() {
if(raw[0] != 0 && raw[0] != 0x80){
Serial.print(raw[2],BIN);
Serial.print("\t");
Serial.print(raw[3],BIN);
Serial.print("\t");
Serial.print(raw[4],BIN);
Serial.print("\t");
Serial.println(raw[5],BIN);
}
}
Если по какой то причине не удается получить абсолютный режим инициализируется 3х байтный Relative mode и массив raw нужно использовать длинной 3 при этом пересчитав циклы для этого массива.
Для получения точнных координат examples
void loop() {
if(raw[0] != 0 && raw[0] != 0x80){
mouse.getAbsoluteAxis(raw, x, y);
Serial.print("Z pressure ");
Serial.print(raw[2]);
Serial.print("\t");
Serial.print("X position ");
Serial.print(x);
Serial.print("\t");
Serial.print("Y position ");
Serial.print(y);
Serial.println();
}