Как избавиться от задержки? Arduino и PS2 Keyboard

krikus
Offline
Зарегистрирован: 22.07.2011

Решил подключить к Ардуино PS2 клавиатуру - получилось. Пробовал использовать библиотеки PS2Keyboard и еще много других. Во всех библиотеках есть задержка между нажатиями клавиш, т.е. нажимаю клавишу и удерживаю - вначале срабатывает 1 раз, а позже нажатия начинают повторятся с небольшой задержкой. Да, это все хорошо для набирания текста, но мне нужно без задержек, т.е нажал и куча срабатываний без задержек, как с кнопкой, подключенной к ардуино. Думаю дело в библиотеке, а иначе как в компьютерных играх совершать какие-либо движения?

---

Заранее Спасибо.

gwer
Offline
Зарегистрирован: 09.06.2012

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

MAFia
Offline
Зарегистрирован: 26.10.2011

Эта задержка исключительно реализуется операционной системой. К примеру, есть в разных языках программирования комманды на подобие  ReadKey, читающие нажатую кнопку. Помнится еще на QBasic в консоле игру шарики писал, используя подобную комманду. Так что, внимательно изучи библиотеку, может найдешь, как избавится от задержки. А лучше - пойми принцип, на котором работает обмен данными с ПС2 и напиши сам с нуля. Не думаю, что это сильно  сложно.

krikus
Offline
Зарегистрирован: 22.07.2011

Принцип - изучил, нашел скетч, работающий вообще без библиотеки - то же самое. Может есть спец.режим в контроллере клавиатуры? Вот тот самый скетч:

/*
PS/2 Keyboard Input
*/

#define LED 13
#define CLK 2
#define DAT 3

// if I put the keyboard map in here then keys[scan code] would return 
// the ascii value of the scan code.
unsigned char keys[128] =
{
};

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(CLK, INPUT);
  pinMode(DAT, INPUT);
  digitalWrite(CLK, HIGH);
  digitalWrite(DAT, HIGH);
  delayMicroseconds(50);
  Serial.begin(9600);
}

void loop()
{
  byte b = readkey(); 
  if (b == 0xF0)
  {
    // key released
    b = readkey();
  }
  else
  {
    Serial.print(b, HEX);
    Serial.print(" ");
  }
}

byte readkey()
{
  byte _start = 0;
  byte buf = 0;
  byte _parity = 0;
  byte _stop = 0;
  
  waitClockLow();
    
  _start = digitalRead(DAT);

  if (_start == 0)
  {
    waitClockLow();
    for (byte c=0; c<8; c++)
    {
      buf = buf | (digitalRead(DAT) << c);
      waitClockLow();
    }
  
    _parity = digitalRead(DAT);
    waitClockLow();
  
    _stop = digitalRead(DAT);
  }
  return buf;
}

void waitClockLow()
{
  if (digitalRead(CLK) == LOW)
    while (digitalRead(CLK) == LOW)
    {
    }
  while (digitalRead(CLK) == HIGH)
  {
  }
}

Из скетча видно - единственное, что может оказать задержку, это функция waitClockLow - и то, она работает в зависимости от состояния clock-пина клавиатуры.

krikus
Offline
Зарегистрирован: 22.07.2011

Спасибо всем, проблему решил. Нужно было просто перевести клавиатуру в режим считывания @make and release@. ЗДесь мы регистрируем только нажатие и отпускание клавиши :-), почти это мне и надо было. Чтобы перевести ее в этот режим нужно:

  kbd.write(0xF0); //Отправляем: переключить scan key на ...
  kbd.write(0x03); //...3
  delayMicroseconds(20); //Задержка(на всякий случий)
  kbd.write(0xF8); //Отправляем: переключить режим считывания
                     //...на make/release
  delayMicroseconds(20);