2013-11-01 2 views
3

저는 python에 익숙하지 않지만 HID 장치 및 evdev에 대한 경험이 있습니다. HID 장치로 인터페이스하는 2D 바코드 스캐너가 있습니다. 목표는 QR 코드에서 문자열을 가져 오는 것입니다. 나는 리눅스에서 스캐너를 인식 할 수 있었으며 심지어/dev/input에 위치를 발견했다.Evdev를 사용하여 Python의 HID 장치에서 String을 가져 오는 방법은 무엇입니까?

나는 evdev를 발견했으며 아래 예제를 내 스캐너로 구현했습니다. 이것은 사이트의 기본 코드 일뿐입니다. 값을 읽지 만 긴 이벤트 코드를 다운 및 업으로 인쇄합니다. 이것을 문자열로 변환하는 쉬운 방법을 볼 수 없습니다. 내가하고 싶은 것은 파이썬의 HID 스캐너에서 문자열로 읽는 것뿐입니다. 어떤 도움이나 방향 (아마 evdev isnt 대답) 감사하겠습니다.

key event at 1383327570.147000, 2 (KEY_1), down 
key event at 1383327570.147990, 2 (KEY_1), up 
key event at 1383327570.148997, 3 (KEY_2), down 
key event at 1383327570.150010, 3 (KEY_2), up 
key event at 1383327570.151009, 29 (KEY_LEFTCTRL), down 
key event at 1383327570.151009, 42 (KEY_LEFTSHIFT), down 
key event at 1383327570.152017, 36 (KEY_J), down 
key event at 1383327570.153005, 36 (KEY_J), up 
key event at 1383327570.154004, 29 (KEY_LEFTCTRL), up 
key event at 1383327570.155005, 32 (KEY_D), down 
key event at 1383327570.155993, 32 (KEY_D), up 
key event at 1383327570.157002, 48 (KEY_B), down 
key event at 1383327570.158015, 48 (KEY_B), up 
key event at 1383327570.158997, 48 (KEY_B), down 
key event at 1383327570.282002, 18 (KEY_E), up 
key event at 1383327570.283004, 49 (KEY_N), down 
key event at 1383327570.284005, 49 (KEY_N), up 
key event at 1383327570.284968, 18 (KEY_E), down 

많은 감사 :

from evdev import * 
dev = InputDevice('/dev/input/event1') 

print(dev) 

for event in dev.read_loop(): 
    if event.type == ecodes.EV_KEY: 
     print(categorize(event)) 

여기에 몇 가지 바코드의 출력은 다음과 같습니다

는 여기에 몇 가지 예를 들어 출력을 내 현재 파이썬 코드입니다!

답변

10

여기에 누락 된 전환 단계가 있습니다. 귀하의 출력은 꽤 형식으로 이미, 그래서 난 당신이 좀 더 침착하게 도움이됩니다 :

    : 당신은 몇 가지 작업을 수행해야

       Timestamp  , scancode, keycode, keystate 
    key event at 1383327570.147000, 2   (KEY_1), down 
    key event at 1383327570.147990, 2   (KEY_1), up 
    

    이의 유용한 이해하기

  1. 특정 유형 (키 = 1, 위로 = 0)의 키스톤에 대해서만 필터로 key_down 유형 이벤트 수신
  2. 스캔 코드를 ASCII 코드로 변환합니다.이 ASCII 코드는 장치마다 다를 수 있으며 체계!

지도를 표시하는 방법은 간단합니다. 온라인 서비스를 사용하여 사용 가능한 모든 문자로 알려진 바코드를 생성 한 다음 해당 바코드를 스캔하고 각 스캔 코드를 스캐너의 올바른 문자/숫자에 매핑하십시오. 당신은 출력의 더 나은 제어를 취할 다음 코드 약간 수정 조각을 사용할 수 있습니다 온라인 어떤 바코드를 생성하면 다음

import evdev 
from evdev import InputDevice, categorize # import * is evil :) 
dev = InputDevice('/dev/input/event1') 

# Provided as an example taken from my own keyboard attached to a Centos 6 box: 
scancodes = { 
    # Scancode: ASCIICode 
    0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8', 
    10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R', 
    20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL', 
    30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u';', 
    40: u'"', 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N', 
    50: u'M', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 100: u'RALT' 
} 
for event in dev.read_loop(): 
    if event.type == evdev.ecodes.EV_KEY: 
     data = evdev.categorize(event) # Save the event temporarily to introspect it 
     if data.keystate == 1: # Down events only 
      key_lookup = scancodes.get(data.scancode) or u'UNKNOWN:{}'.format(data.scancode) # Lookup or return UNKNOWN:XX 
      print u'You Pressed the {} key!'.format(key_lookup) # Print it all out! 

You Pressed the A key! 
You Pressed the B key! 
You Pressed the C key! 
You Pressed the UNKNOWN:99 key! 

이 스크립트의 일부 샘플 출력, 당신 ' 어떤 스캔 코드가 어떤 값으로 매핑되는지 알 수 있습니다. 자신 만의 테이블과 이익을 창출하십시오!

HTH

+0

이것은 내가 필요한 것입니다. 고맙습니다! 그러나 이제 테스트의 다음 단계로 넘어 갔으므로이 코드는 약 10 자 이상의 바코드에서는 작동하지 않습니다. 스캐너는 PC에 연결하고 빈 텍스트 창에 타이핑 할 때도 정상적으로 작동합니다. 그러나 이것으로 바코드의 대부분의 문자를 임의로 삭제합니다. 속도 문제입니까? 아니면 뭔가 잘못하고있는 것입니까? – calumb

+0

루프를 시작하기 전에 오른쪽에 evdev grab 함수를 추가하여이 문제를 해결했습니다. 위의 코드에서 event_loop for 루프 바로 위의'dev.grab() '를 사용했습니다. 또한 내 최종 코드를 내 대답에 추가했습니다. – calumb

4

VooDooNOFX의 코드는 상당히 도움이되었다 오른쪽 방향으로 날을 걷어 찼다. 리눅스에서 파이썬으로 키보드 에뮬레이션을 사용하여 하니웰 MS7580 또는 유사한 광학 스캐너를 인터페이스하려는 다른 사람에게 명료성을 추가하기 위해 내 자신의 질문에 대답하고 싶었습니다.

이 프로젝트는 내가 명령 줄에 액세스 할 수있는 BeagleBone Black을 사용했기 때문에 스캐너를 일반 키보드로 사용할 수 없었습니다. 교대조를 제대로 처리하기 위해 교대 버튼이 눌려 졌을 때 두 번째 그룹의 스캔 코드를 추가해야했습니다. evdev와 올바른 방향으로 날을 가리키는 위해 부두에 너무 많은

import evdev 
from evdev import InputDevice, categorize, ecodes 
dev = InputDevice('/dev/input/event1') 

# Provided as an example taken from my own keyboard attached to a Centos 6 box: 
scancodes = { 
    # Scancode: ASCIICode 
    0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8', 
    10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'q', 17: u'w', 18: u'e', 19: u'r', 
    20: u't', 21: u'y', 22: u'u', 23: u'i', 24: u'o', 25: u'p', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL', 
    30: u'a', 31: u's', 32: u'd', 33: u'f', 34: u'g', 35: u'h', 36: u'j', 37: u'k', 38: u'l', 39: u';', 
    40: u'"', 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'z', 45: u'x', 46: u'c', 47: u'v', 48: u'b', 49: u'n', 
    50: u'm', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 57: u' ', 100: u'RALT' 
} 

capscodes = { 
    0: None, 1: u'ESC', 2: u'!', 3: u'@', 4: u'#', 5: u'$', 6: u'%', 7: u'^', 8: u'&', 9: u'*', 
    10: u'(', 11: u')', 12: u'_', 13: u'+', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R', 
    20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'{', 27: u'}', 28: u'CRLF', 29: u'LCTRL', 
    30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u':', 
    40: u'\'', 41: u'~', 42: u'LSHFT', 43: u'|', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N', 
    50: u'M', 51: u'<', 52: u'>', 53: u'?', 54: u'RSHFT', 56: u'LALT', 57: u' ', 100: u'RALT' 
} 
#setup vars 
x = '' 
caps = False 

#grab provides exclusive access to the device 
dev.grab() 

#loop 
for event in dev.read_loop(): 
    if event.type == ecodes.EV_KEY: 
     data = categorize(event) # Save the event temporarily to introspect it 
     if data.scancode == 42: 
      if data.keystate == 1: 
       caps = True 
      if data.keystate == 0: 
       caps = False 
     if data.keystate == 1: # Down events only 
      if caps: 
       key_lookup = u'{}'.format(capscodes.get(data.scancode)) or u'UNKNOWN:[{}]'.format(data.scancode) # Lookup or return UNKNOWN:XX 
      else: 
       key_lookup = u'{}'.format(scancodes.get(data.scancode)) or u'UNKNOWN:[{}]'.format(data.scancode) # Lookup or return UNKNOWN:XX 
      if (data.scancode != 42) and (data.scancode != 28): 
       x += key_lookup 
      if(data.scancode == 28): 
       print x   # Print it all out! 
       x = '' 

감사 : 여기에 QR 코드에서 문자열을 읽어 내 마지막 코드입니다.