Barcode scanner data

Hello everyone,

I've bought the USB 2.0 shield from www.circuitsathome.com to play with a barcode scanner.
The scanner behaves like a hid keyboard so I used the demo keyboard code and took
everything out which I didn't need. (see attached code)

This code now gives in the serial monitor the value of the barcode ending
with an enter and a ctrl-j (ctrl-j seems to be an new line?)

So far so good, but... every time it sent a single character to the serial port.
After that the character is gone. I would like to have a returned value which
I can use in the loop. What is the best way to do this?

Any help would be highly appreciated :grin:

Thanks in advance! Roland

#include <hidboot.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif

class KbdRptParser : public KeyboardReportParser
{
protected:
void OnKeyDown (uint8_t mod, uint8_t key);
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((char)key);
}

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

void setup()
{
Serial.begin( 115200 );
#if !defined(MIPSEL)
while (!Serial); // Wait for serial port to connect
#endif
if (Usb.Init() == -1)
Serial.println("OSC did not start.");
delay( 200 );
next_time = millis() + 5000;
HidKeyboard.SetReportParser(0, &Prs);

}

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

On approach is to proceed as follows. Care is required because you are receiving characters asynchronously with the main loop. No attention is given here to handling buffer overflows etc.

  1. define a global buffer together with an index into that buffer and a flag to indicate that a scan is complete. Something like this:
    char buff[40] ; // make it big enough
    int buffIndex = 0 ;
    boolean scanComplete = false ;

  2. In function OnKeyPressed( key ):
    Test here if the key pressed indicates an end of scan.
    If yes, set a scanComplete flag which can be tested in the loop.
    If no, convert the key to a character, put it in the buffer and increment the buffer index ready for the next character.

  3. in the loop
    if the buffer flag indicates an end of scan,
    do something with the buffer, say printing it or saving it, then cleaning it out, resetting the index and scanComplete flag (before the next scan starts).

Thanks for the hint! I've made my code this way and it works well for me.
I've canceled all control characters in my code. It might be wise to add a bit of
code to prevent overloading the BarcodeBuffer. That is not implemented now.

#include <hidboot.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif

char BarcodeBuffer[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // Barcode scanner buffer
int BarcodeBufferIndex = 0 ; // Pointer barcode scanner buffer
boolean BarcodeComplete = false ; // Scan complete?

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

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
uint8_t c = OemToAscii(mod, key);
if (c)
if (mod != 1) OnKeyPressed(c); // if control pressed then cancel character
}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
if (key==40)
{ // check for "enter" new line this is end of barcode
BarcodeComplete = true ;
}
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
BarcodeBuffer[BarcodeBufferIndex] = key;
BarcodeBufferIndex ++;
}

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

void setup()
{
Serial.begin( 115200 );
#if !defined(MIPSEL)
while (!Serial); // Wait for serial port to connect
#endif
if (Usb.Init() == -1)
Serial.println("OSC did not start.");
delay( 200 );
next_time = millis() + 5000;
HidKeyboard.SetReportParser(0, &Prs);

}

void loop()
{
BarcodeBufferIndex = 0;
while (!BarcodeComplete)
{
Usb.Task();
}
BarcodeComplete = false ;
BarcodeBufferIndex --;
Serial.write(BarcodeBuffer,BarcodeBufferIndex);
Serial.write('\n');
}