mbed Starter Kit Experiment Guide
This Tutorial is Retired!
This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.
Experiment 6: USB Host and Threading
In this tutorial, we turn the mbed LPC1768 into a USB host. For this, we will use mbed's USBHost library and the USB Type A Female Breakout. Leave the LCD connected, as we will use it to display characters from a USB keyboard. Additionally, we introduce the concept of threading so that we can essentially do 2 things at once (specifically, listen for keystrokes and blink an LED).
IMPORTANT: You will need a USB keyboard for this tutorial.
Suggested Reading
The Circuit
This circuit can be made with parts in the SparkFun mbed Starter Kit. Also, keep in mind that the LPC1768 box contains a USB mini-B cable for programming and power.
Parts List
To follow this experiment, you would will need the following materials if you did not order the SparkFun mbed starter kit. You may not need everything though depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary.
In addition to the listed parts, you will also need a USB keyboard to complete the tutorial.
Schematic
Connections
Connect the LPC1768 to the LCD and USB breakout in the following fashion. Note that the LCD uses the same connections as in Part 3.
Fritzing Diagram
Hookup Table
Place the LPC1768 in a breadboard with pin VOUT in position i1 and pin 20 in position b20.
Connect the rest of the components as follows:
Component | Breadboard | ||||
---|---|---|---|---|---|
uLCD-144-G2* | h26 (RES) | h27 (GND) | h28 (RX) | h29 (TX) | h30 (+5V) |
USB Type A Female Breakout | b26 (VCC) | b27 (D-) | b28 (D+) | b29 (GND) | |
Jumper Wire | j2 | d26 | |||
Jumper Wire | e26 | f30 | |||
Jumper Wire | a1 | ( - ) | |||
Jumper Wire | a9 | f28 | |||
Jumper Wire | a10 | f29 | |||
Jumper Wire | a11 | f26 | |||
Jumper Wire | ( - ) | f27 | |||
Jumper Wire | j9 | e27 | |||
Jumper Wire | j10 | e28 | |||
Jumper Wire | ( - ) | e29 |
* Pins not listed are not used.
The Code
For this tutorial, we will be using the LCD and USB Host libraries. In our main.cpp, we create a thread that runs the USB Host function separately from the rest of the program. This allows us to blink an LED and have it not interrupt or be interrupted by keyboard input.
Libraries
Navigate to the mbed.org, login, and navigate to your Compiler.
Create a new program with the "Blinky LED Hello World" template. Name it something like "usb_host."
Navigate to the following pages and import each library into your "usb_host" program.
The mbed library should already be imported if you used the "Blinky" template.
Program
Click on "main.cpp" in your project, remove the template code, and copy in the following code.
language:c
// USB host keyboard and LCD demo
#include "mbed.h"
#include "USBHostKeyboard.h"
#include "uLCD_4DGL.h"
// LED to demonstrate multi-threading
DigitalOut led(LED1);
// Graphic LCD - TX, RX, and RES pins
uLCD_4DGL uLCD(p9,p10,p11);
// Callback function from thread
void onKey(uint8_t key) {
uLCD.printf("%c", key);
}
// Function that runs continuously in the thread
void keyboard_task(void const *) {
USBHostKeyboard keyboard;
while(1) {
// Try to connect a USB keyboard
uLCD.printf("Waiting...\n");
while(!keyboard.connect()) {
Thread::wait(500);
}
uLCD.printf("Connected!\n");
// When connected, attach handler called on keyboard event
keyboard.attach(onKey);
// Wait until the keyboard is disconnected
while(keyboard.connected()) {
Thread::wait(500);
}
uLCD.printf("\nDisconnected!\n");
}
}
// Main - the program enters here
int main() {
// Initialize LCD
uLCD.baudrate(115200);
uLCD.background_color(BLACK);
uLCD.cls();
uLCD.locate(0,0);
// Create a thread that runs a function (keyboard_task)
Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4);
// Flash an LED forever
while(1) {
led=!led;
Thread::wait(500);
}
}
Run
Compile the program and copy the downloaded file to the mbed. Connect a USB keyboard to the USB breakout board.
Press the mbed's restart button, and the LCD should show "Waiting..." If the keyboard was connected properly, you should see "Connected" on the LCD. Once you see "Connected," start typing! You will see your keystrokes appear on the LCD.
NOTE #1: If you have some trouble getting the keyboard to connect, make sure the keyboard is plugged in and try resetting the mbed.
NOTE #2: The USBHost library is in beta and has some issues connecting USB devices sometimes. Not all keyboards will work with this demo.
Also, if you try typing too fast, you will see repeat keys. This is because the mbed does not process two simultaneous key presses correctly.
Concepts
We covered two important concepts in this tutorial: USB and threading. Both create a unique set of opportunities for embedded systems.
Callbacks
In our program, we define an onKey() function. This is a callback.
onKey(uint8_t key) is a function that is declared in the USBHostKeyboard library, but the definition is left to us to implement. Callbacks are executed whenever an event occurs in another piece of code (within the USBHostKeyboard code, in this case).
We define onKey() in our code (it prints the received character to the LCD), and then we pass the onKey() function to our USBHostKeyboard object with the following line:
language:c
keyboard.attach(onKey);
This lets the USBHostKeyboard object know where to find the onKey() callback function. After that, whenever a keystroke occurs on the connected keyboard, the onKey() function is called.
USB Host
Universal Serial Bus (USB) has been around for many years. Created in the mid-1990s, USB has been the most popular way to connect peripherals to computers. As a result, many embedded systems support USB communications.
While many embedded systems can support being a USB Device, having USB Host capabilities is only seen in more powerful processors. Being able to act as a host means that we can plug in a number of devices normally reserved for computers: keyboards, mice, flash drives, etc. If you really want to get involved in USB development, this book is a great place to start.
Threading
If you are carefully reviewing the code, you might have noticed the keyword "Thread" appear. This is a function built into the mbed library that allows us to run multiple processes at the same time (well, not quite. The processor relies on a technique called Scheduling to determine which process gets run, since only one can run at a time in reality). It is important to understand that our mbed is powerful enough to allow us to run multiple threads (many, smaller microcontrollers, such as the ATmega 328p, of Arduino fame, have trouble with multiple threads).
When a Thread is created, as in our USB Host example, it calls the function given in its parameters (keyboard_task, in this case). The threaded function runs while the rest of the program continues at the same time (in theory, the "Flash an LED forever" section runs while "keyboard_task" is executing simultaneously).
If you would like more control over threads and the scheduling, take a look at mbed's Real Time Operating System (RTOS) library.
Going Further
Adding USB lets us connect many different peripherals to our mbed. Additionally, we learned about threading, which lets us run multiple processes at the same time.
Beyond the Tutorial
- Make the backspace key actually delete characters on the LCD
- Use the graphics functions of the LCD to control a ball with the keyboard's arrow keys
- Use a mouse to control a ball around the LCD (Hint: see USBHostMouse)
- Read some files on a USB flash drive (Hint: see USBHostMSD)
Digging Deeper
- HowStuffWorks has a great overview of USB
- If you are particularly bored (or need the real source material), take a look at the newest USB Specification
- Read about Real Time Operating Systems