Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 17/05/2007, à 09:57

BrunoXxl

Lecteur de code barre (douchette)

Bonjour,
Est-il possible d'utiliser un lecteur de code barre sous X. Il fonctionne très bien sous windows, mais n'écrit rien sous linux, quelle que soit la distribution (Ubuntu, Suse, debian...).
Il s'agit d'un lecteur qui emule les touches clavier en Y sur ce dernier de Marque Percon modèle BB Snapshot.
Quelqu'un a t'il déjà eu ce genre de problème??
Merci d'avance.
Bruno

Dernière modification par BrunoXxl (Le 17/05/2007, à 15:27)

Hors ligne

#2 Le 18/05/2007, à 06:08

BrunoXxl

Re : Lecteur de code barre (douchette)

Précision, ça fonctionne en mode texte, mais pas en X...

Hors ligne

#3 Le 20/05/2007, à 10:26

FireLight

Re : Lecteur de code barre (douchette)

Quel est le modèle de la douchette? Elle est branchée en USB, sur le port clavier, sur le port série?


Connu aussi sous le pseudo de Longhorn
Dell Studio 1537
Ubuntu Linux 10.04  LTS 64 Bits - Gnome 2.30 - KDE 4.4

Hors ligne

#4 Le 20/05/2007, à 10:33

BrunoXxl

Re : Lecteur de code barre (douchette)

Le modèle de douchette est une BB SnapShot de Percon.Europe. Elle se branche sur le port Ps2 en Y sur le clavier.
@+
Bruno

Hors ligne

#5 Le 20/05/2007, à 17:22

FireLight

Re : Lecteur de code barre (douchette)

Mmm, il faudrait essayer faire un test. En gros, tester si, lors du passage d'un produit, le port PS2 renvoit une donnée. Je suis sur XP là, donc, çà va être un peu chaud pour dire ce qu'il faut faire. C'est du genre : cat /dev/input/keyboard (mais je pense pas que çà existe).


Connu aussi sous le pseudo de Longhorn
Dell Studio 1537
Ubuntu Linux 10.04  LTS 64 Bits - Gnome 2.30 - KDE 4.4

Hors ligne

#6 Le 20/05/2007, à 23:59

BrunoXxl

Re : Lecteur de code barre (douchette)

Oui, j'ai testé avec Xev, les séquences de touche lus par la douchette sont bien transmises au port Ps2. Je vois chaque caractère passer, mais ils ne s'affichent pas dans une session Xwin, seulement en mode texte.
par contre dans le Xterminal des codes sont retransmis, mais ne correspondent pas au code barre lu.
On dirait que les problèmes sont au niveau de l'interface Xwin, soit un inputdevice dans le Xorg.conf à régler ou à rajouter...
Je séche...
@+
Bruno

Dernière modification par BrunoXxl (Le 21/05/2007, à 00:00)

Hors ligne

#7 Le 31/05/2007, à 22:39

arsunt

Re : Lecteur de code barre (douchette)

J'ai exactement le même problème, et c'est très embêtant !!
J'ai convaincu toute mon école à passer la bibliothèque sous logiciel libre et sous Ubuntu (7.04 32 bits, desktop édition), et je cale pour les douchettes mad

Je n'ai que des douchettes sur PS/2 avec câble Y clavier et aucune ne fonctionne :
quand je scanne un code barre, il me met à la ligne dans un éditeur texte, sans aucun caractère.
Si je le fait dans le Terminal, il m'affiche une suite de numéro qui n'ont rien à voir avec le code barre scanné.

Some help ?

Hors ligne

#8 Le 04/06/2007, à 13:23

arsunt

Re : Lecteur de code barre (douchette)

quelqu'un a une idée ? roll:|

Hors ligne

#9 Le 21/06/2007, à 16:36

arsunt

Re : Lecteur de code barre (douchette)

bon bah après avoir parcouru le web, avoir parcouru et douché toutes les pages du manuel : je me suis résolu à pouvoir utilisé la douchette uniquement en pressant la touche MAJ (en fait, émulation d'un clavier américain, même en mettant la douchette en mode France).
Pas terrible pour un poste en libre accès.

Donc j'ai acheté des douchettes USB, et tout fonctionne à merveilles si je les paramètres en mode France.
à 50 € (+ frais de port) chez LDLC (sans faire de publicité, mais j'ai retourné le web pour en trouver pas cher, et c'est le minimum que j'ai trouvé) :
http://www.ldlc.com/fiche/PB00055578.html

Hors ligne

#10 Le 28/07/2008, à 17:12

Landru31

Re : Lecteur de code barre (douchette)

Bonjour,

Moi aussi, je me penche sur le problème.
Ma douchette se comporte comme un clavier américain. Comme je n'ai pas trouvé comment dire à mon vrai clavier qu'il est Français et que ma douchette est américaine, j'ai commencé à bidouiller en programmation.

J'en suis arrivé là; j'arrive à lire des codes barres mais je ne sais pas encore traduire en ascii; je pense qu'il me renvoie les codes des touches clavier.
commencer par installer libusb-dev
puis, voilà la code de douchette.c:

#include <stdio.h>
#include <usb.h>
#include <string.h>


void driver_init(void) {               
	usb_init();                    //Initialisation de la librairie (par example determine le chemin du repertoire des bus et peripheriques)
	usb_find_busses();             // Enumère tous les bus USB du systemes
	usb_find_devices();            // Enumère tous les peripheriques sur tous les Bus présents)
}

void usb_scan(void) {
	struct usb_bus *busses;
	struct usb_bus *bus;
	struct usb_device *dev,*fdev;
	printf("\n -- Scanning USB devices -- \n");
	for (bus = usb_busses; bus; bus = bus->next) { // Parcours tous les bus USB
		for (dev = bus->devices; dev; dev = dev->next) {  // Pour chaque bus, parcours tous les appareils branchés
			printf("     * bus : %s Device %s : id Vendor: %04X | id Product : %04X | Manufacturer Name : | Product Name : \n", bus->dirname,dev->filename ,dev->descriptor.idVendor,dev->descriptor.idProduct);
		}
	}
}

struct usb_device *usb_find_My_device(int idV, int idP) {
	struct usb_bus *busses;
	struct usb_bus *bus;
	struct usb_device *dev,*fdev;
	printf("\n -- Searching USB device (%04X|%04X) -- \n", idV, idP);
	for (bus = usb_busses; bus; bus = bus->next) { // Parcours tous les bus USB
		for (dev = bus->devices; dev; dev = dev->next) {   // Pour chaque bus, parcours tous les appareils branchés
			if ((dev->descriptor.idVendor == idV) && (dev->descriptor.idProduct ==idP )) { // on vérifie si les coordonnées (id vendeur; id produit) de notre appareil corespond
				printf("     * Found.\n");
				return(dev);
			}
		}
	}
	printf("      ! Nothing found !\n");
	return(0);
}

void unlinkKernelDriver(usb_dev_handle *hdl) { // fonction pour détacher le driver du kernel (usbhid)
	char str[100];
	printf("\n -- Procedure to unlink Kernel Driver --\n");
	strcpy(&str[0], "truc"); // au cas où la variable soit vide ... parce qu'il faut entrer dans la boucle while.
	while (strlen(str) != 0) {  // boucle pour détacher le driver du kernel (celui qui considère le lecteur code barre comme un clavier)
		memset(&str[0], 0, 100); // réinitialisation de la variable 
		if (usb_get_driver_np(hdl, 0, &str[0], 100) >=0 )printf("     * Checking Kernel Driver --> %s\n", str);  // récupération du driver lié à l'appareil
			else printf("       ! Not able to retrieve Kernel Driver or Kernel Driver allready unlinked !\n");
		if (strlen(str)>0) { // si on en trouve un ...
			printf("     * Unlinking Kernel Driver ...\n"); // on le détache.
			if (usb_detach_kernel_driver_np(hdl,0) !=0) printf("  ! Not able to unlink Kernel Driver or Kernel Driver allready unlinked !\n"); else printf("Done.\n");
		}
	}
}


void listEndpoints(struct usb_device *device) { // navigation à travers l'arborescence de variables
	char endPointType [4][50] = {"Control", "Isochronous", "Bulk", "Interrupt"};
	printf("\n -- Listing endpoints --\n");
	printf("     * usb_device\n     *    config\n     *       interface(%d)\n", device->config->bNumInterfaces);
	for(int i_interface = 0; i_interface< device->config->bNumInterfaces; i_interface++) {
		printf("     *          altsetting(%d)\n", device->config->interface[i_interface].num_altsetting);
		for(int i_altsetting=0; i_altsetting<device->config->interface[i_interface].num_altsetting; i_altsetting++) {
			printf("     *             endpoint(%d)\n", device->config->interface[i_interface].altsetting[i_altsetting].bNumEndpoints);
			for(int i_endpoint=0; i_endpoint<device->config->interface[i_interface].altsetting[i_altsetting].bNumEndpoints; i_endpoint++)
				printf("     *                0x0%02Xh (%s) - length=%d, packet_size=%d\n", device->config->interface[i_interface].altsetting[i_altsetting].endpoint[i_endpoint].bEndpointAddress, endPointType[device->config->interface[i_interface].altsetting[i_altsetting].endpoint[i_endpoint].bmAttributes & USB_ENDPOINT_TYPE_MASK], device->config->interface[i_interface].altsetting[i_altsetting].endpoint[i_endpoint].bLength, device->config->interface[i_interface].altsetting[i_altsetting].endpoint[i_endpoint].wMaxPacketSize);
		}
	}
}

void resetDevice(usb_dev_handle *hdl) { // reset du device
	printf("\n -- Resetting device -- \n");
	if (usb_reset(hdl)<0) printf("       ! Not able to reset device !\n"); else printf("     * Done.\n");

}


void readDevice(usb_dev_handle *hdl) { // lecture des données du device
	char donnees1[16];
	char donnees2[16];
	memset(&donnees1[0], 0, sizeof(donnees1)); // on remet les variables à 0
	memset(&donnees2[0], 0, sizeof(donnees2)); // on remet les variables à 0
	printf("\n -- Beginning reading data -- \n");

	int enlecture=0; // pour gérer les retours à la ligne entre les listes de paquets
	int longueur1, longueur2;
	for(int j = 0; j<500; j++) { // on va faire 100 lectures de 20 millisecondes
		longueur1 = -1;
		longueur2 = -1;
		//if (usb_claim_interface(hdl, 0) ==0)
			longueur1 = usb_interrupt_read(hdl, 0x081, &donnees1[0], sizeof(donnees1), 30);
		//if (usb_claim_interface(hdl, 1) ==0)
			longueur2 = usb_interrupt_read(hdl, 0x082, &donnees2[0], sizeof(donnees2), 30);
		if (longueur1>enlecture) printf("\n"); // si au tour d'avant il n'y avait rien à lire et que maintenant il y a quelque chose
		if (longueur1 >=0) { // il y avait quelque chose à lire ...
			printf("     * %d bytes read on 0x081 : ", longueur1);
			for(int i=0; i<sizeof(donnees1); i++) {
				printf("%02X ", donnees1[i]);
				if ((i+1)%16 == 0) printf("\n");
			}
		}
		if (longueur2 >=0) { // il y avait quelque chose à lire ...
			printf("     * %d bytes read on 0x082 : ", longueur2);
			for(int i=0; i<sizeof(donnees2); i++) {
				printf("%02X ", donnees2[i]);
				if ((i+1)%16 == 0) printf("\n");
			}
		}
		enlecture = longueur1; // on remet à jour le petit flag
	}
}


int main (void) {
	char str[100];

	// *************  Initialise les devices *************
	driver_init();

	// *************  Scanne tous les devices (optionnel) *************
	usb_scan();

	// *************  Recherche du device *************
	struct usb_device *barCodeReader = usb_find_My_device(0x04D9, 0x1400);  // on recherche l'appareil "lecteur code barre"
	if (barCodeReader ==0) {  // si on ne l'a pas trouvé ...
		printf("       ! No Bar Code Reader found !\n");
		return 0;
	}
	
	// *************  Ouverture du device *************
	printf("\n -- Opening USB device (Vendor, Product) = (0x%04X,  0x%04X) --\n", barCodeReader->descriptor.idVendor, barCodeReader->descriptor.idProduct);
	usb_dev_handle *barCodeReaderHandle = usb_open(barCodeReader);  // ouverture du device
	if (!barCodeReaderHandle) { // si l'ouverture s'est mal passée ...
		printf("       ! Not able to open device !\n");
		return 0;
	} else printf("     * Device opened : ");
	if (usb_get_string_simple(barCodeReaderHandle, 1, &str[0], 50) >=0) printf("%s\n", str); // on récupère la description
		else printf("\n       ! Not able to retrieve Description !\n");


	// *************  Opérations sur le device *************
	unlinkKernelDriver(barCodeReaderHandle); // on détache le driver du Kernel (usbhid)
	listEndpoints(barCodeReader);
	resetDevice(barCodeReaderHandle);
	readDevice(barCodeReaderHandle);
	resetDevice(barCodeReaderHandle);

	// *************  Fermeture du device *************
	printf("\n -- Closing USB device (Vendor, Product) = (0x%04X,  0x%04X) -- \n", barCodeReader->descriptor.idVendor, barCodeReader->descriptor.idProduct);
	if (usb_close(barCodeReaderHandle) >=0) printf("     * Device closed.\n");

	return 0;
}

compiler en faisant

gcc -std=c99 -lusb -o douchette douchette.c

#11 Le 28/07/2008, à 17:14

landru31

Re : Lecteur de code barre (douchette)

... j'oubliais

le programme est à lancer en root :

sudo ./douchette

(je pense que c'est parce que je "détache" le driver usbhid de la douchette)

#12 Le 30/07/2008, à 17:30

Landru31

Re : Lecteur de code barre (douchette)

Ayé !

voilà un petit driver pour les douchettes (en espérant qu'elles se comportent comme la mienne)

Le code source "barcodedriver.c"

// barcodedriver.c
#include <stdio.h>
#include <usb.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <X11/extensions/XTest.h>
#define XK_LATIN1 // pour les lettres de l'alphabet
#define XK_MISCELLANY // pour shift et return
#include <X11/keysymdef.h>
#include <stdlib.h>

#define DUREE_PRESSION 2
#define MAXTRANSLATION 37


//gcc -std=c99 -lusb -lX11 -lXtst -o barcodedriver barcodedriver.c

struct _touche {
	unsigned long int code;
	KeySym lettre;
};

struct _touche touche[MAXTRANSLATION] =
// poids faible poids fort, caractere
// par exemple 12 34 56 78 s'écrit 78 56 34 12
{{0x001E0000, XK_1},
{0x001F0000, XK_2},
{0x00200000, XK_3},
{0x00210000, XK_4},
{0x00220000, XK_5},
{0x00230000, XK_6},
{0x00240000, XK_7},
{0x00250000, XK_8},
{0x00260000, XK_9},
{0x00270000, XK_0},
{0x00280000, XK_Return},

{0x00040002, XK_Q},
{0x00050002, XK_B},
{0x00060002, XK_C},
{0x00070002, XK_D},
{0x00080002, XK_E},
{0x00090002, XK_F},
{0x000A0002, XK_G},
{0x000B0002, XK_H},
{0x000C0002, XK_I},
{0x000D0002, XK_J},
{0x000E0002, XK_K},
{0x000F0002, XK_L},
{0x00100002, XK_colon},
{0x00110002, XK_N},
{0x00120002, XK_O},
{0x00130002, XK_P},
{0x00140002, XK_A},
{0x00150002, XK_R},
{0x00160002, XK_S},
{0x00170002, XK_T},
{0x00180002, XK_U},
{0x00190002, XK_V},
{0x001A0002, XK_Z},
{0x001B0002, XK_X},
{0x001C0002, XK_Y},
{0x001D0002, XK_W}};

KeySym translate(unsigned long int valeur) { // Traduction des codes du device en touche clavier (FR)
	if (valeur !=0) {
		for(int j=0; j<MAXTRANSLATION;j++) if (touche[j].code == valeur) return touche[j].lettre;
	}
	return 0;	
}

void driver_init(void) {               
	usb_init();                    //Initialisation de la librairie (par example determine le chemin du repertoire des bus et peripheriques)
	usb_find_busses();             // Enumère tous les bus USB du systemes
	usb_find_devices();            // Enumère tous les peripheriques sur tous les Bus présents)
}

struct usb_device *usb_find_My_device(int idV, int idP) {  // recherche du device avec l'id Vendor et product
	struct usb_bus *busses;
	struct usb_bus *bus;
	struct usb_device *dev,*fdev;
	for (bus = usb_busses; bus; bus = bus->next)  // Parcours tous les bus USB
		for (dev = bus->devices; dev; dev = dev->next)    // Pour chaque bus, parcours tous les appareils branchés
			if ((dev->descriptor.idVendor == idV) && (dev->descriptor.idProduct ==idP ))  // on vérifie si les coordonnées (id vendeur; id produit) de notre appareil corespond
				return(dev);
	return(0);
}

void unlinkKernelDriver(usb_dev_handle *hdl) { // fonction pour détacher le driver du kernel (usbhid)
	char str[100];
	memset(&str[0], 0, 100); // réinitialisation de la variable 
	usb_get_driver_np(hdl, 0, &str[0], 100) >=0;  // récupération du driver lié à l'appareil
	if (strlen(str)>0) usb_detach_kernel_driver_np(hdl,0);
}


int readDevice(usb_dev_handle *hdl, int timeOut) { 
	char donnees[16];
	KeySym lettre;
	unsigned long int* myTouche;
	int longueur;
	memset(&donnees[0], 0, sizeof(donnees)); // on remet les variables à 0
	myTouche = (unsigned long int*)&donnees[0];
	Display* pDisplay;

	while (1) {
		longueur = usb_bulk_read(hdl, 0x081, &donnees[0], sizeof(donnees), timeOut);
		if (longueur >=0) { // il y avait quelque chose à lire ...
			for(int i=0; i<sizeof(donnees)/4; i++) {
				lettre=translate(myTouche[i]);
				if (lettre !=0) {//printf("%c", lettre);
					pDisplay = XOpenDisplay( NULL );
					if (lettre !=XK_Return) XTestFakeKeyEvent ( pDisplay, XKeysymToKeycode( pDisplay, XK_Shift_L), True, DUREE_PRESSION ); // on presse shift
				        XTestFakeKeyEvent ( pDisplay, XKeysymToKeycode( pDisplay, lettre ), True, DUREE_PRESSION ); // on presse la touche correspondant à la lettre
				        XTestFakeKeyEvent ( pDisplay, XKeysymToKeycode( pDisplay, lettre ), False, DUREE_PRESSION ); // on relache la touche
					if (lettre !=XK_Return) XTestFakeKeyEvent ( pDisplay, XKeysymToKeycode( pDisplay, XK_Shift_L), False, DUREE_PRESSION ); // on relache shift
					XCloseDisplay(pDisplay);
				}
			}
		}
	}
	
	return 0;
}


int main (int argc, char * argv[]) {
	char str[100];
	char usage[] = "Usage :\n   -v xxxx - Vendor id\n   -p xxxx - Product id\n   -t xxxx - usb timeout in ms (default = 0, waiting data)\n   -h - This help\n";

		if (getuid() >0) {
			printf("Warning ! you must launch this programme as root !\n\n%s", usage);
			return 0;
		}

		// *************  Lecture des options *************
	
		char * liste_options = "v:p:h";
		int option;
		int e_opt = 0, s_opt = 0, r_opt=0, k_opt=0, id_opt=0;
		int idV=0, idP=0, timeout = 0;
		opterr = 0; // Pas de message d'erreur automatique

		printf("Driver to get data from USB bar code reader\n07/2008 - C. MEICHEL\n\n");

		while((option = getopt(argc, argv, liste_options)) != -1) {
			switch (option) {
				case 'v' :
				    idV = atoi(optarg);
				    id_opt = 1;
				    break;
				case 'p' :
				    idP = atoi(optarg);
				    id_opt = 1;
				    break;
				case 't' :
				    timeout= atoi(optarg);
				    break;
				case 'h' :
				    printf("%s", usage);
				    return 0;
				    break;
				case '?' :
				    printf("%s", usage);
				    return 0;
				    break;
			}
		}
	

		// *************  Initialise les devices *************
		driver_init();

		if ((id_opt) && ((idV) || (idP))) {
		// *************  Recherche du device *************
			struct usb_device *barCodeReader = usb_find_My_device(idV, idP);  // on recherche l'appareil "lecteur code barre" 0x04D9, 0x1400
			if (barCodeReader ==0) {  // si on ne l'a pas trouvé ...
				printf("       ! No Bar Code Reader found !\n");
				return 0;
			}
	
			usb_dev_handle *barCodeReaderHandle = usb_open(barCodeReader);  // ouverture du device
			if (!barCodeReaderHandle) return 0; // si l'ouverture s'est mal passée ...
			unlinkKernelDriver(barCodeReaderHandle); // on détache le driver du Kernel (usbhid)
			usb_reset(barCodeReaderHandle);

			readDevice(barCodeReaderHandle, timeout);

			usb_reset(barCodeReaderHandle);
			usb_close(barCodeReaderHandle);
		}
		if ((id_opt) && ((!idV) || (!idP))) printf("Bad Vendor or/and Product id !\n");
	return 0;
}

et voila le "Makefile"

barcodedriver : barcodedriver.c
	gcc -std=c99 -lusb -lX11 -lXtst -o barcodedriver barcodedriver.c

Y'a plus qu'à faire

sudo apt-get install libxtst-dev libusb-dev
make

et pour le lancer

sudo ./barcodedriver -v 1241 -p 5120

1241 c'est le code vendor
5120 c'est le code product
ces données sont à vérifier en lançant

lsusb

et hop, lorsque vous scannez un code barre, la séquence de touches est envoyée dans la fenêtre active (gedit, Xterm, ...)

Des fois il y a des petits bugs dans le code rendu; à voir d'où ça vient ...

#13 Le 30/07/2008, à 17:47

Landru31

Re : Lecteur de code barre (douchette)

petite erreur ...

le programme se lance plutôt de cette façon

sudo ./barcodedriver -v 1241 -p 5120 &

comma ça il se met en mémoire et rend le control

#14 Le 08/02/2010, à 16:15

karum

Re : Lecteur de code barre (douchette)

Bonjour,

J'ai eu le même problème mais je l'ai résolu en configurant la douchette USB (metrologic Voyager MS9500)
Il a fallu donc scanner le code barre "entrée du mode configuration" puis trouver le code pays le scanner: "french keyboard" et pour terminer le code barre "sortie du mode configuration"

la config reste mémorisée dans la douchette.


Président de l'association Ubuntu-fr

Hors ligne

#15 Le 28/01/2011, à 11:12

le souk des alpes

Re : Lecteur de code barre (douchette)

Bonjours
Je reactualisé ce post car j ai une douchette Metrologic ms9520 sur le port rs232 les donné arrive bien au port rs232

caisse@PC-du-Souk-des-Alpes:~$ cat /dev/ttyS0
3065505613701

9782723467278


Mais car il y a un mais pour mon logiciel de caisse a besoin d une émulation clavier sous la forme (*)+(code barre)+entrer.

quelqu"un a t'il deja utiliser un script  pou cela.

merci

ubuntu 10.04

Hors ligne

#16 Le 21/01/2014, à 20:41

lapenduledargent

Re : Lecteur de code barre (douchette)

Bonsoir,

Je remonte ce poste car j'ai le même problème avec une douchette Konig BarScan 10.
Pour lire mes scan, je dois appuyer sur shift.
J'ai beau relire le manuel mais rien n'y fait. j'ai bien configuré mon clavier
Je suis sous ubuntu 10.04 et clavier belge.

Une idée ?

Merci d'avance

Dernière modification par lapenduledargent (Le 21/01/2014, à 20:42)

Hors ligne