您尚未登录。

楼主 #1 2020-03-27 11:45:10

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

试一试 S3 Linux 4.13 读取 USB 条码枪

IMG_20200327_114442.jpg

离线

楼主 #2 2020-03-27 11:50:31

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      1c22800.lradc
/dev/input/event1:      ns2009_ts
/dev/input/event2:      Manufacturer Barcode Reader
Select the device event number [0-2]: 2
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0xe851 product 0x1000 version 0x101
Input device name: "Manufacturer Barcode Reader"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 1 (KEY_ESC)
    Event code 2 (KEY_1)
    Event code 3 (KEY_2)
    Event code 4 (KEY_3)
    Event code 5 (KEY_4)
    Event code 6 (KEY_5)
    Event code 7 (KEY_6)
    Event code 8 (KEY_7)
    Event code 9 (KEY_8)
    Event code 10 (KEY_9)
    Event code 11 (KEY_0)
    Event code 12 (KEY_MINUS)
    Event code 13 (KEY_EQUAL)
    Event code 14 (KEY_BACKSPACE)
    Event code 15 (KEY_TAB)
    Event code 16 (KEY_Q)
    Event code 17 (KEY_W)
    Event code 18 (KEY_E)
    Event code 19 (KEY_R)
    Event code 20 (KEY_T)
    Event code 21 (KEY_Y)
    Event code 22 (KEY_U)
    Event code 23 (KEY_I)
    Event code 24 (KEY_O)
    Event code 25 (KEY_P)
    Event code 26 (KEY_LEFTBRACE)
    Event code 27 (KEY_RIGHTBRACE)
    Event code 28 (KEY_ENTER)
    Event code 29 (KEY_LEFTCTRL)
    Event code 30 (KEY_A)
    Event code 31 (KEY_S)
    Event code 32 (KEY_D)
    Event code 33 (KEY_F)
    Event code 34 (KEY_G)
    Event code 35 (KEY_H)
    Event code 36 (KEY_J)
    Event code 37 (KEY_K)
    Event code 38 (KEY_L)
    Event code 39 (KEY_SEMICOLON)
    Event code 40 (KEY_APOSTROPHE)
    Event code 41 (KEY_GRAVE)
    Event code 42 (KEY_LEFTSHIFT)
    Event code 43 (KEY_BACKSLASH)
    Event code 44 (KEY_Z)
    Event code 45 (KEY_X)
    Event code 46 (KEY_C)
    Event code 47 (KEY_V)
    Event code 48 (KEY_B)
    Event code 49 (KEY_N)
    Event code 50 (KEY_M)
    Event code 51 (KEY_COMMA)
    Event code 52 (KEY_DOT)
    Event code 53 (KEY_SLASH)
    Event code 54 (KEY_RIGHTSHIFT)
    Event code 55 (KEY_KPASTERISK)
    Event code 56 (KEY_LEFTALT)
    Event code 57 (KEY_SPACE)
    Event code 58 (KEY_CAPSLOCK)
    Event code 59 (KEY_F1)
    Event code 60 (KEY_F2)
    Event code 61 (KEY_F3)
    Event code 62 (KEY_F4)
    Event code 63 (KEY_F5)
    Event code 64 (KEY_F6)
    Event code 65 (KEY_F7)
    Event code 66 (KEY_F8)
    Event code 67 (KEY_F9)
    Event code 68 (KEY_F10)
    Event code 69 (KEY_NUMLOCK)
    Event code 70 (KEY_SCROLLLOCK)
    Event code 71 (KEY_KP7)
    Event code 72 (KEY_KP8)
    Event code 73 (KEY_KP9)
    Event code 74 (KEY_KPMINUS)
    Event code 75 (KEY_KP4)
    Event code 76 (KEY_KP5)
    Event code 77 (KEY_KP6)
    Event code 78 (KEY_KPPLUS)
    Event code 79 (KEY_KP1)
    Event code 80 (KEY_KP2)
    Event code 81 (KEY_KP3)
    Event code 82 (KEY_KP0)
    Event code 83 (KEY_KPDOT)
    Event code 85 (KEY_ZENKAKUHANKAKU)
    Event code 86 (KEY_102ND)
    Event code 87 (KEY_F11)
    Event code 88 (KEY_F12)
    Event code 89 (KEY_RO)
    Event code 90 (KEY_KATAKANA)
    Event code 91 (KEY_HIRAGANA)
    Event code 92 (KEY_HENKAN)
    Event code 93 (KEY_KATAKANAHIRAGANA)
    Event code 94 (KEY_MUHENKAN)
    Event code 95 (KEY_KPJPCOMMA)
    Event code 96 (KEY_KPENTER)
    Event code 97 (KEY_RIGHTCTRL)
    Event code 98 (KEY_KPSLASH)
    Event code 99 (KEY_SYSRQ)
    Event code 100 (KEY_RIGHTALT)
    Event code 102 (KEY_HOME)
    Event code 103 (KEY_UP)
    Event code 104 (KEY_PAGEUP)
    Event code 105 (KEY_LEFT)
    Event code 106 (KEY_RIGHT)
    Event code 107 (KEY_END)
    Event code 108 (KEY_DOWN)
    Event code 109 (KEY_PAGEDOWN)
    Event code 110 (KEY_INSERT)
    Event code 111 (KEY_DELETE)
    Event code 113 (KEY_MUTE)
    Event code 114 (KEY_VOLUMEDOWN)
    Event code 115 (KEY_VOLUMEUP)
    Event code 116 (KEY_POWER)
    Event code 117 (KEY_KPEQUAL)
    Event code 119 (KEY_PAUSE)
    Event code 121 (KEY_KPCOMMA)
    Event code 122 (KEY_HANGUEL)
    Event code 123 (KEY_HANJA)
    Event code 124 (KEY_YEN)
    Event code 125 (KEY_LEFTMETA)
    Event code 126 (KEY_RIGHTMETA)
    Event code 127 (KEY_COMPOSE)
    Event code 128 (KEY_STOP)
    Event code 129 (KEY_AGAIN)
    Event code 130 (KEY_PROPS)
    Event code 131 (KEY_UNDO)
    Event code 132 (KEY_FRONT)
    Event code 133 (KEY_COPY)
    Event code 134 (KEY_OPEN)
    Event code 135 (KEY_PASTE)
    Event code 136 (KEY_FIND)
    Event code 137 (KEY_CUT)
    Event code 138 (KEY_HELP)
    Event code 140 (KEY_CALC)
    Event code 142 (KEY_SLEEP)
    Event code 150 (KEY_WWW)
    Event code 152 (KEY_SCREENLOCK)
    Event code 158 (KEY_BACK)
    Event code 159 (KEY_FORWARD)
    Event code 161 (KEY_EJECTCD)
    Event code 163 (KEY_NEXTSONG)
    Event code 164 (KEY_PLAYPAUSE)
    Event code 165 (KEY_PREVIOUSSONG)
    Event code 166 (KEY_STOPCD)
    Event code 173 (KEY_REFRESH)
    Event code 176 (KEY_EDIT)
    Event code 177 (KEY_SCROLLUP)
    Event code 178 (KEY_SCROLLDOWN)
    Event code 179 (KEY_KPLEFTPAREN)
    Event code 180 (KEY_KPRIGHTPAREN)
    Event code 183 (KEY_F13)
    Event code 184 (KEY_F14)
    Event code 185 (KEY_F15)
    Event code 186 (KEY_F16)
    Event code 187 (KEY_F17)
    Event code 188 (KEY_F18)
    Event code 189 (KEY_F19)
    Event code 190 (KEY_F20)
    Event code 191 (KEY_F21)
    Event code 192 (KEY_F22)
    Event code 193 (KEY_F23)
    Event code 194 (KEY_F24)
    Event code 240 (KEY_UNKNOWN)
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)
  Event type 17 (EV_LED)
    Event code 0 (LED_NUML) state 0
    Event code 1 (LED_CAPSL) state 0
    Event code 2 (LED_SCROLLL) state 0
    Event code 3 (LED_COMPOSE) state 0
    Event code 4 (LED_KANA) state 0
Key repeat handling:
  Repeat type 20 (EV_REP)
    Repeat code 0 (REP_DELAY)
      Value    250
    Repeat code 1 (REP_PERIOD)
      Value     33
Properties:
Testing ... (interrupt to exit)
Event: time 13948.303228, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7001f
Event: time 13948.303228, type 1 (EV_KEY), code 3 (KEY_2), value 1
Event: time 13948.303228, -------------- SYN_REPORT ------------
Event: time 13948.311184, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7001f
Event: time 13948.311184, type 1 (EV_KEY), code 3 (KEY_2), value 0
Event: time 13948.311184, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.311184, type 1 (EV_KEY), code 11 (KEY_0), value 1
Event: time 13948.311184, -------------- SYN_REPORT ------------
Event: time 13948.319298, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.319298, type 1 (EV_KEY), code 11 (KEY_0), value 0
Event: time 13948.319298, -------------- SYN_REPORT ------------
Event: time 13948.327330, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.327330, type 1 (EV_KEY), code 11 (KEY_0), value 1
Event: time 13948.327330, -------------- SYN_REPORT ------------
Event: time 13948.336360, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.336360, type 1 (EV_KEY), code 11 (KEY_0), value 0
Event: time 13948.336360, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70020
Event: time 13948.336360, type 1 (EV_KEY), code 4 (KEY_3), value 1
Event: time 13948.336360, -------------- SYN_REPORT ------------
Event: time 13948.344382, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70020
Event: time 13948.344382, type 1 (EV_KEY), code 4 (KEY_3), value 0
Event: time 13948.344382, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.344382, type 1 (EV_KEY), code 11 (KEY_0), value 1
Event: time 13948.344382, -------------- SYN_REPORT ------------
Event: time 13948.352291, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.352291, type 1 (EV_KEY), code 11 (KEY_0), value 0
Event: time 13948.352291, -------------- SYN_REPORT ------------
Event: time 13948.360337, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.360337, type 1 (EV_KEY), code 11 (KEY_0), value 1
Event: time 13948.360337, -------------- SYN_REPORT ------------
Event: time 13948.369300, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70027
Event: time 13948.369300, type 1 (EV_KEY), code 11 (KEY_0), value 0
Event: time 13948.369300, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7001e
Event: time 13948.369300, type 1 (EV_KEY), code 2 (KEY_1), value 1
Event: time 13948.369300, -------------- SYN_REPORT ------------
Event: time 13948.377302, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7001e
Event: time 13948.377302, type 1 (EV_KEY), code 2 (KEY_1), value 0
Event: time 13948.377302, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70023
Event: time 13948.377302, type 1 (EV_KEY), code 7 (KEY_6), value 1
Event: time 13948.377302, -------------- SYN_REPORT ------------
Event: time 13948.385343, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70023
Event: time 13948.385343, type 1 (EV_KEY), code 7 (KEY_6), value 0
Event: time 13948.385343, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70028
Event: time 13948.385343, type 1 (EV_KEY), code 28 (KEY_ENTER), value 1
Event: time 13948.385343, -------------- SYN_REPORT ------------
Event: time 13948.393352, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70028
Event: time 13948.393352, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0
Event: time 13948.393352, -------------- SYN_REPORT ------------

上面是 evtest 的读取结果, 都是一些 按键按下/抬起/连续按下 等数据,

本来我的应用程序想基于 evtest.c 读按键数据, 看来直接用是不可能了。

离线

#3 2020-03-27 11:54:05

wwng
会员
注册时间: 2020-03-18
已发帖子: 48
积分: 28

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

evtest 学到了 感谢楼主分享

离线

楼主 #4 2020-03-27 11:54:59

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

我想函数直接获取条码上的字符串, 有办法吗? 在线等各位大神回复。

离线

#5 2020-03-27 13:59:39

歌以咏志
会员
注册时间: 2019-09-21
已发帖子: 219
积分: 210

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

想知道这个条码枪用什么方案, 灵敏度如何?

离线

楼主 #6 2020-03-27 14:00:49

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

歌以咏志 说:

想知道这个条码枪用什么方案, 灵敏度如何?

这个还可以扫二维码呢, 方案不知道哦, 晚点我拆拆研究一下。灵敏度我觉得还行。

离线

楼主 #7 2020-03-27 14:07:32

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

http://terzo.acmesystems.it/examples/bar.c

/*
 * Symbol Barcode Scanner Reader Software
 * Written by Andy Stewart
 * June 5, 2007
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Set the debug variable to 1 to get some debug printouts.
 *
 * One must have the Linux kernel sources installed in order for this to compile.
 *
 * To build it:
 * gcc -o bar bar.c
 * 
 * Note: this code was tested on Linux kernel rev. 2.6.32 (FOX Board G20)
 *
 */

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "string.h"

#include <linux/input.h>

/* defined at the end of this file */
char cvt_ev_char(int);      
void debug_rcvd_event(struct input_event *);

#define MAX_IN_SIZE 30

main(int argc, char *argv[]) {

  int debug = 0;                /* set this to 1 to get debug info */

  struct input_event ev[64];    /* each scan causes more than one event...get them all */

  int fd = -1;                  /* file descriptor for the scanner device */
  int bytes_read = 0;           /* number of bytes read by the read function */
  int i;                        /* loop variable */
  char scanner_in[30];          /* set this bigger if scanned input is more than 30 characters */
  char scan_char;               /* this holds one char at a time...will be concatenated into scanner_in[] */
  int wr_ptr = 0;               /* points into scanner_in so we know where to put the next scan_char */

  printf("Go ahead and scan something - press ctrl_C when finished.\n");
  printf("Look for printouts which say: Input from Scanner\n");
  printf("Ignore other printouts\n");

  /* The device interface can be found in /dev/input/by-id/*Symbol*, which should be a link
   * to /dev/input/eventN, where N is some number.  One may need to adjust the permissions of the
   * eventN file.
   *
   * Yeah, I know it sucks for me to have hardcoded this value...sorry, I was too lazy to compute it.
   */

  if ((fd = open("/dev/input/event1", O_RDONLY)) < 0) {
    printf("Error opening file descriptor - do you have sufficient permission? Maybe it is incorrectly hardcoded - check the source. Exiting.\n");
    return -1;
  }

  while (1) {
    bytes_read = read(fd, &ev, sizeof(struct input_event) * 64);

    if (bytes_read < 0) {
      printf("ERROR: can't properly read from device\n");
      return -1;
    }

    for (i=0; i < (int) (bytes_read / sizeof(struct input_event)); i++) {

      /* Look for a "key press" event */
      if ((ev[i].type == EV_KEY) && (ev[i].value == 1)) {

	if (ev[i].code != KEY_LEFTSHIFT) {
	  scan_char = cvt_ev_char(ev[i].code);         /* Extract the character from the event */
	
	  if (debug) {
	    debug_rcvd_event(&ev[i]);
	    printf("Scan char: %c\n", scan_char);
	  }

	  if (ev[i].code != KEY_ENTER) {
	    scanner_in[wr_ptr++] = scan_char;
	  }
	  else {
	    scanner_in[wr_ptr] = '\0';
	    printf("Input from Scanner: \"%s\"\n", scanner_in);
	    wr_ptr = 0;
	  }

	} /* if (ev[i].code ...) */

      } /* if ((ev[i].type.....)) */
      
    } /* for (i=0...) */

  } /* while (1) */

  close(fd);

} /* main */

/*
 * cvt_ev_char: convert the code in the "keyboard" event to an ASCII character
 *              The character definitions came from /usr/include/linux/input.h
 *              Assumption is that barcodes can only have 0-9, A-Z so other
 *              codes have been removed from the list below.
 * 
 */

char cvt_ev_char(int foo) {

  char bar;

  switch (foo) {
    case KEY_0: bar = '0'; break;
    case KEY_1: bar = '1'; break;
    case KEY_2: bar = '2'; break;
    case KEY_3: bar = '3'; break;
    case KEY_4: bar = '4'; break;
    case KEY_5: bar = '5'; break;
    case KEY_6: bar = '6'; break;
    case KEY_7: bar = '7'; break;
    case KEY_8: bar = '8'; break;
    case KEY_9: bar = '9'; break;

    case KEY_A: bar = 'A'; break;
    case KEY_B: bar = 'B'; break;
    case KEY_C: bar = 'C'; break;
    case KEY_D: bar = 'D'; break;
    case KEY_E: bar = 'E'; break;
    case KEY_F: bar = 'F'; break;
    case KEY_G: bar = 'G'; break;
    case KEY_H: bar = 'H'; break;
    case KEY_I: bar = 'I'; break;
    case KEY_J: bar = 'J'; break;
    case KEY_K: bar = 'K'; break;
    case KEY_L: bar = 'L'; break;
    case KEY_M: bar = 'M'; break;
    case KEY_N: bar = 'N'; break;
    case KEY_O: bar = 'O'; break;
    case KEY_P: bar = 'P'; break;
    case KEY_Q: bar = 'Q'; break;
    case KEY_R: bar = 'R'; break;
    case KEY_S: bar = 'S'; break;
    case KEY_T: bar = 'T'; break;
    case KEY_U: bar = 'U'; break;
    case KEY_V: bar = 'V'; break;
    case KEY_W: bar = 'W'; break;
    case KEY_X: bar = 'X'; break;
    case KEY_Y: bar = 'Y'; break;
    case KEY_Z: bar = 'Z'; break;

    case KEY_ENTER: bar = '\n'; break;

    default: bar = '?';

  }

  return bar;

}

void debug_rcvd_event(struct input_event *ev) {

  char type_str[15];

  switch (ev->type) {
    case EV_SYN:  strcpy(type_str, "EV_SYN"); break;
    case EV_KEY:  strcpy(type_str, "EV_KEY"); break;
    case EV_REL:  strcpy(type_str, "EV_REL"); break;
    case EV_ABS:  strcpy(type_str, "EV_ABS"); break;
    case EV_MSC:  strcpy(type_str, "EV_MSC"); break;
    case EV_SW:   strcpy(type_str, "EV_SW"); break;
    case EV_LED:  strcpy(type_str, "EV_LED"); break;
    case EV_SND:  strcpy(type_str, "EV_SND"); break;
    case EV_REP:  strcpy(type_str, "EV_REP"); break;
    case EV_FF:   strcpy(type_str, "EV_FF"); break;
    case EV_PWR:  strcpy(type_str, "EV_PWR"); break;
    case EV_MAX:  strcpy(type_str, "EV_MAX"); break;

    case EV_FF_STATUS: strcpy(type_str, "EV_FF_STATUS"); break;
	    
    default: strcpy(type_str, "UNK");
      
  }

  printf("Event: time %ld.%06ld, type %s, code %d, value %d\n",
	 ev->time.tv_sec, ev->time.tv_usec, type_str,
	 ev->code, ev->value);

}

找到上面的代码,试了一下, 可以用:

# ./bar
Go ahead and scan something - press ctrl_C when finished.
Look for printouts which say: Input from Scanner
Ignore other printouts
Input from Scanner: "20030016"
Input from Scanner: "20030016"
Input from Scanner: "20030016"
Input from Scanner: "20030016"
Input from Scanner: "HM2002210553JS"
Input from Scanner: "HM2002210553JS"

离线

#8 2020-03-27 15:27:01

checkout
会员
注册时间: 2018-11-09
已发帖子: 173
积分: 168

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

这个代码有限制,貌似读不了小写字母

离线

楼主 #9 2020-03-27 16:03:41

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

@checkout 怪不得, 连中划线(减号)都读不出来。

离线

#10 2020-03-27 16:55:34

shaoxi2010
会员
注册时间: 2019-06-13
已发帖子: 364
积分: 313

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

这种扫描枪不就是一个键盘设备嘛,直接输出就行

离线

#11 2020-03-27 17:30:08

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

checkout 说:

这个代码有限制,貌似读不了小写字母

看了一下, 只是 cvt_ev_char 这个函数没有处理 小写字母和特殊字符而且,代码添加一下就好了。

shaoxi2010 说:

这种扫描枪不就是一个键盘设备嘛,直接输出就行

Windows 下确实是这样, Linux下你觉得用什么编程接口读呢?





离线

#12 2020-03-27 18:46:01

checkout
会员
注册时间: 2018-11-09
已发帖子: 173
积分: 168

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

单纯判断键值貌似是区分不了大小写的。
有些键盘shift+a组合表示大写A,Caps Lock锁定大写时按单一a键也是大写A。
直接读raw数据或许准确一些,还可以判断组合键和多键同时按下的情况。

晕哥 说:

看了一下, 只是 cvt_ev_char 这个函数没有处理 小写字母和特殊字符而且,代码添加一下就好了。


Windows 下确实是这样, Linux下你觉得用什么编程接口读呢?

最近编辑记录 checkout (2020-03-27 18:52:38)

离线

#13 2020-03-27 19:01:17

小智
会员
注册时间: 2019-10-16
已发帖子: 109
积分: 86

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

学习

离线

楼主 #14 2020-03-28 09:01:00

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

checkout 说:

单纯判断键值貌似是区分不了大小写的。
有些键盘shift+a组合表示大写A,Caps Lock锁定大写时按单一a键也是大写A。
直接读raw数据或许准确一些,还可以判断组合键和多键同时按下的情况。

原来如此啊, 看来要去看 Qt 怎么读取 event 设备的了。

离线

楼主 #15 2020-03-28 15:36:05

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

/*
 * Symbol Barcode Scanner Reader Software
 * Written by Andy Stewart
 * June 5, 2007
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Set the debug variable to 1 to get some debug printouts.
 *
 * One must have the Linux kernel sources installed in order for this to compile.
 *
 * To build it:
 * gcc -o bar bar.c
 * 
 * Note: this code was tested on Linux kernel rev. 2.6.32 (FOX Board G20)
 *
 */

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "string.h"

#include <linux/input.h>

/* defined at the end of this file */
char cvt_ev_char(int);      
void debug_rcvd_event(struct input_event *);

#define MAX_IN_SIZE 30

main(int argc, char *argv[]) 
{

	int debug = 0;                /* set this to 1 to get debug info */

	struct input_event ev[64];    /* each scan causes more than one event...get them all */

	int fd = -1;                  /* file descriptor for the scanner device */
	int bytes_read = 0;           /* number of bytes read by the read function */
	int i;                        /* loop variable */
	char scanner_in[30];          /* set this bigger if scanned input is more than 30 characters */
	char scan_char;               /* this holds one char at a time...will be concatenated into scanner_in[] */
	int wr_ptr = 0;               /* points into scanner_in so we know where to put the next scan_char */

	printf("Go ahead and scan something - press ctrl_C when finished.\n");
	printf("Look for printouts which say: Input from Scanner\n");
	printf("Ignore other printouts\n");

	/* The device interface can be found in /dev/input/by-id/*Symbol*, which should be a link
	* to /dev/input/eventN, where N is some number.  One may need to adjust the permissions of the
	* eventN file.
	*
	* Yeah, I know it sucks for me to have hardcoded this value...sorry, I was too lazy to compute it.
	*/

	while(1)
	{
		if ((fd = open("/dev/input/event2", O_RDONLY)) < 0)
		{
			printf("Error opening file descriptor - do you have sufficient permission? Maybe it is incorrectly hardcoded - check the source. Exiting.\n");
			//return -1;
			usleep(1000*1000);
			continue;
		}

		while (1)
		{
			bytes_read = read(fd, &ev, sizeof(struct input_event) * 64);

			if (bytes_read < 0)
			{
				printf("ERROR: can't properly read from device\n");
				//return -1;
				usleep(1000*1000);
				break;
			}

			for (i=0; i < (int) (bytes_read / sizeof(struct input_event)); i++)
			{
				/* Look for a "key press" event */
				if ((ev[i].type == EV_KEY) && (ev[i].value == 1))
				{

					if (ev[i].code != KEY_LEFTSHIFT)
					{
						scan_char = cvt_ev_char(ev[i].code);         /* Extract the character from the event */

						if (debug)
						{
							debug_rcvd_event(&ev[i]);
							printf("Scan char: %c\n", scan_char);
						}

						if (ev[i].code != KEY_ENTER)
						{
							scanner_in[wr_ptr++] = scan_char;
						}
						else 
						{
							scanner_in[wr_ptr] = '\0';
							printf("Input from Scanner: \"%s\"\n", scanner_in);
							wr_ptr = 0;
						}

					} /* if (ev[i].code ...) */

				} /* if ((ev[i].type.....)) */

			} /* for (i=0...) */

		} /* while (1) */

		close(fd);
	}

} /* main */

/*
 * cvt_ev_char: convert the code in the "keyboard" event to an ASCII character
 *              The character definitions came from /usr/include/linux/input.h
 *              Assumption is that barcodes can only have 0-9, A-Z so other
 *              codes have been removed from the list below.
 * 
 */

char cvt_ev_char(int foo) {

  char bar;

  switch (foo) {
    case KEY_0: bar = '0'; break;
    case KEY_1: bar = '1'; break;
    case KEY_2: bar = '2'; break;
    case KEY_3: bar = '3'; break;
    case KEY_4: bar = '4'; break;
    case KEY_5: bar = '5'; break;
    case KEY_6: bar = '6'; break;
    case KEY_7: bar = '7'; break;
    case KEY_8: bar = '8'; break;
    case KEY_9: bar = '9'; break;

    case KEY_A: bar = 'A'; break;
    case KEY_B: bar = 'B'; break;
    case KEY_C: bar = 'C'; break;
    case KEY_D: bar = 'D'; break;
    case KEY_E: bar = 'E'; break;
    case KEY_F: bar = 'F'; break;
    case KEY_G: bar = 'G'; break;
    case KEY_H: bar = 'H'; break;
    case KEY_I: bar = 'I'; break;
    case KEY_J: bar = 'J'; break;
    case KEY_K: bar = 'K'; break;
    case KEY_L: bar = 'L'; break;
    case KEY_M: bar = 'M'; break;
    case KEY_N: bar = 'N'; break;
    case KEY_O: bar = 'O'; break;
    case KEY_P: bar = 'P'; break;
    case KEY_Q: bar = 'Q'; break;
    case KEY_R: bar = 'R'; break;
    case KEY_S: bar = 'S'; break;
    case KEY_T: bar = 'T'; break;
    case KEY_U: bar = 'U'; break;
    case KEY_V: bar = 'V'; break;
    case KEY_W: bar = 'W'; break;
    case KEY_X: bar = 'X'; break;
    case KEY_Y: bar = 'Y'; break;
    case KEY_Z: bar = 'Z'; break;

    case KEY_ENTER: bar = '\n'; break;

    default: bar = '?';

  }

  return bar;

}

void debug_rcvd_event(struct input_event *ev) {

  char type_str[15];

  switch (ev->type) {
    case EV_SYN:  strcpy(type_str, "EV_SYN"); break;
    case EV_KEY:  strcpy(type_str, "EV_KEY"); break;
    case EV_REL:  strcpy(type_str, "EV_REL"); break;
    case EV_ABS:  strcpy(type_str, "EV_ABS"); break;
    case EV_MSC:  strcpy(type_str, "EV_MSC"); break;
    case EV_SW:   strcpy(type_str, "EV_SW"); break;
    case EV_LED:  strcpy(type_str, "EV_LED"); break;
    case EV_SND:  strcpy(type_str, "EV_SND"); break;
    case EV_REP:  strcpy(type_str, "EV_REP"); break;
    case EV_FF:   strcpy(type_str, "EV_FF"); break;
    case EV_PWR:  strcpy(type_str, "EV_PWR"); break;
    case EV_MAX:  strcpy(type_str, "EV_MAX"); break;

    case EV_FF_STATUS: strcpy(type_str, "EV_FF_STATUS"); break;
	    
    default: strcpy(type_str, "UNK");
      
  }

  printf("Event: time %ld.%06ld, type %s, code %d, value %d\n",
	 ev->time.tv_sec, ev->time.tv_usec, type_str,
	 ev->code, ev->value);

}

改了几行代码, 拔出再插入条码枪也能用。

离线

楼主 #16 2020-03-28 16:49:45

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

/*
 * Symbol Barcode Scanner Reader Software
 * Written by Andy Stewart
 * June 5, 2007
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Set the debug variable to 1 to get some debug printouts.
 *
 * One must have the Linux kernel sources installed in order for this to compile.
 *
 * To build it:
 * gcc -o bar bar.c
 * 
 * Note: this code was tested on Linux kernel rev. 2.6.32 (FOX Board G20)
 *
 */

#define _GNU_SOURCE /* for asprintf */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <linux/version.h>
#include <linux/input.h>

#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <ctype.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>




/* defined at the end of this file */
char cvt_ev_char(int);      
void debug_rcvd_event(struct input_event *);

#define MAX_IN_SIZE 30
#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"
#define BARCODE_1 "Manufacturer Barcode Reader"

/**
 * Filter for the AutoDevProbe scandir on /dev/input.
 *
 * @param dir The current directory entry provided by scandir.
 *
 * @return Non-zero if the given directory entry starts with "event", or zero
 * otherwise.
 */
static int is_event_device(const struct dirent *dir) {
	return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}

/**
 * Scans all /dev/input/event*, display them and ask the user which one to
 * open.
 *
 * @return The event device file name of the device file selected. This
 * string is allocated and must be freed by the caller.
 */
static char* scan_devices(void)
{
	struct dirent **namelist;
	int i, ndev, devnum;
	char *filename;
	int max_device = 0;
	int checkitem = -1;

	ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, versionsort);
	if (ndev <= 0)
		return NULL;

	fprintf(stderr, "Available devices:\n");

	for (i = 0; i < ndev; i++)
	{
		char fname[64];
		int fd = -1;
		char name[256] = "???";

		snprintf(fname, sizeof(fname),
			 "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
		fd = open(fname, O_RDONLY);
		if (fd < 0)
			continue;
		ioctl(fd, EVIOCGNAME(sizeof(name)), name);

		fprintf(stderr, "%s:	%s\n", fname, name);
		close(fd);

		sscanf(namelist[i]->d_name, "event%d", &devnum);

		int r = strncmp(name, BARCODE_1, strlen(BARCODE_1));
		printf("name = %s, r=%d \n", name, r);

		if(r == 0)
		{
			checkitem = devnum;
		}

		if (devnum > max_device)
			max_device = devnum;

		free(namelist[i]);
	}

	fprintf(stderr, "Select the device event number [0-%d]: ", max_device);
	//scanf("%d", &devnum);
	devnum = checkitem;
	fprintf(stderr, "now select [%d]\n", devnum);
	if (devnum > max_device || devnum < 0)
		return NULL;

	asprintf(&filename, "%s/%s%d",
		 DEV_INPUT_EVENT, EVENT_DEV_NAME,
		 devnum);

	return filename;
}

main(int argc, char *argv[]) 
{

	int debug = 0;                /* set this to 1 to get debug info */

	struct input_event ev[64];    /* each scan causes more than one event...get them all */

	int fd = -1;                  /* file descriptor for the scanner device */
	int bytes_read = 0;           /* number of bytes read by the read function */
	int i;                        /* loop variable */
	char scanner_in[30];          /* set this bigger if scanned input is more than 30 characters */
	char scan_char;               /* this holds one char at a time...will be concatenated into scanner_in[] */
	int wr_ptr = 0;               /* points into scanner_in so we know where to put the next scan_char */

	printf("Go ahead and scan something - press ctrl_C when finished.\n");
	printf("Look for printouts which say: Input from Scanner\n");
	printf("Ignore other printouts\n");

	/* The device interface can be found in /dev/input/by-id/*Symbol*, which should be a link
	* to /dev/input/eventN, where N is some number.  One may need to adjust the permissions of the
	* eventN file.
	*
	* Yeah, I know it sucks for me to have hardcoded this value...sorry, I was too lazy to compute it.
	*/

	while(1)
	{
		char* filename_barcode = scan_devices();
		if(!filename_barcode)
		{
			usleep(1000*1000);
			continue;
		}

		printf("find device -> %s\n", filename_barcode);

		if ((fd = open(filename_barcode, O_RDONLY)) < 0)
		{
			printf("Error opening file descriptor - do you have sufficient permission? Maybe it is incorrectly hardcoded - check the source. Exiting.\n");
			//return -1;
			usleep(1000*1000);
			continue;
		}

		while (1)
		{
			bytes_read = read(fd, &ev, sizeof(struct input_event) * 64);

			if (bytes_read < 0)
			{
				printf("ERROR: can't properly read from device\n");
				//return -1;
				usleep(1000*1000);
				break;
			}

			for (i=0; i < (int) (bytes_read / sizeof(struct input_event)); i++)
			{
				/* Look for a "key press" event */
				if ((ev[i].type == EV_KEY) && (ev[i].value == 1))
				{

					if (ev[i].code != KEY_LEFTSHIFT)
					{
						scan_char = cvt_ev_char(ev[i].code);         /* Extract the character from the event */

						if (debug)
						{
							debug_rcvd_event(&ev[i]);
							printf("Scan char: %c\n", scan_char);
						}

						if (ev[i].code != KEY_ENTER)
						{
							scanner_in[wr_ptr++] = scan_char;
						}
						else 
						{
							scanner_in[wr_ptr] = '\0';
							printf("Input from Scanner: \"%s\"\n", scanner_in);
							wr_ptr = 0;
						}

					} /* if (ev[i].code ...) */

				} /* if ((ev[i].type.....)) */

			} /* for (i=0...) */

		} /* while (1) */

		close(fd);
	}

} /* main */

/*
 * cvt_ev_char: convert the code in the "keyboard" event to an ASCII character
 *              The character definitions came from /usr/include/linux/input.h
 *              Assumption is that barcodes can only have 0-9, A-Z so other
 *              codes have been removed from the list below.
 * 
 */

char cvt_ev_char(int foo) {

  char bar;

  switch (foo) {
    case KEY_0: bar = '0'; break;
    case KEY_1: bar = '1'; break;
    case KEY_2: bar = '2'; break;
    case KEY_3: bar = '3'; break;
    case KEY_4: bar = '4'; break;
    case KEY_5: bar = '5'; break;
    case KEY_6: bar = '6'; break;
    case KEY_7: bar = '7'; break;
    case KEY_8: bar = '8'; break;
    case KEY_9: bar = '9'; break;

    case KEY_A: bar = 'A'; break;
    case KEY_B: bar = 'B'; break;
    case KEY_C: bar = 'C'; break;
    case KEY_D: bar = 'D'; break;
    case KEY_E: bar = 'E'; break;
    case KEY_F: bar = 'F'; break;
    case KEY_G: bar = 'G'; break;
    case KEY_H: bar = 'H'; break;
    case KEY_I: bar = 'I'; break;
    case KEY_J: bar = 'J'; break;
    case KEY_K: bar = 'K'; break;
    case KEY_L: bar = 'L'; break;
    case KEY_M: bar = 'M'; break;
    case KEY_N: bar = 'N'; break;
    case KEY_O: bar = 'O'; break;
    case KEY_P: bar = 'P'; break;
    case KEY_Q: bar = 'Q'; break;
    case KEY_R: bar = 'R'; break;
    case KEY_S: bar = 'S'; break;
    case KEY_T: bar = 'T'; break;
    case KEY_U: bar = 'U'; break;
    case KEY_V: bar = 'V'; break;
    case KEY_W: bar = 'W'; break;
    case KEY_X: bar = 'X'; break;
    case KEY_Y: bar = 'Y'; break;
    case KEY_Z: bar = 'Z'; break;

    case KEY_ENTER: bar = '\n'; break;

    default: bar = '?';

  }

  return bar;

}

void debug_rcvd_event(struct input_event *ev) {

  char type_str[15];

  switch (ev->type) {
    case EV_SYN:  strcpy(type_str, "EV_SYN"); break;
    case EV_KEY:  strcpy(type_str, "EV_KEY"); break;
    case EV_REL:  strcpy(type_str, "EV_REL"); break;
    case EV_ABS:  strcpy(type_str, "EV_ABS"); break;
    case EV_MSC:  strcpy(type_str, "EV_MSC"); break;
    case EV_SW:   strcpy(type_str, "EV_SW"); break;
    case EV_LED:  strcpy(type_str, "EV_LED"); break;
    case EV_SND:  strcpy(type_str, "EV_SND"); break;
    case EV_REP:  strcpy(type_str, "EV_REP"); break;
    case EV_FF:   strcpy(type_str, "EV_FF"); break;
    case EV_PWR:  strcpy(type_str, "EV_PWR"); break;
    case EV_MAX:  strcpy(type_str, "EV_MAX"); break;

    case EV_FF_STATUS: strcpy(type_str, "EV_FF_STATUS"); break;
	    
    default: strcpy(type_str, "UNK");
      
  }

  printf("Event: time %ld.%06ld, type %s, code %d, value %d\n",
	 ev->time.tv_sec, ev->time.tv_usec, type_str,
	 ev->code, ev->value);

}

又改了一点,把 evtest.c 的 scan_devices() 也加进来了, 这样只要代码指定:

#define BARCODE_1 "Manufacturer Barcode Reader"

程序会自动去找出设备名是Manufacturer Barcode Reader对应的设备路径 /dev/input/eventX

然后自动打开设备, 自动读取条码号。

离线

楼主 #17 2020-03-28 17:44:10

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

/*
 * Symbol Barcode Scanner Reader Software
 * Written by Andy Stewart
 * June 5, 2007
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Set the debug variable to 1 to get some debug printouts.
 *
 * One must have the Linux kernel sources installed in order for this to compile.
 *
 * To build it:
 * gcc -o bar bar.c
 * 
 * Note: this code was tested on Linux kernel rev. 2.6.32 (FOX Board G20)
 *
 */

#define _GNU_SOURCE /* for asprintf */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <linux/version.h>
#include <linux/input.h>

#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <ctype.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>




/* defined at the end of this file */
char cvt_ev_char(int);      
void debug_rcvd_event(struct input_event *);

#define MAX_IN_SIZE 30
#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"
#define BARCODE_1 "Manufacturer Barcode Reader"

/**
 * Filter for the AutoDevProbe scandir on /dev/input.
 *
 * @param dir The current directory entry provided by scandir.
 *
 * @return Non-zero if the given directory entry starts with "event", or zero
 * otherwise.
 */
static int is_event_device(const struct dirent *dir) {
	return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}

/**
 * Scans all /dev/input/event*, display them and ask the user which one to
 * open.
 *
 * @return The event device file name of the device file selected. This
 * string is allocated and must be freed by the caller.
 */
static char* scan_devices(void)
{
	struct dirent **namelist;
	int i, ndev, devnum;
	char *filename;
	int max_device = 0;
	int checkitem = -1;

	ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, versionsort);
	if (ndev <= 0)
		return NULL;

	fprintf(stderr, "Available devices:\n");

	for (i = 0; i < ndev; i++)
	{
		char fname[64];
		int fd = -1;
		char name[256] = "???";

		snprintf(fname, sizeof(fname),
			 "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
		fd = open(fname, O_RDONLY);
		if (fd < 0)
			continue;
		ioctl(fd, EVIOCGNAME(sizeof(name)), name);

		fprintf(stderr, "%s:	%s\n", fname, name);
		close(fd);

		sscanf(namelist[i]->d_name, "event%d", &devnum);

		int r = strncmp(name, BARCODE_1, strlen(BARCODE_1));
		printf("name = %s, r=%d \n", name, r);

		if(r == 0)
		{
			checkitem = devnum;
		}

		if (devnum > max_device)
			max_device = devnum;

		free(namelist[i]);
	}

	fprintf(stderr, "Select the device event number [0-%d]: ", max_device);
	//scanf("%d", &devnum);
	devnum = checkitem;
	fprintf(stderr, "now select [%d]\n", devnum);
	if (devnum > max_device || devnum < 0)
		return NULL;

	asprintf(&filename, "%s/%s%d",
		 DEV_INPUT_EVENT, EVENT_DEV_NAME,
		 devnum);

	return filename;
}

//main(int argc, char *argv[]) 
void* thread_poll_barcode(void* p)
{

	int debug = 0;                /* set this to 1 to get debug info */

	struct input_event ev[64];    /* each scan causes more than one event...get them all */

	int fd = -1;                  /* file descriptor for the scanner device */
	int bytes_read = 0;           /* number of bytes read by the read function */
	int i;                        /* loop variable */
	char scanner_in[30];          /* set this bigger if scanned input is more than 30 characters */
	char scan_char;               /* this holds one char at a time...will be concatenated into scanner_in[] */
	int wr_ptr = 0;               /* points into scanner_in so we know where to put the next scan_char */

	printf("Go ahead and scan something - press ctrl_C when finished.\n");
	printf("Look for printouts which say: Input from Scanner\n");
	printf("Ignore other printouts\n");

	/* The device interface can be found in /dev/input/by-id/*Symbol*, which should be a link
	* to /dev/input/eventN, where N is some number.  One may need to adjust the permissions of the
	* eventN file.
	*
	* Yeah, I know it sucks for me to have hardcoded this value...sorry, I was too lazy to compute it.
	*/

	while(1)
	{
		char* filename_barcode = scan_devices();
		if(!filename_barcode)
		{
			usleep(1000*1000);
			continue;
		}

		printf("find device -> %s\n", filename_barcode);

		if ((fd = open(filename_barcode, O_RDONLY)) < 0)
		{
			printf("Error opening file descriptor - do you have sufficient permission? Maybe it is incorrectly hardcoded - check the source. Exiting.\n");
			//return -1;
			usleep(1000*1000);
			continue;
		}

		while (1)
		{
			bytes_read = read(fd, &ev, sizeof(struct input_event) * 64);

			if (bytes_read < 0)
			{
				printf("ERROR: can't properly read from device\n");
				//return -1;
				usleep(1000*1000);
				break;
			}

			for (i=0; i < (int) (bytes_read / sizeof(struct input_event)); i++)
			{
				/* Look for a "key press" event */
				if ((ev[i].type == EV_KEY) && (ev[i].value == 1))
				{

					if (ev[i].code != KEY_LEFTSHIFT)
					{
						scan_char = cvt_ev_char(ev[i].code);         /* Extract the character from the event */

						if (debug)
						{
							debug_rcvd_event(&ev[i]);
							printf("Scan char: %c\n", scan_char);
						}

						if (ev[i].code != KEY_ENTER)
						{
							scanner_in[wr_ptr++] = scan_char;
						}
						else 
						{
							scanner_in[wr_ptr] = '\0';
							printf("Input from Scanner: \"%s\"\n", scanner_in);
							wr_ptr = 0;
						}

					} /* if (ev[i].code ...) */

				} /* if ((ev[i].type.....)) */

			} /* for (i=0...) */

		} /* while (1) */

		close(fd);
	}

} /* main */

/*
 * cvt_ev_char: convert the code in the "keyboard" event to an ASCII character
 *              The character definitions came from /usr/include/linux/input.h
 *              Assumption is that barcodes can only have 0-9, A-Z so other
 *              codes have been removed from the list below.
 * 
 */

char cvt_ev_char(int foo) {

  char bar;

  switch (foo) {
    case KEY_0: bar = '0'; break;
    case KEY_1: bar = '1'; break;
    case KEY_2: bar = '2'; break;
    case KEY_3: bar = '3'; break;
    case KEY_4: bar = '4'; break;
    case KEY_5: bar = '5'; break;
    case KEY_6: bar = '6'; break;
    case KEY_7: bar = '7'; break;
    case KEY_8: bar = '8'; break;
    case KEY_9: bar = '9'; break;

    case KEY_A: bar = 'A'; break;
    case KEY_B: bar = 'B'; break;
    case KEY_C: bar = 'C'; break;
    case KEY_D: bar = 'D'; break;
    case KEY_E: bar = 'E'; break;
    case KEY_F: bar = 'F'; break;
    case KEY_G: bar = 'G'; break;
    case KEY_H: bar = 'H'; break;
    case KEY_I: bar = 'I'; break;
    case KEY_J: bar = 'J'; break;
    case KEY_K: bar = 'K'; break;
    case KEY_L: bar = 'L'; break;
    case KEY_M: bar = 'M'; break;
    case KEY_N: bar = 'N'; break;
    case KEY_O: bar = 'O'; break;
    case KEY_P: bar = 'P'; break;
    case KEY_Q: bar = 'Q'; break;
    case KEY_R: bar = 'R'; break;
    case KEY_S: bar = 'S'; break;
    case KEY_T: bar = 'T'; break;
    case KEY_U: bar = 'U'; break;
    case KEY_V: bar = 'V'; break;
    case KEY_W: bar = 'W'; break;
    case KEY_X: bar = 'X'; break;
    case KEY_Y: bar = 'Y'; break;
    case KEY_Z: bar = 'Z'; break;

    case KEY_ENTER: bar = '\n'; break;

    default: bar = '?';

  }

  return bar;

}

void debug_rcvd_event(struct input_event *ev) {

  char type_str[15];

  switch (ev->type) {
    case EV_SYN:  strcpy(type_str, "EV_SYN"); break;
    case EV_KEY:  strcpy(type_str, "EV_KEY"); break;
    case EV_REL:  strcpy(type_str, "EV_REL"); break;
    case EV_ABS:  strcpy(type_str, "EV_ABS"); break;
    case EV_MSC:  strcpy(type_str, "EV_MSC"); break;
    case EV_SW:   strcpy(type_str, "EV_SW"); break;
    case EV_LED:  strcpy(type_str, "EV_LED"); break;
    case EV_SND:  strcpy(type_str, "EV_SND"); break;
    case EV_REP:  strcpy(type_str, "EV_REP"); break;
    case EV_FF:   strcpy(type_str, "EV_FF"); break;
    case EV_PWR:  strcpy(type_str, "EV_PWR"); break;
    case EV_MAX:  strcpy(type_str, "EV_MAX"); break;

    case EV_FF_STATUS: strcpy(type_str, "EV_FF_STATUS"); break;
	    
    default: strcpy(type_str, "UNK");
      
  }

  printf("Event: time %ld.%06ld, type %s, code %d, value %d\n",
	 ev->time.tv_sec, ev->time.tv_usec, type_str,
	 ev->code, ev->value);

}

int main(int argc, char *argv[]) 
{
	pthread_t thread_barcode;
	int r_barcode = pthread_create(&thread_barcode, NULL, thread_poll_barcode, NULL);
	if(0 == r_barcode)
	{
		printf("thread create successful!\n");
	}

	while(1)
	{
		usleep(5 * 1000*1000); //sleep 5 second
		printf("-----------------------\n");
	}
}

把读条码包装到线程里面。

离线

楼主 #18 2020-03-31 11:14:20

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

/*
 * Symbol Barcode Scanner Reader Software
 * Written by Andy Stewart
 * June 5, 2007
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Set the debug variable to 1 to get some debug printouts.
 *
 * One must have the Linux kernel sources installed in order for this to compile.
 *
 * To build it:
 * gcc -o bar bar.c
 * 
 * Note: this code was tested on Linux kernel rev. 2.6.32 (FOX Board G20)
 *
 */

#define _GNU_SOURCE /* for asprintf */
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <linux/version.h>
#include <linux/input.h>

#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <ctype.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>




/* defined at the end of this file */
char cvt_ev_char(int);      
void debug_rcvd_event(struct input_event *);

#define MAX_IN_SIZE 30
#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"
#define BARCODE_1 "Manufacturer Barcode Reader"

/**
 * Filter for the AutoDevProbe scandir on /dev/input.
 *
 * @param dir The current directory entry provided by scandir.
 *
 * @return Non-zero if the given directory entry starts with "event", or zero
 * otherwise.
 */
static int is_event_device(const struct dirent *dir) {
	return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}

/**
 * Scans all /dev/input/event*, display them and ask the user which one to
 * open.
 *
 * @return The event device file name of the device file selected. This
 * string is allocated and must be freed by the caller.
 */
static char* scan_devices(void)
{
	struct dirent **namelist;
	int i, ndev, devnum;
	char *filename;
	int max_device = 0;
	int checkitem = -1;

	ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, versionsort);
	if (ndev <= 0)
		return NULL;

	fprintf(stderr, "Available devices:\n");

	for (i = 0; i < ndev; i++)
	{
		char fname[64];
		int fd = -1;
		char name[256] = "???";

		snprintf(fname, sizeof(fname),
			 "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
		fd = open(fname, O_RDONLY);
		if (fd < 0)
			continue;
		ioctl(fd, EVIOCGNAME(sizeof(name)), name);

		fprintf(stderr, "%s:	%s\n", fname, name);
		close(fd);

		sscanf(namelist[i]->d_name, "event%d", &devnum);

		int r = strncmp(name, BARCODE_1, strlen(BARCODE_1));
		printf("name = %s, r=%d \n", name, r);

		if(r == 0)
		{
			checkitem = devnum;
		}

		if (devnum > max_device)
			max_device = devnum;

		free(namelist[i]);
	}

	fprintf(stderr, "Select the device event number [0-%d]: ", max_device);
	//scanf("%d", &devnum);
	devnum = checkitem;
	fprintf(stderr, "now select [%d]\n", devnum);
	if (devnum > max_device || devnum < 0)
		return NULL;

	asprintf(&filename, "%s/%s%d",
		 DEV_INPUT_EVENT, EVENT_DEV_NAME,
		 devnum);

	return filename;
}

//time_t last_get_barcode = 0;
char scanner_in[30];          /* set this bigger if scanned input is more than 30 characters */
struct timeval tv_last_get_barcode;
int trigger = 0;//1: trigger, 0: no
//main(int argc, char *argv[]) 
void* thread_poll_barcode(void* p)
{
	int debug = 0;                /* set this to 1 to get debug info */

	struct input_event ev[64];    /* each scan causes more than one event...get them all */

	int fd = -1;                  /* file descriptor for the scanner device */
	int bytes_read = 0;           /* number of bytes read by the read function */
	int i;                        /* loop variable */
	char scan_char;               /* this holds one char at a time...will be concatenated into scanner_in[] */
	int wr_ptr = 0;               /* points into scanner_in so we know where to put the next scan_char */

	printf("Go ahead and scan something - press ctrl_C when finished.\n");
	printf("Look for printouts which say: Input from Scanner\n");
	printf("Ignore other printouts\n");

	/* The device interface can be found in /dev/input/by-id/*Symbol*, which should be a link
	* to /dev/input/eventN, where N is some number.  One may need to adjust the permissions of the
	* eventN file.
	*
	* Yeah, I know it sucks for me to have hardcoded this value...sorry, I was too lazy to compute it.
	*/

	while(1)
	{
		char* filename_barcode = scan_devices();
		if(!filename_barcode)
		{
			usleep(1000*1000);
			continue;
		}

		printf("find device -> %s\n", filename_barcode);

		if ((fd = open(filename_barcode, O_RDONLY)) < 0)
		{
			printf("Error opening file descriptor - do you have sufficient permission? Maybe it is incorrectly hardcoded - check the source. Exiting.\n");
			//return -1;
			usleep(1000*1000);
			continue;
		}

		while (1)
		{
			bytes_read = read(fd, &ev, sizeof(struct input_event) * 64);

			if (bytes_read < 0)
			{
				printf("ERROR: can't properly read from device\n");
				//return -1;
				usleep(1000*1000);
				break;
			}

			for (i=0; i < (int) (bytes_read / sizeof(struct input_event)); i++)
			{
				/* Look for a "key press" event */
				if ((ev[i].type == EV_KEY) && (ev[i].value == 1))
				{

					if (ev[i].code != KEY_LEFTSHIFT)
					{
						scan_char = cvt_ev_char(ev[i].code);         /* Extract the character from the event */

						if (debug)
						{
							debug_rcvd_event(&ev[i]);
							printf("Scan char: %c\n", scan_char);
						}

						if (ev[i].code != KEY_ENTER)
						{
							scanner_in[wr_ptr++] = scan_char;
						}
						else 
						{
							trigger = 1;
							gettimeofday(&tv_last_get_barcode, NULL);
							scanner_in[wr_ptr] = '\0';
							//printf("Input from Scanner: \"%s\"\n", scanner_in);
							wr_ptr = 0;
						}

					} /* if (ev[i].code ...) */

				} /* if ((ev[i].type.....)) */

			} /* for (i=0...) */

		} /* while (1) */

		close(fd);
	}

} /* main */

/*
 * cvt_ev_char: convert the code in the "keyboard" event to an ASCII character
 *              The character definitions came from /usr/include/linux/input.h
 *              Assumption is that barcodes can only have 0-9, A-Z so other
 *              codes have been removed from the list below.
 * 
 */

char cvt_ev_char(int foo) {

  char bar;

  switch (foo) {
    case KEY_0: bar = '0'; break;
    case KEY_1: bar = '1'; break;
    case KEY_2: bar = '2'; break;
    case KEY_3: bar = '3'; break;
    case KEY_4: bar = '4'; break;
    case KEY_5: bar = '5'; break;
    case KEY_6: bar = '6'; break;
    case KEY_7: bar = '7'; break;
    case KEY_8: bar = '8'; break;
    case KEY_9: bar = '9'; break;

    case KEY_A: bar = 'A'; break;
    case KEY_B: bar = 'B'; break;
    case KEY_C: bar = 'C'; break;
    case KEY_D: bar = 'D'; break;
    case KEY_E: bar = 'E'; break;
    case KEY_F: bar = 'F'; break;
    case KEY_G: bar = 'G'; break;
    case KEY_H: bar = 'H'; break;
    case KEY_I: bar = 'I'; break;
    case KEY_J: bar = 'J'; break;
    case KEY_K: bar = 'K'; break;
    case KEY_L: bar = 'L'; break;
    case KEY_M: bar = 'M'; break;
    case KEY_N: bar = 'N'; break;
    case KEY_O: bar = 'O'; break;
    case KEY_P: bar = 'P'; break;
    case KEY_Q: bar = 'Q'; break;
    case KEY_R: bar = 'R'; break;
    case KEY_S: bar = 'S'; break;
    case KEY_T: bar = 'T'; break;
    case KEY_U: bar = 'U'; break;
    case KEY_V: bar = 'V'; break;
    case KEY_W: bar = 'W'; break;
    case KEY_X: bar = 'X'; break;
    case KEY_Y: bar = 'Y'; break;
    case KEY_Z: bar = 'Z'; break;

    case KEY_ENTER: bar = '\n'; break;

    default: bar = '?';

  }

  return bar;

}

void debug_rcvd_event(struct input_event *ev) {

  char type_str[15];

  switch (ev->type) {
    case EV_SYN:  strcpy(type_str, "EV_SYN"); break;
    case EV_KEY:  strcpy(type_str, "EV_KEY"); break;
    case EV_REL:  strcpy(type_str, "EV_REL"); break;
    case EV_ABS:  strcpy(type_str, "EV_ABS"); break;
    case EV_MSC:  strcpy(type_str, "EV_MSC"); break;
    case EV_SW:   strcpy(type_str, "EV_SW"); break;
    case EV_LED:  strcpy(type_str, "EV_LED"); break;
    case EV_SND:  strcpy(type_str, "EV_SND"); break;
    case EV_REP:  strcpy(type_str, "EV_REP"); break;
    case EV_FF:   strcpy(type_str, "EV_FF"); break;
    case EV_PWR:  strcpy(type_str, "EV_PWR"); break;
    case EV_MAX:  strcpy(type_str, "EV_MAX"); break;

    case EV_FF_STATUS: strcpy(type_str, "EV_FF_STATUS"); break;
	    
    default: strcpy(type_str, "UNK");
      
  }

  printf("Event: time %ld.%06ld, type %s, code %d, value %d\n",
	 ev->time.tv_sec, ev->time.tv_usec, type_str,
	 ev->code, ev->value);

}

int get_barcode(char* code, int length)
{
	struct timeval tv_now;

	gettimeofday(&tv_now, NULL);

	int t_now = tv_now.tv_sec*1000 + tv_now.tv_usec/1000;
	int t_last_get_barcode = tv_last_get_barcode.tv_sec*1000 + tv_last_get_barcode.tv_usec/1000;

	if((trigger == 1) && (t_now - t_last_get_barcode < 500))
	{
		memset(code, 0, length);
		strncpy(code, scanner_in, length-1);
		trigger = 0;
		return 0;
	}

	return 1;
}

int main(int argc, char *argv[]) 
{
	char barcode[64];
	pthread_t thread_barcode;
	int r_barcode = pthread_create(&thread_barcode, NULL, thread_poll_barcode, NULL);
	if(0 == r_barcode)
	{
		printf("thread create successful!\n");
	}

	while(1)
	{
		usleep(50*1000); //sleep 50 millsecond

		if(0 == get_barcode(barcode, sizeof(barcode)))
		{
			printf("read ok: %s\n", barcode);
		}
	}
}

随手改了一下, 应用程序调用这个函数即可读出二维码数据(目前不支持小写字母和其他字符):

get_barcode(barcode, sizeof(barcode))

离线

#19 2020-03-31 15:58:31

sy373466062
会员
注册时间: 2018-11-12
已发帖子: 130
积分: 116

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

查了下这个条码枪倒是不贵

离线

楼主 #20 2020-03-31 16:22:28

barcode
会员
注册时间: 2020-03-27
已发帖子: 3
积分: 2.5

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

sy373466062 说:

查了下这个条码枪倒是不贵

选的是 一/二维码全能有线-用于(收银/商品/多功能)HS26高速 那个套餐, 228元.

我拆了一下, 貌似用全志 F1C100s 方案,

现在有个棘手的问题, 每次上电重启之后, 要重插USB扫码器才行,

这个真是一个非常差的体验, 不知道应该如何修改?

离线

#21 2020-08-11 21:05:20

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: 试一试 S3 Linux 4.13 读取 USB 条码枪

barcode 说:

选的是 一/二维码全能有线-用于(收银/商品/多功能)HS26高速 那个套餐, 228元.

我拆了一下, 貌似用全志 F1C100s 方案,

现在有个棘手的问题, 每次上电重启之后, 要重插USB扫码器才行,

这个真是一个非常差的体验, 不知道应该如何修改?

通病了,usb部分处理不好。需要扫描枪找我

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn