Arduino PS / 2 Klavye Öykünücüsü Sorunları


10

Evet, Arduino.cc forumlarını aradım ve burada. Evet, ps2dev kütüphanesi ile ilgili makaleleri buldum. Evet, bu web sitesindeki kesin PS / 2 arayüz makalesini okudum (tamam, bazıları yağsız) . Evet, böyle çalışıyorum, biraz. Tam olarak çalışabilmek için bazı fikirlere ihtiyacım var. :)

Hayır, sadece bir USB HID Klavyeyi taklit edemem ve bırakamam - PS / 2 Klavye emülasyonu olması gerekiyor. Evet, doğru marka yapma ve kesme sinyalleri gönderiyorum - hatta çok karmaşık tuş vuruşu kombinasyonlarını bile ele alıyor. Şu anda olduğu gibi, Arduino'm için aşağıda belirtildiği gibi kod yazdım (teknik olarak bir Freeduino 1.22) ve Seri Monitör veya PuTTY terminali ile tuş vuruşlarını ve gerçek gönderen kullanışlı bir Python sarıcı / sürücü ile gönderdim PS / 2 tarama kodu bilgileri - ve genellikle hayatımı daha kolay hale getirir - ayrıca yükün bir kısmını Arduino'dan çıkarır.

Şu anda, Arduino'da çalışan bir PS / 2 Klavye taklit eden bir kroki var. Doğal olarak, "hedef" makinemi (PS / 2 Fişin girdiği makine) açmam gerekiyor ve "el sıkışmasının" gerçekleştiğini görüyorum. WinDoze'e önyükleme yapın, not defterini açın ve Python "sürücümü" kullanarak tuş vuruşlarını ekrana (başarılı bir şekilde) sürün. (Sürücü, Seri Monitör / PuTTY terminalinin yerini alır ve PySerial adlı bir modül kullanarak seri bağlantı noktasını okur / yazar.) Bunların hepsi ASUS anakart "target" içindeki bir AMD üzerinde yapılır.

Şimdi amaç, Intel anakart tabanlı "hedef" içinde Intel'im üzerinde çalışmasını sağlamak, takıyorum, önyükleme yapıyorum ve zar yok. Böylece, küçük Ardy arkadaşımda gerçekte olup bitenler hakkında bir fikir vermek için taslağı biraz değiştirdim. Modlardan sonraki sürüm aşağıda görüntülenir. Anladığım kadarıyla (kod burada başka bir Arduino.cc forum mesajından "ödünç alındı" ) İlk önce PS / 2 üzerinden "hedef" ile bir bağlantı kurmaya çalışacak. bağlantı kuruldu. Intel hedefi .5 saniyelik periyodu geçemez ve "host" ile Seri Bağlantı kurulmaz.

Sorum şu: ps / 2 klavyelerin hedef makineleriyle iletişim kurma biçiminde büyük bir fark var mı? Gerçekten bir tasarım farkı mı yoksa burada daha temel bir şey mi aramalıyım? Veri / saat girişlerinde pull-up dirençlere ihtiyaç duyma hakkında bir şey duydum, ancak kodda ele alınmalı, özellikle de başka bir hedef üzerinde çalışıyor, çünkü üzerinde çalışmam gereken bir şey değil.

Herhangi bir fikir? Bu ASAP çalışmak istiyorum - hata ayıklama yapmaya devam edeceğim, herhangi bir işaretçi veya öneri büyük takdir edilecektir. Hepsine tam olarak bakılacak çünkü bu konuda bazı taze gözlere ihtiyacım var. Belki de ps2dev kütüphanesinde daha iyi uygulama gereklidir?

#include "ps2dev.h" // to emulate a PS/2 device

// Orange = 2
// Blue = 3
// Red = 5V (3 in)
// Black = GND (4 in)
// EXT Power, USB for COM only

PS2dev keyboard(3,2); // PS2dev object (2:data, 3:clock)
int enabled = 0; // pseudo variable for state of "keyboard"
boolean serialConnected = false;
int incomingByte = 0;

void ack() {
  //acknowledge commands
  while(keyboard.write(0xFA));
}

int kbdCmd(int command) {
  unsigned char val;
  switch (command) {
  case 0xFF: //reset
    ack();
    //the while loop lets us wait for the host to be ready
    while(keyboard.write(0xAA)!=0);
    break;
  case 0xFE: //resend
    ack();
    break;
  case 0xF6: //set defaults
    //enter stream mode
    ack();
    break;
  case 0xF5: //disable data reporting
    //FM
    enabled = 0;
    ack();
    break;
  case 0xF4: //enable data reporting
    //FM
    enabled = 1;
    ack();
    break;
  case 0xF3: //set typematic rate
    ack();
    keyboard.read(&val); //do nothing with the rate
    ack();
    break;
  case 0xF2: //get device id
    ack();
    keyboard.write(0xAB);
    keyboard.write(0x83);
    break;
  case 0xF0: //set scan code set
    ack();
    keyboard.read(&val); //do nothing with the rate
    ack();
    break;
  case 0xEE: //echo
    //ack();
    keyboard.write(0xEE);
    break;
  case 0xED: //set/reset LEDs
    ack();
    keyboard.read(&val); //do nothing with the rate
    ack();
    break;
  }
}

void connectHost() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}

void setup() {
  pinMode(13, OUTPUT);
  //establish serial connection with host
  Serial.begin(9600);
  // establish ps/2 connection with target
  while(keyboard.write(0xAA)!=0){
    digitalWrite(13, HIGH);
    delay(500); 
    digitalWrite(13, LOW);
    delay(500);
  }
  delay(100);  
  
  connectHost();
  Serial.println("\nSerial Host Connected");
  Serial.flush();
}

void loop() {
  unsigned char c;
  if( (digitalRead(3)==LOW) || (digitalRead(2) == LOW)) {
    if(digitalRead(3)==LOW){
      Serial.println("pin 3  is LOW");
    } else {
      Serial.println("pin 2 is LOW");
    }
    while(keyboard.read(&c));
    kbdCmd(c);
    Serial.print("Target: 0x");
    Serial.println(c, HEX);
  }  
  else {//if host device wants to send a command:
    //echo ASCII code from terminal and write to ps/2
    if(Serial.available() > 0) {
      incomingByte = Serial.read();
      keyboard.write(incomingByte);      
      Serial.print("Host: 0x");
      Serial.print(incomingByte, HEX);
      Serial.print(" ");
      Serial.print(incomingByte);
      Serial.print(" ");
      Serial.println(incomingByte, BIN);
    }
  }
}

Birkaç soru: "Sketch" Arduino-lingo "program" için mi? Bu python sürücüsü şeyler hedef makineden bağımsız, değil mi? Senin sorunun şu, bir hedef makinede çalışıyor, diğerinde değil, değil mi? PS / 2 klavye takılıyken çalışmayan hedefi önyüklemeyi denedikten sonra Arduino ile değiştirdiniz mi?
AndreKR

Evet, Ardu-lingo'daki Sketch == programı. Bunu denedim ve işe yaramadı (ancak çizimi göndermeden önce ACK'ları hedeften beklememek için taslağı değiştirmem gerekiyor.) Test etme şansı bulduğumda size bildireceğim bugün daha sonra.
chisaipete

Programı önerdiğin gibi test ettim ve işe yarıyor! Sonunda, klavye emülatörü takılıyken hedefi güç döngüsüne sokmak ve BIOS ayarlarını onunla değiştirmek istiyorum. Başlangıç ​​el sıkışmasının kapalı olduğunu düşünüyorum.
chisaipete

Evet muhtemelen. Başlatma sırasını computer-engineering.org/ps2keyboard'un en altında gördünüz mü ? Dizimi bununla karşılaştırarak başlardım.
AndreKR

1
Maalesef, bu konunun bayatlamasına izin verdim - AndreKR'nin çözümünü denemek için zamanım olmadı. Ayrıca, çekme dirençleri kullanmıyorum, bu yüzden hangi ucun
çekme

Yanıtlar:


5

Anladığım kadarıyla, Arduino'nuzu iki farklı hedef makineye bağlarsınız ve bir tanesi çalışır, diğeri çalışmaz.

Yani iki makinenin başlatma gereksinimleri arasında bir fark var gibi görünüyor. Açık bu sayfayı çok alt olası bir başlatma dizisinin bir liste var. Başlamanızı bu ayarla karşılaştırarak başlayın.

Bir mantık analizörü kullanarak çok daha kolay olacaktır. Intronix Logicport kullanıyorum , ancak aynı anda olmasa da, hem daha ucuz hem de daha iyi olanlar var.

Açık kollektörlü bir veriyoluna dokunmak biraz hantaldır çünkü hangi cihazın konuştuğunu göremezsiniz. Bununla birlikte, çekmenin olmadığı bir uca seri direnç koyarsanız , voltaj seviyesini hangi cihazın veri yolunu tuttuğunu söyleyebilirsiniz. Her açık toplayıcı veri yolunun (PS / 2 gibi) çekme dirençlerine ihtiyacı vardır, genellikle PC'de bulunurlar. Bir DSO'da farklı voltaj seviyelerini kolayca görebilirsiniz. Sadece bir LA ile farklı eşik gerilimleri ile iki kez kayıt yapmanız gerekir.


Ödülün kime verileceğine dair karar beklediğimden daha zordu ama cevabınız en çok oyu topladı ve biraz tercih ediyorum. Herkesi ödüllendirmeyi tercih ederdim!
Kortuk

3

Projenizin bir anakartla çalıştığı ve başka bir anakartla çalışmadığı göz önüne alındığında, projenizde ve hatta anakartlardan birinde bile klasik bir "kısmi şartlara uygunluk" vakası var gibi görünüyor. Ancak çoğu klavye herhangi bir anakartla çalışır, bu nedenle sağlam bir uygulama taşınabilir olmalıdır. Asıl zorluk, neden senin olmadığını anlamak zorunda kalacaksın.

Bunu sadece probleme bakarak ve nasıl çalışması gerektiğini düşünerek yapabilirsiniz (belki bir aradan sonra - ya da bir gün cevap size duşta vurur) ama izleyebiliyorsanız daha etkili olacaksınız. ne oluyor. Elektriksel konular için bir kapsam, protokol olanlar için bir mantık analizörü. Bu alanda bazı ucuz seçenekler var, örneğin klavye protokolü için belirli bir özelliğe sahip "otobüs korsan" panosu veya daha uzun bir yakalama arabelleğine sahip olabilecek FPGA tabanlı bir şey (bkz. Sump.org).

Deneyebileceğiniz başka bir şey, bir klavye ana bilgisayarı oluşturmak için mikrodenetleyici veya FPGA gibi başka bir cihaz kullanmak ve projenizi şartnamenin sınırlarına göre test etmek için kullanmak olabilir.


2

Tam olarak nasıl çalıştığını görmek için ps2dev kütüphanesine bakmadım, ama bir şey bana atladı.

Şu anda "ana bilgisayar" bilgisayarına bağlanmak için tek bir girişimde bulunulmaktadır. Bu başarısız olduğunda, başka bir girişimde bulunulmadan önce bir saniye beklenir (0,5 sn'de LED, 0,5 sn'de LED söner).

Intel anakart klavye algılaması için yeterince uzun süre beklemiyorsa, önyükleme sırasına devam etmeden asla bağlantı girişiminde bulunmayabilir.

Bekleme süresini 0,1 sn (gecikme (500) satırını gecikme (50) olarak değiştirin) olarak değiştirirseniz, biraz şansınız olabilir.

Değilse, daha da hızlı deneyin. Cehennem, hiç gecikmeden denemek ve nasıl gittiğini görmek.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.