how to scan barcode with barcode scanner

hallo, i want to scan two barcode (8 digit and 10 digit) and then print to serial monitor.
first i scan a 8 digit barcode, then i scan a 10 digit barcode after that serial monitor display the numbers of 8 digit barcode and 10 digit barcode or first i scan a 10 digit barcode then i scan a 8 digit barcode after that serial monitor display the numbers of 10 digit barcode and 8 digit barcode.

and this is my code just scan 10 digit barcode

#include <hid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <Usb.h>
#include <hidboot.h>
#include <avr/pgmspace.h>

const byte BarcodeLength = 11;
const byte WeightLength = 15;
const int buzzer = 2;

class BarcodeReader : public KeyboardReportParser
{
    USB Usb;
    USBHub Hub;
    HIDUniversal Hid;
    HIDBoot<HID_PROTOCOL_KEYBOARD> Keyboard;

    uint8_t buffer[BarcodeLength + 1];
    byte length;
    bool valid;

    void addCharacter(uint8_t c);

  public:
    BarcodeReader();
    void begin();
    void task();
    const uint8_t* barcode();
    void reset();

  protected:
    virtual void OnKeyDown(uint8_t mod, uint8_t key);
};

BarcodeReader::BarcodeReader()
  : Usb()
  , Hub(&Usb)
  , Hid(&Usb)
  , Keyboard(&Usb)
  , length(0)
  , valid(false)
{
}

void BarcodeReader::begin()
{
  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }
  Hid.SetReportParser(1, this);
}

void BarcodeReader::task()
{
  Usb.Task();
}

void BarcodeReader::addCharacter(uint8_t c)
{
  if (valid) {
    // already have a barcode, new one will overwrite it
    reset();
  }

  // could check for \n or \r if necessary, or even implement a timing
  // mechanism for detecting end of barcode input, but for now we just
  // assume fixed width field with no output separators

  buffer[length++] = c;
  buffer[length] = '\0';

  if (length == BarcodeLength) valid = true;
};

// return value no longer valid after another call to task()
const uint8_t* BarcodeReader::barcode()
{
  return (valid) ? buffer : 0;
}

void BarcodeReader::reset()
{
  length = 0;
  valid = false;
}

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

BarcodeReader barcodeReader;

void setup() {

  pinMode(buzzer,OUTPUT);
  Serial.begin(9600);
  
  barcodeReader.begin();


void loop() {
  barcodeReader.task();
  const char* barcode = barcodeReader.barcode();

  if ( (barcode) {

    Serial.println(barcode);
  barcodeReader.reset();
  weightReader.reset();
}

can you help me? thanks

Delta_G:

const byte BarcodeLength = 11;

Gee, I wonder what variable in that code affects the length of the barcode it looks for.

i think it's for keep barcode data until 10 digit and then give the output 10 digit in serial monitor.

i try this code, and actually the code can scan any digit barcode but the output is not like what i want.

#include <hid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <Usb.h>
#include <hidboot.h>
#include <avr/pgmspace.h>

const byte BarcodeLength = 11;
const int buzzer = 2;

class BarcodeReader : public KeyboardReportParser
{
    USB Usb;
    USBHub Hub;
    HIDUniversal Hid;
    HIDBoot<HID_PROTOCOL_KEYBOARD> Keyboard;

    uint8_t buffer[15];
    byte length;
    bool valid;

    void addCharacter(uint8_t c);

  public:
    BarcodeReader();
    void begin();
    void task();
    const uint8_t* barcode();
    void reset();

  protected:
    virtual void OnKeyDown(uint8_t mod, uint8_t key);
};

BarcodeReader::BarcodeReader()
  : Usb()
  , Hub(&Usb)
  , Hid(&Usb)
  , Keyboard(&Usb)
  , length(0)
  , valid(false)
{
}

void BarcodeReader::begin()
{
  if (Usb.Init() == -1) {
    Serial.println("OSC did not start.");
  }
  Hid.SetReportParser(1, this);
}

void BarcodeReader::task()
{
  Usb.Task();
}

void BarcodeReader::addCharacter(uint8_t c)
{
  if (valid) {
    // already have a barcode, new one will overwrite it
    reset();
  }

  // could check for \n or \r if necessary, or even implement a timing
  // mechanism for detecting end of barcode input, but for now we just
  // assume fixed width field with no output separators

  buffer[length++] = c;
  //buffer[length] = '\0';
  
  if (buffer[length] == '\0') 
  {
    valid = true;
  }
};

// return value no longer valid after another call to task()
const uint8_t* BarcodeReader::barcode()
{
  return (valid) ? buffer : 0;
}

void BarcodeReader::reset()
{
  length = 0;
  valid = false;
}

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

BarcodeReader barcodeReader;

void setup() {

  pinMode(buzzer,OUTPUT);
  Serial.begin(9600);
  Serial3.begin(9600);
  
  barcodeReader.begin();
 }

void loop() {
  barcodeReader.task();
  const char* barcode = barcodeReader.barcode();
  
  if  (barcode) {
    Serial.println(barcode);
        barcodeReader.reset();
    }
}

if i scan barcode "10769876"
the output in serial monitor is:
1
0
7
6
9
8
7
6

if i scan barcode "0009285201"
the output in serial monitor is:
0
0
0
9
2
8
5
2
0
1

if i scan barcode "KG"
the output in serial monitor is:
K
G

I guess you want each barcode on one line? If so, replace Serial.printlln() by Serial.print() for starters.

Do you receive a carriage return or newline when you scan the barcode? If so, use that to go to a new line in the serial monitor (an empty Serial.println() will do that for you).

If you don't receive a carriage return or newline, you can implement a timeout on the receive. E.g. once no new data is received for e.g. 500ms, print an empty line using an empty Serial.println().

Try this it works for me..

#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);
  delay(1);
}

void MyParser::OnScanFinished() {
  //Serial.println(" - Finished");
  Serial.println(F("\r"));
 
}

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 hope that OP did not wait a year for the solution :wink:

hi, can you provide me usb host shield barcode scanner code?
i have to further study on it
i am using mega 2560

jaden126:
hi, can you provide me usb host shield barcode scanner code?
i have to further study on it
i am using mega 2560

Did you look at the codes and the advise that were given?