|
By Oleg Mazurov
In previous article I started talking about constructing magnetic stirrer from PC fan, a pair of rare earth magnets, and plastic can. In this article I will show the rest of the construction as well as program code to control the motor.
When building cases for my designs, I tend to avoid techniques requiring accurate (read “any”) measurements and calling for non-round holes. The design that I’m describing here is no exception. In order to complete it I needed just a few extra parts in addition to plastic joint compound can, PC fan and magnets, arrangement of which was described earlier. I used Arduino controller equipped with Motor Shield from Adafruit to supply PWM current to the fan, 3 nylon standoffs with adhesive bottoms to mount Arduno, rotary encoder to set stirrer speed, and panel-mounted 2.1mm DC power jack. The stirrer is powered from 12V wall wart capable of supplying 300mA or more.
I was thinking of implementing monitoring of motor current to track the moment when stirrer bar loses attraction to the magnets and stops rotating. When I was playing with the stirrer powered from bench suplly the change in current was quite visible. However, I found out later that when motor is supplied with PWM signal, current stays almost constant over the whole range of duty cycles and loads and current tracking won’t work. With regret, I abandoned this clever feedback idea. On the bright side, the code necessary to control the stirrer immediately became much simple, short and easy to understand.
|
 Stirrer code
|
Continue reading Vigorius stirring redefined. Part 2 – electronics
By Oleg Mazurov  Four configurations in Arduino blue
[EDIT] This post is about legacy product which is no longer supported. Visit USB Host Shield project page for up-to-date information[/EDIT]
Arduino USB Host Shields are in the store. If you are not yet familiar with the project, please browse “USB Shield” category of the site and read the articles. In short, the purpose of this shield is to add USB Host interface capability to Arduino. The software libraries for this shield currently support control and bulk-in transfers, while bulk-out transfer is in the works. Access to GPIO pins of MAX3421E is also supported. Sketch examples, demonstrating USB device control queries and polling USB keyboard, are published. More code will be developed in the future.
At present, four configurations of the shield are available. The first one, called “Minimal”, contains USB core components only. It is compatible with 3.3V Arduinos, such as Arduino Pro from Sparkfun. Also, since no 5V is available, only communication with self-powered devices is possible. Moreover, not every self-powered device would work in this configuration. For unknown reasons, some external hard drives refused to answer until VBUS voltage was raised to 5V. On the other hand, all printers and digital cameras that I and several beta-testers tried worked fine as well as other people’s external hard drives. “Minimal” configuration is the best one for battery-powered projects since 3.3V Arduinos consume less electricity.
Continue reading USB Host Shield in store.
By Oleg Mazurov  USB constructor
The time has come to start using the code to communicate to peripheral devices. There are many devices which work well with microcontrollers. HID devices, such as keyboards, joysticks, and Radio Controller look-a-likes are useful and not too difficult to implement. Another good application of embedded USB host is digital camera control. Communication using Bluetooth and WiFi peripherals are also a possibility.
Today I’m going to show how to communicate with USB keyboard. Standard USB keyboard belongs to a class of devices, called HID (Human Interface Device). The format of data generated by HID device is quite flexible and each device stores it’s data definitions in structures called Report descriptor and Physical descriptor. Generally, to work with the device, report descriptor has to be retrieved and parsed. Because of HID flexibility, a universal HID driver will take many many lines of code. Luckily for us, if all we need is to talk to the keyboard, there is an easier way.
Continue reading Arduino USB Host – Peripherals.
By Oleg Mazurov  Tornado in the flask
Magnetic stirrer is a handy tool to help in any household activity, where agitation or mixing of relatively small (under 4L/1Gal) volumes of liquid or suspension are involved – from yeast starter preparation to dissolving fertilizer to chemical experiments. As almost any piece of laboratory equipment, factory-made magnetic stirrers are way overpriced. At the same time, such stirrer is rather easy to make from junk lying around the house. There are plenty of information on the Internet describing building mechanical part of a stirrer. Google for other people’s projects, some of which are much nicer than mine. I started this project mainly to play with motor control piece so mechanical setup was simplified as much as possible. As far a motor control goes, the main difference of mine will be ability to track stirrer bar behaviour. When a bar is spinning close to the maximum speed for given viscosity, it tends to lose strong attraction to the magnet of a motor and stop. Usual remedy is then to slow down the motor until it catches the bar and slowly increase the speed. Since moment of losing attraction is easy to register by monitoring current to the motor, the process of catching the stir bar can be automated. Also, I have a suspicion that a current change will be observed just before the disconnection and can be avoided altogether by corrective action. I will check this possibility during control circuit firmware design. Now, while waiting for Adafruit Motor/Stepper/Servo Shield for Arduino kit to join piles of junk lying around the house, I will describe mechanical implementation of the stirrer.
Continue reading Vigorius stirring redefined. Part 1 – mechanics.
By Oleg Mazurov  Get device descriptor trace
I finished porting USB transfers from PIC C to Arduino C++. There is now a USB class in the repository. Two main types of USB transfers – control and bulk, are implemented. If you want to know more about USB transfer mechanics, take a look at this article. The code was written to work on Microchip PIC, however, the Arduino code is almost identical.
Since we now have tools to talk to USB device, let’s start using them by looking at USB descriptors. In order for sketches from this article to work you need to copy current repository contents ( *.cpp and *.h files ) to a sub directory in your Arduino hardware libraries directory. In addition, don’t forget to supply 5V to Vbus and connect a USB device, such as flash drive or mouse to USB connector of a breakout board.
First sketch demonstrates access to device descriptor. Device descriptor is the first descriptor that the host retrieves from the device during enumeration. The information which host needs is device endpoint zero maximum packet size. In this example, maximum packet size is already set by a function in USB class, called “Task”. In addition to maximum packet size device descriptor contains other information, used during device configuration.
Continue reading Arduino USB Host – USB Descriptors.
By Oleg Mazurov  MAX3421E on a protoshield
I started porting my PIC USB host code to Arduino platform. There is now a repository on GitHub. Right now it contains a single class of functions talking to MAX3421E. This is not enough to support full USB host functionality, but enough to get started. To follow examples given in this article, create a sub-directory in your Arduino hardware libraries directory and copy MAX3421E*.* files from the repository into it.
MAX3421E talks to Arduino via SPI, so you will need Arduino SPI library. SPI uses pin13 – a pin also used to blink LEDs. Some Arduinos even have this LED hard-wired to pin13. My Arduino has it, and it co-exists peacefully with MAX3421E, however, there is no guarantee it will work on others. It would depend on current drawn by the LED. If you have problems communicating with MAX3421E and/or you can’t see SPI clock on this pin with your oscilloscope or protocol analyzer, try to disconnect the LED and see if it changes anything.
Picture on the right shows the final arrangement. The breakout board sitting on top of protoshield is a 3.3V part. Since I’m using 3.3V Arduino Pro from Sparkfun, no level converters are necessary. Look at the previous article for the closeout picture and schematic. The breakout receives power from Arduino.
Continue reading Arduino USB host – First programs.
By Oleg Mazurov  MAX3421E on a keyboard
Human interface device AKA HID is likely the most simple class for USB host to interact with. Reports are easy to parse and timing is not critical. In addition to that, HID standard defines simplified variety of the protocol, called “boot protocol”.
Modern USB keyboards, as well as mice, support boot protocol. It was designed to be used by PC BIOS during POST setup. No report parsing is necessary; as soon as device is put into configured state, it’s interrupt IN endpoint starts generating fixed-format 8-byte packet. This packet contains basic information about peripheral events. For keyboard, such packet contains information about modifier keys (control, shift, alt ) plus keys pressed. Mouse would give state of up to three buttons, plus amount of travel in X and Y direction since last poll.
Look at the code, function HIDMprobe or HIDKprobe. This function is called during enumeration to configure device which was just attached. By default, HID peripheral is configured to talk report protocol. In order to change it to boot protocol, host has to send “Set protocol” request with single data byte set to 0. After this is done, device starts generating interrupts( i.e., host can start periodically polling interrupt endpoint for new data.
It is worth mentioning that not all HID devices support boot protocol. Interface subclass set to 1 indicates that boot protocol is supported for this interface.
The first byte in 8-byte packet from a keyboard contains states of modifier keys – Control, Shift, Alt, and Windows. The next byte is reserved, it’s state means nothing to us. Last 6 bytes is a keyboard buffer – it contains so-called HID codes of keys being pressed since last poll.
Continue reading Lightweight USB host. Part 6 – introduction to HID.
By Oleg Mazurov  MAX3421E and mouse
All data on USB bus is transferred under host control. Even though some transfers are called IN and some other OUT, they all start at the host. There are four types of transfers, the most interesting of which is control transfer. This type of transfer is used all the time in communication with every class of devices. In this article, I give a short description on programming control transfers.
Control transfer consists of three steps( or stages ): setup, data, and status. Some of them carry necessary data in setup packet itself and don’t have data stage at all. Good example of such short request is “Set address” – the information to transfer is just one byte and is sent by filling a certain setup packet field.
Even though USB specification defines several different destinations for the transfer, such as device, interface and endpoint, on the lowest level each packet address consists of two parts – device and endpoint. Some endpoints are IN or OUT only. Other, such as “default control pipe” AKA endpoint 0, are bi-directional. Before each transfer can be sent out, peripheral address must be loaded into MAX3421E PERADDR register.
Continue reading Lightweight USB Host. Part 5 – control transfers.
By Oleg Mazurov  Arduino USB Host Shield prototype
I have been thinking about expanding ways to use my recently conceived USB Host controller based on MAX3421E. Nice and very popular AVR development platform called Arduino looked like logical target. After quick Internet search, I went to SparkFun to pick up an 3.3V 8 MHz Atmega168 Arduino Pro, a protoshield, and USB to serial cable. After checking that everything works fine together, I populated a MAX3421E breakout and soldered it on the top of protoshield ( see schematic ).
I wanted to make a quick prototype and not worry about level translation for now. Arduino Pro is 3.3V and is able to talk to MAX3421E directly. The circuitry to adapt this shield for 5V Arduinos will be added later. This is going to be interesting since MAX3421E is not only a USB controller but also a port expander. It provides 8 general purpose outputs and 8 inputs, which can be configured as interrupt sources, all accessible via SPI. I’m using 1 input and 1 output for Vbus tracking, the rest is available for general use.
In order to use Atmega’s SPI peripheral I imported SPI library from Arduino playground. The default initialization will work. Below is the quick sketch that I wrote to make sure that MAX3421E is talking. Here I’m defining pins, setting initial state, and configuring MAX3421E SPI to full-duplex mode. This is not the right way to initialize MAX3421E, however, the beauty of this controller is that its SPI subsystem is separate from the rest of the chip and will work in any state as long as power is applied. No fancy resets are necessary.
Continue reading Arduino USB host – Pre-prototyping.
By Oleg Mazurov  MAX3421E breakout
A couple of updates. First, second prototype for the breakout board arrived from BatchPCB (pictured on the right ). I placed an order for the first batch with PCBcart, it is supposed to be here in 2 weeks. Also, I made this prototype public at BatchPCB, this is the product link. The prototype has a little defect – the USB connector is placed a little bit too close to resistors; however, it’s totally buildable, just make sure you insert USB connector last, when the rest is soldered and checked.
Second, I created a code repository for the project. From now on, all firmware development will be posted there. The hardware files don’t change that often; they will still be hosted here in downloads section.
At present, the code doesn’t do much past enumeration. From USB point of view, it knows how to generate control and bulk-IN transfers; bulk-OUT is going to be written together with mass storage client driver code, which is going to be next big step. Also, it is probably buggy and this is my reason for publishing it – “given enough eyeballs, all bugs are shallow”. If you try the code and it doesn’t work, let me know. Or better yet, fork a code, fix it and let me know what you fixed and why.
Continue reading Lightweight USB Host. Part 4 – The code.
|
|