Scanning different digit barcode and then print to label printer

hello, i want to print two different barcode and different digits number with barcode scanner, print the date and print the output from my weighing scale with zebra label printer.
i use arduino mega, barcode scanner enibit bs90, arduino usb host shield, two rs232tottl, zebra label printer gk420d and ds3231

i can print 1 barcode with same digit number (example: 0009285201 or 0123456789 or something with 10 digits)

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

#include <DS3231.h>
DS3231  rtc(SDA, SCL);

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);
}

class WeightReader
{
    uint8_t buffer[WeightLength + 1];
    byte length;
    bool valid;

  public:
    WeightReader();
    void begin();
    void task();
    const uint8_t* weight();
    void reset();
};

WeightReader::WeightReader()

  :length(0)
  ,valid(false)
{
}

void WeightReader::begin()
{
  
  Serial2.begin(9600);
}

void WeightReader::task()
{
  if (Serial2.available()) {
    uint8_t c = Serial2.read();
    if (valid) {
      // already have a weight, new one will overwrite it
      reset();
    }

    switch (c) {
      case '\r': // discard carriage return
        break;
      case '\n': // end of weight
        if (length == WeightLength) {
          valid = true;
        } else {
          // missed the beginning of the weight
          reset();
        }
        break;
      default: // store weight characters
        if (length < WeightLength) {
          buffer[length++] = c;
          buffer[length] = '\0';
        } else 
        {
          // unexpected output from scales; should never happen
          reset();
        }
    }
  }
}
// return value no longer valid after another call to task()
const uint8_t* WeightReader::weight()
{
  return (valid) ? buffer : 0;
}

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

BarcodeReader barcodeReader;
WeightReader weightReader;

void setup() {

  pinMode(buzzer,OUTPUT);
  Serial.begin(9600);
  Serial3.begin(9600);
  
  barcodeReader.begin();
  weightReader.begin();
  rtc.begin();
  
   //The following lines can be uncommented to set the date and time
//  rtc.setDOW(TUESDAY);     // Set Day-of-Week to SUNDAY
//  rtc.setTime(11, 55, 0);     // Set the time to 12:00:00 (24hr format)
//  rtc.setDate(07, 12, 2017);   // Set the date to January 1st, 2014
}

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

  if ( (barcode) && weight[0] =='S') {

    Serial.println(barcode);
    Serial.println(weight);
    Serial.println(rtc.getDateStr());

  Serial3.println("^XA");
  Serial3.println("^LH24,24");
  Serial3.println("^FO0,5");
  Serial3.println("^A0,20,20");
  Serial3.println("^FDBATCH: ");
  Serial3.println(barcode);
  Serial3.println("^FS");

  Serial3.println("^FO0,25");
  Serial3.println("^A0,20,20");
  Serial3.println("^FDBERAT: ");
  Serial3.println(weight);
  Serial3.println("^FS");

  Serial3.println("^FO0,45");
  Serial3.println("^A0,20,20");
  Serial3.println("^FDTGL    : ");
  Serial3.println(rtc.getDateStr());
  Serial3.println("^FS");
  Serial3.println("^XZ");

  barcodeReader.reset();
  weightReader.reset();
}
  if ( (barcode) && weight[0] =='U') 
  {
    Serial.println("alarm euy");
  tone(buzzer,1500);
  delay(200);
  noTone(buzzer);
  delay(200);
  tone(buzzer,1500);
  delay(200);
  noTone(buzzer);
  barcodeReader.reset();
  weightReader.reset();  
  }
}

and print results is:

BATCH: 0009285201 -------> FROM BARCODE SCANNER
BERAT: ST,+00018.70  g---> FROM WEIGHING SCALE
TGL    : 29-01-2018---------> DATE FROM DS3231

this is what i want : example: i have 2 barcode with different digits (1:0009285201 2:01234567).

  • i scan barcode 1 with barcode scanner
  • i scan barcode 2 with barcode scanner
  • i send data from my weighing to arduino
  • i print them to zebra label printer

and print results what i want is:

BATCH: 0009285201 -------> BARCODE 1 FROM BARCODE SCANNER
ID      : 01234567 ----------> BARCODE 2 FROM BARCODE SCANNER
BERAT: ST,+00018.70  g---> FROM WEIGHING SCALE
TGL    : 29-01-2018---------> DATE FROM DS3231

just ignore weighing scale and ds3231 (because i think its okay no problem). what should i do?
Thank you....

  // 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

This means that YOU must do this, since YOU don't want to always scan bar codes of the same length.

I suggest adding Serial.print to see what is coming from the scanner. Hopefully, it sends \n or \r or both.

  Serial.print("barcode 0x"); Serial.println(c, HEX);
  buffer[length++] = c;

ASIDE- Do you need two separate scanners?
No need if the codes are read at the same workstation...

Why create more code than necessary.

gdsports:
I suggest adding Serial.print to see what is coming from the scanner. Hopefully, it sends \n or \r or both.

  Serial.print("barcode 0x"); Serial.println(c, HEX);

buffer[length++] = c;

i add your code to my code. if i scan 0009285201
the output is

barcode 0x30
0
barcode 0x30
0
barcode 0x30
0
barcode 0x39
9
barcode 0x32
2
barcode 0x38
8
barcode 0x35
5
barcode 0x30
0
barcode 0x31
1

and this is my code after i add your code

#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;
int i=1;

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

    uint8_t buffer[12];
    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
  Serial.print("barcode 0x"); Serial.println(c, HEX);
  buffer[length++] = c;
  //buffer[length] = '\0';
  
    for (length=0;length < 14;)
    {
      if (buffer[length]>=0) 
      {
        length++;
      }
      else length = 13;
      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() 
{
  for(i=1;i<14;i++)
  {
  barcodeReader.task();
      const char* barcode = barcodeReader.barcode();
    if ((barcode) && ( barcode != 0x20))
    {
      Serial.println (barcode);
    barcodeReader.reset();
    }
  }
}

lastchancename:
ASIDE- Do you need two separate scanners?
No need if the codes are read at the same workstation...

Why create more code than necessary.

actually i just use 1 barcode scanner, i want to scan 2 different digits barcode and then print them to zebra label printer.

Scan the short barcode and show the console output.

gdsports:
Scan the short barcode and show the console output.

if i scan barcode "KG"
the output is

barcode 0x4B
K
barcode 0x47
G
barcode 0x13

0x13 is the same as CR or '\r'. So terminate the input string when the program sees at '\r'. There is similar code to handle the weight string from the scale.