Arduino reading digital scale
I am the proud owner of Stamps.com Model 510 5lb digital scale. It is a nice little scale which works very well (much better than Stamps.com service itself) while attached to my workstation. The scale doesn’t have a display making any kind of standalone use difficult. However, since the scale is a USB HID device reading data from it should be as easy as from a joystick and Arduino board should be adequate to provide a display function for it. To test this theory I made a simple setup consisting of Arduino UNO, USB Host shield and HD44780-compatible LCD display. I also wrote a small sketch which polls the scale and outputs the weight. The secondary objective of this project was to demonstrate LCD support in USB Host shield library.
For this project I used the following:
- An Arduino board. Standard size board, such as UNO, Duemilanove or Leonardo, will work
- USB Host Shield
- Toshiba HD44780-compatible LCD display, in 16×1 or 16×2 configuration. If you’re planning to use this sketch for something else, like data logging, the display is optional – all output from the scale is repeated to the serial port
- Stamps.com 5lb digital scale. Scales are standard HID devices with usage table 0x8d, therefore, scales from other brands may work as well with no or minimal modifications to the code
- USB Host library
The example code is also hosted at github, as well as in ‘examples’ section of the library under ‘HID’. It has been tested with Arduino IDE version 1.0.5.
In this project, the LCD is connected to the shield’s GPOUT pins, as documented in max_LCD.h header file. In addition to data lines, 5V and ground must also be connected to the shield’s 5V and GND terminals; the RW pin must be grounded – I do it on the LCD itself. In order to see the characters, the display must be biased – a 5K-10K pot with wiper on Vo and other two pins on 5V and ground will provide contrast adjustment.
Continue reading Adding a display to a digital scale using Arduino and USB Host shield
Power switch populated
About a month ago I started shipping USB host shields built on PCB bearing revision number 2.0.1. On this PCB I added a new feature, suggested by Andrew Kroll – a VBUS power switch. The board comes with power switch unpopulated and if you don’t care about this feature it can simply be ignored. However, if you do care about power control, read on.
The ability to turn VBUS on and off at will can be very beneficial. In battery-powered projects the run time can be significantly increased by powering on USB device only when needed. Some other devices can’t even be initialized reliably without a powercycle. Also, many power switches incorporate current limiting circuitry allowing VBUS overload detection and prevention.
An example of populated power switch is shown in the title picture (click on it to make it larger). A is a power switch IC (in this case, Micrel MIC2004). B is 0.1uF ceramic capacitor in 0603 package. C is a wire from MAX3421E GPX pin to the ENABLE pin of the power switch. Finally, D is VBUS Power jumper which needs to be opened, as pictured. Current revision of USB Host 2.0 library is needed to support power control.
Next picture will be used to explain the details of the power control circuitry.
Arrow A points to the jumper which needs to be cut open
Arrow B shows the position where 0603 0.1uF ceramic capacitor needs to be placed
C and D show the places for the power switches (only one switch is needed). Many switches packaged in SOT23-5 and SOT23-6 use this footprint, use On Semiconductor NCP380 as a reference. Also, some other 5 pin switches, such as Maxim MAX4793 and Micrel MIC20xx, will work while placed on SOT23-6 footprint, as shown on the title picture.
Certain switches, such as 6 pin NCP380, allow for adjustable current limit. The position for current setting 0603 resistor is marked ILIM – for the value of this resistor consult the datasheet for the part you’re planning on using
Many switches provide FAULT pin to signal various fault conditions, like output overload, reverse votage, or over-temperature. The pin is typically active low open drain type. It is broken out to a pad labelled VBUS OVL. The signal can be used in several different ways. A LED with a series resistor can be connected across VBUS OVL and a power rail. Also, it can be connected to a MCU input. In this case, a position labelled 10K should be populated with 0603 resistor, typical value is 10K. The other (upper) end of the resistor is connected to 5V rail with a trace which is placed under the letter K; if 3.3V level signal is desired, cut the trace and solder the upper end of the resistor to the 3.3V rail.
The power control signal is labelled VBUS EN. The library uses GPX pin for
Init() functions. There is also a variant of
Init() function which will hold the VBUS off for the number of milliseconds passed to it as a parameter. See usbhost.h file for details. Also, testusbhostFAT.ino demonstrates usage of powercycling
Continue reading VBUS power control on USB Host shield
Logitech joystick connected to Arduino
HID report parsing explained in the previous article works pretty well with properly aligned HID reports. The analog controls are placed on a byte or word boundary and buttons occupy dedicated fields. The majority of HID devices are designed this way, however, some other devices are not that simple to interface and today I’m going to show how to handle one of those.
A Logitech Extreme 3D Pro joystick is one nice HID device. It is good looking, well-built, and have a twist handle, which adds third axis to a stick making this model popular among FPV fliers since you can control pitch, roll and yaw with one hand. Also, X and Y axis are 10 bits which gives good precision. There is one problem with this joystick – its input report.
Logitech, in its infinite wisdom, decided to pack all the high and low resolution analog controls plus 12 buttons in 6 bytes of input report. The report looks like this – 10 bits of X, 10 bits of Y, and 4 bits of hat switch. After that, things become easier – one byte of Rz AKA “twist handle”, one byte of buttons, one byte of throttle (called “slider” in the report), and finally, one partially filled byte holding the rest of the buttons. Take a look at the screenshot below – two most important controls are not byte aligned, therefore, simple straightforward parsing of the report is not possible. Also,
USBHID_descr won’t show this report correctly.
To demonstrate how to deal with this report I wrote a simple Arduino sketch. It was made by modifying an example from the previous article. I also made it as simple as possible – as soon as any of the controls changes its value, new report is printed on the serial terminal. The sample output is shown below followed by code explanation.
Continue reading Using Logitech Extreme 3D Pro joystick with Arduino HID library
This article focuses on how to use the existing USB code library and HID report descriptor info to implement joystick functionality. Human readable HID report descriptor and report information can be easily obtained using
USBHID_desc.pde sketch – see previous article for details. This information will help you getting field details such as size and count info. Also, if you don’t have Arduino Mega or 2560 to run
USBHID_desc, report descriptor for your device can be obtained using one of many PC tools known as USB analyzers, or even the official usb.org device verification tool. This article is written by Alex Glushchenko – a developer behind second revision of USB Host Library as well as majority of device support code.
As you may already know report is a data structure used by HID device to return the information about the certain device parameters such as joystick coordinates or button events, or receive new settings such as switching on/off LEDs on keyboard.
Report descriptor is a data structure which describes report or reports, if there are few in number, field sequence, sizes and counts. Each report descriptor consists of several items. Each item describes some field property. I am not going too deep into details on items, explaining only the most important ones which are absolutely necessary in writing your own report parser.
The items usually describe type of field (input/output/feature), minimum, maximum field values, units, value meaning (usage) etc.
Continue reading Developing Arduino code for HID Joystick
Human Interface Device class of USB devices has a unique property – a report descriptor which contains information about data that device is sending to the host as well as data that can be sent to the device. This property allows for variety of devices – keyboards, mice, joysticks, digital scales, uninterruptible power sources, GPS receivers, and even toy missile launchers to belong to a single class – HID. A vendor just needs to pick a usage table which contains controls similar to vendor’s device – every OS has a generic support for HID devices so in most cases specific device driver is not necessary. The report descriptor again makes this possible – it contains definitions or report fields therefore a generic parser can process reports from any arbitrary HID device. However, this generic parser will take too much space on small microcontroller systems such as Arduino due to the amount of constants that needs to be present in the program code.
It shall be noted that a HID report itself is a simple structure of fixed fields and when this structure is known a very lightweight parser can easily be developed. HID development in legacy USB library has stopped at this point; I thought people will just take a look at the spec and write report parser for their device. It soon became evident that very few are actually willing to do this and in rev.2.0 of the library the HID report parsing is semi-automatic – a report descriptor has to be analyzed first using USBHID_desc utility presented in this article and then actual reports for the device can be parsed using library facilities (an article about coding report parsing is here).
Continue reading Visualizing HID device reports and report descriptors
A MOSFET controlling VBUS
Today I want to show a simple USB Host Shield 2.0 modification which allows controlling power to USB peripheral. I learned this technique from Camille’s comment to one of digital camera USB control articles. In short, the idea was to cut VBUS connection between USB host and peripheral, simulating disconnect state. P-channel MOSFET, inserted into VBUS, worked as a switch. I designed this capability into USB Host Shield 2.0 but never needed the functionality therefore this useful feature was left undocumented. Recently I started working with very interesting Nikon P&S camera which can be turned on and off with VBUS power so I finally made this modification. It is very simple.
Take a look at the title picture (click on it to make it larger). The modification uses existing VBUS power select pads of the shield. Out of the box, the one labeled 5V is shorted with solder bridge. First step is to remove this bridge with a solder wick so both pads are clean.
It can be seen that a MOSFET in SOT-23 package fits nicely on those pads (I’m using FDN306P). Drain and source pins are soldered to VBUS and 5V, respectively, and gate, which hangs in the air, is routed to an unused digital pin via an 1M resistor. When digital pin is low the MOSFET conducts. When digital pin goes high the MOSFET switches off disconnecting VBUS from the peripheral.
If you are going to drive high-power peripherals, like digital cameras or phones, it is a good idea to add some capacitance to 5V. I’m using 220uF low-ESR organic polymer tantalum cap in 1210 package which fits nicely on 0.1″ spaced 5V and GND pins of the shield; an ordinary leaded 100-200uF aluminum capacitor will work as well.
While playing with some cheap USB to RS-232 converters which use counterfeit PL2303 chips I found a bug in acm code which was sitting there from initial release. This bug was causing sluggish response from serial devices, as well as random
0x06 error codes. The bug is now fixed and corrected version of the library has been posted on GitHub a moment ago.
As a side effect to aforementioned bug fix some new functionality is now available. First,
PL2303 classes now have
isReady() method which can be used to check if certain device has been enumerated, initialized, and ready for service. This method is now used in all sample sketches, see, for example, pl2303_tinygps.pde, line 98.
Another addition is a block of code which performs proper PL2303 initialization. It is a mix of Linux pl2303.c code and Windows Prolific driver USB protocol traces. This block was added during troubleshooting; it turned out that it doesn’t make any difference on PL2303-based devices that I have – either genuine or counterfeit. However, it is tempting to be able to simulate “proper” manufacturer-recommended behaviour in the code so I decided to keep the initialization. It is turned off by default; if desired, it can be added during compilation by defining
PL2303_COMPAT (see cdcprolific.h, line 41 and cdcprolific.cpp, lines 159-179 ). The block adds ~500 bytes to the binary so don’t turn it on just in case.
Please check the new code with your devices and let me know if you can see any improvements or new issues.
Fresh update of USB Host Library 2.0 has just been posted to GitHub. The primary purpose of this release is to maintain compatibility with Arduino releases – the USB Host Library is now compiles in 1.0 as well as pre-1.0 versions of Arduino IDE. Enjoy!
Several important changes have been made to the code, some related to 1.0 compatibility and some not. The library examples were all tested and corrected, the information below is intended for developers using the library in their own projects:
- PL2302 driver. Arduino 1.0 defines PL symbol internally (thank you, Paul for finding this out!), therefore, I needed to change name of Prolific class driver. The new name is
PL2302; I updated library examples to compile correctly, if someone uses this class in their own development, the right way to define an instance of Prolific device is now
PL2303 Pl(&Usb, &AsyncOper);
- NAK handling. A bug preventing long polls of an endpoint has been fixed. Previously, if
bmNakPower member of
epInfo structure was left unitialized the transfer to this endpoint would stop after receiving a single NAK. With current version, the endpoint would be polled for up to 5 seconds. This is rarely desirable, so please initialize
USB_NAK_MAX_POWER. If a single poll is desired, as is often the case with interrupt endpoints, specify
USB_NAK_NOWAIT and if more than maximum number of NAKs (up to 5 seconds) is necessary, specify
- Code speed. An unnecessary delay of 20ms has been found (thank you, Alex for discovering this!) and removed from
USB::setAddress() member function. As a result, every USB transfer is now 20ms faster. While generally a good thing, it could inadvertently affect data exchanges with slow endpoints. If after upgrading to the current version you start seeing more NAKs, that’s probably why.
One nice thing about Arduino 1.0 is built-in PROGMEM support for strings. It is now possible to free about 300-400 bytes of RAM by redefining USBTRACE and USBTRACE2 macros used in debugging output (thank you, John, for the tip!). For example,
USBTRACE (Serial.print(F(s))) will move all USBTRACE strings to PROGMEM. The code size will increase so be careful with this feature if your code size is close to the limit for your Arduino board.
This is the end of announcement – download the code, play with it and if you have any issues please share your findings in the comments.
ND-100S GPS receiver connected to USB Host shield
After posting an article about interfacing USB GPS receiver to Arduino I started receiving e-mails from people asking about a decent inexpensive GPS receiver compatible with USB Host library. After some research and testing I finally found a device which I really like.
ND-100S from USGlobalsat is small, inexpensive (less than $30 shipped at DealExtreme) GPS receiver with excellent characteristics. Below are some bullet points:
- Lightweight – my scale shows 19g for the dongle without connector cover. It is possible to get weight close to 15g by removing the case, USB connector and hardwiring the module to USB Host shield.
- Sensitive – SiRF Star III high sensitivity GPS chip allows this module to lock in less than a minute from my basement (!). Outdoor performance is simply amazing while power consumption stays around 50ma.
- Easy to use – the module uses Prolific PL2303 USB to serial converter supported by USB Host library 2.0 and the sketch from the previous article works without any modifications. Also, the module has status LED showing when GPS position is fixed – comes in handy during field tests when serial console is not available. The dongle ships with semi-rigid USB cable which can be used as a raiser.
Overall, ND-100S is very small, sensitive and inexpensive GPS receiver. It can be used with USB Host shield using PL2303 USB to serial converter support in USB Host library rev.2.0. I have a couple of projects in mind which would use this receiver – will post as soon as I have more information about it.