arduino mega,usb host shield, barcode scanner, zebra printer (SOLVED)

hello!

i want to connect arduino mega to weighing,zebra printer and barcode scanner(weighing and zebra use rs232 and barcode use usb host shield). actually i want print the output from barcode and weighing.
i can connect from arduino to weighing or arduino to zebra printer or barcode to arduino or barcode to arduino to zebra printer)
but if i connect arduino to weighing,zebra printer and barcode, the output is nothing.
this is my code

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

int inpt = 2;
int outpt =3;

SoftwareSerial mySerial(inpt,outpt); // RX, TX

const byte BarcodeLength = 14;
const byte WeightLength = 15;
const byte WeightRxPin = 14;
const byte WeightTxPin = 15;

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
{
    SoftwareSerial ss;

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

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

WeightReader::WeightReader()
  : ss(WeightRxPin, WeightTxPin)
  , length(0)
  , valid(false)
{
}

void WeightReader::begin()
{
  pinMode(WeightRxPin, INPUT);
  pinMode(WeightTxPin, OUTPUT);
  ss.begin(9600);
}

void WeightReader::task()
{
  
  if (ss.available()) {
    uint8_t c = ss.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() {
  Serial.begin(9600);
  pinMode(inpt, INPUT);
  pinMode(outpt, OUTPUT);
  mySerial.begin(9600);

  
  barcodeReader.begin();
  weightReader.begin();
}

void loop() {
  barcodeReader.task();
  weightReader.task();

  const char* barcode = barcodeReader.barcode();
  const char* weight = weightReader.weight();

Serial.println(weight);
  if ( barcode && weight) {
  Serial.println(weight);
  Serial.println(barcode);
  mySerial.println("^XA");
  mySerial.println("^LH30,30");
  mySerial.println("^FO150,40");
  mySerial.println("^ADN,90,50");
  mySerial.println("^AD^FD");
  mySerial.println(barcode);
  mySerial.println("^FS");
  
  mySerial.println("^FO150,80");
  mySerial.println("^ADN,90,50");
  mySerial.println("^AD^FD");
  mySerial.println(weight);
  mySerial.println("^FS");
  mySerial.println("^XZ");
  barcodeReader.reset();
  weightReader.reset();
  //delay(20000);
}
}

what should i do if i want this hardware working? thank you

what should i do if i want this hardware working?

You have a Mega but you use that horrible SoftwareSerial? Not only once but twice? This cannot work because you can have only one SoftwareSerial listening at any given point in time. Throw all SoftwareSerial code away and use the hardware serial interfaces the Mega offers (it has 4 of them).

pylon:
You have a Mega but you use that horrible SoftwareSerial? Not only once but twice? This cannot work because you can have only one SoftwareSerial listening at any given point in time. Throw all SoftwareSerial code away and use the hardware serial interfaces the Mega offers (it has 4 of them).

i edit this code using hardware serial for weighing

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

int inpt = 2; //abu abu
int outpt =3; //putih

SoftwareSerial mySerial(inpt,outpt); // RX, TX

const byte BarcodeLength = 14;
const byte WeightLength = 15;


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() {
  Serial.begin(9600);
  pinMode(inpt, INPUT);
  pinMode(outpt, OUTPUT);
  mySerial.begin(9600);

  
  barcodeReader.begin();
  weightReader.begin();
}

void loop() {
  barcodeReader.task();
  weightReader.task();

  const char* barcode = barcodeReader.barcode();
  const char* weight = weightReader.weight();

Serial.println(weight);
  if ( weight && barcode) {
  
//  Serial.println(weight);
//  Serial.println(barcode);
  mySerial.println("^XA");
  mySerial.println("^LH30,30");
  mySerial.println("^FO150,30");
  mySerial.println("^ADN,90,50");
  mySerial.println("^AD^FD");
  mySerial.println(barcode);
  mySerial.println("^FS");

  mySerial.println("^FO150,50");
  mySerial.println("^ADN,90,50");
  mySerial.println("^AD^FD");
  mySerial.println(weight);
  mySerial.println("^FS");
  mySerial.println("^XZ");
  barcodeReader.reset();
  weightReader.reset();
  //delay(20000);
}
}

if i use ( if ( weight && barcode) ) the printer cant print anything.
but if i use ( if ( weight)) the printer can print the weight from weighing
and if i use ( if ( barcode)) the printer can print the barcode cant print the weight

what's wrong with my code or my hardware? what should i do?

After i change All of softwareserial to hardware serial, its work.

thank you, it's SOLVED :slight_smile: