LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-25-2006, 03:27 AM   #1
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Rep: Reputation: 16
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
 
Old 10-25-2006, 10:00 AM   #2
bernied
Member
 
Registered: Mar 2006
Location: Edinburgh, UK
Distribution: debian
Posts: 304

Rep: Reputation: 30
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
 
Old 10-25-2006, 08:55 PM   #3
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Original Poster
Rep: Reputation: 16
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.
 
Old 04-19-2007, 10:30 PM   #4
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Original Poster
Rep: Reputation: 16
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
 
Old 05-28-2007, 06:58 AM   #5
dhrubajyoti.deka
LQ Newbie
 
Registered: May 2007
Posts: 2

Rep: Reputation: 0
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
 
Old 05-29-2007, 11:42 PM   #6
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Original Poster
Rep: Reputation: 16
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;
}
 
Old 05-30-2007, 02:21 AM   #7
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Original Poster
Rep: Reputation: 16
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;
}
 
Old 05-31-2007, 12:01 AM   #8
dhrubajyoti.deka
LQ Newbie
 
Registered: May 2007
Posts: 2

Rep: Reputation: 0
Smile 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
 
Old 06-10-2009, 08:16 PM   #9
ellappan
LQ Newbie
 
Registered: May 2009
Posts: 14

Rep: Reputation: 0
Quote:
Originally Posted by bricedebrignaisplage View Post
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?
 
Old 06-12-2009, 12:22 AM   #10
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Original Poster
Rep: Reputation: 16
in main() call initScanner once and then call readScanner in a loop.
 
Old 06-21-2009, 09:55 PM   #11
ellappan
LQ Newbie
 
Registered: May 2009
Posts: 14

Rep: Reputation: 0
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?
 
Old 06-22-2009, 04:34 AM   #12
bricedebrignaisplage
Member
 
Registered: Apr 2006
Location: singapore
Distribution: debian
Posts: 51

Original Poster
Rep: Reputation: 16
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.
 
Old 12-06-2016, 01:14 PM   #13
ysaucedo
LQ Newbie
 
Registered: Dec 2016
Posts: 1

Rep: Reputation: Disabled
Thumbs up 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");
}
}
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Scanner help.. failed to open device snapscan/dev/usb/scanner johnathan Linux - Hardware 2 10-12-2007 06:06 PM
barcode scanner metrologic ms9520 j-ray Linux - Hardware 2 03-03-2006 05:49 AM
FC4 and Symbol USB Microscan Barcode Scanner MardukKurios Linux - Hardware 0 10-20-2005 04:17 PM
barcode scanner manueljose Linux - Hardware 1 09-09-2005 08:19 PM
Scanner driver for USB scanner rros Linux - Newbie 1 04-23-2001 12:30 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:30 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration