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

Apress - Smart Home Automation with Linux (2010)- P17 ppsx

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 (388.94 KB, 5 trang )

CHAPTER 2 ■ APPLIANCE HACKING

63

apt-get install gcc-avr avr-libc avrdude

Java, if uninstalled, will need an extra line, like this:

apt-get install openjdk-6-jre

From here, it’s a simple matter of installing the IDE. This is provided as a single archive from the
web site at Extract this to an appropriate directory (root access is
not required for any of these steps), and run ./arduino from the directory. You should then set up the
appropriate USB device and type of Arduino (Tools
➤ Serial Port and Tools ➤ Board, respectively)
before use.
You can begin a project by selecting File
➤ New from the menu. This creates what the Arduino IDE
calls a sketch. This involves a subdirectory in the Arduino working folder and a primary source file. Other
source files can be added into the sketch (through Sketch
➤ Add File) and will be automatically included
into the project build. There is no Makefile equivalent here, and every file added to the sketch, even if it
is a library file from another directory, is copied into the sketch directory. Note that despite the visual
similarity to C code, all files are given the extension .pde for clarity.
Then verify the build, and if everything is working,
9
upload it to the Arduino.
■ Note You cannot create a sketch of a given name. Instead, you must create a blank new sketch and then select
Save As as a separate step.
The build process itself is handled behind the scenes using avr-gcc, a cross-compilation toolchain
for the Atmel AVR RISC processors, of which the ATmega168 is one. It creates a separate applet directory


inside the sketch folder and copies all the header files into it, along with a concatenation of all the source
files (ending in .pde). It is this (.cpp) source file that is then cross-compiled into hex for upload to the
Arduino.
Arduino Software
The simplest circuit that most people build to test their setup is that of a flashing light. Pin 13 on the
Arduino Diecimila board has a built-in resistor, allowing you to directly connect an LED to it and the 0v
supply without damaging it. Some boards also have a surface-mount LED, so you don’t even need that!
The blink tutorial code, which can be loaded from the IDE (File
➤ Examples ➤ Examples), is simply this:



9
There are various problems in Debian Etch with mismatched versions here, which cause a 0-byte sketch to be
created. The latest version of the IDE (17) requires version 2.18 of the AVR tools.
CHAPTER 2 ■ APPLIANCE HACKING

64

int ledPin = 13; // LED connected to digital pin 13

void setup() // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop() // run over and over again
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second

digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}

It is easy to understand this code, with many of the usual C/C++/Java-ism being unnecessary:
• No header files are needed.
• Main has been replaced by two functions: setup and loop.
• There is no event loop or callbacks. You must read the pin states each time around
a loop.
If you are a classically trained developer, who vehemently opposes the blocking function delay
that’s used here, then there are examples that demonstrate the use of the millis function to infer the
timing without blocking.
For most complex software and libraries, you can, of course, reference header files, but remember
that any additional source files added to the project will be copied. It is certainly possible to create your
own libraries, but on such small-scale projects, it often proves to be a bigger time sink.
Reading Digital Inputs
These are the simplest circuit to build, because they consist of a single resistor and switch combination,
as shown in Figure 2-2.


Figure 2-2. Reading a digital switch on the Arduino
CHAPTER 2 ■ APPLIANCE HACKING

65

In this configuration, pin 2 is used as an example and reports a 1 (high) voltage to the Arduino at all
times the switch is open. This is because of the “pull-up” resistor, R1. Without it, the pin is effectively
disconnected, so its voltage may fluctuate to any value between 0 and 5v, causing false readings. (Most
of the time, however, it will float up to 1.) When the switch is closed, the pin is connected directly to the
0v ground rail, causing a 0 to be read. The Arduino code then watches for this change as follows:


int inputSwitchPin = 2;
int lastState = HIGH;

void setup() {
Serial.begin(9600);
pinMode(inputSwitchPin, INPUT);
}

void loop() {
int pinState = digitalRead(inputSwitchPin);

if (pinState != lastState) {
Serial.println(pinState?"released":"pressed");
lastState = pinState;
}
}

This will work in some situations but not all, since hardware isn’t that simple! Switches, being
mechanical beasts, have a tendency to “bounce” between on and off a few times when they’re pressed. If
this switch was connected to a light, you probably wouldn’t see it switch on and off, however, since the
time involved is measured in milliseconds. But a computer is fast enough to spot it, so you need to
program the code to ignore any state changes that occur within, say, 100 ms of each other.

int inputSwitchPin = 2;
int lastState;

long timeLastPressed;
long debouncePeriod = 100;


void setup() {
Serial.begin(9600);
pinMode(inputSwitchPin, INPUT);
lastState = digitalRead(inputSwitchPin);
timeLastPressed = millis();
}

void loop() {
int pinState = digitalRead(inputSwitchPin);

if (pinState != lastState && millis() - timeLastPressed > debouncePeriod) {
Serial.println(pinState?"released":"pressed");
timeLastPressed = millis();
lastState = pinState;
}
}
CHAPTER 2 ■ APPLIANCE HACKING

66

The switch I’ve used here is normally open and, as the name suggests, remains open (so that no
current flows between the contacts) under normal circumstances and is closed when the switch is
pressed. Some switches are marked as normally closed, in which case you simply reverse the output in
the example.
It is also possible to use analog devices, such as a light sensor, to report a digital on/off input when
you’re are not concerned with the quantity involved. In this example, you might be interested in whether
it is light outside but not how bright the light was. You can amend the circuit as shown in Figure 2-3.


Figure 2-3. Reading the light on the Arduino

This circuit is known as a potential divider circuit, since the voltage (known formally as potential) is
divided proportionally by the resistors placed across the supply rails. R2 is a light-dependent resistor
(LDR), which has a very high resistance (like an open switch) when it is dark but acts almost like a closed
switch (that is, low resistance) when it is light. (This is an oversimplification of the process but is enough
to get things working.) The exact resistance of the LDR under these conditions is governed by the
specific LDR, and not all manufacturers or suppliers provide this information, so you might have to
experiment.
This basic circuit can be used to switch on lights when it gets dark (remembering to point the LDR
away from the light in question!) and can be used to monitor people passing by the sensor because their
shadow is usually enough to switch the LDR off. You can also get infrared transmitters and receivers that
work in similar fashion, which can be placed on either side of a doorway or front gates, so you can get
forewarning when someone is approaching your house.
■ Note When you’re interested in the state change from off to on, this is known as a rising edge trigger. And
changes from on to off are called falling edge triggers.
CHAPTER 2 ■ APPLIANCE HACKING

67

Reading Analog Inputs
These detect a continuous range of values. Unlike the digital pins, which can be used as either input or
output, the analog pins on an Arduino are hardwired, so there is no need for initial configuration. This
leaves you nothing to do except read their value.

int analogInputPin = 0;
int value = analogRead(analogInputPin);

The result of value will be in the range 0 to 1023 and represents the voltage on the pin, between 0
and 5v.
If you reuse circuit from Figure 2-3, feeding the input to an analog pin instead of a digital one, you
can watch the range of values being output by using this:


Serial.print("LDR brightness = ");
Serial.println(value);

This allows you to determine the precise brightness of the light empirically. You will notice a lot of
fluctuations with this data, so the best approach is to determine whether it’s bright or dark enough to
control the light, by having two limits and a dead band in the middle. That is, if the number drops from
greater than X to less than X, then it’s considered light, and if it increases from less than X+N to greater
than X+N, then it’s dark.
You can then add a variable resistor into the circuit to fine-tune this brightness, as shown in Figure
2-4.


Figure 2-4. Controlling the brightness at which the Arduino is controlled

×