felis / USB_Host_Shield_2.0

Revision 2.0 of USB Host Library for Arduino.
https://chome.nerpa.tech
1.79k stars 779 forks source link

Barcode Scanner doesn't Work #323

Closed RadhiFadlillah closed 6 years ago

RadhiFadlillah commented 6 years ago

Hi guys, I'm trying to connect my barcode scanner to Arduino using the USB Host Shield. I've followed tutorial from circuit@home, and there it said :

To make sure a device is indeed a boot keyboard, take a look at device descriptors using USB_Desc example from USB Host library – a sample output is given below. Class, Subclass, Protocol in interface descriptor (lines 29-31) should be 03, 01, 01. If Subclass is zero, boot protocol is not supported. Non-boot scanner is still useful but accessing it is going to be slightly more complicated. I will cover HID report protocol in one of the next articles.

Fortunately, my barcode scanner has Intf. Class = 03, Intf. Subclass = 01 and Intf. Protocol = 01, therefore according to the tutorial, my barcode scanner should work using HID Protocol Keyboard. However, in practice two of my barcode scanners didn't work, but my wired keyboard worked. The barcode is powered up, but doesn't print anything.

Here is my code :

#include <hidboot.h>
#include <usbhub.h>
#include <SPI.h>

class KbdRptParser : public KeyboardReportParser
{
  protected:
    virtual void OnKeyDown(uint8_t mod, uint8_t key);
    virtual void OnKeyPressed(uint8_t key);
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
  uint8_t c = OemToAscii(mod, key);
  if (c) OnKeyPressed(c);
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
  Serial.print("ASCII: ");
  Serial.println((char)key);
};

USB Usb;
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);
KbdRptParser Prs;

void setup()
{
  Serial.begin( 115200 );
  Serial.println("Start");

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }

  delay( 200 );

  HidKeyboard.SetReportParser(0, &Prs);
}

void loop()
{
  Usb.Task();
}

Here is my USB_desc :

Start

01
--

Device descriptor: 
Descriptor Length:  12
Descriptor type:    01
USB version:        0200
Device class:       00
Device Subclass:    00
Device Protocol:    00
Max.packet size:    40
Vendor  ID:     0483
Product ID:     5750
Revision ID:        0200
Mfg.string index:   01
Prod.string index:  02
Serial number index:    03
Number of conf.:    01

Configuration descriptor:
Total length:       0022
Num.intf:       01
Conf.value:     01
Conf.string:        00
Attr.:          C0
Max.pwr:        64

Interface descriptor:
Intf.number:        00
Alt.:           00
Endpoints:      01
Intf. Class:        03
Intf. Subclass:     01
Intf. Protocol:     01
Intf.string:        00
Unknown descriptor:
Length:     09
Type:       21
Contents:   10010001222D000705

Endpoint descriptor:
Endpoint address:   81
Attr.:          03
Max.pkt size:       0008
Polling interval:   01

Addr:1(0.0.1)

And here is my USBHID_desc :

Start
0000: 05 01 09 06 A1 01 95 08 75 01 05 07 19 E0 29 E7 
0010: 15 00 25 01 81 02 95 01 75 08 81 01 95 06 75 08 
0020: 15 00 25 FF 05 07 19 00 29 FF 81 00 C0 
Usage Page Gen Desktop Ctrls(01)
Usage Keypad
Collection Application
Report Count(08)
Report Size(01)
Usage Page Kbrd/Keypad(07)
Usage Min(E0)
Usage Max(E7)
Logical Min(00)
Logical Max(01)
Input(00000010)
Report Count(01)
Report Size(08)
Input(00000001)
Report Count(06)
Report Size(08)
Logical Min(00)
Logical Max(FF)
Usage Page Kbrd/Keypad(07)
Usage Min(00)
Usage Max(FF)
Input(00000000)
End Collection
RadhiFadlillah commented 6 years ago

Since my barcode scanner doesn't work when using KeyboardReportParser, I've decide to create my own parser. Here is my first parser's code :

#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <SPI.h>

class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  Serial.println(*buf);
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

void setup() {
  Serial.begin( 115200 );
  Serial.println("Start");

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

void loop() {
  Usb.Task();
}

When I try it on my barcode :

barcode

my code gives following result :

Start
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

Well, it obviously doesn't work, but at least there are some kind of event that detected by my parser, so maybe I'm in right direction.

RadhiFadlillah commented 6 years ago

After looking around the hidboot.cpp and hidboot.h, I've updated my code into this :

#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <SPI.h>

class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  // If error, return
  // I don't know why it starts on 2, I just following the example
  if (buf[2] == 1) return;

  // If empty, return
  // I check on 2 because the previous if check on 2 too
  if (buf[2] == 0) return;

  // Like above, WHY it starts on 2 ?
  // What is the purpose of bit in 0 and 1 ?
  for (uint8_t i = 2; i < 8; i++) {
    Serial.print(buf[i]);
    Serial.print(" ");
  }

  Serial.println();
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

void setup() {
  Serial.begin( 115200 );
  Serial.println("Start");

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

void loop() {
  Usb.Task();
}

I've tested this code on three barcode with following content :

For all numbers, I use barcode with value 1234567890 and got following result :

barcode-number

30 0 0 0 0 0 => 1
31 0 0 0 0 0 => 2
32 0 0 0 0 0 => 3
33 0 0 0 0 0 => 4
34 0 0 0 0 0 => 5
35 0 0 0 0 0 => 6
36 0 0 0 0 0 => 7
37 0 0 0 0 0 => 8
38 0 0 0 0 0 => 9
39 0 0 0 0 0 => 0
40 0 0 0 0 0 => Enter ?

For uppercase letters, I use value ABCDEFGH with following result :

barcode-upper

225 4 0 0 0 0 => A
225 5 0 0 0 0 => B
225 6 0 0 0 0 => C
225 7 0 0 0 0 => D
225 8 0 0 0 0 => E
225 9 0 0 0 0 => F
225 10 0 0 0 0 => G
225 11 0 0 0 0 => H
40 0 0 0 0 0 => Enter

And last, for lowercase letters, I use abcdefgh with following result :

barcode-lower

4 0 0 0 0 0 => a
5 0 0 0 0 0 => b
6 0 0 0 0 0 => c
7 0 0 0 0 0 => d
8 0 0 0 0 0 => e
9 0 0 0 0 0 => f
10 0 0 0 0 0 => g
11 0 0 0 0 0 => h
40 0 0 0 0 0 => Enter ?

So, now my code can read the value for number, letter and enter signal. All I have to do now is to translate that from value into ASCII. It's quite interesting to see that uppercase and lowercase letters has same value, but different bit position.

RadhiFadlillah commented 6 years ago

Alright guys, it works now. I just have to modify the OemToAscii to satisfy my need. Here is my final code :

#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <hidboot.h>
#include <SPI.h>

class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
  protected:
    uint8_t KeyToAscii(bool upper, uint8_t mod, uint8_t key);
    virtual void OnKeyScanned(bool upper, uint8_t mod, uint8_t key);
    virtual void OnScanFinished();
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  // If error or empty, return
  if (buf[2] == 1 || buf[2] == 0) return;

  for (uint8_t i = 7; i >= 2; i--) {
    // If empty, skip
    if (buf[i] == 0) continue;

    // If enter signal emitted, scan finished
    if (buf[i] == UHS_HID_BOOT_KEY_ENTER) {
      OnScanFinished();
    }

    // If not, continue normally
    else {
      // If bit position not in 2, it's uppercase words
      OnKeyScanned(i > 2, buf, buf[i]);
    }

    return;
  }
}

uint8_t MyParser::KeyToAscii(bool upper, uint8_t mod, uint8_t key) {
  // Letters
  if (VALUE_WITHIN(key, 0x04, 0x1d)) {
    if (upper) return (key - 4 + 'A');
    else return (key - 4 + 'a');
  }

  // Numbers
  else if (VALUE_WITHIN(key, 0x1e, 0x27)) {
    return ((key == UHS_HID_BOOT_KEY_ZERO) ? '0' : key - 0x1e + '1');
  }

  return 0;
}

void MyParser::OnKeyScanned(bool upper, uint8_t mod, uint8_t key) {
  uint8_t ascii = KeyToAscii(upper, mod, key);
  Serial.print((char)ascii);
}

void MyParser::OnScanFinished() {
  Serial.println(" - Finished");
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

void setup() {
  Serial.begin( 115200 );
  Serial.println("Start");

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

void loop() {
  Usb.Task();
}

Now that it's done, the code looks really simple. I guess it took me so long because I never use C or C++ before, which make me a bit confused about pointer, bits and bytes.


Before I close this issue, I have several questions to ask. While I'm making this parser, I've tried this code :

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  for (uint8_t i = 0; i < 8; i++) {
    Serial.print(buf[i]);
    Serial.print(" ");
  }
}

When I use this code to scan barcode with letter A on it, it gives following result :

0 0 225 4 0 0 0 0 

My questions are :

  1. Why the bit value only started and checked from index 2 ? What is the purpose of bit in index 0 and 1 ? Are they always empty ?

  2. According to this blog, uint8_t data type is basically the same as byte in Arduino. Both of them is used to store an 8-bit unsigned number, from 0 to 255. So, when I loop through a variable with data type uint8_t or byte, I should get the bit value on index 0 to 7. Now, I know that bit is only 1 and 0. So, why that loop print value 225 and 4 ? Or maybe I'm misunderstanding the purpose of that loop ?

Well, that's all. Thank you.

krushnaR commented 6 years ago

Great work man.. It helped a lot..

Thank you very much.

Lauszus commented 6 years ago

@RadhiFadlillah thanks for sharing.

Regarding the code you posted. It simply just prints the raw incoming bytes, which are specific to your device. You never posted the model of barcode scanner you are using, so I can't look up the specification.

Also you are mixing up the terms bits and bytes. Remember that a byte consist of 8-bits and in your code you are printing 8 bytes. I'm not sure if that answers your questions?

RadhiFadlillah commented 6 years ago

@krushnaR you're welcome, I'm glad it solved your problem.

@Lauszus thanks for your response.

You never posted the model of barcode scanner you are using, so I can't look up the specification.

I'm sorry about that. Unfortunately, my barcode scanner is a brandless, chinese product that I bought dirt cheap from my local seller, that's why I don't know what is the model of my barcode scanner.

Also you are mixing up the terms bits and bytes.

LOL yeah that's true. Next time, I should take a rest before submitting my question.

Lauszus commented 6 years ago

LOL yeah that's true. Next time, I should take a rest before submitting my question.

Haha no worries, we have all been there :)

SaadatKhan26 commented 6 years ago

Your code is fantastic. Could you please tell me where is the data being stored when scanned through the barcode scanner, I'm asking this because I want to write the serial to a text file.

Lauszus commented 6 years ago

@SaadatKhan26 Simply store the data in the Parse function. For instance you could write to a SD card like so:

for (uint8_t i = 0; i < 8; i++) {
    file.print(buf[i]);
    file.print(" ");
}

Where file is a files object. Please see: https://www.arduino.cc/en/Reference/SD for more information.

HERTAS commented 6 years ago

@RadhiFadlillah Good job well done. Thank yo u very much. It helped a lot..

imranfoodtech commented 5 years ago

Thanks to RadhiFadlillah, I am also able to get the barcode exactly as it is without a bit of knowledge of arduino programming. However, Now I want to perform specific function (like running a stepper motor certain steps on a specific barcode value). can anyone please help me with this?

lsdnes commented 5 years ago

"dot " can't be read?

niquiniqui commented 5 years ago

Hi i'm using this code to read qrcodes. Is it possible to read other symbol such has "." or "$"? I already find in the code where letters and numbers are read but i cant understand a way for other symbols. Any help or tips?

WRelihan commented 5 years ago

Hi. Thanks for the code. I am using a 4POS scanner. This code helped a lot. The difference that I got was that with Capital letters buf[0] contained a 2 and the key still in buff[2]. This was sorted easily inside the Parse function by changing the call: OnKeyScanned(buf[0]==2, 0, buf[i]); /// replace buf with 0 Also the second parameter was a problem for the compiler as it was before: OnKeyScanned(buf[0]==2, buf, buf[i]); /// replace buf with 0 There was a type mismatch as it expects an uint8_t and buf is a pointer to an array, I just put in 0, as I did not know what uint8_t mod was, and also mod does not seem to be used.

I would like to ask the question though: 1) When I plug this scanner into my pc, the text is printed onto notepad as if I entered the text on the keyboard. Is there some kind of similar parser that gets loaded for the scanner on the pc that converts these array of 8's to Ascii before sending it to Notepad? 2) Why are the codes that you get from the scanner [in buf(2)] not the same as Ascii codes? 3)Can anyone recomend some more reading for me to get up to speed with the whole USB thing. 4) Is there some explanations covering the different USB libraries, or do I have to pick appart the code to discover what each one does. (Maybe in some of the broken links to circuitsathome?)

Thanks

alaleman commented 5 years ago

@SaadatKhan26 Simply store the data in the Parse function. For instance you could write to a SD card like so:

for (uint8_t i = 0; i < 8; i++) {
    file.print(buf[i]);
    file.print(" ");
}

Where file is a files object. Please see: https://www.arduino.cc/en/Reference/SD for more information.

I am going to implement this logic to save the scanned bar codes on an SD however I am having this problem, for a while now, in wiring SD Card module over the USB Host Shield. Can someone enlighten me about SPI and USB Host shield?

Edit: I tried saving data to SD card without the USB Host Shield and it is working fine. However when the Shield is attached, both SD Card and USB Barcode Scanner are not working. I am using Arduino UNO

wagnerideali commented 5 years ago

Hi everyone

This code is great, but I have a bar code reader that is not run .....somebody can Help me to give an ideia how to solve this? What I must to work in this code maybe to solve it. This reader is chinese brandless. Best regards Ideali

vickysivasrivi commented 4 years ago

sir when try to work this project using USB host shield and arduino uno and barcode scanner when I first try USB_desc it gives me Start ) 00705

Endpoint descriptor: Endpoint address: 81 Attr.: 03 Max.pkt size: 0008 Polling interval: 02

Addr:1(0.0.1) 00705

Endpoint descriptor: Endpoint address: 81 Attr.: 03 Max.pkt size: 0008 Polling interval: 02

Addr:1(0.0.1) ⸮j⸮hsX 8⸮&⸮AqX this some illegal characters and when I load USBHID_desc it shows Start port Size(08) Logical Max(FF00) Usage Page Kbrd/Keypad(07) Usage Min(00) Usage Max(91) Input(00000000) End Collection) Report Size(08) Logical Max(FF00) Usage Page Kbrd/Keypad(07) Usage Min(00) Usage Max(91) Input(00000000) End Collection⸮⸮(⸮⸮⸮-⸮⸮1

%⸮84⸮Ȋ⸮b⸮VI,⸮>/⸮⸮⸮@⸮⸮M ⸮ӧ⸮⸮⸮fARq same song un seen characters anyone can suggest any ideas please

sasword commented 4 years ago

Hi everyone, I want to ask how is it possible to create a variable that has a value as the number of characters in the barcode. Thanks.

Seednovate commented 4 years ago

Alright guys, it works now. I just have to modify the OemToAscii to satisfy my need. Here is my final code :


#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <hidboot.h>
#include <SPI.h>

class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
  protected:
    uint8_t KeyToAscii(bool upper, uint8_t mod, uint8_t key);
    virtual void OnKeyScanned(bool upper, uint8_t mod, uint8_t key);
    virtual void OnScanFinished();
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  // If error or empty, return
  if (buf[2] == 1 || buf[2] == 0) return;

  for (uint8_t i = 7; i >= 2; i--) {
    // If empty, skip
    if (buf[i] == 0) continue;

    // If enter signal emitted, scan finished
    if (buf[i] == UHS_HID_BOOT_KEY_ENTER) {
      OnScanFinished();
    }

    // If not, continue normally
    else {
      // If bit position not in 2, it's uppercase words
      OnKeyScanned(i > 2, buf, buf[i]);
    }

    return;
  }
}

uint8_t MyParser::KeyToAscii(bool upper, uint8_t mod, uint8_t key) {
  // Letters
  if (VALUE_WITHIN(key, 0x04, 0x1d)) {
    if (upper) return (key - 4 + 'A');
    else return (key - 4 + 'a');
  }

  // Numbers
  else if (VALUE_WITHIN(key, 0x1e, 0x27)) {
    return ((key == UHS_HID_BOOT_KEY_ZERO) ? '0' : key - 0x1e + '1');
  }

  return 0;
}

void MyParser::OnKeyScanned(bool upper, uint8_t mod, uint8_t key) {
  uint8_t ascii = KeyToAscii(upper, mod, key);
  Serial.print((char)ascii);
}

void MyParser::OnScanFinished() {
  Serial.println(" - Finished");
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

void setup() {
  Serial.begin( 115200 );
  Serial.println("Start");

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

void loop() {
  Usb.Task();
}

HI! @RadhiFadlillah ,when I upload this I got these errors:

F:\Users\Documents\Arduino\Barcodetest_9\Barcodetest_9.ino: In member function 'virtual void MyParser::Parse(USBHID, bool, uint8_t, uint8_t)':

F:\Users\Documents\Arduino\Barcodetest_9\Barcodetest_9.ino:35:38: warning: invalid conversion from 'uint8_t {aka unsigned char}' to 'uint8_t {aka unsigned char}' [-fpermissive]

   OnKeyScanned(i > 2, buf, buf[i]);

                                  ^

F:\Users\Documents\Arduino\Barcodetest_9\Barcodetest_9.ino:13:18: note: initializing argument 2 of 'virtual void MyParser::OnKeyScanned(bool, uint8_t, uint8_t)'

 virtual void OnKeyScanned(bool upper, uint8_t mod, uint8_t key);

              ^

I don't really understand how to fix this. It just printing "start" on a serial monitor and when I scan a barcode, nothing happens on the serial monitor. What will I do for this?

zack-t commented 3 years ago

Hi @RadhiFadlillah , thank you for your wonderful code. I would like to send the barcode to another Arduino using I2C for inventory purposes but I am new to hid so I hardly get the idea of the code. Could you help me on this matter? Thanks again for the code. I attached my datasheet of my scanner: `Device descriptor: Descriptor Length: 12 Descriptor type: 01 USB version: 0110 Device class: 00 Device Subclass: 00 Device Protocol: 00 Max.packet size: 20 Vendor ID: FFFF Product ID: 0035 Revision ID: 0001 Mfg.string index: 01 Prod.string index: 02 Serial number index: 03 Number of conf.: 01

Configuration descriptor: Total length: 0022 Num.intf: 01 Conf.value: 01 Conf.string: 00 Attr.: A0 Max.pwr: 64

Interface descriptor: Intf.number: 00 Alt.: 00 Endpoints: 01 Intf. Class: 03 Intf. Subclass: 01 Intf. Protocol: 01 Intf.string: 04 Unknown descriptor: Length: 09 Type: 21 Contents: 100121012241000705

Endpoint descriptor: Endpoint address: 81 Attr.: 03 Max.pkt size: 0008 Polling interval: 02`

abdo20050 commented 2 years ago

here is my contribution on @RadhiFadlillah 's code. added some extra ascii code like ($,! ...) . Since am using "Aibecy 2D QR scanner" it's detecting shift signal differently so you need to keep that in mind

#include <usbhid.h>
#include <usbhub.h>
#include <hiduniversal.h>
#include <hidboot.h>
#include <SPI.h>
const uint8_t numKeys[10] PROGMEM = {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')'};
const uint8_t symKeysUp[12] PROGMEM = {'_', '+', '{', '}', '|', '', ':', '"', '', '<', '>', '?'};
const uint8_t symKeysLo[12] PROGMEM = {'-', '=', '[', ']', '\\', ' ', ';', '\'', '`', ',', '.', '/'};
const uint8_t padKeys[5] PROGMEM = {'/', '*', '-', '+', '\r'};
bool shift = false;
class MyParser : public HIDReportParser {
  public:
    MyParser();
    void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
  protected:
    uint8_t KeyToAscii(bool upper, uint8_t mod, uint8_t key);
    virtual void OnKeyScanned(bool upper, uint8_t mod, uint8_t key);
    virtual void OnScanFinished();
};

MyParser::MyParser() {}

void MyParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
  // If error or empty, return
//  if (buf[2] == 1 || buf[2] == 0) {
//    return;
//  }

  if(buf[0] == 2)
      shift = true;
  for (uint8_t i = 7; i >= 2; i--) {
    // If empty, skip
    if (buf[i] == 0) continue;

    // If enter signal emitted, scan finished
    if (buf[i] == UHS_HID_BOOT_KEY_ENTER) {
      OnScanFinished();
    }

    // If not, continue normally
    else {
      // If bit position not in 2, it's uppercase words
      OnKeyScanned(shift, buf, buf[i]);
      shift = false;
    }

    return;
  }
}

uint8_t MyParser::KeyToAscii(bool upper, uint8_t mod, uint8_t key) {
  // Letters
  if (VALUE_WITHIN(key, 0x04, 0x01d)) {
    if (upper) return (key - 4 + 'A');
    else return (key - 4 + 'a');
  }

  // Numbers
  else if (VALUE_WITHIN(key, 0x1e, 0x27)) {
    if (shift)
      return ((uint8_t)pgm_read_byte(&numKeys[key - 0x1e]));
    else
      return ((key == UHS_HID_BOOT_KEY_ZERO) ? '0' : key - 0x1e + '1');

  }
  // Keypad Numbers
  else if (VALUE_WITHIN(key, 0x59, 0x61)) {
    return (key - 0x59 + '1');
  } else if (VALUE_WITHIN(key, 0x2d, 0x38))
    return ((upper) ? (uint8_t)pgm_read_byte(&symKeysUp[key - 0x2d]) : (uint8_t)pgm_read_byte(&symKeysLo[key - 0x2d]));
  else if (VALUE_WITHIN(key, 0x54, 0x58))
    return (uint8_t)pgm_read_byte(&padKeys[key - 0x54]);
  else {
    switch (key) {
      case UHS_HID_BOOT_KEY_SPACE: return (0x20);
      case UHS_HID_BOOT_KEY_ENTER: return ('\r'); // Carriage return (0x0D)
    }
  }
  //Serial.println(key, HEX);
  return 0;
}

void MyParser::OnKeyScanned(bool upper, uint8_t mod, uint8_t key) {
  //Serial.print(upper);
  uint8_t ascii = KeyToAscii(upper, mod, key);
  Serial.print((char)ascii);
}

void MyParser::OnScanFinished() {
  Serial.println(" - Finished");
}

USB          Usb;
USBHub       Hub(&Usb);
HIDUniversal Hid(&Usb);
MyParser     Parser;

void setup() {
  Serial.begin( 115200 );
  Serial.println("Start");

  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }

  delay( 200 );

  Hid.SetReportParser(0, &Parser);
}

void loop() {
  Usb.Task();
} 
Mobin-Mortazavi commented 1 year ago

hi my Scanner info is : Intf. Class: 03 Intf. Subclass: 00 Intf. Protocol: 01 Intf.string: 00

and it doesn't work with the Codes I found in the internet...

in the PC Device Manager it is Known as a Keyboard

but it's not working with the Arduino mega ADK

any idea?

wagnerideali commented 1 year ago

Hi,I think that the protocol must be 06 but not 01Enviado do meu iPhoneEm 16 de jan. de 2023, à(s) 06:08, Mobin Mortazavi @.***> escreveu: hi my Scanner info is : Intf. Class: 03 Intf. Subclass: 00 Intf. Protocol: 01 Intf.string: 00 and it doesn't work with the Codes I found in the internet... in the PC Device Manager it is Known as a Keyboard but it's not working with the Arduino mega ADK any idea?

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

touchgadget commented 1 year ago

In hidboot.h, the driver is looking for a HID device with (class,subclass,protocol), of (3,1,1). If your keyboard does not have this, the driver does not recognize it as a keyboard. You can experiment to make the driver accept (3,0,1) but the scanner/keyboard may not work.

https://github.com/felis/USB_Host_Shield_2.0/blob/59cc3d287dd1afe8d89856a8d4de0ad8fe9ef3c7/hidboot.h#L407