© Charles Bell 2020
C. BellBeginning Sensor Networks with XBee, Raspberry Pi, and Arduinohttps://doi.org/10.1007/978-1-4842-5796-8_6

6. Arduino-Based Sensor Nodes

Charles Bell1 
(1)
Warsaw, VA, USA
 

One of the greatest advances in physical computing has been the proliferation of microcontrollers. A microcontroller consists of a processor with a small instruction set, memory, and programmable input/output circuitry contained on a single chip. Microcontrollers are usually packaged with supporting circuitry and connections on a small printed circuit board.

Microcontrollers are used in embedded systems where small software programs can be tailored to control and monitor hardware devices, making them ideal for use in sensor networks. One of the most successful and most popular microcontrollers is the Arduino platform.

In this chapter, you explore the Arduino platform with the goal of using the Arduino to manage sensor nodes. You see a short tutorial on the Arduino and several projects to help get you started working with the Arduino.

What Is an Arduino?

The Arduino is an open source hardware prototyping platform supported by an open source software environment. It was first introduced in 2005 and was designed with the goal of making the hardware and software easy to use and available to the widest audience possible. Thus, you do not have to be an electronics expert to use the Arduino.

The original target audience included artists and hobbyists who needed a microcontroller to make their designs and creations more interesting. However, given its ease of use and versatility, the Arduino has quickly become the choice for a wider audience and a wider variety of projects.

This means you can use the Arduino for all manner of projects from reacting to environmental conditions to controlling complex robotic functions. The Arduino has also made learning electronics easier through practical applications.

Another aspect that has helped the rapid adoption of the Arduino platform is the growing community of contributors to a wealth of information made available through the official Arduino website (http://arduino.cc/en/). When you visit the website, you find an excellent “getting started” tutorial as well as a list of helpful project ideas and a full reference guide to the C-like language for writing the code to control the Arduino (called a sketch).

Arduino also provides an integrated development environment called the Arduino IDE. The IDE runs on your computer (called the host), where you can write and compile sketches and then upload them to the Arduino via USB connections. The IDE is available for Linux, Mac, and Windows. It is designed around a text editor especially designed for writing code and a set of limited functions designed to support compilation and loading of sketches.

Sketches are written in a special format consisting of only two required methods—one that executes when the Arduino is reset or powered on and another that executes continuously. Thus, your initialization code goes in setup() and your code to control the Arduino goes in loop(). The language is C-like, and you may define your own variables and functions. For a complete guide to writing sketches, see http://arduino.cc/en/Tutorial/Sketch.

You can expand the functionality of sketches and provide for reuse by writing libraries that encapsulate certain features such as networking, using memory cards, connecting to databases, doing mathematics, and the like.

The Arduino supports a number of analog and digital pins that you can use to connect to various devices and components and interact with them. The mainstream boards have specific pin layouts, or headers, that allow the use of expansion boards called shields. Shields let you add additional hardware capabilities such as Ethernet, Bluetooth, and XBee support to your Arduino. The physical layout of the Arduino and the shield allow you to stack shields. Thus, you can have an Ethernet shield as well as an XBee shield, because each uses different I/O pins. You learn the use of the pins and shields as you explore the application of Arduino to sensor networks.

The next sections examine the various Arduino boards and briefly describe their capabilities. I list the boards by when they became available, starting with the most recent models. Many more boards and variants are available, and a few new ones are likely to be out by the time this book is printed, but these are the ones that are typically used in a sensor network project.

Arduino Models

A growing number of Arduino boards are available. Some are configured for special applications, whereas others are designed with different processors and memory configurations. Some boards are considered official Arduino boards because they are branded and endorsed by Arduino.cc. Since the Arduino is licensed using a Creative Commons Attribution Share-Alike license, anyone can build Arduino-compatible boards if they adhere to the license. This section examines some of the more popular Arduino-branded boards.

The basic layout of an Arduino board consists of a USB connection, a power connector, a reset switch, LEDs for power and serial communication, and a standard spaced set of headers for attaching shields. The official boards sport a distinctive blue-colored PCB with white lettering. With the exception of one model, all the official boards can be mounted in a chassis (they have holes in the PCB for mounting screws). The exception is an Arduino designed for mounting on a breadboard.

Uno

The Uno board is the standard Arduino board that most new to the Arduino will choose. It features an ATmega328P processor; 14 digital I/O pins, of which 6 can be used as pulse-width modulation (PWM)1 output; and 6 analog input pins. The Uno board has 32KB of flash memory and 2KB of SRAM.

The Uno is available either as a surface-mount device (SMD) or a standard IC socket. The IC socket version allows you to exchange processors should you desire to use an external IC programmer to build custom solutions. Details and a full datasheet are available at https://store.arduino.cc/usa/arduino-uno-rev3. It has a standard USB type B connector and supports all shields. Figure 6-1 shows the Arduino Uno board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig1_HTML.jpg
Figure 6-1

Arduino Uno Rev3 (courtesy of Arduino.cc)

There is also a version of this board that has a built-in Wi-Fi chip, making it possible for use in sensor networks or situations where using a Wi-Fi shield is problematic (lack of space, conflicts with other shields, etc.). While it is named the same, it differs from the standard Uno in several ways. Aside from the Wi-Fi chip, it has a different processor and one less PWM pin. You can read more about the Uno Wi-Fi board at https://store.arduino.cc/usa/arduino-uno-WiFi-rev2. Figure 6-2 shows the Arduino Uno Wi-Fi board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig2_HTML.jpg
Figure 6-2

Arduino Uno Wi-Fi Rev2 (courtesy of Arduino.cc)

Leonardo

The Leonardo board represents another of the standard boards in the pantheon of Arduino platform. It is a little different in that, while it supports the standard header layout, it also has a USB controller that allows the board to appear as a USB device (e.g., mouse or keyboard) to the host computer. The board uses a newer ATmega32u4 processor with 20 digital I/O pins, of which 12 can be used as analog pins and 7 can be used as a pulse-width modulation (PWM) output. It has 32KB of flash memory and 2.5KB of SRAM.

The Leonardo has more digital pins than the Uno, but continues to support most shields. The USB connection uses a smaller USB connector. The board is also available with and without headers. Figure 6-3 depicts an official Leonardo board. Details and a full datasheet can be found at https://store.arduino.cc/usa/leonardo.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig3_HTML.jpg
Figure 6-3

Arduino Leonardo (courtesy of Arduino.cc)

Due

The Arduino Due is a new, larger, and faster board based on the Atmel SAM3X8E ARM Cortex-M3 processor. The processor is a 32-bit processor, and the board supports a massive 54 digital I/O ports, of which 14 can be used for PWM output; 12 analog inputs; and 4 UART chips (serial ports) as well as 2 digital-to-analog (DAC) and 2 two-wire interface (TWI) pins. The new processor offers several advantages:
  • 32-bit registers

  • DMA controller (allows CPU-independent memory tasks)

  • 512KB flash memory

  • 96KB SRAM

  • 84MHz clock

The Due has the larger form factor (called the mega footprint) but still supports the use of standard shields as well as mega format shields. The new board has one distinct limitation: unlike other boards that can accept up to 5V on the I/O pins, the Due is limited to 3.3V on the I/O pins. Details and a full datasheet can be found at https://store.arduino.cc/usa/due.

The Arduino Due is intended to be used for projects that require more processing power, more memory, and more I/O pins. Despite the significant capabilities of the new board, it remains open source and comparable in price to its predecessors. Look to the Due for your projects that require the maximum hardware performance. Figure 6-4 shows an Arduino Due board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig4_HTML.jpg
Figure 6-4

Arduino Due (courtesy of Arduino.cc)

Mega 2560

The Arduino Mega 2560 is an older form of the Due. It is based on the ATmega2560 processor (hence the name). Like the Due, the board supports a massive 54 digital I/O ports, of which 14 can be used as PWM output, 16 analog inputs, and 4 UARTs (hardware serial ports). It uses a 16MHz clock and has 256KB of flash memory. Details and a full datasheet can be found at https://store.arduino.cc/usa/mega-2560-r3.

The Mega 2560 is essentially a larger form of the standard Arduino Uno and Leonardo but supports the standard shields (as well as “mega” shields). Figure 6-5 shows the Arduino Mega 2560 board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig5_HTML.jpg
Figure 6-5

Arduino Mega (courtesy of Arduino.cc)

Interestingly, the Arduino Mega 256 is the board of choice for Prusa Mendel and similar 3D printers that require the use of a controller board named RepRap Arduino Mega Pololu Shield (RAMPS).

Tip

Notice how much larger the Due is than the Uno. If you choose to incorporate a Due, Mega, or similar board, you may have to set aside more room to mount the board.

Micro

The Arduino Micro is a special form of the Leonardo board and uses the same processor with 20 digital I/O pins, of which 12 can be used as analog pins and 7 can be used as PWM output. It has 32KB of flash memory and 2.5KB of SRAM. Details and a full datasheet can be found at https://store.arduino.cc/usa/arduino-micro.

The Micro was made for use on breadboards in the same way as the Mini but in a newer, updated form. But unlike the Mini, the Micro is a full-featured board complete with USB connector. And like the Leonardo, it has built-in USB communication, allowing the board to connect to a computer as a mouse or keyboard. Figure 6-6 shows the Arduino Micro board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig6_HTML.jpg
Figure 6-6

Arduino Micro (courtesy of Arduino.cc)

Although branded as an official Arduino board, the Arduino Micro is produced in cooperation with Adafruit.

Nano

The Arduino Nano is an older form of the Arduino Micro. In this case, it is based on the functionality of the Duemilanove4 and has the ATmega328 processor (older models use the ATmega168) and 14 digital I/O pins, of which 6 can be used as PWM output and 8 analog inputs. The mini has 32KB of flash memory and uses a 16MHz clock. Details and a full datasheet can be found at https://store.arduino.cc/usa/arduino-nano.

Like the Micro, it has all the features needed for connecting to and programming via a USB connection. Figure 6-7 shows an Arduino Nano board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig7_HTML.jpg
Figure 6-7

Arduino Nano (courtesy of Arduino.cc)

MKR-Series Boards

There is another form of Arduino called the MKR (for “maker”) series. The MKR series includes a variety of boards based on the (now retired Zero) board that have various communication capabilities such as Wi-Fi, LoRa, LoRaWAN, and GSM.

They are based on the Atmel ATSAMW25 SoC (System on Chip) and designed for IoT projects and devices. It also supports cryptographic authentication. For those working on projects that require battery port, the MKR series of boards include a LiPo charging circuit for charging a LiPo battery while running on external power. Details and a full datasheet can be found at https://store.arduino.cc/usa/arduino-mkr1000.

The boards do not use the same pin layout as the Uno-compatible shield-based boards (but you can get an adapter). Rather, they are designed like the Nano and Mini (but a bit larger) to minimize the size of the board to make it easier to incorporate into your projects. In fact, they are one of the boards of choice for Internet of Things (IoT) projects and make an excellent choice for sensor network projects. Since they are relatively new and some have specialized communication options, most new to Arduino would be better served starting with the Arduino boards that support Uno-compatible shields.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig8_HTML.jpg
Figure 6-8

MKR1000 (courtesy of Arduino.cc)

Caution

The MKR boards run on 3.3V power and have a maximum input on the GPIO pins of 3.3V.

Arduino Clones

A growing number of Arduino boards are available from a large number of sources. Because the Arduino is open hardware, it is not unusual or the least bit illicit to find Arduino boards made by vendors all over the world.

Although some would insist the only real Arduinos are those branded as such, the truth of the matter is that as long as the build quality is sound and the components are of high quality, the choice of using a branded vs. a copy, hence clone, is one of personal preference. I have sampled Arduino boards from a number of sources, and with few exceptions, they all perform their intended functions superbly.

Except for the Arduino Mini, the Arduino clone boards have a greater variety of hardware configurations. Some Arduinos are designed for use in embedded systems or on breadboards, and some are designed for prototyping. I examine a number of the more popular clone boards in the following sections.

Arduino Pro Mini

The Arduino Pro Mini is another board from SparkFun. It is based on the ATmega168 processor (older models use the ATmega168) and has 14 digital I/O pins, of which 6 can be used as PWM output, and 8 analog inputs. The Pro Mini has 16KB of flash memory and 1KB of SRAM, and it uses a 16MHz clock. Details and a full datasheet can be found at www.sparkfun.com/products/11113.

The Arduino Pro Mini is modeled on the Arduino Mini and is also intended for use on breadboards but does not come with headers. This makes the Arduino Pro Mini ideal for use in semi-permanent installations where the pins can be soldered to the components or circuitry and space is a premium. Figure 6-9 shows an Arduino Pro Mini board. It really is that tiny.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig9_HTML.jpg
Figure 6-9

Arduino Pro Mini (courtesy of SparkFun)

Also, the Pro Mini does not include a USB connector and therefore must be connected to and programmed with a FTDI cable or similar breakout board. It comes as either a 3.3V model with an 8MHz clock or a 5V model with a 16MHz clock.

Fio

The Arduino Fio is yet another board made by SparkFun. It was designed for use in wireless projects. It is based on the ATmega32U4 processor with 14 digital I/O pins, of which 6 can be used as PWM outputs, and 8 analog pins. Details and a full datasheet can be found at www.sparkfun.com/products/11520.

The Fio requires a 3.3V power supply, which allows for use with a lithium polymer (LiPo) battery which can be recharged via the USB connector on the board.

Its wireless pedigree can be seen in the XBee socket on the bottom of the board. Although the USB connection lets you recharge the battery, you must use an FTDI cable or breakout adapter to connect to and program the Fio. Similar to the Pro models, the Fio does not come with headers, allowing the board to be used in semi-permanent installations where connections are soldered in place. Figure 6-10 shows an Arduino Fio board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig10_HTML.jpg
Figure 6-10

Arduino Fio (courtesy of SparkFun)

Seeeduino

The Seeeduino is an Arduino clone made by Seeed Studio (www.seeedstudio.com). It is based on the ATmega328P processor and has 14 digital I/O pins, of which 6 can be used as PWM outputs, and 8 analog pins. It has 32KB of flash memory and 2KB of SRAM. Details and a full datasheet can be found at www.seeedstudio.com/Seeeduino-V4-2-p-2517.html.

The board has a footprint similar to the Arduino Uno and supports all standard headers. It supports a number of enhancements such as I2C and serial Grove connectors and a mini USB connector, and it uses SMD components. It is also a striking red color with yellow headers. Figure 6-11 shows a Seeeduino board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig11_HTML.jpg
Figure 6-11

Seeeduino (courtesy of Seeed Studio)

Seeed Studio also makes a “mini” version of this board ().

Sippino

The Sippino from SpikenzieLabs (www.spikenzielabs.com) is designed to be used on a solder-less breadboard. It costs less because it has fewer components and a much smaller footprint. It comes unassembled and, if you are learning to solder, can make for a very enjoyable afternoon project.

It is based on the ATmega328 processor and has 14 digital I/O pins, of which 6 can be used as PWM output, and 6 analog input pins. The Sippino board has 32KB of flash memory and 2KB of SRAM. Details and a full datasheet can be found at www.spikenzielabs.com/Catalog/arduino/sippino-prototino-8482/sippino-kit?cPath=1&.

The Sippino does not have a USB connection, so you have to use an FTDI cable to program it. The good news is you need only one cable no matter how many Sippinos you have in your project. I have a number of Sippinos and use them in many of my Arduino projects where space is at a premium. Figure 6-12 shows a Sippino mounted on a breadboard.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig12_HTML.jpg
Figure 6-12

Sippino (courtesy of SpikenzieLabs)

SpikenzieLabs also makes a version with a USB connector (www.spikenzielabs.com/Catalog/arduino/sippino-prototino-8482/sippino8482-usb-kit?cPath=1&).

While you cannot use normal shields with the Sippino, SpikenzieLabs also provides a special adapter called a shield dock that allows you to use a Sippino with standard Arduino shields. The shield dock is an amazing add-on that lets you use the Sippino as if it were a standard Uno or Duemilanove. Figure 6-13 shows a Sippino mounted on a shield dock. Details and a full datasheet can be found at www.spikenzielabs.com/Catalog/spikenzielabs/the-shield-dock.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig13_HTML.jpg
Figure 6-13

Sippino on a shield dock (courtesy of SpikenzieLabs)

Prototino

The Prototino is another product of SpikenzieLabs. It has the same components as the Sippino, but instead of a breadboard-friendly layout, it is mounted on a PCB that includes a full prototyping area. Like the Sippino, it is based on the ATmega328 processor and has 14 digital I/O pins, of which 6 can be used as PWM output, and 6 analog input pins. The Prototino board has 32KB of flash memory and 2KB of SRAM. Details and a full datasheet can be found at www.spikenzielabs.com/Catalog/arduino/sippino-prototino-8482/prototino?cPath=1&.

The Prototino is ideal for building solutions that have supporting components and circuitry. In some ways, it is similar to the Nano, Mini, and similar boards, in that you can use it for permanent installations. But unlike those boards (and even the Arduino Pro), the Prototino provides a space for you to add your components directly to the board. I have used a number of Prototino boards for projects where I have added the components to the Prototino and install it in the chassis. This allowed me to create a solution using a single board and even build several copies quickly and easily.

Like the Sippino, the Prototino does not have a USB connection, so you have to use an FTDI cable to program it. Figure 6-14 shows a Prototino board.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig14_HTML.jpg
Figure 6-14

Prototino (courtesy of SpikenzieLabs)

Metro from Adafruit

The Metro from Adafruit is a set of Arduino-compatible boards supporting a number of formats including several that support Arduino shields. The version I like as a balance of compatibility and cost is the Metro 328 (www.adafruit.com/product/2488). Figure 6-15 shows the Metro 328 board from Adafruit. The board uses the ATmega328P at 16MHz and host of minor improvements to make the Metro an excellent alternative to an Arduino Uno. Check out the product page for more details.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig15_HTML.jpg
Figure 6-15

Metro 328 (courtesy of Adafruit)

Note

Adafruit also has several CircuitPython models. Some are smaller and thus may be an option if you need to minimize the footprint of your node. For more details, see www.adafruit.com/category/966.

There is Even One Made of Paper

Every now and then, you encounter something mundane that’s made truly interesting by a change in medium. Such is the case of the PAPERduino created by Guilherme Martins. The PAPERduino is a minimal Arduino that uses a paper template in place of the PCB. All you need to do is download and print out the templates, purchase a small list of commonly available discrete components, and follow the connection diagram printed on the template to solder the components to short lengths of wire. You can find out more by visiting the following website: http://lab.guilhermemartins.net/2009/05/06/paperduino-prints/.

So, Which Do I Buy?

If you’re wondering which Arduino to buy, the answer depends on what you want to do. For most of the projects in this book, any Arduino Uno or similar clone that supports the standard shield headers is fine. You need not buy the larger Due or its predecessors, since the added memory and I/O pins aren’t needed.

I use the Arduino Uno, Uno Wi-Fi, or Leonardo for all the projects in this book. Although you can use an older board without issues, there are some issues with using the Leonardo board. I point these out as you encounter them. Most issues have to do with the relocated pins on the Leonardo board. For example, the SPI header pins (at upper left in Figure 6-3) have been moved on the Leonardo.

For future projects, there are some things you should consider before choosing the Arduino. For example, if your project is largely based on a breadboard or you want to keep the physical size of the project to a minimum, and you aren’t going to use any shields, the Arduino Mini may be the better choice. Conversely, if you plan to do a lot of programming to implement complex algorithms for manipulating or analyzing data, you may want to consider the Due for its added processing power and memory.

The bottom line is that most of the time your choice will be based on physical characteristics (size, shield support, and so on) and seldom on processing power or memory. SparkFun has an excellent buyer’s guide in which you can see the pros and cons of each choice. See www.sparkfun.com/pages/arduino_guide for more details.

Where to Buy

Due to the popularity of the Arduino platform, many vendors sell Arduino and Arduino clone boards, shields, and accessories. The Arduino.cc website (https://store.arduino.cc/usa) also has a page devoted to approved distributors. If none of the resources listed here are available to you, you may want to check this page for a retailer near you.

Online Retailers

There are a growing number of online retailers where you can buy Arduino boards and accessories. The following lists a few of the more popular sites:
  • SparkFun: From discrete components to the company’s own branded Arduino clones and shields, SparkFun has just about anything you could possibly want for the Arduino platform (www.sparkfun.com/).

  • Adafruit: Carries a growing array of components, gadgets, and more. It has a growing number of products for the electronics hobbyist, including a full line of Arduino products. Adafruit also has an outstanding documentation library and wiki to support all the products it sells (www.adafruit.com/).

You can also visit the manufacturers of some of the clone boards. The following are the leading clone manufacturers and links to their storefronts:

Retail Stores (United States)

There are also brick-and-mortar stores that carry Arduino products. Although there aren’t as many as there are online retailers and their inventories are typically limited, if you need a new Arduino board quickly, you can find them at the following retailers. You may find additional retailers in your area. Look for popular hobby electronics stores:
  • Fry’s: An electronics superstore with a huge warehouse of electronics, components, microcontrollers, computer parts, and more available for order. Fry’s carries Arduino-branded boards, shields, and accessories as well as products from Parallax, SparkFun, and many more (http://frys.com/).

  • Micro Center: Micro Center is similar to Fry’s, offering a huge inventory of products. However, most Micro Center stores have a smaller inventory of electronic components than Fry’s (www.microcenter.com/).

Now that you have a better understanding of the hardware details and the variety of Arduino boards available, let’s dive into how to use and program the Arduino. The next section provides a tutorial for installing the Arduino programming environment and programming the Arduino. Later sections present projects to build your skills for developing sensor networks.

Arduino Tutorial

This section is a short tutorial on getting started using an Arduino. It covers obtaining and installing the IDE and writing a sample sketch. Rather than duplicate the excellent works that precede this book, I cover the highlights and refer readers who are less familiar with the Arduino to online resources and other books that offer a much deeper introduction. Also, the Arduino IDE has many sample sketches that you can use to explore the Arduino on your own. Most have corresponding tutorials on the Arduino.cc site.

Learning Resources

A lot of information is available about the Arduino platform. If you are just getting started with the Arduino, Apress offers an impressive array of books covering all manner of topics concerning the Arduino, ranging from getting started using the microcontroller to learning the details of its design and implementation. The following is a list of the more popular books. Some are a little older than you may expect but still quite useful.
  • Beginning Arduino by Michael McRoberts (Apress, 2010)

  • Practical Arduino: Cool Projects for Open Source Hardware (Technology in Action) by Jonathan Oxer and Hugh Blemings (Apress, 2009)

  • Arduino Internals by Dale Wheat (Apress, 2011)

There are also some excellent online resources for learning more about the Arduino, the Arduino libraries, and sample projects. The following are some of the best:

The Arduino IDE

The Arduino IDE is available for download for the Mac, Linux (32- and 64-bit versions), and Windows platforms. You can download the IDE from http://arduino.cc/en/Main/Software. There are links for each platform as well as a link to the source code if you need to compile the IDE for a different platform.

Tip

Interestingly, there is a web version of the IDE that you can use without installing it on your computer. This may be helpful if you want to use it on a PC where you don’t want (or cannot) install the IDE.

Installing the IDE is straightforward. I omit the actual steps of installing the IDE for brevity, but if you require a walk-through of installing the IDE, you can see the Getting Started link on the download page or read more in Beginning Arduino by Michael McRoberts (Apress, 2010).

Once the IDE launches, you see a simple interface with a text editor area (a white background by default), a message area beneath the editor (a black background by default), and a simple button bar at the top. The buttons are (from left to right) Compile, Compile and Upload, New, Open, and Save. There is also a button to the right that opens the serial monitor. You use the serial monitor to view messages from the Arduino sent (or printed) via the Serial library. You see this in action in your first project. Figure 6-16 shows the Arduino IDE.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig16_HTML.jpg
Figure 6-16

The Arduino IDE

Notice that in Figure 6-16 you see a sample sketch (called blink) and the result of a successful compile operation. I loaded this sketch by clicking FileExamplesBasicBlink. Notice also at the bottom that it tells you that you are programming an Arduino Leonardo board on a specific serial port.

Due to the differences in processor and supporting architecture, there are some differences in how the compiler builds the program (and how the IDE uploads it). Thus, one of the first things you should do when you start the IDE is choose your board from the ToolsBoard menu. Figure 6-17 shows a sample of selecting the board on the Mac.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig17_HTML.jpg
Figure 6-17

Choosing the Arduino board

Notice the number of boards available. Be sure to choose the one that matches your board. If you are using a clone board, check the manufacturer’s site for the recommended setting to use. If you choose the wrong board, you typically get an error during upload, but it may not be obvious that you’ve chosen the wrong board. Because I have so many different boards, I’ve made it a habit to choose the board each time I launch the IDE.

The next thing you need to do is choose the serial port to which the Arduino board is connected. To connect to the board, use the ToolsPort menu option. Figure 6-18 shows an example on the Mac. In this case, no serial ports are listed. This can happen if you haven’t plugged your Arduino in to the computer’s USB ports (or hub), you had it plugged in but disconnected it at some point, or you have not loaded the drivers for the Arduino (Windows). Typically, this can be remedied by simply unplugging the Arduino and plugging it back in and waiting until the computer recognizes the port.

Note

If you use a Mac, it doesn’t matter which port you choose: either the one that starts with tty or the one that starts with cu will work.

../images/313992_2_En_6_Chapter/313992_2_En_6_Fig18_HTML.jpg
Figure 6-18

Choosing the serial port

Tip

See www.arduino.cc/en/Guide/HomePage?from=Guide.Howto if you need help installing the drivers on Windows.

OK, now that you have your Arduino IDE installed, you can connect your Arduino and set the board and serial port. You see the LEDs on the Arduino illuminate. This is because the Arduino is getting power from the USB. Thus, you do not need to provide an external power supply when the Arduino is connected to your computer. Next, you dive into a simple project to demonstrate the Arduino IDE and learn how basic sketches are built, compiled, and uploaded.

Project: Hardware “Hello, World!”

The ubiquitous “Hello, World!” project for the Arduino is the blinking light. The project uses an LED, a breadboard, and some jumper wires. The Arduino turns on and off through the course of the loop() iteration . That’s a fine project for getting started, but it does not relate to how sensors could be used.

Thus, in this section, you expand on the blinking light project by adding a sensor. In this case, you still keep things simple by using what is arguably the most basic of sensors: a pushbutton. The goal is to illuminate the LED whenever the button is pushed.

Hardware Connections

Let’s begin by assembling an Arduino. Be sure to disconnect (power down) the Arduino first. You can use any Arduino variant that has I/O pins. Place one LED and one pushbutton in the breadboard. Wire the 5V pin to the breadboard power rail and the ground pin to the ground rail, and place the pushbutton in the center of the breadboard. Place the LED to one side of the breadboard, as shown in Figure 6-19.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig19_HTML.jpg
Figure 6-19

Diagram of an LED with a pushbutton

You’re almost there. Now wire a jumper from the power rail to one side of the pushbutton, and wire the other side of the pushbutton to (DIGITAL) pin 2 on the Arduino (located on the side with the USB connector). Next, wire the LED to ground on the breadboard and a 150 Ohm resistor (colors: brown, green, brown, gold). The other side of the resistor should be wired to pin 13 on the Arduino. You also need a resistor to pull the button low when the button is not pressed. Place a 10K Ohm resistor (colors: brown, black, orange, gold) on the side of the button with the wire to pin 2 and ground.

The longest side of the LED is the positive side. The positive side should be the one connected to the resistor. It doesn’t matter which direction you connect the resistor; it is used to limit the current to the LED. Check the drawing again to ensure that you have a similar setup.

Note

Most Arduino boards have an LED connected to pin 13. You reuse the pin to demonstrate how to use analog output. Thus, you may see a small LED near pin 13 illuminate at the same time as the LED on the breadboard.

Cool Gadget

One of the coolest gadgets for working with the Arduino is the Arduino mounting plate from Adafruit (www.adafruit.com/products/275).

This small acrylic plate has space for a half-sized breadboard and an Arduino. It even has mounting holes for bolting the Arduino to the plate and small rubber feet to keep the plate off the work surface. The following illustration (courtesy of Adafruit) shows the mounting plate in action.
../images/313992_2_En_6_Chapter/313992_2_En_6_Figa_HTML.jpg

Although you can make your own Arduino mounting plate from Lexan or Plexiglas (I have), the Adafruit product is just a notch better than what you can make yourself. For about US$5.00, you can keep your Arduino and breadboard together and avoid scratches on your table (from the sharp prongs on the bottom of the Arduino)—and, better still, avoid the nasty side effects of accidentally placing a powered Arduino on a conductive surface (never a good idea).

Writing the Sketch

The sketch you need for this project uses two I/O pins on the Arduino: one output and one input. The output pin will be used to illuminate the LED, and the input pin will detect the pushbutton engagement. You connect positive voltage to one side of the pushbutton and the other side to the input pin. When you detect voltage on the input pin, you tell the Arduino processor to send positive voltage to the output pin. In this case, the positive side of the LED is connected to the output pin.

As you can see in the drawing in Figure 6-18, the input pin is pin 2 and the output pin is pin 13. Let’s use a variable to store these numbers so you do not have to worry about repeating the hard-coded numbers (and risk getting them wrong). Use the pinMode() method to set the mode of each pin (INPUT, OUTPUT). You place the variable statements before the setup() method and set the pinMode() calls in the setup() method, as follows:
int led = 13;     // LED on pin 13
int button = 2;   // button on pin 2
void setup() {
  pinMode(led, OUTPUT);
  pinMode(button, INPUT);
}

In the loop() method, you place code to detect the button press. Use the digitalRead() method to read the status of the pin (LOW or HIGH), where LOW means there is no voltage on the pin and HIGH means positive voltage is detected on the pin.

You also place in the loop() method the code to turn on the LED when the input pin state is HIGH. In this case, you use the digitalWrite() method to set the output pin to HIGH when the input pin state is HIGH and similarly set the output pin to LOW when the input pin state is LOW. The following code shows the statements needed:
void loop() {
  int state = digitalRead(button);
  if (state == HIGH) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);
  }
}
Now let’s see the entire sketch, complete with proper documentation. Listing 6-1 shows the completed sketch.
/*
  Simple Sensor - Beginning Sensor Networks Second Edition
  For this sketch, we explore a simple sensor (a pushbutton) and a simple response to sensor input (a LED). When the sensor
  is activated (the button is pushed), the LED is illuminated.
*/
int led = 13; // LED on pin 13
int button = 2;   // button on pin 2
// the setup routine runs once when you press reset:
void setup() {
  // initialize pin 13 as an output.
  pinMode(led, OUTPUT);
  pinMode(button, INPUT);
}
// the loop routine runs over and over again forever:
void loop() {
  // read the state of the sensor
  int state = digitalRead(button);
  // if sensor engaged (button is pressed), turn on LED
  if (state == HIGH) {
    digitalWrite(led, HIGH);
  }
  // else turn off LED
  else {
    digitalWrite(led, LOW);
  }
}
Listing 6-1

Simple Sensor Sketch

When you’ve entered the sketch as written, you are ready to compile and run it. Name the sketch basic_sensor.ino.

Tip

Want to avoid typing all this by hand? You can find the source code on the Apress site for this book.

Compiling and Uploading

Once you have the sketch written, test the compilation using the Compile button in the upper-left corner of the IDE. Fix any compilation errors that appear in the message window. Typical errors include misspellings or case changes (the compiler is case sensitive) for variables or methods.

After you have fixed any compilation errors, click the Upload button. The IDE compiles the sketch and uploads the compiled sketch to the Arduino board. You can track the progress via the progress bar at lower right, above the message window. When the compiled sketch is uploaded, the progress bar disappears.

Testing the Sensor

Once the upload is complete, what do you see on your Arduino? If you’ve done everything right, the answer is nothing. It’s just staring back at you with that one dark LED—almost mockingly. Now, press the pushbutton. Did the LED illuminate? If so, congratulations: you’re an Arduino programmer!

If the LED did not illuminate, hold the button down for a second or two. If that does not work, check all of your connections to make sure you are plugged in to the correct runs on the breadboard and that your LED is properly seated with the longer leg connected to the resistor, which is connected to pin 13.

On the other hand, if the LED stays illuminated, try reorienting your pushbutton 90 degrees. You may have set the pushbutton in the wrong orientation.

Try out the project a few times until the elation passes. If you’re an old hand at Arduino, that may be a very short period. If this is all new to you, go ahead and push that button and bask in the glory of having built your first sensor node!

The next section examines a more complicated sensor node, using a temperature and humidity sensor that sends digital data. As you will see, there is a lot more to do.

Hosting Sensors with Arduino

The digital and analog pins of the Arduino make it an ideal platform for hosting sensors. Since most sensors need very little in the way of supporting components, you can often host multiple sensors on one Arduino. For example, it is possible to host a temperature sensor or even multiple temperature sensors, barometric, humidity, and so on, for sampling weather conditions from a given site.

SparkFun and Adafruit have excellent websites that provide a great deal of information about the products they sell. Often the sensor product page includes links to examples and more information about using the sensor. If you are new to electronics, you should stick to sensors that provide examples of their use. It may sound like cheating, but unless you have a good knowledge of electronics, using a sensor incorrectly can get expensive as you burn your way through a few destroyed components before you get it right.

However, when there is another sensor you want to use, you should examine its datasheet. Most manufacturers and vendors supply the datasheet via a link on the product page. The datasheet provides all the information you need to use the sensor but may not have an actual example of its use. If you are familiar with electronics, this is all you are likely to need.

If you are more of a hobbyist or novice at electronics, check the wikis and forums on Arduino.cc, SparkFun, and Adafruit. These sites have a wealth of information and a great many examples, complete with sample code. If you cannot find any examples, you can try googling for one. Use terms like “Arduino <sensor name> example”. If you cannot find any examples and are not an experienced electronics technician, you might want to reconsider using the sensor.

Another thing to consider is how you connect the sensor to the Arduino. Recall that there are a number of different physical layouts, depending on the Arduino you choose. Thus, you should be familiar with the pin layout of your Arduino when planning your Arduino-hosted sensor nodes. If you are hosting a single sensor with your Arduino, this may not be an issue. By way of example, Figure 6-20 shows an Arduino Leonardo board with the I/O pins highlighted. If you look carefully at your Arduino board, you see abbreviated text next to each pin to indicate its purpose. Some smaller-form-factor Arduino boards may not have room for the labels. In this case, consult the vendor’s product page and print it out for future reference.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig20_HTML.jpg
Figure 6-20

Identifying the I/O pins on an Arduino board

Now let’s put the knowledge you’ve gained from learning about the Arduino to use in building a sensor node with an Arduino and a sensor.

Project: Building an Arduino Temperature Sensor

In this project, you build a more sophisticated Arduino-hosted sensor node. This project not only demonstrates how to host sensors with an Arduino but also provides an example of why you need a microcontroller to host certain types of sensors. In this case, the DHT22 sensor is a digital sensor that has its own protocol, which requires a bit of logic to interpret correctly, thereby making it more complicated to use with an XBee.2 Later, you see an example of a simple analog sensor that you can connect directly to an XBee module.

This project uses a DHT22 temperature and humidity sensor connected to the Arduino via a breadboard. The DHT22 is a simple digital sensor that produces digital signals. It requires a single resistor to pull up from the data pin to voltage. Pull-up in this case makes sure the data value is “pulled up” to the voltage level to ensure a valid logic level on the wire.

Let’s jump right in and connect the hardware.

Note

This example was adapted from an example on the Adafruit website (http://learn.adafruit.com/dht).

Hardware Setup

The hardware required for this project includes an Arduino, a DHT22 humidity and temperature sensor, a breadboard, a 4.7K Ohm resistor (colors: yellow, purple, red, gold), and breadboard jumper wires.

Tip

If you get stuck or want more information, there is an excellent tutorial on Adafruit’s website.

Begin by placing your Arduino next to a breadboard. Plug the DHT22 sensor in to one side of the breadboard, as shown in Figure 6-21. Please refer to this figure often and double-check your connections before powering on your Arduino (or connecting it to your laptop). You want to avoid accidental experiments in electrical chaos theory.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig21_HTML.jpg
Figure 6-21

Wiring the DHT22

Next, connect the power from the Arduino to the breadboard. Use one jumper wire to connect the 5V pin on the Arduino to the breadboard power rail and another for the ground (GND) pin on the Arduino to the ground rail on the breadboard. With these wires in place, you are ready to wire the sensor. You use three of the four pins, as shown in Table 6-1.
Table 6-1

DHT22 Connections

Pin

Connected To

1

+5V, 4.7K resistor between the power supply and the data pin (strong pull-up)

2

Pin 7 on Arduino, 4.7K resistor

3

No connection

4

Ground

Next, connect the ground and power of the sensor to the breadboard power and ground rails. Then connect one wire from the data pin on the sensor to pin 7 of the Arduino. There is one last connection: you use a pull-up resistor of 4.7K Ohm connected to the data wire and the power rail of the breadboard.

Software Setup

To use the DHT22 with an Arduino, you need to have the latest DHT22 library. You can install the library right from the Arduino IDE by searching the library manager. Open the Arduino IDE and then open a new sketch and choose SketchInclude LibraryManage Libraries… from the menu. Figure 6-22 shows the library manager.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig22_HTML.jpg
Figure 6-22

Library manager

It may take a moment for the library manager to connect to the server and download the latest catalog. When it is complete, you can type DHT22 into the text box in the upper right and press ENTER. This will search the library catalog for all of the libraries that match.

Choose the DHT sensor library from Adafruit and click Install. If you are prompted to install the supporting libraries, click Install all to ensure all prerequisites are installed as shown in Figure 6-23.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig23_HTML.jpg
Figure 6-23

Install all libraries

Now that you have the hardware configured and the DHT22 library set up, let’s write some code!

Writing the Sketch

Like any sketch, we need to include some libraries, define some constant, and instantiate the DHT object in the preamble. Here you include the DHT library header, define the data pin for the sensor as pin 7 on the Arduino, add a delay constant of 5 seconds, and instantiate an instance of the DHT class. Since the library supports more than one type of DHT sensor, we also must use the special type declared in the library. For example, to tell the library to use the DHT22 sensor, we set the type to DHT22 accordingly. The following is the preamble for the sketch:
#include "DHT.h"
#define DHTPIN 7          // DHT2 data is on pin 7
#define read_delay 5000   // 5 seconds
#define DHTTYPE DHT22     // DHT 22 (AM2302)
Next, we need to instantiate the DHT class. We do this by passing in the pin we want to use along with the DHT type.
DHT dht(DHTPIN, DHTTYPE);
The DHT22 has its own protocol for communicating data. Fortunately, the libraries from Adafruit make reading from the sensor easy. To read the data, you simply call the appropriate method as shown in Table 6-2 that returns the value so you can save it in a variable.
Table 6-2

Data Methods from DHT Library

Method

Description

dht.readHumidity()

Read the humidity

dht.readTemperature()

Read temperature in Celsius

dht.readTemperature(true)

Read temperature in Fahrenheit

dht.computeHeatIndex(temp_c, humidity, false)

Get heat index in Celsius

dht.computeHeatIndex(temp_c, humidity, true)

Get heat index in Fahrenheit

Knowing that, all we need to do to read the data is call these methods saving the data to variables and then print them out. To make the sketch easy and tidy, we can place this logic in a method named read_data(). Listing 6-2 shows the completed read_data() method.
void read_data() {
  // Read humidity
  float humidity = dht.readHumidity();
  // Read temperature as Celsius
  float temp_c = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float temp_f = dht.readTemperature(true);
  // Check for errors and return if any variable has no value
  if (isnan(temp_c) || isnan(temp_f) || isnan(humidity)) {
    Serial.println("ERROR: Cannot read all data from DHT-22.");
    return;
  }
  // Calculate heat index for Celsius
  float hi_c = dht.computeHeatIndex(temp_c, humidity, false);
  // Calculate heat index for temperature in Fahrenheit
  float hi_f = dht.computeHeatIndex(temp_f, humidity, true);
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print("%, ");
  Serial.print(temp_c);
  Serial.print("C, ");
  Serial.print(temp_f);
  Serial.println("F ");
  Serial.print("      Heat Index: ");
  Serial.print(hi_c);
  Serial.print("C, ");
  Serial.print(hi_f);
  Serial.println("F ");
}
Listing 6-2

The read_data() Method

Notice the code is pretty simple. We just read the values and then use the Serial.print() and Serial.println() methods to write the data to the serial monitor.

The only thing left is the setup() and loop() methods. The setup() method simply initializes the Serial and dht classes. The loop() method uses a delay and calls the read_data() method. Listing 6-3 shows the completed sketch.
/*
  Beginning Sensor Networks Second Edition
  Sensor Networks Example Arduino Hosted Sensor Node
  This sensor node uses a DHT22 sensor to read temperature and humidity printing the results in the serial monitor.
*/
#include "DHT.h"
#define DHTPIN 7          // DHT2 data is on pin 7
#define read_delay 5000   // 5 seconds
#define DHTTYPE DHT22     // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
void read_data() {
  // Read humidity
  float humidity = dht.readHumidity();
  // Read temperature as Celsius
  float temp_c = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float temp_f = dht.readTemperature(true);
  // Check for errors and return if any variable has no value
  if (isnan(temp_c) || isnan(temp_f) || isnan(humidity)) {
    Serial.println("ERROR: Cannot read all data from DHT-22.");
    return;
  }
  // Calculate heat index for Celsius
  float hi_c = dht.computeHeatIndex(temp_c, humidity, false);
  // Calculate heat index for temperature in Fahrenheit
  float hi_f = dht.computeHeatIndex(temp_f, humidity, true);
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print("%, ");
  Serial.print(temp_c);
  Serial.print("C, ");
  Serial.print(temp_f);
  Serial.println("F ");
  Serial.print("      Heat Index: ");
  Serial.print(hi_c);
  Serial.print("C, ");
  Serial.print(hi_f);
  Serial.println("F ") ;
}
void setup() {
  Serial.begin(115200);  // Set the serial port speed
  dht.begin();
  delay(1000);
  Serial.println("Welcome to the DHT-22 Arduino example! ");
}
void loop() {
  delay(read_delay);
  read_data();
}
Listing 6-3

Completed Sketch: Reading a DHT-22 Sensor

If you have not done so already, open a new Arduino sketch by clicking the New menu button or by choosing FileNew. Now you can compile, upload, and test the project. You can name it whatever you like such as dht22_example.ino.

Test Execution

Executing the sketch means uploading it to your Arduino and watching it run. If you haven’t connected your Arduino, you can do that now.

I like to begin by compiling the sketch. Click the check mark on the left side of the Arduino application, and observe the output in the message screen at the bottom. If you see errors, fix them and retry the compile. Common errors include missing the DHT22 library (which may require restarting the Arduino application), typing errors, syntax errors, and the like. Once everything compiles correctly, you are ready to upload your sketch by clicking the Upload button on the toolbar.

Right after the upload completes, open the serial monitor by clicking the button at right on the toolbar. Observe the Arduino messages. Listing 6-4 shows the typical output you should see.
Welcome to the DHT-22 Arduino example!
Humidity: 48.00%, 18.20C, 64.76F
      Heat Index: 17.33C, 63.19F
Humidity: 50.00%, 18.30C, 64.94F
      Heat Index: 17.49C, 63.48F
Humidity: 51.80%, 19.10C, 66.38F
      Heat Index: 18.42C, 65.15F
Humidity: 53.60%, 20.20C, 68.36F
      Heat Index: 19.67C, 67.42F
Humidity: 53.20%, 21.40C, 70.52F
      Heat Index: 20.98C, 69.77F
Humidity: 51.50%, 22.10C, 71.78F
      Heat Index: 21.71C, 71.08F
Humidity: 50.00%, 22.50C, 72.50F
      Heat Index: 22.11C, 71.80F
Humidity: 48.50%, 22.60C, 72.68F
      Heat Index: 22.18C, 71.93F
Listing 6-4

Output of the DHT22 Sensor Sketch

If you see similar output, congratulations! You have just built your first Arduino-hosted sensor node. This is an important step in building your sensor network, as you now have the tools needed to start building more sophisticated, wireless sensor nodes and aggregate nodes for recording sensor data.

Let’s take the Arduino sensor experience one step further and add XBee modules to enable the sensor to be placed away from the Arduino. This effectively demonstrates how an Arduino can remotely host a number of sensor nodes and thus become an aggregate node in a sensor network.

Project: Using an Arduino As a Data Collector for XBee Sensor Nodes

This project combines what you have learned about the Arduino in this chapter and the XBee in Chapters 2 and 4. More specifically, you use an Arduino and a remote sensor that connects the sensor with the Arduino using XBee modules. We will reuse the XBee sensor node from Chapter 4 and use the Arduino to read the data.

XBee Sensor Node

Follow the text from Chapter 4 to create the XBee sensor node. As a reminder, this node is constructed as shown in Figure 6-24.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig24_HTML.jpg
Figure 6-24

XBee sensor node

If you have not configured the sensor node from Chapter 4 or if you need to reset the module, you should begin by ensuring the latest firmware is loaded and use the settings shown in Table 6-3. Note that you do not need the IR setting from Chapter 4, but it’s OK if you want to reuse the module you used in that chapter.
Table 6-3

XBee Sensor Node Options and Values

Code

Setting Name

Description

Value

D3

AD3/DIO3

Trigger analog or digital data recording

2—ADC

ID

PAN ID

Id for the network

8088

IR

I/O Sampling Rate

Time to wait to send data

3A98—15,000ms

NI

Node Identifier

Name for the node

TMP36

V+

Supply Voltage Threshold

Supply voltage

FFFF (always send)

Notice unlike the project from Chapter 5, we must set up the I/O sampling rate. This is because the library we will be using does not have the same ability to search the ZigBee network for our remote node. Rather, in this project, the Arduino will poll until an IO sample is delivered to the coordinator node. Thus, we have seen two different ways to get data from a ZigBee network—requesting data directly from a node (Chapter 5) and polling for data sent from nodes (this chapter).

Coordinator Node

The coordinator node should be configured similarly with the latest firmware loaded and the settings shown in Table 6-4.
Table 6-4

XBee Coordinator Options and Values

Code

Setting Name

Description

Value

ID

PAN ID

Id for the network

8088

NI

Node Identifier

Name for the node

Coordinator

There is no need to install the XBee module just yet. You need to configure its settings. You do that in the next section.

Now, let’s set up the Arduino and XBee.

Arduino with XBee Shield

You can use an Arduino to read the data from the XBee sensor node. This gives you an example of using an Arduino as a data aggregator (collector) of sensor data from XBee sensor nodes. Let’s set up an Arduino with an XBee. This project demonstrates using an Arduino to receive data via XBee, but you can also send data via XBee.

Hardware Setup

The sample setup in this section uses a typical Arduino (Uno, Leonardo, etc.) that supports standard shields. Although it is not expressly necessary to use a shield designed to accept an XBee module, most XBee shields are designed to make the use of the XBee easier. In other words, you don’t have to worry about how to wire the XBee to the Arduino. Figure 6-25 shows an Arduino with an XBee shield from SparkFun.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig25_HTML.jpg
Figure 6-25

Arduino XBee shield (courtesy of SparkFun)

I use this shield to demonstrate how to communicate with an XBee module. If you decide to use another shield, be sure to check that shield’s documentation for examples of how to use it and compare it with the code in this project. Make the appropriate modifications (hardware connections and changes to the sketch) so that your project will work correctly with your shield.

The shield lets you choose to communicate with the Arduino with the onboard serial circuitry (UART3) for the Arduino via digital pins 0 and 1. But these are also the pins used when communicating with the Arduino via USB from the Arduino IDE. Fortunately, the SparkFun XBee shield has a small switch that allows you to choose to use pins 2 and 3 instead. You use this option so that you can write a script to read data from the shield via the XBee and still connect to the Arduino IDE and use the serial monitor. But there is a catch: only one UART is available. You must use the software serial library to simulate a second serial connection. The software serial library is included in the Arduino IDE. You see how to do this in the “Software Setup” section.

Tip

If you are using a different XBee shield, you should consult the documentation on the shield and use the pins as instructed. Some shields are hard wired.

If you do not want to use a shield, you can wire your XBee to an Arduino as you did earlier. In this case, you use an XBee breakout board from SparkFun to mate to a breadboard. Figure 6-26 shows the wiring diagram for wiring the XBee Explorer Regulated breakout board to an Arduino. Notice that you use the 5V pin from the Arduino. If you are using a nonregulated breakout board, you should use the 3.3V pin instead. Always double-check the maximum voltage of any component you use before powering on the project.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig26_HTML.jpg
Figure 6-26

Connecting an XBee to an Arduino via a SparkFun XBee breakout board

Note

Either of these methods will work for this project.

Whichever method you choose, take the XBee coordinator module off your USB adapter and insert it into the XBee shield or the XBee Explorer Regulated breakout board. Now that the hardware is ready, let’s set up your Arduino environment and write a sketch to read the data from the XBee sensor node.

Software Setup

Like most sensors, we need a library to connect to and read the data. Fortunately, there is a nice XBee serial library for Arduino. We install it like we did the DHT22 library by opening a new sketch and choose SketchInclude LibraryManage Libraries… from the menu, then search for XBee, and install the library from Andrew Rapp. Figure 6-27 shows the library manager with the correct library chosen. Install it by clicking Install.
../images/313992_2_En_6_Chapter/313992_2_En_6_Fig27_HTML.jpg
Figure 6-27

Loading the XBee Arduino library

Once the library is installed and you have restarted your Arduino IDE, you can write the script to read the data from the XBee. The library has classes for each of the popular XBee data packets to send and receive data to or from an XBee. This project uses the IO sample class because you know that is the only packet we are interested in using in this project.

You need to create several parts of the sketch. Using the XBee library is easier than writing your own communication methods, but the library has certain setup steps and methods you need to use to read the data packet.

To begin, let’s include the library headers for the XBee and software serial libraries. Recall that the software serial library is part of the Arduino IDE:
#include <XBee.h>
#include <SoftwareSerial.h>
Now you must define the pins you use to communicate to the XBee module. You use the serial monitor as an output device, so you need to use alternative pins. In this case, you use pins 2 and 3 for the receive and transmit connections. You need to define these and initialize the software serial library and use that to communicate to the XBee. The following shows the definitions needed:
uint8_t recv = 8;
uint8_t trans = 9;
SoftwareSerial soft_serial(recv, trans);
Next, you must instantiate the XBee library and helper classes. In this case, you need the helper class for the I/O data sample packet:
XBee xbee = XBee();
ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse();
Now we are ready to write the startup code. For this project, you must initiate the software serial library and pass that to the XBee library for use in communicating with the XBee module. You also need to initialize the default serial class so that you can use print() statements to display the data read in a later portion of the code. The following shows the complete setup() method :
void setup() {
  Serial.begin(9600);
  while (!Serial);   // Leonardo boards need to wait for Serial to start
  soft_serial.begin(9600);
  xbee.setSerial(soft_serial);
}

Notice the line with the while loop. You need to add this for use on Leonardo boards. If you omit this and run the sketch on a Leonardo board, the XBee may fail to work. Add this loop to allow the Leonardo time to start the Serial instance.

Now let’s code the methods you use to read the data from the packet. You learn how to read the packet from the XBee a bit later. First, let’s examine how to get the source address for the data packet. The following shows the code for doing so:
void get_address(ZBRxIoSampleResponse *ioSample) {
  Serial.print("Received data from address: ");
  Serial.print(ioSample->getRemoteAddress64().getMsb(), HEX);
  Serial.print(ioSample->getRemoteAddress64().getLsb(), HEX);
  Serial.println("");
}

Notice that you simply use the ioSample class instance and call the method getRemoteAddress64().getMsb(). Actually, this is a call to a subclass (RemoteAddress64) and its method getMsb(). This returns the most significant byte (high 16 bits) of the 64-bit address. You do the same for the least significant bit with the getRemoteAddress64().getLsb() call. You then print these values, specifying that you want to print them in hexadecimal. If you were reading data from multiple XBee nodes, it would be handy to apply a name to each address, such as “bedroom” or “living room”. I leave that to you as an exercise.

Next, you want to read the data payload. In this case, you want to read the temperature data sent to the XBee coordinator from the XBee sensor node. The following shows the code needed to do this. You use the formulas discussed previously to convert the millivolt value read by the sensor to temperature in Celsius and then convert that to Fahrenheit.
void get_temperature(ZBRxIoSampleResponse *ioSample) {
  float adc_data = ioSample->getAnalog(3);
  Serial.print("Temperature is ");
  float temperatureC = ((adc_data * 1200.0 / 1024.0) - 500.0) / 10.0;
  Serial.print(temperatureC);
  Serial.print("c, ");
  float temperatureF = ((temperatureC * 9.0)/5.0) + 32.0;
  Serial.print(temperatureF);
  Serial.println("f");
}

Finally, you need to read the supply voltage from the data packet. In this case, the supply voltage appears after the data samples. Because you know there is only one data sample (via the analog sample mask), you know that the analog voltage appears right before the checksum. Sadly, there is no method currently to fetch that information from the I/O sample packet in the XBee library. However, all is not lost, because the author of the library stores the data in an array and has supplied a subclass for you to use to fetch the raw data. In this case, you want bytes 17 (most significant byte) and 18 (least significant byte) from the data. You know these are the indexes needed by counting from the byte following the frame type starting from zero. See Table 6-5 for details.

Like the temperature data, you must convert the value read to volts using the formula discussed previously. The following shows the code needed to read, convert, and display the supply voltage for the XBee sensor node. Notice that you shift the most significant byte 8 bits so that you can preserve the 16-byte floating-point value.
void get_supply_voltage() {
  Serial.print("Supply voltage is ");
  int ref = xbee.getResponse().getFrameData()[17] << 8;
  ref += xbee.getResponse().getFrameData()[18];
  float volts = (float(ref) * float(1200.0 / 1024.0))/1000.0;
  Serial.print(" = ");
  Serial.print(volts);
  Serial.println(" volts.");
}

Take some time to examine the calculations. In this example, you convert the voltage read and sent by the XBee sensor node to Celsius and then again to Fahrenheit. You also convert the supply voltage to volts for easier reading. All these values are sent to the serial monitor for feedback during testing.

Once you have those methods implemented, you place the code to read the data from the XBee in the loop() method, calling these methods to decipher the data and print it to the serial monitor.

Because this loop() method is called repeatedly, you use the XBee class method to read the packet and then determine if the packet is the I/O data sample packet. If it is, you read the data from the packet. If it is not, you add some simple error handling so that the Arduino can continue to read data rather than stop. The following shows the completed loop() method:
void loop() {
  xbee.readPacket();
  if (xbee.getResponse().isAvailable()) {
    if (xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE) {
      xbee.getResponse().getZBRxIoSampleResponse(ioSample);
      // Read and display data
      get_address(&ioSample);
      get_temperature(&ioSample);
      get_supply_voltage();
    }
    else {
      Serial.print("Expected I/O Sample, but got ");
      Serial.print(xbee.getResponse().getApiId(), HEX);
    }
  } else if (xbee.getResponse().isError()) {
    Serial.print("Error reading packet.  Error code: ");
    Serial.println(xbee.getResponse().getErrorCode());
  }
}

Notice that in the code you check to see whether the packet is available; if it is, you read it. If the packet read is the right frame type, in this case ZB_IO_SAMPLE_RESPONSE, you read the data from the packet and display it. If it isn’t the right packet, you print out to the serial monitor the frame type of the packet received. If there is an error reading the packet, you capture that in the last else and display the error to the serial monitor.

Notice the contents of the block of code for the ZB_IO_SAMPLE_RESPONSE condition. You begin by initializing the I/O data sample class with the data read, then read the address of the XBee that sent the packet, and then perform the calculations for temperature and reference voltage.

Once you understand the code so far, start a new file and type the information into your new sketch window. Listing 6-5 shows the completed sketch for the Arduino XBee receiver project. This code is also available on the Apress site at the source code link for this book.
/**
  Beginning Sensor Networks Second Edition
  Sensor Networks Example Arduino Receiver Node
  This project demonstrates how to receive sensor data from
  an XBee sensor node. It uses an Arduino with an XBee shield
  with an XBee coordinator installed.
  Note: This sketch was adapted from the examples in the XBee
  library created by Andrew Rapp.
*/
#include <XBee.h>
#include <SoftwareSerial.h>
// Setup pin definitions for XBee shield
uint8_t recv = 2;
uint8_t trans = 3;
SoftwareSerial soft_serial(recv, trans);
// Instantiate an instance of the XBee library
XBee xbee = XBee();
// Instantiate an instance of the IO sample class
ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse();
void setup() {
  Serial.begin(9600);
  while (!Serial);   // Leonardo boards need to wait for Serial to start
  soft_serial.begin(9600);
  xbee.setSerial(soft_serial);
  Serial.println("Hello. Welcome to the Arduino XBee Data Aggregator.");
}
// Get address and print it
void get_address(ZBRxIoSampleResponse *ioSample) {
  Serial.print("Received data from address: ");
  Serial.print(ioSample->getRemoteAddress64().getMsb(), HEX);
  Serial.print(ioSample->getRemoteAddress64().getLsb(), HEX);
  Serial.println("");
}
// Get temperature and print it
void get_temperature(ZBRxIoSampleResponse *ioSample) {
  float adc_data = ioSample->getAnalog(3);
  Serial.print("Temperature is ");
  float temperatureC = ((adc_data * 1200.0 / 1024.0) - 500.0) / 10.0;
  Serial.print(temperatureC);
  Serial.print("c, ");
  float temperatureF = ((temperatureC * 9.0)/5.0) + 32.0;
  Serial.print(temperatureF);
  Serial.println("f");
}
// Get supply voltage and print it
void get_supply_voltage() {
  Serial.print("Supply voltage is ");
  int ref = xbee.getResponse().getFrameData()[17] << 8;
  ref += xbee.getResponse().getFrameData()[18];
  float volts = (float(ref) * float(1200.0 / 1024.0))/1000.0;
  Serial.print(" = ");
  Serial.print(volts);
  Serial.println(" volts.");
}
void loop() {
  //attempt to read a packet
  xbee.readPacket();
  if (xbee.getResponse().isAvailable()) {
    // got something
    if (xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE) {
      // Get the packet
      xbee.getResponse().getZBRxIoSampleResponse(ioSample);
      // Read and display data
      get_address(&ioSample);
      get_temperature(&ioSample);
      get_supply_voltage();
    }
    else {
      Serial.print("Expected I/O Sample, but got ");
      Serial.print(xbee.getResponse().getApiId(), HEX);
    }
  } else if (xbee.getResponse().isError()) {
    Serial.print("Error reading packet.  Error code: ");
    Serial.println(xbee.getResponse().getErrorCode());
  }
}
Listing 6-5

Arduino XBee Receiver

Take some time to ensure that the sketch compiles before you upload it to your Arduino. Remember, once the sketch is uploaded, it begins to run. Save it as xbee_sensor.ino.

Testing the Final Project

To test the project, ensure that you start your Arduino first and then the XBee sensor node. Start the Arduino, upload the sketch, and then turn on the serial monitor. You should observe the link lights on the XBee regulated breakout board flicker as the XBee node is accepted by the coordinator on the Arduino and added to the network. Within about 5 seconds, the XBee sensor node begins sending data. When this occurs, the Arduino sketch should start printing statements to your serial monitor. Listing 6-6 shows an example of the output you should see in the serial monitor.
Hello. Welcome to the Arduino XBee Data Aggregator.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.83 volts.
Received data from address: 13A2004192DB79
Temperature is 11.76c, 53.16f
Supply voltage is  = 3.83 volts.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.82 volts.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.83 volts.
Received data from address: 13A2004192DB79
Temperature is 12.34c, 54.22f
Supply voltage is  = 3.83 volts.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.82 volts.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.82 volts.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.82 volts.
Received data from address: 13A2004192DB79
Temperature is 12.46c, 54.43f
Supply voltage is  = 3.82 volts.
Listing 6-6

Sample Output of the XBee Arduino Sketch

Did you see something similar? If so, you’re doing great work and now have the rudimentary components to build sensor nodes and Arduino-based sensor data aggregators.

If you do not see any output in the serial monitor, do not panic. Instead, double-check that the XBee on your Arduino is plugged in correctly and that you are using the correct pins in the sketch that correspond to how the XBee shield you are using connects to the Arduino (not all shields use pins 2 and 3 like the SparkFun shield). Hint: Check the documentation for your shield.

If all that is correct, make sure you are using the coordinator API firmware on the XBee connected to the Arduino and the router API firmware on the XBee sensor node. If you are still having issues, step back to the previous project to ensure that the sensor node is still working.

You can also try turning off both the Arduino and the XBee sensor node; then turn on the Arduino, wait about 10 seconds, and turn the XBee sensor node back on. Sometimes the handshake process and network join can stall, and nothing happens for a while. Turning an XBee off and back on in this order ensures that it will reattempt to configure.

On the other hand, maybe you are getting data, but it is not correct—the temperature read is far too low for the actual environment. I had this happen once when the wire I was using to connect to the data pin on the TMP36 was accidentally removed. The bottom line is always check and recheck your wiring.

For More Fun

If you would like to expand the project, you can add a second XBee sensor node and modify the Arduino sketch to supply a location for each node. For example, you could label one node “office” and the other “kitchen”. The sketch should record (write to the serial monitor) the location of the sensor along with the sensor data from the XBee.

Component Shopping List

A number of components are needed to complete the projects in this chapter. They are listed in Table 6-5.
Table 6-5

Components Needed

Item

Vendors

Est. Cost USD

Qty Needed

LED (any color)

www.sparkfun.com/products/9592

$0.35

1

Pushbutton (breadboard mount)

www.sparkfun.com/products/97

$0.35

1

Breadboard (not mini)

www.sparkfun.com/products/9567

$5.95

1

Breadboard jumper wires

www.sparkfun.com/products/8431

$3.95

1

www.adafruit.com/product/758

DHT22

www.sparkfun.com/products/10167

$9.95

1

www.adafruit.com/products/385

150 Ohm resistor

Most online and retail stores

Varies

1

4.7K Ohm resistor

Most online and retail stores

Varies

1

10K Ohm resistor

Most online and retail stores

Varies

1

Arduino XBee shield

www.sparkfun.com/products/10854

$24.95

1

XBee-ZB (ZB) series 2, 2.5, or 3

www.sparkfun.com

$25.00+

2

www.adafruit.com

www.makershed.com

TMP36 sensor

www.sparkfun.com/products/10988

$1.50

1

www.adafruit.com/products/165

Breadboard power supply

www.sparkfun.com/products/10804

$14.95

1

Wall power supply (6V–12V)

www.sparkfun.com/products/15314

$5.95

1

0.10mF capacitor

www.sparkfun.com/products/8375

$0.25

1

XBee Explorer Regulated with headers

www.sparkfun.com/products/11373

$9.95

1

Breakaway male headers (optional)

www.adafruit.com/products/392

$4.95

1

Arduino Uno (any that supports shields)

Various

$25.00 and up

1

SparkFun XBee shield

www.sparkfun.com/products/10854

$24.95

1

Soldering iron and solder (optional)

Most online and retail stores

Varies

1

Summary

This chapter covered a lot of ground. You explored the Arduino platform, including the many forms available and how to write sketches (programs) to control the Arduino. I also showed you how to host sensors with the Arduino by using a temperature and humidity sensor.

You applied the information you learned about the XBee in Chapters 2 and 4 to create an XBee sensor node to read temperature data. You then set up an Arduino with an XBee coordinator to receive the sensor data from the XBee sensor node and display it in the serial monitor.

In the next chapter, you will discover various mechanisms for storing sensor data either onboard or in the cloud.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.23.127.197