barcode scanner with wiegand output decoder??

Hi all,

I am having bar code scanner of Honeywell orbit 7120 with Rs 232 connection…

I can read the scanner with max232 IC (rs232 to TTL)

but I Want to read the wiegand out of barcode scanner (with Rs232 to wiegand connector)thats an requirement …but I cant Read it properly :frowning:

I have tried the Grumpy_mikes code but no output… :frowning:

// WiegandReader
// credit to Mike Cook
// http://www.thebox.myzen.co.uk/Hardware/Crazy_People.html

// version 0.05.00

#include "pins_arduino.h"

#define ID_LEN 26
#define DATA_PIN_0 4
#define DATA_PIN_1 5

/*
 pins_arduino.h is an extension to the interrupt support for arduino.
 add pin change interrupts to the external interrupts, giving a way
 for users to have interrupts drive off of any pin.
 Refer to avr-gcc header files, arduino source and atmega datasheet.

 Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts.
 The PCINT corresponding to the pin must be enabled and masked, and
 an ISR routine provided.  Since PCINTs are per port, not per pin, the ISR
 must use some logic to actually implement a per-pin interrupt service.

 Pin to interrupt map:
 D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
 D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
 A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
*/


////////////////////////////////////////////////////////
// interrupt code
////////////////////////////////////////////////////////

volatile uint8_t *port_to_pcmask[] = { &PCMSK0, &PCMSK1, &PCMSK2 };
typedef void (*voidFuncPtr)(void);
volatile static voidFuncPtr PCintFunc[24] = { NULL };
volatile static uint8_t PCintLast[3];

////////////////////////////////////////
// attach an interrupt to a specific pin using pin change interrupts.
void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode) 
{

  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  uint8_t slot;
  volatile uint8_t *pcmask;

  if (mode != CHANGE) 
  {
    return;
  }

  // map pin to PCIR register
  if (port == NOT_A_PORT) 
  {
    return;
  } 
  else 
  {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

  slot = port * 8 + (pin % 8);
  PCintFunc[slot] = userFunc;

  // set the mask
  *pcmask |= bit;

  // enable the interrupt
  PCICR |= 0x01 << port;

}

////////////////////////////////////////
void PCdetachInterrupt(uint8_t pin) 
{
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *pcmask;

  // map pin to PCIR register
  if (port == NOT_A_PORT) 
  {
    return;
  } 
  else 
  {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

  // disable the mask.
  *pcmask &= ~bit;

  // if that's the last one, disable the interrupt.
  if (*pcmask == 0) 
  {
    PCICR &= ~(0x01 << port);
  }
}

////////////////////////////////////////
// common code for isr handler. "port" is the PCINT number.
// there isn't really a good way to back-map ports and masks to pins.
static void PCint(uint8_t port) 
{
  uint8_t bit;
  uint8_t curr;
  uint8_t mask;
  uint8_t pin;

  // get the pin states for the indicated port.
  curr = *portInputRegister(port+2);
  mask = curr ^ PCintLast[port];
  PCintLast[port] = curr;

  // mask is pins that have changed. screen out non pcint pins.
  if ((mask &= *port_to_pcmask[port]) == 0) 
  {
    return;
  }

  // mask is pcint pins that have changed.
  for (uint8_t i=0; i < 8; i++) 
  {
    bit = 0x01 << i;
    if (bit & mask) 
    {
      pin = port * 8 + i;
      if (PCintFunc[pin] != NULL) 
      {
        PCintFunc[pin]();
      }
    }
  }
}

////////////////////////////////////////
SIGNAL(PCINT0_vect) 
{
  PCint(0);
}

////////////////////////////////////////
SIGNAL(PCINT1_vect) 
{
  PCint(1);
}

////////////////////////////////////////
SIGNAL(PCINT2_vect) 
{
  PCint(2);
}

////////////////////////////////////////////////////////
// end of interrupt code
////////////////////////////////////////////////////////

volatile long reader1 = 0; 
volatile int reader1Count = 0;

////////////////////////////////////////
void read0(void) 
{
  if(digitalRead(DATA_PIN_0) == LOW)
  {
    reader1Count++;
    reader1 = reader1 << 1;  
    Serial.print("0");
  }
}

////////////////////////////////////////
void read1(void) 
{
  if(digitalRead(DATA_PIN_1) == LOW)
  {
    reader1Count++;
    reader1 = reader1 << 1;
    reader1 |= 1;
    Serial.print("1");
  }
}

////////////////////////////////////////
void setup()
{

  Serial.begin(57000);

  // Attach pin change interrupt service routines from the Wiegand RFID readers
  PCattachInterrupt(DATA_PIN_0, read0, CHANGE);
  PCattachInterrupt(DATA_PIN_1, read1, CHANGE);
  
  delay(10);

  // the interrupt in the Atmel processor misses out the first negative pulse as the inputs are already high,
  // so this gives a pulse to each reader input line to get the interrupts working properly.
  // Then clear out the reader variables.
  // The readers are open collector sitting normally at a one so this is OK
  for(int i = 4; i<10; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, HIGH); // enable internal pull up causing a one
    digitalWrite(i, LOW);  // disable internal pull up causing zero and thus an interrupt
    pinMode(i, INPUT);
    digitalWrite(i, HIGH); // enable internal pull up
  }

  delay(10);

  // clear the reader input variables
  reader1 = 0;
  reader1Count = 0; 
  digitalWrite(13, HIGH);  // show Arduino has finished initialisation

  Serial.println("");
  Serial.println("****************");
  Serial.println("setup done");
  Serial.println("****************"); 

}

////////////////////////////////////////
void loop() 
{
  if(reader1Count >= ID_LEN)
  {
    Serial.println("");
    Serial.println("---------------------");    

    Serial.print("bits: ");
    Serial.println(reader1Count);
    Serial.print("data: ");
    Serial.println(reader1 & 0xfffffff);

    Serial.print("hex: ");
    Serial.println(reader1, HEX);

    Serial.println("---------------------"); 
    
    reader1 = 0;
    reader1Count = 0;
  }
    
}

Which variant do you have?

MS7120-38 RS232, Full Speed USB, Keyboard Emulation, or Serial Emulation
MS7120-41 Full RS232C
MS7120-47 Keyboard Wedge, Stand-Alone Keyboard, or RS232 Send/Receive
MS7120-106 RS485, and Full Speed USB

There is no indication in the User's Guide that any of the variants has a Wiegand output. What are you trying to do?!?

I am having ms7120-41 full rs232 ...I can read the barcode while connected through rs232 (with DB9 connector) using max232 IC for voltage conversion
I am reading whatever available on serial port
(Software serial)

Requirement:
I have another rs232 to wiegand out converter ..
I have d0 ,d1 output to be connected to arduino
I want to read barcode via wiegand interface..but don't know where to start for decoding barcode?

Do you have the specifications for the RS232-to-Wiegand converter? Do you have a signal ground connected to the GND of your Arduino? What is the output signal voltage of the converter? What is the data format the converter sends (the meaning of groups of bits within the stream of bits)? Does it just take the characters sent by RS232 and send them out as 8 (or possibly 7) binary bits?

Hii Sir,

yes signal ground of converter and ground of ext. 12v power supply is connected to the Gnd of Arduino

I am using wiegand to rs232 converter with 12v output signal voltage ...

please check following link of rs232 to wiegand converter:

https://www.alibaba.com/product-detail/Wiegand-to-RS232-Interface-female-and_60427934546.html

I am getting attached output

after uploading this code :

// WiegandReader
// credit to Mike Cook
// http://www.thebox.myzen.co.uk/Hardware/Crazy_People.html

// version 0.05.00

#include "pins_arduino.h"

#define ID_LEN 34
#define DATA_PIN_0 8
#define DATA_PIN_1 9

/*
  pins_arduino.h is an extension to the interrupt support for arduino.
  add pin change interrupts to the external interrupts, giving a way
  for users to have interrupts drive off of any pin.
  Refer to avr-gcc header files, arduino source and atmega datasheet.

  Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts.
  The PCINT corresponding to the pin must be enabled and masked, and
  an ISR routine provided.  Since PCINTs are per port, not per pin, the ISR
  must use some logic to actually implement a per-pin interrupt service.

  Pin to interrupt map:
  D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
  D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
  A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
*/


////////////////////////////////////////////////////////
// interrupt code
////////////////////////////////////////////////////////

volatile uint8_t *port_to_pcmask[] = { &PCMSK0, &PCMSK1, &PCMSK2 };
typedef void (*voidFuncPtr)(void);
volatile static voidFuncPtr PCintFunc[24] = { NULL };
volatile static uint8_t PCintLast[3];

////////////////////////////////////////
// attach an interrupt to a specific pin using pin change interrupts.
void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode)
{

  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  uint8_t slot;
  volatile uint8_t *pcmask;

  if (mode != CHANGE)
  {
    return;
  }

  // map pin to PCIR register
  if (port == NOT_A_PORT)
  {
    return;
  }
  else
  {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

  slot = port * 8 + (pin % 8);
  PCintFunc[slot] = userFunc;

  // set the mask
  *pcmask |= bit;

  // enable the interrupt
  PCICR |= 0x01 << port;

}

////////////////////////////////////////
void PCdetachInterrupt(uint8_t pin)
{
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *pcmask;

  // map pin to PCIR register
  if (port == NOT_A_PORT)
  {
    return;
  }
  else
  {
    port -= 2;
    pcmask = port_to_pcmask[port];
  }

  // disable the mask.
  *pcmask &= ~bit;

  // if that's the last one, disable the interrupt.
  if (*pcmask == 0)
  {
    PCICR &= ~(0x01 << port);
  }
}

////////////////////////////////////////
// common code for isr handler. "port" is the PCINT number.
// there isn't really a good way to back-map ports and masks to pins.
static void PCint(uint8_t port)
{
  uint8_t bit;
  uint8_t curr;
  uint8_t mask;
  uint8_t pin;

  // get the pin states for the indicated port.
  curr = *portInputRegister(port + 2);
  mask = curr ^ PCintLast[port];
  PCintLast[port] = curr;

  // mask is pins that have changed. screen out non pcint pins.
  if ((mask &= *port_to_pcmask[port]) == 0)
  {
    return;
  }

  // mask is pcint pins that have changed.
  for (uint8_t i = 0; i < 8; i++)
  {
    bit = 0x01 << i;
    if (bit & mask)
    {
      pin = port * 8 + i;
      if (PCintFunc[pin] != NULL)
      {
        PCintFunc[pin]();
      }
    }
  }
}

////////////////////////////////////////
SIGNAL(PCINT0_vect)
{
  PCint(0);
}

////////////////////////////////////////
SIGNAL(PCINT1_vect)
{
  PCint(1);
}

////////////////////////////////////////
SIGNAL(PCINT2_vect)
{
  PCint(2);
}

////////////////////////////////////////////////////////
// end of interrupt code
////////////////////////////////////////////////////////

volatile long reader1 = 0;
volatile int reader1Count = 0;

////////////////////////////////////////
void read0(void)
{
  if (digitalRead(DATA_PIN_0) == LOW)
  {
    reader1Count++;
    reader1 = reader1 << 1;
    Serial.print("0");
  }
}

////////////////////////////////////////
void read1(void)
{
  if (digitalRead(DATA_PIN_1) == LOW)
  {
    reader1Count++;
    reader1 = reader1 << 1;
    reader1 |= 1;
    Serial.print("1");
  }
}

////////////////////////////////////////
void setup()
{

  Serial.begin(57600);

  // Attach pin change interrupt service routines from the Wiegand RFID readers
  PCattachInterrupt(DATA_PIN_0, read0, CHANGE);
  PCattachInterrupt(DATA_PIN_1, read1, CHANGE);

  delay(10);

  // the interrupt in the Atmel processor misses out the first negative pulse as the inputs are already high,
  // so this gives a pulse to each reader input line to get the interrupts working properly.
  // Then clear out the reader variables.
  // The readers are open collector sitting normally at a one so this is OK
  for (int i = 4; i < 10; i++)
  {
    pinMode(i, OUTPUT);
    digitalWrite(i, HIGH); // enable internal pull up causing a one
    digitalWrite(i, LOW);  // disable internal pull up causing zero and thus an interrupt
    pinMode(i, INPUT);
    digitalWrite(i, HIGH); // enable internal pull up
  }

  delay(10);

  // clear the reader input variables
  reader1 = 0;
  reader1Count = 0;
  digitalWrite(13, HIGH);  // show Arduino has finished initialisation

  Serial.println("");
  Serial.println("****************");
  Serial.println("setup done");
  Serial.println("****************");

}

////////////////////////////////////////
void loop()
{
  if (reader1Count >= ID_LEN)
  {
    Serial.println("");
    Serial.println("---------------------");

    Serial.print("bits: ");
    Serial.println(reader1Count);
    Serial.print("data: ");
    Serial.println(reader1 & 0xfffffff );


    Serial.print("hex: ");
    Serial.println(reader1, HEX);

    Serial.println("---------------------");

    reader1 = 0;
    reader1Count = 0;
  }

}

is my barcode is only 16 bit wide?what about when barcode is in ASCII format?

while connected Rfid wiegand reader with 34 bits tags above code works fine…but not with barcodes :confused:

i am pretty much confused about barcodes

Does the ASCII output format of your scanner match the ASCII input format of your ASCII-to-Wiegand converter? The 'documentation' only shows the Wiegand-to-ASCII direction but it's not unreasonable to assume that the ASCII-to-Wiegand direction will accept as input what the Wiegand-to-ASCII direction uses for output:

(0x02), decimal digits for a 24 or 32-bit value, (0x0D), (0x0A), (0x03)

Communication Format: Baud Rate 9600, 8-bit, NoParity, 1 Stop Bit

WG34 input: 4 bytes + two parity bits, for example: 0x3C3F8334 (Decimal 1010795316)
RS232 output: 02 31 30 31 30 37 39 35 33 31 36 0D 0A 03
02 (STX, Ctrl-B) Start of Text
31 30 31 30 37 39 35 33 31 36 is the card number in ASCII Decimal "1010795316"
0D 0A is a Carriage Return / Line Feed
03 (ETX, Ctrl-C) End of Text

WG26 input: 3 bytes + two parity bits, for example: 0x3F8334 (Decimal 4162356)
RS232 output: 02 34 31 36 32 33 35 36 0D 0A 03
02 (STX, Ctrl-B) Start of Text
34 31 36 32 33 35 36 is the card number in ASCII Decimal "4162356"
0D 0A is a Carriage Return / Line Feed
03 (ETX, Ctrl-C) End of Text

Hi all,

I am getting 34 bit data from barcode scanner like "193470060" while actual barcode number is "53794"

Why I am getting different data ..I have masked the data with fffffff ..