Hello,
I try to read barcodes with a Datalogic Gryphon GFS4470 scanner.
I'am using an Arduino Uno (Elegoo Uno R3) with an USB host shield.
The first thing I tried to do was this project:
https://chome.nerpa.tech/mcu/connecting-barcode-scanner-arduino-usb-host-shield/comment-page-1/
There the scanner is used as a HID device. This works properly with my setup.
I want to use the scanner in USB-COM mode (not as [here stupid] keyboard) because I want to trigger the moment of scanning with the arduino and not with the button at the scanner.
I set the scanner to the USB-COM mode and the scanner works fine with a programm on a windows PC. I can trigger the scanning by sending ASCII STX 0x02 and stop the scanning by sending ASCII ETX 0x03. Then I can read the scanning result from the scanner.
The properties from the (virtual) COM Port are 9600/8/1 with no handshake. The driver (downloaded from datalogic) says "USB-COM-CDC/ACM" (cdcacmpo_x64.sys) so I asume that this device works with the ACM protokol.
Therefore I used the example "ACM_terminal" from the USB Host Shield Library 2.0. ( I also tried other with FTDI/PL2303 but same problem).
My problem:
Sending of 0x02 (start scanning) and 0x03 (stop scanning) works. The scanner is also reading the barcode ( beaming a green dot to the surface). But the reading of the result fails.
rcode = Acm.RcvData(&rcvd, buf); returns 0x04 - this seems to be NAK
A second attempt to scan a barcode (Start and Sto scanning works again) did not showing the "green dot". I think this is because the first reading result is not fetched from the scanner.
Scanner works fine with WinPC. Arduino Hardware works fine with scanner in HID mode.
But reading from scanner failed, writing to scanner works. What can I do? Any ideas ?
Regards Peter
USB description:
08:48:36.670 ->
08:48:36.670 ->
08:48:36.670 -> 01
08:48:36.670 -> --
08:48:36.670 ->
08:48:36.670 -> Device descriptor:
08:48:36.670 -> Descriptor Length: 12
08:48:36.670 -> Descriptor type: 01
08:48:36.670 -> USB version: 0200
08:48:36.670 -> Device class: 02
08:48:36.670 -> Device Subclass: 00
08:48:36.670 -> Device Protocol: 00
08:48:36.670 -> Max.packet size: 40
08:48:36.670 -> Vendor ID: 05F9
08:48:36.670 -> Product ID: 4204
08:48:36.670 -> Revision ID: 1138
08:48:36.670 -> Mfg.string index: 01
08:48:36.670 -> Prod.string index: 02
08:48:36.670 -> Serial number index: 03
08:48:36.670 -> Number of conf.: 01
08:48:36.670 ->
08:48:36.670 -> Configuration descriptor:
08:48:36.670 -> Total length: 0043
08:48:36.717 -> Num.intf: 02
08:48:36.717 -> Conf.value: 01
08:48:36.717 -> Conf.string: 04
08:48:36.717 -> Attr.: 80
08:48:36.717 -> Max.pwr: C8
08:48:36.717 ->
08:48:36.717 -> Interface descriptor:
08:48:36.717 -> Intf.number: 00
08:48:36.717 -> Alt.: 00
08:48:36.717 -> Endpoints: 01
08:48:36.717 -> Intf. Class: 02
08:48:36.717 -> Intf. Subclass: 02
08:48:36.717 -> Intf. Protocol: 01
08:48:36.717 -> Intf.string: 05
08:48:36.717 -> Unknown descriptor:
08:48:36.717 -> Length: 05
08:48:36.717 -> Type: 24
08:48:36.717 -> Contents: 0010010424
08:48:36.717 -> Unknown descriptor:
08:48:36.717 -> Length: 04
08:48:36.717 -> Type: 24
08:48:36.717 -> Contents: 02020524
08:48:36.717 -> Unknown descriptor:
08:48:36.717 -> Length: 05
08:48:36.717 -> Type: 24
08:48:36.717 -> Contents: 0600010524
08:48:36.717 -> Unknown descriptor:
08:48:36.717 -> Length: 05
08:48:36.717 -> Type: 24
08:48:36.717 -> Contents: 0103010705
08:48:36.717 ->
08:48:36.717 -> Endpoint descriptor:
08:48:36.717 -> Endpoint address: 81
08:48:36.717 -> Attr.: 03
08:48:36.717 -> Max.pkt size: 0010
08:48:36.717 -> Polling interval: 01
08:48:36.770 ->
08:48:36.770 -> Interface descriptor:
08:48:36.770 -> Intf.number: 01
08:48:36.770 -> Alt.: 00
08:48:36.770 -> Endpoints: 02
08:48:36.770 -> Intf. Class: 0A
08:48:36.770 -> Intf. Subclass: 00
08:48:36.770 -> Intf. Protocol: 00
08:48:36.770 -> Intf.string: 07
08:48:36.770 ->
08:48:36.770 -> Endpoint descriptor:
08:48:36.770 -> Endpoint address: 82
08:48:36.770 -> Attr.: 02
08:48:36.770 -> Max.pkt size: 0040
08:48:36.770 -> Polling interval: FF
08:48:36.770 ->
08:48:36.770 -> Endpoint descriptor:
08:48:36.770 -> Endpoint address: 03
08:48:36.770 -> Attr.: 02
08:48:36.770 -> Max.pkt size: 0040
08:48:36.770 -> Polling interval: FF
08:48:36.770 ->
08:48:36.770 ->
08:48:36.770 -> Addr:1(0.0.1)
used code:
#include <cdcacm.h>
#include <usbhub.h>
#include "pgmstrings.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
class ACMAsyncOper : public CDCAsyncOper
{
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
if (rcode)
{
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 9600;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup()
{
Serial.begin( 9600 );
#if !defined(__MIPSEL__)
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("OSCOKIRQ failed to assert");
delay( 200 );
}
void loop()
{
Usb.Task();
if( Acm.isReady()) {
uint8_t rcode;
/* reading the keyboard */
if(Serial.available()) {
Serial.println("L1");
uint8_t data= Serial.read();
Serial.println("L2");
data= 2;
/* sending to the phone */
rcode = Acm.SndData(1, &data);
delay(150);
data= 3;
/* sending to the phone */
rcode = Acm.SndData(1, &data);
if (rcode){
Serial.println("L3");
ErrorMessage<uint8_t>(PSTR("SndData"), rcode); }
}//if(Serial.available()...
delay(500);
/* reading the phone */
/* buffer size must be greater or equal to max.packet size */
/* it it set to 64 (largest possible max.packet size) here, can be tuned down
for particular endpoint */
uint8_t buf[64];
uint16_t rcvd = 64;
Serial.println(rcode);
rcode = Acm.RcvData(&rcvd, buf);
Serial.println(rcode);
Serial.println(rcvd);
if (rcode && rcode != hrNAK){
Serial.println("L45");
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);}
if( rcvd ) { //more than zero bytes received
Serial.println("L5");
for(uint16_t i=0; i < rcvd; i++ ) {
Serial.print((char)buf[i]); //printing on the screen
}
}
delay(10);
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..