离线
# 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 读按键数据, 看来直接用是不可能了。
离线
evtest 学到了 感谢楼主分享
离线
我想函数直接获取条码上的字符串, 有办法吗? 在线等各位大神回复。
离线
想知道这个条码枪用什么方案, 灵敏度如何?
离线
想知道这个条码枪用什么方案, 灵敏度如何?
这个还可以扫二维码呢, 方案不知道哦, 晚点我拆拆研究一下。灵敏度我觉得还行。
离线
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"
离线
这个代码有限制,貌似读不了小写字母
离线
@checkout 怪不得, 连中划线(减号)都读不出来。
离线
这种扫描枪不就是一个键盘设备嘛,直接输出就行
离线
离线
单纯判断键值貌似是区分不了大小写的。
有些键盘shift+a组合表示大写A,Caps Lock锁定大写时按单一a键也是大写A。
直接读raw数据或许准确一些,还可以判断组合键和多键同时按下的情况。
看了一下, 只是 cvt_ev_char 这个函数没有处理 小写字母和特殊字符而且,代码添加一下就好了。
Windows 下确实是这样, Linux下你觉得用什么编程接口读呢?
最近编辑记录 checkout (2020-03-27 18:52:38)
离线
学习
离线
单纯判断键值貌似是区分不了大小写的。
有些键盘shift+a组合表示大写A,Caps Lock锁定大写时按单一a键也是大写A。
直接读raw数据或许准确一些,还可以判断组合键和多键同时按下的情况。
原来如此啊, 看来要去看 Qt 怎么读取 event 设备的了。
离线
/*
* 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);
}
改了几行代码, 拔出再插入条码枪也能用。
离线
/*
* 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
然后自动打开设备, 自动读取条码号。
离线
/*
* 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");
}
}
把读条码包装到线程里面。
离线
/*
* 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))
离线
查了下这个条码枪倒是不贵
离线
查了下这个条码枪倒是不贵
选的是 一/二维码全能有线-用于(收银/商品/多功能)HS26高速 那个套餐, 228元.
我拆了一下, 貌似用全志 F1C100s 方案,
现在有个棘手的问题, 每次上电重启之后, 要重插USB扫码器才行,
这个真是一个非常差的体验, 不知道应该如何修改?
离线
选的是 一/二维码全能有线-用于(收银/商品/多功能)HS26高速 那个套餐, 228元.
我拆了一下, 貌似用全志 F1C100s 方案,
现在有个棘手的问题, 每次上电重启之后, 要重插USB扫码器才行,
这个真是一个非常差的体验, 不知道应该如何修改?
通病了,usb部分处理不好。需要扫描枪找我
离线