Arduino using USB Host Shield (อ้างอิง : https://www.circuitsathome.com/mcu/connecting-barcode-scanner-arduino-usb-host-shield/ )

Connecting barcode scanner to Arduino using USB Host Shield

Scanning barcodes using Arduino and USB Host Shield
Scanning barcodes using Arduino and USB Host Shield
An addition of Human Input Device Class support to USB Host Shield library 2.0, announced several days ago allows using powerful and inexpensive input devices with USB interface in Arduino projects. Sample sketches demonstrating sending and receiving data to one of the most useful HID device types – boot keyboard/mouse, has been released along with the library. The beauty of boot protocol lies in the simplicity of device report – a data packet containing information about button presses and mouse movements. However, samples were designed to demonstrate all features of the class and because of that, they are somewhat heavy. In real-life applications, it is often not necessary to implement each and every virtual function – only what is needed. In today’s article I will show practical application of HID boot device building a simple gadget.
Originally, HID boot protocol was meant to be used with keyboards and mice. When USB became popular, other keyboard-emulating devices, such as barcode scanners and magnetic card readers have been migrated from PS/2 standard to USB while keeping their keyboard-emulating property. As a result, many modern “not-so-human” input devices behave exactly like a keyboard including boot protocol support. A gadget that I demonstrate today is portable autonomous barcode scanner built using Arduino board, USB Host shield, handheld USB barcode scanner and LCD display (see title picture). The operation is simple – when handheld scanner button is pressed, it scans the barcode and sends it to Arduino symbol by symbol. Arduino then outputs these symbols on LCD display. LCD is erased before outputting each new barcode by tracking time between arrival of two consecutive symbols. To keep the code simple, I intentionally did not implement any data processing, however, since Arduino sketch for the gadget compiles in just a little over 14K, there is plenty of memory space left for expansion.

Let’s talk a little bit about necessary parts. First of all, we’ll need Arduino board and USB Host Shield. I use standard 16×2 HD44780-compatible LCD display, connected similarly to one in Arduino LiquidCrystal tutorial. Since USB Host shield uses pins 11 and 12 to interface to Arduino, I had to move corrsponding LCD signals to pins 6 and 7; the rest of the connections shall be made exactly like in the tutorial. Lastly, we need compatible handheld barcode scanner. The best place to search for one is eBay; look for phrases “no driver required” and “USB HID device” in product description.
To make sure a device is indeed a boot keyboard, take a look at device descriptors using USB_Desc example from USB Host library – a sample output is given below. Class, Subclass, Protocol in interface descriptor (lines 29-31) should be 03, 01, 01. If Subclass is zero, boot protocol is not supported. Non-boot scanner is still useful but accessing it is going to be slightly more complicated. I will cover HID report protocol in one of the next articles.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Device descriptor:
Descriptor Length:      12
Descriptor type:        01
USB version:            0100
Device class:           00
Device Subclass:        00
Device Protocol:        00
Max.packet size:        08
Vendor  ID:             04B4
Product ID:             0100
Revision ID:            0100
Mfg.string index:       01
Prod.string index:      02
Serial number index:    00
Number of conf.:        01
 
Configuration descriptor:
Total length:           0022
Num.intf:               01
Conf.value:             01
Conf.string:            04
Attr.:                  A0
Max.pwr:                64
 
Interface descriptor:
Intf.number:            00
Alt.:                   00
Endpoints:              01
Intf. Class:            03
Intf. Subclass:         01
Intf. Protocol:         01
Intf.string:            05
Unknown descriptor:
Length:         09
Type:           21
Contents:       00011001223F000705
 
Endpoint descriptor:
Endpoint address:       81
Attr.:                  03
Max.pkt size:           0008
Polling interval:       0A
Below is the sketch which needs to be compiled and loaded into Arduino. I wrote it by copying the keyboard example, taking out all unnecessary code and adding LCD support. The sketch can be copied from this page and pasted to Arduino IDE window. An explanation of key pieces is given after the listing.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 
Portable barcode scanner. Uses USB HID barcode scanner, Arduino Board, USB Host Shield and HD44780-compatible LCD display
 
  The circuit:
 * LCD RS pin to digital pin 7
 * LCD Enable pin to digital pin 6
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
*/
 
#include <LiquidCrystal.h>
#include <avr/pgmspace.h>
 
#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>
#include <hidboot.h>
 
#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>
 
#define DISPLAY_WIDTH 16
 
// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
 
USB     Usb;
//USBHub     Hub(&Usb);
HIDBoot<HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);
 
class KbdRptParser : public KeyboardReportParser
{
 
protected:
 virtual void OnKeyDown (uint8_t mod, uint8_t key);
 virtual void OnKeyPressed(uint8_t key);
};
 
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) 
{
    uint8_t c = OemToAscii(mod, key);
 
    if (c)
        OnKeyPressed(c);
}
 
/* what to do when symbol arrives */
void KbdRptParser::OnKeyPressed(uint8_t key) 
{
static uint32_t next_time = 0;      //watchdog
static uint8_t current_cursor = 0;  //tracks current cursor position  
 
    if( millis() > next_time ) {
      lcd.clear();
      current_cursor = 0;
      delay( 5 );  //LCD-specific 
      lcd.setCursor( 0,0 );
    }//if( millis() > next_time ...
 
    next_time = millis() + 200;  //reset watchdog
 
    if( current_cursor++ == ( DISPLAY_WIDTH + 1 )) {  //switch to second line if cursor outside the screen
      lcd.setCursor( 0,1 );
    }
 
    Serial.println( key );
    lcd.print( key );
};
 
KbdRptParser Prs;
 
void setup()
{
    Serial.begin( 115200 );
    Serial.println("Start");
 
    if (Usb.Init() == -1) {
        Serial.println("OSC did not start.");
    }
 
    delay( 200 );
 
    Keyboard.SetReportParser(0, (HIDReportParser*)&Prs);
    // set up the LCD's number of columns and rows: 
    lcd.begin(DISPLAY_WIDTH, 2);
    lcd.clear();
    lcd.noAutoscroll();
    lcd.print("Ready");
    delay( 200 );
}
 
void loop()
{
  Usb.Task();
}
  • Lines 5-15. This comment contains information about necessary LCD connections
  • Lines 46-52. KeyboardReportParser declaration. Compare with keyboard example. Here, we only need OnKeyDown() and OnKeyPressed() methods.
  • Lines 54-60. OnKeyDown() callback definition. When a keyboard key is pressed, it receives scan code of this key plus modifiers (Ctrl, Alt, Shift). Since our LCD takes ASCII codes the callback performs scan code to ASCII conversion and then calls OnKeyPressed()
  • Line 63. OnKeyPressed() definition
  • Lines 68-73.Clears the display before outputting first symbol of new barcode, i.e., if pause between symbols is larger than 200ms. Note delay in line 71 – my display is old and slow and unless I wait a little, it won’t print the first symbol of the sequence. Newer displays should work fine without it
  • Lines 81-82. The output. A symbol is sent to serial terminal and LCD
The rest of the sketch contains standard initialization of USB Host and Liquidcrystal libraries, as well as periodic calling of Usb.Task(), from which keyboard callbacks are called.
Reading RFID tags with Arduino/USB Host Shield
Reading RFID tags with Arduino/USB Host Shield
Lastly, a bonus material for those who managed to keep reading the article to this place. Since the sketch assumes HID boot device, it can be used with many different devices. For example, it is possible to produce an output using ordinary keyboard (due to watchdod, in order to get more than one symbol on the LCD display, you’d have to type pretty fast). Also, the same setup makes pretty good RFID reader – many inexpensive USB readers in 125KHz class are implemented as HID boot keyboards. Picture on the left shows one such device connected to Arduino. It also shows a way of providing power via Arduino USB port using portable USB charger. RFID cloning, anyone?

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

LED Blinking Sequence using PIC Microcontroller

Robotic Arm Control using PIC Microcontroller

Digital Thermometer using LM35 and PIC Microcontroller