Tải bản đầy đủ (.pdf) (10 trang)

Practical Arduino Cool Projects for Open Source Hardware- P8 ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (228.14 KB, 10 trang )

CHAPTER 3  TIME-LAPSE CAMERA CONTROLLER
home.hccnet.nl/s.vd.palen.For more information about how to use it and what codecs to install, see the
brief tutorial on the AddictiveTips site at www.addictivetips.com/windows-tips/make-time-lapse-video-
from-sequence-photos. Another option is to use Windows Movie Maker, included with many versions of
Windows. However, Windows Movie Maker has a limitation that it can only create time-lapse movies up
to 8 frames per second, which may make your movie look a bit jerky.
Macintosh
The free version of QuickTime included with MacOS X can create time-lapse movies, but has the
limitation that it can’t resize the end result, It also doesn’t apply any compression. If you have
QuickTime Pro (or, better still, Apple Final Cut) they have more options, but for a basic movie the regular
version of QuickTime, included with Leopard and earlier releases of MacOS X, will do.
Be careful if you have Snow Leopard, though: you’ll need to do a little bit more preparation because
it ships with a dumbed-down version of QuickTime called QuickTime X and doesn’t include this
functionality. You’ll need to insert your Snow Leopard disk, select Customize, and install the 7.x version
of QuickTime. It will then be available under Applications
h Utilities h QuickTime Player 7. More
information on this process is available at support.apple.com/kb/HT3678.
Once you have QuickTime installed, launch it and go to the File menu, select Open File , then
choose the last image in your sequence. You’ll then see a new movie player containing the image. Then
select all the other images in the Finder in the correct order (excluding the last image) and drag them on
top of the open movie window. The additional images will be added as frames in order before the
already opened image, which is why we started by selecting the last image first. Confusing, but it works.
At this point you can’t save the movie directly through the menu so you have to click the Close
button in the window. Rather than immediately closing, QuickTime will then ask if you want to save the
unsaved movie.
Select the “Save as a self-contained movie” option, give the movie a name, and save it.
The result will be a fairly large, uncompressed movie that runs at 15fps. If you want to put it online,
you’ll probably need to process it with a movie editor to compress it.
Variations
Adding a light-level sensor to the Arduino allows it to skip taking photos when it’s too dark, which can be
very handy if you’re making a movie outside that you can’t light artificially at night.


Light-dependent resistors (LDRs) vary their resistance inversely to the amount of light that is falling
on them: in other words, in bright light they have very low resistance and allow a current to flow, while in
darkness they have very high resistance and prevent current from flowing. The schematic shows how to
add an LDR so that it can be read using an analog input to detect the current light level.
Connect an LDR so that one lead is connected to analog input 0 on the Arduino and the other lead is
connected to the VCC (+5V) pin. Then connect a 10k resistor so that one pin connects to the analog
input 0 and the other end goes to GND. What this will do is create a variable voltage divider that will
present a low voltage to the analog input when it’s dark and a high voltage when it’s light. The voltage
will also vary between those two extremes in partial lighting. You can then run the alternative example
sketch, available from the Practical Arduino site, to have your Arduino only take photos when it is light.
The takePhoto() function can then be extended to wrap its functionality inside an analog read so
that if the voltage divider is above a certain level it will operate, but otherwise it will do nothing.

49
CHAPTER 3  TIME-LAPSE CAMERA CONTROLLER
50
void takePhoto()
{
if(analogRead(0) > 300)
{
digitalWrite(ledPin, HIGH); // Turn on activity LED
digitalWrite(focusPin, HIGH); // Turn on focus relay
digitalWrite(shutterPin, HIGH); // Turn on shutter relay
delay(500); // Hold the button for 1/2 second
digitalWrite(ledPin, LOW); // Turn off activity LED
digitalWrite(shutterPin, LOW); // Turn off shutter relay
digitalWrite(focusPin, LOW); // Turn off focus relay
}
}


You might need to experiment with the comparison value for the analogRead to have the sketch
dis
able the shutter output at the correct light level.

C H A P T E R 4

  

Virtual USB Keyboard
Giving your Arduino the ability to pretend to be a keyboard, mouse, or joystick opens up a whole world
of possibilities because it means your Arduino can now interact with software that was never intended
for automated control by a smart device. This could be desktop software, such as a game or a web
browser. For example, your Arduino could “type” into a web form and submit it on your behalf, or act as
a custom controller for a game.
You could also use an Arduino to connect a custom input device to your computer so that it is seen
as a regular keyboard or joystick. The custom input device could be a chording keyboard, for example, or
even something such as a virtual-reality glove or head tracking system that controls the cursor location
in joystick mode. The required parts are shown in Figure 4-1, and the complete schematic is in Figure
4-2.
Parts Required
1 Arduino Duemilanove, Arduino Pro, Seeeduino, or equivalent
1 Prototyping shield
1 PCB-mount female USB “B” connector
1 USB A-to-B cable (commonly used as a printer cable)
2 3.6V Zener diodes (must be rated at 0.5W or less, 1W won’t work)
1 2.2K 0.25W or 0.5W resistor
2 68R 0.25W or 0.5W resistor
4 SPST push buttons (optional)
Source code available from www.practicalarduino.com/projects/virtual-usb-keyboard.





51
CHAPTER 4  VIRTUAL USB KEYBOARD

Figure 4-1. Parts required for the Virtual USB Keyboard


Figure 4-2. Schematic for the Virtual USB Keyboard
52
CHAPTER 4  VIRTUAL USB KEYBOARD
Instructions
Populate Prototyping Shield
While there’s not much that can go drastically wrong, before beginning construction you should
consider using a USB hub to connect your virtual USB keyboard shield to your computer the first few
times. Even though they have excellent internal protection already, we wouldn’t want a fault in the
shield to fry a USB port in your expensive computer—much better to sacrifice a cheap USB hub.
There aren’t many parts in this project so the layout isn’t particularly critical. You can rearrange
components to suit yourself if you have particular requirements for fitting it inside a case and still getting
access to the USB connector.
Start by mounting the USB connector on one edge of the prototyping shield. It’s important to
mount it in such a way that you will be able to plug the USB lead into the connector while it is mounted
on the board without any other components getting in the way. PCB-mount USB connectors have two
tabs sticking out of the body to provide physical stability since the force of plugging and unplugging a
cable can be quite large, so it’s important to use the tabs to hold the socket in place rather than rely on
the four tiny pins used for electrical connections. As a general principle it’s not a good idea to have
mechanical support (“strain relief”) provided by signal-carrying electrical connections if you can avoid
it, and many parts designed to be subjected to physical force provide mechanical mounts separate from
the pins.

The tabs on the bottom of the USB socket are kinked so they can clip into appropriately sized holes,
but that provides very weak support and we certainly wouldn’t rely on it. Instead we used a pair of pliers
to straighten the tabs and then drilled two holes through the prototyping shield so they could slide down
neatly with the four pins aligned with existing holes in the shield. Then, with the socket pushed hard
against the shield, we bent the tabs inward and soldered them onto pads on the shield to give it a very
strong physical mount that won’t budge when a USB cable is inserted or removed. Make sure you keep
the tabs away from the pads used to connect the pins to prevent any short circuits.
Before adding any more parts to the shield it’s a good idea to use the USB cable to connect it to the
computer and use a multimeter to verify the 0V and +5V connections on the socket pins. Then
disconnect the USB lead and fit the 2K2 resistor linking the D– line (pin 2) to Arduino digital I/O pin 5.
This allows the UsbKeyboard library to reset the USB connection under software control.
If you’re curious about how USB works, it can be interesting at this point to temporarily connect
digital I/O pin 5 to the +5V pin and plug the shield back into the cable connected to your computer. If
you watch the system log on your computer while you do it, you’ll discover that even the basic shield
with nothing on it but the connector and one resistor will be identified by the computer as a low-speed
USB device! Obviously it can’t actually send or receive data because there’s no intelligence in it yet, but it
demonstrates that device presence detection is an electrical operation and has nothing to do with data
flowing on the bus.
Disconnect the temporary connection between digital I/O pin 5 and +5V if you performed the
previous experiment and proceed to fitting the 68R resistors that connect the D– and D+ USB data lines
to the Arduino digital I/O lines. D– (USB pin 2) connects via one resistor to Arduino digital I/O pin 4,
while D+ (USB pin 3) connects via the other resistor to digital I/O pin 2 (see Figure 4-3).

53
CHAPTER 4  VIRTUAL USB KEYBOARD

Figure 4-3. Physical pinout of USB “B” socket
Table 4-1. Pin assignment of USB “B” socket
Pin Name Cable Color Description
1 VCC Red +5 VDC

2 D– White Data –
3 D+ Green Data +

Note that the use of Arduino digital I/O pins 2 and 4 is hard-coded into the UsbKeyboard library
itself and can’t be changed in your program. The use of digital I/O pin 2, in particular, is critical because
the library relies on the “interrupt” associated with that pin to detect events on the USB connection.
Fit the 3.6V Zener diodes that link the D– (USB pin 2) and D+ (USB pin 3) USB data lines to ground,
being careful with orientation of the diodes: the ends with the bands connect to the data lines with the
other ends connected to ground.
The purpose of the Zener diodes may seem a bit cryptic at first, but they are absolutely critical to the
operation of the circuit. The USB standard specifies that even though the power supply line is +5V, the
communication lines themselves run at a nominal voltage of 3.3V. It’s also a little different to what you
may have seen on other serial connections, such as RS232, which have “TX” (transmit) and “RX”
(receive) lines. The D– and D+ lines are not independent TX/RX lines, as you may expect, but are actually
what is known as a “half-duplex differential signalling pair.” This approach helps USB run at very high
data rates by reducing the effect of electrical noise.
54
CHAPTER 4  VIRTUAL USB KEYBOARD
A Zener diode has a special property in that it “clamps” a voltage to around the same voltage level as
the diode is specified for. In the forward direction it acts just like a normal diode, conducting with the
common 0.6V drop. However, in the reverse direction, unlike a normal diode which is basically open
circuit until it breaks down, the Zener diode will start conducting at its specified voltage. This is
commonly called “clamping.”This makes them very useful for regulating and setting voltage levels in
low-power circuits, and also invaluable as voltage reduction and protection devices.
In this circuit the Zener diodes clip the 5V supplied by the Arduino I/O pins down to the 3.3V USB
standard.
But wait. Why use a 3.6V Zener to achieve a 3.3V limit?
That’s because, in this particular application, the electrical characteristics of the circuit mean that
the voltage actually achieved will be a little below the rating on the Zener. Using a 3.6V Zener results in
the voltage on the data lines ending up clipped to approximately the correct 3.3V level. Since the USB

standard specifies that the voltage must be in the range of 2.8 to 3.6V, it doesn’t matter if we exceed 3.3V
a little and it all works out just nicely.
One final word about the Zener diodes: power rating is critical, but not in the way you might expect.
Power rating on components is based on how much energy they can safely dissipate before the magic
smoke comes out, so most of the time it’s perfectly safe to overrate your parts and use a component with
a higher rating than required for the particular circuit. However, in this case that approach can actually
prevent the circuit from working because the trade-off in Zener diode design is that as its power rating
increases it also exhibits more capacitance—not only will it behave like a Zener, but it will also behave
like a tiny capacitor! For simple power-regulation requirements that’s just fine. However, in this case,
the data lines need to change state very fast and any capacitance added to the line will effectively
“damp” the data lines and prevent them from moving between low and high values fast enough.
Capacitance on a high-speed data line is very bad and needs to be avoided or the circuit simply won’t
work. In practice, a 1/4W Zener diode should work fine; a 1/2W Zener should work, but is a bit on the
borderline; and a 1W Zener almost certainly won’t work—it will simply have too much capacitance.
Finding stock of through-hole (leaded) Zeners below 1W can be quite tricky now because many
electronics shops only stock the 1W versions, but if you’re lucky you may find a shop with old stock of
1/4W or 1/2W diodes. If not, you may need to resort to using surface-mount diodes: SMD Zeners are
commonly available in low power ratings. With a steady hand and a small soldering iron tip you should
be able to solder them between adjacent pads on a prototyping shield without too much difficulty,
particularly if you can find them in a larger package size such as 1206 or 0805.
Zener diodes are truly bizarre components with some very unusual characteristics. If you want to
find out more about them, read the Wikipedia article at en.wikipedia.org/wiki/Zener_diode.
Finally, install jumper leads from the GND pin on the USB connector (pin 4) to the Arduino’s
ground connection on the shield, and VCC (USB connector pin 1) to the Arduino’s +5V on the shield.
This can’t be seen in the photograph of our prototype (see Figure 4-4) because the connection was made
directly underneath the shield from one pad to another. The connection from USB VCC to Arduino +5V
is optional, and if you are going to power your Arduino from some other power source you should leave
it off. However, with that connection in place the Arduino can draw its power from the USB port on the
host and doesn’t need any other connections at all. It allows you to just plug your USB shield/Arduino
combination into a host using the socket on the shield and the Arduino will power up automatically.


55
CHAPTER 4  VIRTUAL USB KEYBOARD

Figure 4-4. USB “B” connector, Zener diodes, and resistors assembled on shield
Prepare the UsbKeyboard Library
The example sketch simply emulates a USB keyboard and reads the value of four digital input lines and
sends characters to the host computer whenever one of the inputs is pulled low. On our shield we
installed four PCB-mount push buttons that connect Arduino inputs 8, 9, 10, and 11 to ground when
pressed, but you could just as easily use an external sensor such as the output from a motion detector to
pull one of the inputs low and trigger transmission of characters.
The program relies on the UsbKeyboard Arduino library, created by Philip Lindsay, that
incorporates a generic USB library created by Objective Development (www.obdev.at). The UsbKeyboard
library is available for download from Lindsay’s site at code.rancidbacon.com/ProjectLogArduinoUSB.
Unfortunately, at the time of writing the library won’t compile under Arduino 0017 or 0018. You’ll
need to download and install version 0016 (still available from the Arduino web site) for this project.
The library download is a compressed tarball called arduinousb_release_002.tar.gz. Download and
extract it. Inside you’ll find a directory called libraries/UsbKeyboard. With Arduino 0017 and later you
can install libraries inside the libraries directory inside your sketchbook, but that location doesn’t work
with Arduino 0016 so instead you’ll need to move the UsbKeyboard directory into the libraries directory
inside your actual Arduino 0016 installation.
56
CHAPTER 4  VIRTUAL USB KEYBOARD
Compile and Upload Sketch
The very first thing the sketch does is include the UsbKeyboard library.

#include "UsbKeyboard.h"

It then specifies which digital inputs to use for the four buttons. Note that the labels for the buttons
could have been anything you like and doesn’t have any correlation to what characters might be sent

when that button is pushed: we just used those names so it would be easy to remember what each one
represents. The sketch also specifies a pin for a status LED at this point.

#define BUTTON_A 8
#define BUTTON_B 9
#define BUTTON_MSG 10
#define BUTTON_ENTER 11
byte ledPin = 13;

The setup function has to do a few different things, starting with setting up the status LED and
setting the pins for the button connections to inputs, as follows.

void setup()
{
pinMode (ledPin, OUTPUT);
digitalWrite (ledPin, HIGH);
pinMode (BUTTON_A, INPUT);
pinMode (BUTTON_B, INPUT);
pinMode (BUTTON_MSG, INPUT);
pinMode (BUTTON_ENTER, INPUT);

To save some external components, it then enables the CPU’s internal pull-up resistors on the pins
being used for the buttons. By doing this, we don’t need to connect external pull-up resistors, just the
buttons themselves.

digitalWrite (BUTTON_A, HIGH);
digitalWrite (BUTTON_B, HIGH);
digitalWrite (BUTTON_MSG, HIGH);
digitalWrite (BUTTON_ENTER, HIGH);


Now for the USB setup. Because USB is extremely time-critical we need to mess with the interrupts
a bit to ensure the Arduino will enumerate itself properly with the host computer. Notice that while
forcing re-enumeration there is a 250 millisecond delay using a function called delayMs(), which is not a
built-in Arduino function. Because timer0 has been disabled at that point in the code we can’t use
functions like delay() and must define our own.

TIMSK0&=!(1<<TOIE0);

The sketch then clears the interrupt flags before it performs time-critical operations.

cli();

57
CHAPTER 4  VIRTUAL USB KEYBOARD
To make the host detect that the Arduino is present, the program uses functions in the UsbKeyboard
library to disconnect and then reconnect. This forces it to be re-enumerated by the host.

usbDeviceDisconnect();
delayMs(250);
usbDeviceConnect();

The interrupts then need to be enabled again.

sei();
}

The main program loop is very simple and repetitive. It just loops as fast as possible and calls the
update() function in the UsbKeyboard library each time through, then checks each of the digital inputs
to see if any of them have been pulled low by a push button or other device connecting it to ground. If
they have, it calls sendKeyStroke() to send an appropriate keypress event to the host.


void loop()
{
UsbKeyboard.update();
if (digitalRead(BUTTON_A) == LOW) {
UsbKeyboard.sendKeyStroke(KEY_A);
digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
}

if (digitalRead(BUTTON_B) == LOW) {
UsbKeyboard.sendKeyStroke(KEY_B);
digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
}

if (digitalRead(BUTTON_MSG) == LOW) {
UsbKeyboard.sendKeyStroke(KEY_H, MOD_SHIFT_LEFT);
UsbKeyboard.sendKeyStroke(KEY_E);
UsbKeyboard.sendKeyStroke(KEY_L);
UsbKeyboard.sendKeyStroke(KEY_L);
UsbKeyboard.sendKeyStroke(KEY_O);
UsbKeyboard.sendKeyStroke(KEY_SPACE);
UsbKeyboard.sendKeyStroke(KEY_W, MOD_SHIFT_LEFT);
UsbKeyboard.sendKeyStroke(KEY_O);
UsbKeyboard.sendKeyStroke(KEY_R);
UsbKeyboard.sendKeyStroke(KEY_L);
UsbKeyboard.sendKeyStroke(KEY_D);
UsbKeyboard.sendKeyStroke(KEY_ENTER);
digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
}


if (digitalRead(BUTTON_ENTER) == LOW) {
UsbKeyboard.sendKeyStroke(KEY_ENTER);
digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle status LED
}
}
58

×