LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   read from a USB barcode scanner that simulates a keyboard (https://www.linuxquestions.org/questions/programming-9/read-from-a-usb-barcode-scanner-that-simulates-a-keyboard-495358/)

bricedebrignaisplage 10-25-2006 03:27 AM

read from a USB barcode scanner that simulates a keyboard
 
I have a USB barcode scanner that acts like a keyboard: whenever a barcode is read it sends the code where the keyboard would normally write. I would like to write some code (preferably in C) to modify this behavior and to be able to listen to the scanner from a program, just like I would read from a socket or a serial port for instance.

I am writing code to control a robot, the barcode scanner is used for localization. So I need the control code to be able to listen to the scanner.

Maybe you don't know the solution but can give some ideas that would put me on the way. I have the feeling that I could use the ioctl function, but I am not familiar with the underlying concepts, and it's a pretty complex function.

Thanks
Brice

National University of Singapore

bernied 10-25-2006 10:00 AM

Maybe you could have a look at phidgets - these are usb devices for controlling and sensing various things. Lots of robotics applications. Anyway they have libraries in C, C#, VB and others, that you could look at the source of to see how they talk through the usb bus. There's sure to be a way to define a particular device (all devices are defined by a vendor:device identifier so can be specifically targeted) and to stop the keyboard driver from using it.
Phidgets are here:
http://www.phidgets.com/index.php

bricedebrignaisplage 10-25-2006 08:55 PM

Hi

There was a similar thread, which had never received any answer.
http://www.linuxquestions.org/questi...errerid=260969
So I posted the topic again here hoping I would get more chance (and I did, thanks bernied), but in the meantime I contacted this guy to see if he had managed to find a solution. Here is the answer he kindly gave me. I post it here for reference:
They normally configure as a keyboard, though in Linux, by default, some of the COM ports may not be accessible. Add "8250.nr_uarts=8" to the end of your kernel line to have it configure past COM4.
I.E.: kernel /boot/vmlinuz-2.6.15-1.2054_FC5 ro root=LABEL=/ 8250.nr_uarts=8
If you cat /dev/ttySX (X is the number of the COM port you want to listen to) and scan something, you should see input.
If it's a USB scanner, they seem to always configure as a USB keyboard.
I am going to work on those two ideas, and post my results here. In the meantime, more suggestions are welcome.

bricedebrignaisplage 04-19-2007 10:30 PM

I managed to read from the USB barcode scanner using libhid. However I have the feeling that there should be some way to redirect whatever comes from that barcode to a file without using libhid. My ultimate goal is to redirect it to a FIFO (/dev/rtfX).

What MardukKurios (the guy I quoted in previous post) suggested sounds like a good idea, but unfortunately 8250.nr_uarts is not an option recognized by my kernel.

However, this suggests that what I want to do should be possible. I've always thought that the main advantage of Linux is that everything is possible, provided that you have enough knowledge.

Does anybody here has enough knowledge to help me? At least some ideas I could start with.

PS: dmesg shows this
usb 2-1: new full speed USB device using uhci_hcd and address 3
input: � Symbol Technologies, Inc, 2000 Symbol Bar Code Scanner as /class/input/input3
input: USB HID v1.10 Keyboard [� Symbol Technologies, Inc, 2000 Symbol Bar Code Scanner ] on usb-0000:00:1d.0-1

dhrubajyoti.deka 05-28-2007 06:58 AM

read from a USB barcode scanner that simulates a keyboard
 
Quote:

Originally Posted by bricedebrignaisplage
I managed to read from the USB barcode scanner using libhid. However I have the feeling that there should be some way to redirect whatever comes from that barcode to a file without using libhid. My ultimate goal is to redirect it to a FIFO (/dev/rtfX).

What MardukKurios (the guy I quoted in previous post) suggested sounds like a good idea, but unfortunately 8250.nr_uarts is not an option recognized by my kernel.

However, this suggests that what I want to do should be possible. I've always thought that the main advantage of Linux is that everything is possible, provided that you have enough knowledge.

Does anybody here has enough knowledge to help me? At least some ideas I could start with.

PS: dmesg shows this
usb 2-1: new full speed USB device using uhci_hcd and address 3
input: � Symbol Technologies, Inc, 2000 Symbol Bar Code Scanner as /class/input/input3
input: USB HID v1.10 Keyboard [� Symbol Technologies, Inc, 2000 Symbol Bar Code Scanner ] on usb-0000:00:1d.0-1

Hi,

I am also facing the same problem using a usb device which simulates keyboard types. I am able to get the device information like (vendor name, product name etc.) using libhid. But I am facing problem in reading the output from the usb-device. it is simply sending the reads to the cursor location of the native terminal.

As you solved this problem and able to read the usb device using libhid, could you please give me a guide or send me a sample code to me. my email id is dhrubajyoti.deka@gmail.com .

Thanks in advance.
Dhruba

bricedebrignaisplage 05-29-2007 11:42 PM

I am no longer using libusb/libhid, but I am using the input layer of the kernel instead. The idea is to read from the /dev/input/event device associated with your device. To know which /dev/input/event node is associated with my device, I open all of them, get vendor ID and product ID and compare. If you don't have /dev/input, you must enable it in your kernel.
Btw, I got all this information from Vojtech Pavlik, the guy who wrote the input layer of the kernel.

I haven't found how to deal with capital letter though (shift key), and not all characters are in my conversion table... but that should get you started.

Here is my code:

Code:

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

#define VENDORID  0x5e0
#define PRODUCTID 0x200

int scan_fd = -1;

int initScanner(){
  int count=0;
  char path[32];
  struct dirent **files=NULL;
  struct input_id id;

  count = scandir("/dev/input",&files,0,0);
  while( count>=0 ){
    if( scan_fd==-1 && strncmp(files[count]->d_name,"event",5)==0 ){
      sprintf(path,"/dev/input/%s",files[count]->d_name);
      scan_fd = open(path,O_RDONLY);
      if( scan_fd>=0 ){
        if( ioctl(scan_fd,EVIOCGID,(void *)&id)<0 ) perror("ioctl EVIOCGID");
        else{
          if( id.vendor==VENDORID && id.product==PRODUCTID )
            printf("scanner attached to %s\n",path);
          else{
            close(scan_fd);
            scan_fd = -1;
          }
        }
      }
      else{
        fprintf(stderr,"Error opening %s",path);
        perror("");
      }
    }
    free(files[count--]);
  }
  free(files);

  if( scan_fd>=0 ) ioctl(scan_fd,EVIOCGRAB);
  else{ printf("scanner not found or couldn't be opened\n"); return 0;}
  return 1;
}


int closeScanner(){
  close(scan_fd);
  scan_fd = -1;
  return 1;
}


char keycodelist(int scancode){
  char ret = '-';
  return (unsigned char)scancode;
  switch(scancode){
  case 0x02: ret ='1';break;
  case 0x03: ret ='2';break;
  case 0x04: ret ='3';break;
  case 0x05: ret ='4';break;
  case 0x06: ret ='5';break;
  case 0x07: ret ='6';break;
  case 0x08: ret ='7';break;
  case 0x09: ret ='8';break;
  case 0x0a: ret ='9';break;
  case 0x0b: ret ='0';break;
  case 0x0c: ret ='-';break;

  case 0x10: ret ='q';break;
  case 0x11: ret ='w';break;
  case 0x12: ret ='e';break;
  case 0x13: ret ='r';break;
  case 0x14: ret ='t';break;
  case 0x15: ret ='y';break;
  case 0x16: ret ='u';break;
  case 0x17: ret ='i';break;
  case 0x18: ret ='o';break;
  case 0x19: ret ='p';break;

  case 0x1e: ret ='a';break;
  case 0x1f: ret ='s';break;
  case 0x20: ret ='d';break;
  case 0x21: ret ='f';break;
  case 0x22: ret ='g';break;
  case 0x23: ret ='h';break;
  case 0x24: ret ='j';break;
  case 0x25: ret ='k';break;
  case 0x26: ret ='l';break;

  case 0x2c: ret ='z';break;
  case 0x2d: ret ='x';break;
  case 0x2e: ret ='c';break;
  case 0x2f: ret ='v';break;
  case 0x30: ret ='b';break;
  case 0x31: ret ='n';break;
  case 0x32: ret ='m';break;
  default: break;
  }
  return ret;
}


//read a barcode from the scanner.
//reads as long as *loopcond!=0 (if loopcond is NULL then read
//forever). If termination condition is met, returns NULL.
//read all characters from barcode untill we read 0x28 (carriage
//return).
char* readScanner(int *loopcond){
  static char barcode[SCN_BCD_SZ];
  char code[SCN_BCD_SZ];
  int i=0;
  struct input_event ev;

  while( loopcond==NULL?1:*loopcond ){
    read(scan_fd,&ev,sizeof(struct input_event));
    if( ev.type==1 && ev.value==1 ){
      if( ev.code==28 ){ //carriage return
        code[i] = 0;
        strcpy(barcode,code);
        return barcode;
      }
      else{
        if( ev.code!=0 ){
          code[i++] = keycodelist(ev.code);
          if( i==SCN_BCD_SZ-1 ){ printf("Barcode buffer full\n"); return NULL;}
        }
      }
    }
  }
  return NULL;
}


bricedebrignaisplage 05-30-2007 02:21 AM

And here is some (older) code that uses libhid.

Code:

#include <stdio.h>
#include <string.h>
#include <ctype.h> //for toupper()
#include <hid.h>

#define VENDORID  0x5e0
#define PRODUCTID 0x200

HIDInterface* hid;


int initScanner(){
  hid_return ret;
  HIDInterfaceMatcher matcher = { VENDORID, PRODUCTID, NULL, NULL, 0 };

  /* see hid.h for possible values */
  hid_set_debug(HID_DEBUG_ALL);
  hid_set_debug_stream(stderr);
  /* passed directly to libusb */
  hid_set_usb_debug(0);
 
  ret = hid_init();
  if (ret != HID_RET_SUCCESS){
    fprintf(stderr,"hid_init failed with return code %d\n", ret);
    return 0;
  }

  hid = hid_new_HIDInterface();
  if (hid == 0) {
    fprintf(stderr,"hid_new_HIDInterface() failed, out of memory?\n");
    return 0;
  }

  /* How to detach a device from the kernel HID driver:
  * You can use hotplug to automatically give permissions to the device on
  * connection. Please see
  *  http://cvs.ailab.ch/cgi-bin/viewcvs.cgi/external/libphidgets/hotplug/
  * for an example. Try NOT to work as root!
  */

  ret = hid_force_open(hid, 0, &matcher, 3);
  if (ret != HID_RET_SUCCESS) {
    fprintf(stderr,"hid_force_open failed with return code %d\n", ret);
    return 0;
  }

  return 1;
}


int closeScanner(){
  hid_return ret;

  if(( ret=hid_close(hid)) != HID_RET_SUCCESS) {
    fprintf(stderr,"hid_close failed with return code %d\n", ret);
    return 0;
  }
  hid_delete_HIDInterface(&hid);

  if(( ret=hid_cleanup()) != HID_RET_SUCCESS) {
    fprintf(stderr,"hid_cleanup failed with return code %d\n", ret);
    return 0;
  }
  return 1;
}


char keycodelist(int scancode){
  char ret = '-';

  // from /usr/src/linux/drivers/usb/input/usbkbd.c
  char usb_kbd_keycode[256] = {
    0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
    50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
    4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
    27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
    65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
  105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
    72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
  191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
  115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
  122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
  150,158,159,128,136,177,178,176,142,152,173,140
  };

  switch(usb_kbd_keycode[scancode]){
  case 0x02: ret ='1';break;
  case 0x03: ret ='2';break;
  case 0x04: ret ='3';break;
  case 0x05: ret ='4';break;
  case 0x06: ret ='5';break;
  case 0x07: ret ='6';break;
  case 0x08: ret ='7';break;
  case 0x09: ret ='8';break;
  case 0x0a: ret ='9';break;
  case 0x0b: ret ='0';break;                       
  case 0x1e: ret ='a';break;
  case 0x30: ret ='b';break;
  case 0x2e: ret ='c';break;
  case 0x20: ret ='d';break;
  case 0x12: ret ='e';break;
  case 0x21: ret ='f';break;
  case 0x22: ret ='g';break;
  case 0x23: ret ='h';break;
  case 0x17: ret ='i';break;
  case 0x24: ret ='j';break;
  case 0x25: ret ='k';break;
  case 0x26: ret ='l';break;
  case 0x32: ret ='m';break;
  case 0x31: ret ='n';break;
  case 0x18: ret ='o';break;
  case 0x19: ret ='p';break;
  case 0x10: ret ='q';break;
  case 0x13: ret ='r';break;
  case 0x1f: ret ='s';break;
  case 0x14: ret ='t';break;
  case 0x16: ret ='u';break;
  case 0x2f: ret ='v';break;
  case 0x11: ret ='w';break;
  case 0x2d: ret ='x';break;
  case 0x15: ret ='y';break;
  case 0x2c: ret ='z';break;
  case 0x0c: ret ='-';break; 
  default: break;
  }
  return ret;
}


#define PACKET_LEN 8
char* readScanner(){
  static char barcode[PACKET_LEN];
  char packet[PACKET_LEN], code[PACKET_LEN];
  int i=0;

  memset(code,0,PACKET_LEN);
  while( 1 ){
    memset(packet,0,PACKET_LEN);
    if( hid_interrupt_read(hid,0x81,packet,PACKET_LEN,1000)==HID_RET_SUCCESS ){
      if( packet[2]==0x28 ){
        strcpy(barcode,code);
        return barcode;
      }
      else{
        if( packet[2]!=0 ){
          if( packet[0]==2 ) //SHIFT is pressed: upper case character
            code[i++] = toupper(keycodelist(packet[2]));
          else
            code[i++] = keycodelist(packet[2]);
        }
      }
    }
  }
  return NULL;
}


dhrubajyoti.deka 05-31-2007 12:01 AM

Thanks a lot!!!
 
Quote:

Originally Posted by bricedebrignaisplage
And here is some (older) code that uses libhid.

Code:

#include <stdio.h>
#include <string.h>
#include <ctype.h> //for toupper()
#include <hid.h>

#define VENDORID  0x5e0
#define PRODUCTID 0x200

HIDInterface* hid;


int initScanner(){
  hid_return ret;
  HIDInterfaceMatcher matcher = { VENDORID, PRODUCTID, NULL, NULL, 0 };

  /* see hid.h for possible values */
  hid_set_debug(HID_DEBUG_ALL);
  hid_set_debug_stream(stderr);
  /* passed directly to libusb */
  hid_set_usb_debug(0);
 
  ret = hid_init();
  if (ret != HID_RET_SUCCESS){
    fprintf(stderr,"hid_init failed with return code %d\n", ret);
    return 0;
  }

  hid = hid_new_HIDInterface();
  if (hid == 0) {
    fprintf(stderr,"hid_new_HIDInterface() failed, out of memory?\n");
    return 0;
  }

  /* How to detach a device from the kernel HID driver:
  * You can use hotplug to automatically give permissions to the device on
  * connection. Please see
  *  http://cvs.ailab.ch/cgi-bin/viewcvs.cgi/external/libphidgets/hotplug/
  * for an example. Try NOT to work as root!
  */

  ret = hid_force_open(hid, 0, &matcher, 3);
  if (ret != HID_RET_SUCCESS) {
    fprintf(stderr,"hid_force_open failed with return code %d\n", ret);
    return 0;
  }

  return 1;
}


int closeScanner(){
  hid_return ret;

  if(( ret=hid_close(hid)) != HID_RET_SUCCESS) {
    fprintf(stderr,"hid_close failed with return code %d\n", ret);
    return 0;
  }
  hid_delete_HIDInterface(&hid);

  if(( ret=hid_cleanup()) != HID_RET_SUCCESS) {
    fprintf(stderr,"hid_cleanup failed with return code %d\n", ret);
    return 0;
  }
  return 1;
}


char keycodelist(int scancode){
  char ret = '-';

  // from /usr/src/linux/drivers/usb/input/usbkbd.c
  char usb_kbd_keycode[256] = {
    0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
    50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
    4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
    27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
    65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
  105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
    72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
  191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
  115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
  122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
  150,158,159,128,136,177,178,176,142,152,173,140
  };

  switch(usb_kbd_keycode[scancode]){
  case 0x02: ret ='1';break;
  case 0x03: ret ='2';break;
  case 0x04: ret ='3';break;
  case 0x05: ret ='4';break;
  case 0x06: ret ='5';break;
  case 0x07: ret ='6';break;
  case 0x08: ret ='7';break;
  case 0x09: ret ='8';break;
  case 0x0a: ret ='9';break;
  case 0x0b: ret ='0';break;                       
  case 0x1e: ret ='a';break;
  case 0x30: ret ='b';break;
  case 0x2e: ret ='c';break;
  case 0x20: ret ='d';break;
  case 0x12: ret ='e';break;
  case 0x21: ret ='f';break;
  case 0x22: ret ='g';break;
  case 0x23: ret ='h';break;
  case 0x17: ret ='i';break;
  case 0x24: ret ='j';break;
  case 0x25: ret ='k';break;
  case 0x26: ret ='l';break;
  case 0x32: ret ='m';break;
  case 0x31: ret ='n';break;
  case 0x18: ret ='o';break;
  case 0x19: ret ='p';break;
  case 0x10: ret ='q';break;
  case 0x13: ret ='r';break;
  case 0x1f: ret ='s';break;
  case 0x14: ret ='t';break;
  case 0x16: ret ='u';break;
  case 0x2f: ret ='v';break;
  case 0x11: ret ='w';break;
  case 0x2d: ret ='x';break;
  case 0x15: ret ='y';break;
  case 0x2c: ret ='z';break;
  case 0x0c: ret ='-';break; 
  default: break;
  }
  return ret;
}


#define PACKET_LEN 8
char* readScanner(){
  static char barcode[PACKET_LEN];
  char packet[PACKET_LEN], code[PACKET_LEN];
  int i=0;

  memset(code,0,PACKET_LEN);
  while( 1 ){
    memset(packet,0,PACKET_LEN);
    if( hid_interrupt_read(hid,0x81,packet,PACKET_LEN,1000)==HID_RET_SUCCESS ){
      if( packet[2]==0x28 ){
        strcpy(barcode,code);
        return barcode;
      }
      else{
        if( packet[2]!=0 ){
          if( packet[0]==2 ) //SHIFT is pressed: upper case character
            code[i++] = toupper(keycodelist(packet[2]));
          else
            code[i++] = keycodelist(packet[2]);
        }
      }
    }
  }
  return NULL;
}


Hi,
Thanks a lot!!! your idea really worked. Its amazing. Thanks a lot...

Dhruba

ellappan 06-10-2009 08:16 PM

Quote:

Originally Posted by bricedebrignaisplage (Post 2767643)
I am no longer using libusb/libhid, but I am using the input layer of the kernel instead. The idea is to read from the /dev/input/event device associated with your device. To know which /dev/input/event node is associated with my device, I open all of them, get vendor ID and product ID and compare. If you don't have /dev/input, you must enable it in your kernel.
Btw, I got all this information from Vojtech Pavlik, the guy who wrote the input layer of the kernel.

I haven't found how to deal with capital letter though (shift key), and not all characters are in my conversion table... but that should get you started.

Here is my code:

Code:

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

#define VENDORID  0x5e0
#define PRODUCTID 0x200

int scan_fd = -1;

int initScanner(){
  int count=0;
  char path[32];
  struct dirent **files=NULL;
  struct input_id id;

  count = scandir("/dev/input",&files,0,0);
  while( count>=0 ){
    if( scan_fd==-1 && strncmp(files[count]->d_name,"event",5)==0 ){
      sprintf(path,"/dev/input/%s",files[count]->d_name);
      scan_fd = open(path,O_RDONLY);
      if( scan_fd>=0 ){
        if( ioctl(scan_fd,EVIOCGID,(void *)&id)<0 ) perror("ioctl EVIOCGID");
        else{
          if( id.vendor==VENDORID && id.product==PRODUCTID )
            printf("scanner attached to %s\n",path);
          else{
            close(scan_fd);
            scan_fd = -1;
          }
        }
      }
      else{
        fprintf(stderr,"Error opening %s",path);
        perror("");
      }
    }
    free(files[count--]);
  }
  free(files);

  if( scan_fd>=0 ) ioctl(scan_fd,EVIOCGRAB);
  else{ printf("scanner not found or couldn't be opened\n"); return 0;}
  return 1;
}


int closeScanner(){
  close(scan_fd);
  scan_fd = -1;
  return 1;
}


char keycodelist(int scancode){
  char ret = '-';
  return (unsigned char)scancode;
  switch(scancode){
  case 0x02: ret ='1';break;
  case 0x03: ret ='2';break;
  case 0x04: ret ='3';break;
  case 0x05: ret ='4';break;
  case 0x06: ret ='5';break;
  case 0x07: ret ='6';break;
  case 0x08: ret ='7';break;
  case 0x09: ret ='8';break;
  case 0x0a: ret ='9';break;
  case 0x0b: ret ='0';break;
  case 0x0c: ret ='-';break;

  case 0x10: ret ='q';break;
  case 0x11: ret ='w';break;
  case 0x12: ret ='e';break;
  case 0x13: ret ='r';break;
  case 0x14: ret ='t';break;
  case 0x15: ret ='y';break;
  case 0x16: ret ='u';break;
  case 0x17: ret ='i';break;
  case 0x18: ret ='o';break;
  case 0x19: ret ='p';break;

  case 0x1e: ret ='a';break;
  case 0x1f: ret ='s';break;
  case 0x20: ret ='d';break;
  case 0x21: ret ='f';break;
  case 0x22: ret ='g';break;
  case 0x23: ret ='h';break;
  case 0x24: ret ='j';break;
  case 0x25: ret ='k';break;
  case 0x26: ret ='l';break;

  case 0x2c: ret ='z';break;
  case 0x2d: ret ='x';break;
  case 0x2e: ret ='c';break;
  case 0x2f: ret ='v';break;
  case 0x30: ret ='b';break;
  case 0x31: ret ='n';break;
  case 0x32: ret ='m';break;
  default: break;
  }
  return ret;
}


//read a barcode from the scanner.
//reads as long as *loopcond!=0 (if loopcond is NULL then read
//forever). If termination condition is met, returns NULL.
//read all characters from barcode untill we read 0x28 (carriage
//return).
char* readScanner(int *loopcond){
  static char barcode[SCN_BCD_SZ];
  char code[SCN_BCD_SZ];
  int i=0;
  struct input_event ev;

  while( loopcond==NULL?1:*loopcond ){
    read(scan_fd,&ev,sizeof(struct input_event));
    if( ev.type==1 && ev.value==1 ){
      if( ev.code==28 ){ //carriage return
        code[i] = 0;
        strcpy(barcode,code);
        return barcode;
      }
      else{
        if( ev.code!=0 ){
          code[i++] = keycodelist(ev.code);
          if( i==SCN_BCD_SZ-1 ){ printf("Barcode buffer full\n"); return NULL;}
        }
      }
    }
  }
  return NULL;
}




Hi..

Thank a lot pls can you help where exactly i need to insert this code to read from barcode scanner?

bricedebrignaisplage 06-12-2009 12:22 AM

in main() call initScanner once and then call readScanner in a loop.

ellappan 06-21-2009 09:55 PM

Hi,

Thanks a lot..I have done the changes already...your code and explanation really helped me....thanks a lot again....
Please can you help me ..Now my problem is how to detect the device when it is inserted or removed. Becuase once i remove the device and if i insert again new event is assigned to the device.

Please can you help me how to detect device of it is insertion and removal?

bricedebrignaisplage 06-22-2009 04:34 AM

An idea would be to detect when device is removed as when a reading error occurs. Then you would have to call initialize() again, which will scan the devices again to find your scanner.

ysaucedo 12-06-2016 01:14 PM

Little Changes And Run Ok!
 
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include <stdlib.h>

#define VENDORID 0xc2e
#define PRODUCTID 0x200
#define SCN_BCD_SZ 15

int scan_fd = -1;

int initScanner(){
int count;
char path[32];
struct dirent **files;
struct input_id id;

printf("Inicializa \n");

count = scandir("/dev/input", &files, NULL, alphasort);
printf("Archivos: %i \n", count);
while( count>0 ){
count--;
if( scan_fd==-1 && strncmp(files[count]->d_name,"event",5)==0 ){
sprintf(path,"/dev/input/%s",files[count]->d_name);
scan_fd = open(path,O_RDONLY);
if( scan_fd>=0 ){
if( ioctl(scan_fd,EVIOCGID,(void *)&id)<0 ) perror("ioctl EVIOCGID");
else{
if( id.vendor==VENDORID && id.product==PRODUCTID )
printf("scanner attached to %s\n",path);
else{
close(scan_fd);
scan_fd = -1;
}
}
}
else{
fprintf(stderr,"Error opening %s",path);
perror("");
}
}
free(files[count--]);
}
free(files);

if( scan_fd>=0 ) ioctl(scan_fd,EVIOCGRAB);
else{ printf("scanner not found or couldn't be opened\n"); return 0;}
return 1;
}


int closeScanner(){
close(scan_fd);
scan_fd = -1;
return 1;
}


char keycodelist(int scancode){
char ret = '-';
//return (unsigned char)scancode;
switch(scancode){
case 0x02: ret ='1';break;
case 0x03: ret ='2';break;
case 0x04: ret ='3';break;
case 0x05: ret ='4';break;
case 0x06: ret ='5';break;
case 0x07: ret ='6';break;
case 0x08: ret ='7';break;
case 0x09: ret ='8';break;
case 0x0a: ret ='9';break;
case 0x0b: ret ='0';break;
case 0x0c: ret ='-';break;

case 0x10: ret ='q';break;
case 0x11: ret ='w';break;
case 0x12: ret ='e';break;
case 0x13: ret ='r';break;
case 0x14: ret ='t';break;
case 0x15: ret ='y';break;
case 0x16: ret ='u';break;
case 0x17: ret ='i';break;
case 0x18: ret ='o';break;
case 0x19: ret ='p';break;

case 0x1e: ret ='a';break;
case 0x1f: ret ='s';break;
case 0x20: ret ='d';break;
case 0x21: ret ='f';break;
case 0x22: ret ='g';break;
case 0x23: ret ='h';break;
case 0x24: ret ='j';break;
case 0x25: ret ='k';break;
case 0x26: ret ='l';break;

case 0x2c: ret ='z';break;
case 0x2d: ret ='x';break;
case 0x2e: ret ='c';break;
case 0x2f: ret ='v';break;
case 0x30: ret ='b';break;
case 0x31: ret ='n';break;
case 0x32: ret ='m';break;
default: break;
}
return ret;
}


//read a barcode from the scanner.
//reads as long as *loopcond!=0 (if loopcond is NULL then read
//forever). If termination condition is met, returns NULL.
//read all characters from barcode untill we read 0x28 (carriage
//return).
char* readScanner(int *loopcond){
static char barcode[SCN_BCD_SZ];
char code[SCN_BCD_SZ];
int i=0;
struct input_event ev;

while( loopcond==NULL?1:*loopcond ){
read(scan_fd,&ev,sizeof(struct input_event));
if( ev.type==1 && ev.value==1 ){
if( ev.code==28 ){ //carriage return
//printf("Carriage Return Read \n");
code[i] = 0;
strcpy(barcode,code);
return barcode;
}
else{
if( ev.code!=0 ){
code[i++] = keycodelist(ev.code);
//printf("Char: %i-%i \n", keycodelist(ev.code), ev.code);
if( i==SCN_BCD_SZ-1 ){ printf("Barcode buffer full\n"); return NULL;}
}
}
}
}
return NULL;
}

main(){
initScanner();
printf("Escaner Ok \n");
while(1){
printf("%s \n", readScanner(NULL));
printf("Sigiente Código... \n");
}
}


All times are GMT -5. The time now is 07:40 PM.