Arduino For Ham Radio 5 PDF Free
Arduino For Ham Radio 5 PDF Free
Arduino For Ham Radio 5 PDF Free
Copyright© 2014 by
The American Radio Relay League, Inc.
ISBN: 978-1-62595-016-1
First Edition
Second Printing
73,
Glen Popiel, KW5GP
kwSgp@arrl.net
May 2014
About the ARRL
The seed for Amateur Radio was planted in the 1890s, when Guglielmo Marconi began his
experiments in wireless telegraphy. Soon he was joined by dozens, then hundreds, of others who
were enthusiastic about sending and receiving messages through the air-some with a commercial
interest, but others solely out of a love for this new communications medium. The United States
government began licensing Amateur Radio operators in 1912.
By 1914, there were thousands of Amateur Radio operators- hams- in the United States.
Hiram Percy Maxim, a leading Hartford, Connecticut inventor and industrialist, saw the need for an
organization to band together this fledgling group of radio experimenters. In May 1914 he founded
the American Radio Relay League (ARRL) to meet that need.
Today ARRL, with approximately 155,000 members, is the largest organization of radio ama-
teurs in the United States. The ARRL is a not-for-profit organization that:
• promotes interest in Amateur Radio communications and experimentation
• represents US radio amateurs in legislative matters, and
• maintains fraternalism and a high standard of conduct among Amateur Radio operators.
At ARRL headquarters in the Hartford suburb of Newington, the staff helps serve the needs of
members. ARRL is also International Secretariat for the International Amateur Radio Union, which
is made up of similar societies in 150 countries around the world.
ARRL publishes the monthly journal QST and an interactive digital version of QST, as well as
newsletters and many publications covering all aspects of Amateur Radio . Its headquarters station,
WlAW, transmits bulletins of interest to radio amateurs and Morse code practice sessions. The
ARRL also coordinates an extensive field organization, which includes volunteers who provide
technical information and other support services for radio amateurs as well as communications for
public-service activities. In addition, ARRL represents US amateurs with the Federal Communica-
tions Commission and other government agencies in the US and abroad.
Membership in ARRL means much more than receiving QST each month. In addition to the
services already described, ARRL offers membership services on a personal level, such as the Tech-
nical Information Service-where members can get answers by phone, email or the ARRL website,
to all their technical and operating questions.
Full ARRL membership (available only to licensed radio amateurs) gives you a voice in how
the affairs of the organization are governed. ARRL policy is set by a Board of Directors (one from
each of 15 Divisions). Each year, one-third of the ARRL Board of Directors stands for election by
the full members they represent. The day-to-day operation of ARRL HQ is managed by an Execu-
tive Vice President and his staff.
No matter what aspect of Amateur Radio attracts you, ARRL membership is relevant and
important. There would be no Amateur Radio as we know it today were it not for the ARRL. We
would be happy to welcome you as a member! (An Amateur Radio license is not required for Asso-
ciate Membership.) For more information about ARRL and answers to any questions you may have
about Amateur Radio, write or call:
ARRL-the national association for Amateur Radio®
225 Main Street
Newington CT 06111-1494
Voice: 860-594-0200
Fax: 860-594-0259
E-mail: hq@arrl.org
Internet: www.arrl.org
Prospective new amateurs call (toll-free):
800-32-NEW HAM (800-326-3942)
You can also contact us via e-mail at newham@arrl.org
0 r check out the ARRL website at www.arrl.org
CHAPTER 1
Introduction
to the Arduino
The Arduino has become wildly popular among the hobbyist community.
In 2011, there were an estimated 300,000 Arduino boards in use, not counting
the many "clone" boards produced under the Arduino's unique Open Source
licensing model. With its standalone single-board design, the Arduino can
interface with a wide variety of sensors and controls easily and inexpensively.
Based on the Atmel series of microcontrollers, the Arduino, with its onboard
digital and analog 1/0 (input/output), is an easy and inexpensive way to build
extremely versatile electronic projects.
Released under the Open Source Creative Commons Attribution Share-Alike
license, the Arduino is totally Open Source, as described later in this chapter.
From the board designs and schematic files, to the Arduino programs (known as
"sketches") and libraries, everything is Open Source. You are free to do whatever
you desire, as long as you properly credit the authors in your work and share
any changes you make to the existing code and libraries. For the most part, this
means that everything about the Arduino is either free or very low cost.
The Hardware
Although there are now numerous variations on the Arduino, the
most common Arduino, the Uno consists of an Atmel ATmega328 8-bit
microcontroller with a clock speed of 16 MHz. The ATmega328 has 32 KB of
flash memory, 2 KB of static RAM (SRAM), and 1 KB of electrically erasable
programmable read-only memory (EEPROM) onboard. The Arduino has 14
digital 110 pins. Six of these pins can also do pulse width modulation (PWM),
and six 10-bit analog inputs can also be used for digital 110 pins. Two of the
digital pins also directly support external hardware interrupts, and all 24110
pins support pin state change interrupts, allowing external hardware control of
program execution.
Typically powered via the USB programming port, with its low current
drain and onboard power regulator the Arduino is ideally suited for battery
powered projects. The Arduino supports multiple communication protocols,
including standard Serial, Serial Peripheral Interface (SPI), Two-Wire
(also known as Inter-Integrated Circuit or 12C), and 1-Wire. Designed for
expandability, the Arduino 110 and power connections are brought out to a
series of headers on the main board. The header layout is standard among the
majority of the Uno-type boards and many of the basic Arduino add-ons, also
known as shields, can be plugged directly into these headers and stacked one
on top of the other, providing power and 110 directly to the shield without any
additional wiring needed.
Many types of shields are available, including all manner of displays,
Ethernet, Wi-Fi, motor driver, MP3, and a wide array of other devices. My
personal favorite is the prototyping shield, which allows you to build your own
interface to an even wider array of Arduino-compatible components, modules,
and breakout boards. You can find GPS, real time clock, compass, text-to-
speech, and lightning detection modules, for example, along with an endless
1-2 Chapter 1
list of sensors such accelerometers, pressure, humidity, proximity, motion,
vibration, temperature, and many more. We'll explore some of these modules
and sensors in projects presented in later chapters of this book.
History
As living proof that necessity is the mother of invention, the Arduino was
created at the Interaction Design Institute lvrea, in the northern Italian town
of lvrea. Originally designed as an inexpensive Open Source tool for students,
replacing the more expensive and less powerful Parallax "Basic Stamp"
development platform then used by students at the institute, the Arduino began
as a thesis project in 2003 by artist and design student, Hernando Barragan,
designed for a non-technical audience.
This project, known as Wiring, was based on a ready-to-use circuit board
with an Integrated Development Environment (IDE) based on the Processing
language created by Ben Fry and one of Barragan's thesis advisors, Casey
Reas . Wiring was then adapted in 2005 by a team co-founded by another of
Barragan's thesis advisors, Massimo Banzi. This team consisted of Hernando
Barragan, Massimo Banzi, David Cuartielles, Dave Mellis, Gianluca Marino,
and Nicholas Zambetti. Their goal was to further simplify the Wiring platform
and design a simple, inexpensive Open Source prototyping platform to be used
by non-technical artists, designers, and others in the creative field. Banzi's
design philosophy regarding the Arduino is best outlined in his quote "Fifty
years ago, to write software you needed people in white aprons who knew
everything about vacuum tubes. Now, even my mom can program."
Unfortunately, at the same time, due a lack of funding the Institute was
forced to close its doors . Fearing their projects would not survive or be
misappropriated, the team decided to make the entire project Open Source.
Released under the Open Source Creative Commons license, the Arduino
became one of the first, if not the first, Open Source hardware products.
Needing a name for the project, the team decided to name it Arduino after
a local pub named "Bar Di Re Arduino" which itself honors the memory of
Italian King Arduin.
Everything about the Arduino is Open Source. The board designs and
schematic files are Open Source, meaning that anyone can create their own
version of the Arduino free of charge. The Creative Commons licensing
agreement allows for unrestricted personal and commercial derivatives as long
as the developer gives credit to Arduino, and releases their work under the
same license. Only the name Arduino is trademarked, which is why the various
Arduino-compatible boards have names like lduino, Ardweeny, Boarduino,
Freeduino, and so on. Typically these boards are fully compatible with their
official Arduino counterpart, and they may include additional features not on
the original Arduino board.
Massimo Banzi's statement about the Arduino project, "You don't need
anyone's permission to make something great," and Arduino team member
David Cuartielles's quote, "The philosophy behind Arduino is that if you
want to learn electronics, you should be able to learn as you go from day one,
instead of starting by learning algebra" sums up what has made the Arduino
1-4 Chapter 1
at your back, creating code and projects that you can use in your own projects,
saving you weeks and months of development. As you will see in some of the
projects in this book, it takes longer to wire and solder things together than it
does to actually get it working. That is the true power of Open Source, everyone
working together as a collective, freely sharing their work, so that others can
join in on the fun.
1-6 Chapter 1
along unchanged and in its entirety, with credit given to the original creator.
•Attribution-NonCommercial-NoDerivs (CC BY-NC-ND) - This is the
most restrictive of the Creative Commons licenses, only allowing others to
download a work and share them with others as long as they credit the creator.
Works released under this license cannot be modified in any way, nor can they
be used commercially.
The Arduino is released under the Creative Commons Attribution-
ShareAlike (CC BY-SA) license. You can freely use the original design files and
content from the Arduino website, www.arduino.cc, both commercially and
non-commercially, as long as credit is given to Arduino and any derivative work
is released under the same licensing. So, if by chance you do create something
that you would like to sell, you are free to do so, as long as you give the
appropriate credit to Arduino and follow the requirements outlined in the FAQ
on the Arduino website, as you may not be required to release your source code
if you follow specific guidelines. If you include libraries in your work, be sure
you use them within their licensing guidelines. The core Arduino libraries are
released under the LGPL and the Java-based IDE is released under the GPL.
In Conclusion
It is this Open Source licensing that has made the Arduino so popular
among hobbyists. You have the freedom to do just about anything you want and
there are many others developing code and libraries you can freely incorporate
in your code, which helps make developing on the Arduino so much fun. For
example, I know very little about Fast Fourier transforms, but there is a fully
functional library out there just waiting for me to come up with a way to use
it. That's the beauty of the Arduino and Open Source. You don't have to be a
programming genius to create fully functional projects as long as you have the
entire Open Source developer community to draw upon. And, when you do start
creating wonderful new things, remember to share them back to the community,
so that others following in your footsteps can benefit from your work and create
wonderful new things of their own.
References
Arduino - www.arduino.cc
Arduino Shield List - www.shieldlist.org
Atheros Communications - www.atheros.com
Atmel Corp - www.atmel.com
Creative Commons - http://creativecommons.org
GNU Operating System - www.gnu.org
Open Source Initiative - http://opensource.org
Texas Instruments - www.ti.com
Trying to decide which of the various Arduino boards to use in your project
can be confusing. Many versions of the Arduino have been developed since its
creation in 2005, and there is no straightforward way to identify the capabilities
and specifications of each board. In this chapter, we will briefly explore the
various Arduino boards to help you determine which board best suits your
project ideas.
2-2 Chapter 2
Figure 2.3 - Arduino Uno.
2-4 Chapter 2
Figure 2.7- Solarbotics Ardweeny.
2-6 Chapter 2
compatible with most of the Arduino shields designed for the Uno and similar
Arduinos. The Arduino Mega ups the program flash memory to 128 KB, the
SRAM to 8 KB, and the EEPROM to 4 KB.
The Mega was superseded by the Mega2560 and Mega2560 ADK. The 16-
MHz Mega2560 (Figure 2.10) is based on the Atmel ATmega 2560 processor,
with 256 KB of program flash memory. The Mega2560 also adds an additional
digital 1/0 pin that can provide PWM, for a total of 15 PWM outputs. The
Mega2560 ADK adds a USB host port to enable communication with Android
phones for use with Google's Android Accessory Development Kit.
Figure 2.12 -Arduino Esplora. [courtesy Adafruit Industries (product code: 1348)]
2-8 Chapter 2
[ J
[ l
on the Sitara processor include 512 MB of DDR3 RAM, a 10/100 Ethernet port,
four USB 2.0 host ports, along with HDMI video and audio ports.
2-10 Chapter 2
Figure 2.16 - chipKIT Uno32.
the chipKIT board. Unlike the Arduino Uno, to use pins A4 and A5 for PC
communications, jumpers must be set on the chipKIT board. The chipKIT
Uno32 also has a jumper-selectable option to allow the Uno32 to function as
either an SPI Master or SPI Slave device.
Max32 has the same form factor as the Arduino Mega series and is compatible
with many Arduino shields, as well as the larger shields designed for the
Arduino Mega boards. The Max32 has 512 KB of fl.ash program memory and
128 KB of SRAM data memory, but has no onboard EEPROM. The Max32 has
67 digital 1/0 pins, sixteen 10-bit analog-to-digital 1/0 pins than can also be
configured to be digital 1/0 pins, and four hardware serial ports.
As with the chipKIT Uno32, the Max32 is a 3.3 V board. All pins are
5 V tolerant. The chipKIT Max32 also has a jumper-selectable option to allow
the board to function as either an SPI Master or SPI Slave device. As with the
Uno32, five of the digital 1/0 pins can be configured to support pulse width
modulation and five digital 1/0 pins can be configured to support hardware
interrupts for hardware program control. The Max32 also has an onboard real-
time clock calendar (RTCC). To enable the RTCC functions, a 32.768 kHz
crystal must be added to the board in the appropriate location.
The Max32 includes several features not found on the chipKIT Uno32.
These include a USB On-The-Go (OTG) controller that allows the Max32 USB
port to act as a USB device, USB host, or USB OTG host/device. With the
addition of transceiver components, the Max 32 provides a 10/
100 MB/s Ethernet port and two controller area network (CAN) ports. CAN is
2-12 Chapter 2
a networking standard that was originally developed for use in the automotive
industry and is now finding its way into building automation and other
industrial applications.
The Max32 is programmed using the same custom version of the Integrated
Development Environment (IDE) used with the Uno32, the Multi-Platform
Integrated Development Environment (MPIDE). The MPIDE is backward-
compatible with the standard Arduino IDE allowing most sketches written for
the Arduino to run on the Max32.
With so many versions of the Arduino and Arduino-compatible boards, the
comparison chart in Table 2.1 can be used to help you decide which board best
suits your project's needs
References
Adafruit Industries - www.adafruit.com
Arduino - www.arduino.cc
Atmel Corp - www.atmel.com
Atheros Communications - www.atheros.com
Diligent - www.digilentinc.com
Solarbotics - solarbotics.com
SparkFun Electronics - www.sparkfun.com
Texas Instruments - www.ti.com
The power and simplicity of the Arduino is its ability to interface to a wide
variety of sensors and devices. While the list of devices you can interface to an
Arduino is seemingly endless and growing day by day, assembled here is a list
of the various Arduino shields, modules, and devices I have found to be useful
in ham radio projects.
Shields
As you begin to create projects with the Arduino, you may want to start
out with preassembled shields rather than design and wire up individual
modules and devices. Shields are boards designed to plug into the headers on
the Arduino main board and allow instant access to the features on the shield
without having to do any additional wiring. Multiple shields can be stacked one
on top of the other, adding functionality with each stacked shield; however, the
result can become cumbersome rather quickly and there is the risk of pin usage
conflicts between the various shields. Typically, you'll want to have only one or
Figure 3.1 -16 character by 2 line (16x2) LCD display. [courtesy .Adafruit Industries
(product code: 772)]
3·2 Chapter 3
Figure 3.3 - ColorTFT shield. [courtesy Adafruit Industries (product code: 802)]
Relay Shield
Controlling things is one of the reasons we got the Arduino in the first place.
Relays allow you the freedom to control high voltage and high current devices
that otherwise would turn your Arduino into a pile of smoldering mush if you
tried to connect them directly. The DFRobot relay shield (Figure 3.4) allows
you to control four onboard relays and includes test buttons and indicator LEDs.
As with the relay shield, the motor driver shield shown in Figure 3.5 allows
you to control motors from your Arduino. The Arduino motor driver shield can
drive two bidirectional de motors or one bipolar stepper motor.
Audio Shields
At some point you'll want your Arduino to make sounds or play audio in
response to the sensor inputs. With one of the various audio shields, you can
quickly and easily add high quality sound and music to your Arduino sketches.
3-4 Chapter 3
The Adafruit wave shield (Figure 3.6) can play up to 22-kHz, 12-bit WAV audio
files that are stored in the onboard SD memory card. The SparkFun MP3 player
shield can store and play MP3 files from its onboard microSD memory card.
Ethernet Shield
The Arduino Ethernet shield (Figure 3.7) gives your Arduino access to the
Internet. With its powerful libraries and examples, you can tum your Arduino
into a web-enabled simple chat server, web server or telnet client. It can make
WiFi Shield
The Arduino WiFi shield (Figure 3.9) allows your Arduino to connect
Figure3.9-
Arduino WiFi
shield. [courtesy
www.arduino.cc]
3-6 Chapter 3
to IEEE 802.llb/g wireless networks and supports WEP and WPA wireless
encryption. As with the Ethernet shield library, the WiFi library and examples
allow you to turn your Arduino into a web-enabled simple chat server, web
server, or telnet client. It can make http requests and much more. The WiFi
shield also has an onboard rnicroSD adapter that can be used to store files and
other data.
SD Card Shields
The SD card shields such as those shown in Figures 3.10 and 3.11 allow
you to interface standard and rnicroSD cards to the Arduino. With one of these
cards you can add mass-storage capabilities for FAT-16 and FAT-32 file access
and data logging. Some versions of the SD card shields also have an onboard
real-time clock calendar (RTCC) allowing you to timestamp your data and
provide date and time information for your Arduino sketches.
Figure 3.1 O -
Solarbotics
microSD shield.
[courtesy
Solarbotics
(product code:
50833)]
Figure 3.11 -
Adafruit data
logging shield.
[courtesy Adafruit
Industries (product
code: 1141)]
Xbee Shield
The Xbee shield (Figure 3.13) allows an Arduino board to communicate
wirelessly using the ZigBee protocol. ZigBee is based on the IEEE 802.15
standard and is used to create a small "personal area network" suitable
for communication with remote sensors or devices. The Xbee shield can
communicate at a speed of 250 Kb/s at distances up to 100 feet indoors or
300 feet outdoors, and can be used as a serial/USB replacement or in a
broadcast/mesh network.
3-8 Chapter 3
Figure 3.13 - Solarbotics Xbee shield. [courtesy
Solarbotics (product code: 50835)]
Breadboard Shield
As you grow more confident and experienced in your Arduino adventures,
you'll want to be able to prototype and test your designs. For the smaller
projects that only involve a chip or two, I have found the breadboard shield
(Figure 3.16) to be a quick and simple solution. Smaller than a full size
~ a ~ J • ~ a ~ » ~ X • T ~ 7
~ 2 2 i • A a • • C % a & I ~ • ~
~ ~ A 2 a A a ~ a r ~ W ~ • % a X
a a ~ J a m • ~ a s 2 a z i x • ~
~ i 2 ~ • • • • • • x • • • • s •
• ~ ~ a • • • s ~ • a ~ R : • s s
a ~ g ~ • » • 2 ' 2 • • • • a s ~
a ~ m , • ~ i ~ ~ ~ a • • 2 a x I
~ ~ • a ~ 2 a 2 ~ m • • • 2 • s x
m w • • • • 1 o & a •
3-10 Chapter 3
breadboard and without the need for soldering, the breadboard shield allows
quick and simple setup and redesign of your project prior to taking it full scale.
When you're done, just as in a full size breadboard, simply remove the chips
and wires and it's ready for the next project.
Prototyping Shield
The final step in your project will usually require a more permanent solution
involving wiring and soldering components. I have found the easiest method to
interface my projects to the Arduino is to use the prototyping shield
(Figure 3.17). The protoshield brings all of the Arduino pins and voltages to
solder pads with the center of the board laid out like a standard prototyping
board. I like to solder header pins in the prototyping area so that I can wire
the Arduino pins to the header, and then use a connector to interface to my
off-board modules and components. This allows for easy troubleshooting,
reconfiguration, and replacement of the external parts when I happen to let the
smoke out of them occasionally.
Arduino Modules
While shields provide a quick and easy way to interface with the Arduino,
the real fun in the Arduino is interfacing with modules and additional
components. It is here that the real blending of computing and electronics takes
place. With just a handful of modules and parts, you can wire up some pretty
amazing projects. Most of the modules include libraries, which greatly simplify
communication between the Arduino and module, and you can create fully
functional projects in just a matter of hours.
Using individual modules and components also lessens the pain, if and
Displays
There are many display modules available for the Arduino, from the easy
to use basic two line text displays all the way up to the newer color graphic and
ePaper displays.
3-12 Chapter 3
Figure 3.19-16
character by 4 line
(16x4) LCD display.
Figure 3.20 - 16
character by 2 line
LCD display with
12C backpack.
Figure 3.21 - 16
character by 4 line
LCD Display with
PC backpack.
SCL pins, and can share the 12C bus with other devices. As with the standard
Hitachi HD44780-compatible LCD, this display type is available in both 2 and
4-line versions (Figures 3.20 and 3.21).
3-14 Chapter 3
four LED backlight that can be controlled through use of an additional digital
1/0 pin.
• • ••• •111•
••
•• ., .
••
• •
• •
3-16 Chapter 3
Figure 3.27 - 40 Systems uVGA II module.
FTDI Module
The FTDI module (named after the Future Technologies Devices International
- FTDI - chip used on the module), is used to communicate with an Arduino
board that does not support a USB connection, such as the Ardweeny and DC
Boarduino. The FTDI module converts the USB data from your workstation to
standard TTL serial signals used by the non-USB Arduino. See Figure 3.28.
3-18 Chapter 3
two signal voltage levels. The SparkFun logic level converter module shown in
Figure 3.29 can convert between 3.3 V and 5 V levels on four pins (two input
and two output). It can also be used to adapt 1.8 V and 2.7 V devices to 5 V.
Weather Sensors
Many hams have an interest in monitoring weather conditions, whether for
emergency preparedness or just plain old weather watching. The Arduino has a
wide array of sensors that can be used to monitor various weather-related data
such as temperature, relative humidity, barometric pressure, and other weather-
related information.
3-20 Chapter 3
BMP085 Barometric Pressure Sensor
The Bosch BMP085 barometric pressure sensor module measures
barometric pressure from 300 to 100 hPa (hectopascals) with an accuracy of
±1.5 hPa and a resolution of 0.01 hPa. The BMP085 also includes a temperature
sensor with a range of -40 to +85°C and an accuracy of ±2 °C at a resolution
of 0.1 °C. The BMP085 is self-calibrating and operates with a supply voltage
of 1.8 to 3.3 V (some modules also support 5 V) and communicates with the
Arduino using the FC bus. The program libraries for the BMP085 add the
capability to directly calculate altitude from the BMP085 data.
Figure 3.35 - Midnight Design Solutions DDS-60 module using the AD9851 chip.
3-22 Chapter 3
GPS Module
With a GPS module such as the one shown
@Sl<YLAB in Figure 3.36, you can add all of the power of
SKM53 a standard GPS to your Arduino, providing such
information as time (down to 11100 of a second),
1
latitude, longitude, altitude, speed, course, and
l Ill I llllllllllllllllllllilllllll
IIIII Ill III Ill l\I
many other features of a standard GPS. These
HBLAE-133 11294
GPS modules communicate with the Arduino via
a standard serial I/O port, typically with a default
speed of 9600 baud and they output standard
Figure 3.36 - SKYLAB SKM53 GPS module. National Marine Electronics Association (NMEA)
NMEA-0183 messages. The TinyGPS and
TinyGPS+++ program libraries parse the NMEA messages sent by the GPS into
data that can be accessed using simple function calls from within your sketch.
3-24 Chapter 3
Figure 3.40 - INA 169 current sensor
module.
Texas Instruments INA169 chip converts the de current flow across a shunt
resistor into an output voltage that corresponds to 1 V/A (volt per ampere) that
can be read using an analog input pin on the Arduino. Capable of monitoring up
to 5 A at a maximum of 60 V continuously, the load resistor on the module can
be changed to increase or decrease the sensitivity of the sensor.
Bluetooth Module
There are two forms of Bluetooth modules, slave and master. See Figure
3.41. A Bluetooth slave module allows you to pair and connect your Arduino
to a device such as a workstation or cell phone and have the Arduino act as
a mouse, keyboard, or any other human interface device (HID). A Bluetooth
master module allows you to pair and connect multiple Bluetooth slave modules
to your Arduino.
Some of the currently available Bluetooth modules can be switched
between slave and master mode from within your Arduino sketch. The
3-26 Chapter 3
Figure 3.43 - SC card module.
Backed up by a lithium coin-cell battery, the DS 1307 can run and retain data
for a minimum of nine years. The DS 1307 also contains 56 bytes of battery-
backed-up nonvolatile RAM (NVRAM) that can be used to store data. The
newer libraries for the DS 1307 include support for reading and writing to the 56
bytes of NVRAM.
SD Card Modules
SD card readers allow the use of SD and microSD cards with your Arduino
for read/write file access and data logging. While some of the various shields
and other modules include an SD card slot, often you cannot access the SD card
while using the primary device (often a TFf display). By using a standalone
SD card reader (Figure 3.43), you can communicate with the SD card and your
other SPI devices without this limitation. The standard SD and microSD card
modules communicate with the Arduino via the SPI bus and include onboard
level shifters to allow use at 3.3 or 5 V.
3-28 Chapter 3
ground. For many projects, this resolution is more than adequate; however,
there will be occasions where you will want higher resolution on your analog
measurements. In the case of an antenna rotator position sensor, you will want
to read the position from 0 to 360° (or 450° in the case of some rotators). Using
a 10-bit AID, this leaves you with a resolution of about 1°. A 12-bit AID can
provide you with a resolution of about Yio 0 , and a 16-bit AID will provide a
resolution of about Yioo 0 • As you can see, the more bits your AID has, the higher
the resolution. While you may not need that level of resolution, in this case, it
will help to position your antennas more accurately.
The Texas Instruments ADS1015 12-bit AID module can provide a range of
0 to 4096 on four single-ended or two differential inputs with sampling speed
selectable up to 3300 samples per second. The Texas Instruments ADSl 115
16-bit AID module (Figure 3.45) can provide a range of 0 to 65535 on four
single-ended or two differential inputs with sampling speed selectable up to
860 samples per second. Both communicate with the Arduino using the PC bus
and feature six program-selectable gain settings from Y:i to 16, allowing you to
maximize the resolution of the attached sensors. The Arduino program libraries
for these modules allow you to control all of the internal parameters of the AID
chips and make using these modules in your sketches a snap.
Digital-to-Analog Converters
One thing I wish the Arduino had is a digital-to-analog (DIA) converter
output. In my lab, I have built multiple versions of DIA converters for the
Arduino, from a simple 8-bit resistor ladder all the way up to using a serial
DIA converter. Of these versions, I have found the Microchip MCP4725 12-bit
12C DIA converter shown in Figure 3.46 to be the simplest and easiest to use.
Other Devices
There are number of individual chips and components you
may want to use in your Arduino projects. Here are a few that I
keep on hand in my parts supply.
As you may recall, some of the Arduinos and variants do not
have onboard EEPROM memory. To save data such as calibration
settings and other values that you don't want to go away after
a reset or power cycle, you can use a serial EEPROM (Figure
3.47). Available from Atmel and Microchip in sizes from 128 bit
up to 1 megabit, serial EEPROMs communicate with the Arduino
via SPI or FC, are well supported by Arduino libraries and are
Figure 3.47 - Atmel 24C64 64K easy to use.
12C EEPROM.
12C Digital 1/0 Expanders
Sometimes, the 14 pins of digital 1/0 available on the standard
Arduino just aren't enough, and you don't want to splurge for a
Mega or a Due. Using an 8 or 16 pin UO expander chip may just
fit the bill and only cost you a couple of dollars. The Microchip
MCP23008 FC serial I/O expander chip (Figure 3.48) will add eight pins and
the Microchip MCP23017 (Figure 3.49) will add 16 pins of digital UO to your
Arduino. Fully supported by Arduino program libraries, the serial UO expander
chips communicate with the Arduino using the FC bus and have programmable
address settings, allowing for up to eight devices on a single FC bus. This
means you can add up to 64 or 128 pins of digital UO to your Arduino to handle
the biggest of Arduino projects. The MCP23S08 and MCP23S 17 provide
similar capability, but communicate using the SPI bus.
3-30 Chapter 3
Analog Switch Chips
Your project may have a need to switch audio or other analog signals
but you don't want to waste the power and board space on a relay. For these
projects, there are the Analog Devices ADG888 CMOS switch (Figure 3.50)
and the IXYS LCC120 OptoMOS relays (Figure 3.51). The ADG888 is a
double-pole, double-throw (DPDT) CMOS chip designed for high performance
audio switching and has an ultralow "on" resistance of 0.8 n and is capable of
switching up to 400 mA at 5 V. The LCC120 is an optically-driven SPDT MOS
relay that has an "on" resistance of 20 n and is capable of switching 170 mA at
250V.
Other Components
-- ·---~
1:1. 1:1. 1:1. 1:1. In the area of general components, I also recommend
a stock of LEDs (red, green, blue, white, RGB, bar graph,
7-segment, and 8x8 array), diodes (silicon, Schottky,
Zener, and photo), 2N2222 and 2N3055 transistors for
Figure 3.54 - 7 Segment LED display. relay driving and other high current needs, photoresistors,
capacitors (both ceramic and electrolytic), and 4N25
optoisolators to provide switching isolation between the
Arduino and things such as rig-keying circuits.
- -~ . ~!' ~:;.
Don't forget an assortment of switches. In addition to
the standard mini switches, I like to keep a couple binary
' ' ' coded decimal (BCD) switches (Figure 3.58) on hand,
~
' ·~ . ~ .L.
to allow me to use one switch and four digital 1/0 pins
~ .: ' L!.
- - =~ to select up to 16 settings. It's also good to have some op
~ 1 ~.. r: ... . l .• amps on hand. I prefer the LM324 dual op-amp, and for
power audio applications I like the LM386 audio amplifier
! r,_e 'l~
-- chip. No parts bin would be complete without a couple
~ ~ .~ H LM555 timers and NE567 PLL tone decoder chips.
, For my projects involving Arduino protoshields, I
... -
I like to use the DuPont-style 2.54 mm-spacing pins and
housings, which allow you to easily disconnect the external
components as needed.
Figure 3.55 - 8x8 LED matrix.
3-32 Chapter 3
Figure 3.56 - Zilog passive infrared motion detector
module.
MEAS
3-34 Chapter 3
Figure 3.62 - SparkFun clear enclosure for
pcDuino/Arduino (product code: PRT-11797).
3-36 Chapter 3
Figure 3.70 - Zigo Arduino Mega enclosure.
References
4D Systems - www.4dsystems.com.au
Adafruit Industries - www.adafruit.com
AMS - www.ams.com
Analog Devices - www.analog.com
Arduiniana - www.arduiniana.org
Arduino - www.arduino.cc
Atmel Corp - www.atmel.com
Bosch - www.bosch-sensortec.com
Crisp Concept - www.crispconcept.com
D&D Engineering - sensorguys.com
Grand Idea Studio - www.grandideastudio.com
IXYS Integrated Circuits - www.ixysic.com
Maxim Integrated - www.maximintegrated.com
Microchip Technology - www.microchip.com
Midnight Design Solutions - www.midnightdesignsolutions.com
Parallax - www.parallax.com
Pololu Robotics and electronics - www.pololu.com
RadioShack - www.radioshack.com
Skylab Technology Company - www.skylab.com.cn
Solarbotics - www.solarbotics.com
SparkFun Electronics - www.sparkfun.com
STMicroelectronics - www.st.com
Texas Instruments - www.ti.com
Tindie - www.tindie.com
Wikipedia - www.wikipedia.com
ZiGo - www.zigo.am
The ability of the Arduino to interface with so many different sensors and
devices is one of the main reasons for its popularity. The primary methods of
I/O on the Arduino are digital I/O, digital I/O with pulse width modulation
(PWM), analog input, and TTL/USB serial communication. The Arduino
supports several bus-type protocols, including the Serial Peripheral Interface
(SPI), Inter-Integrated Circuit (FC), and 1-Wire. The Arduino also supports
hardware and software interrupts, which allow program execution flow to be
changed (interrupted) by an external event.
Digital 1/0
The simplest and most common form of I/O on the Arduino is done using
the digital I/O pins. Using the onboard digital I/O pins, the Arduino can tum
on LEDs, relays, and other external devices with a single pin as well as sense
a switch, pushbutton, or other form of on-off (digital) input. Taken to the next
level, there are several program libraries for the Arduino that allow you to use
digital I/O to emulate TTL serial or SPI communication on pins other than the
pins designated for hardware serial and SPI communications. The Arduino
Analog Input
The Arduino Uno has six analog input pins. These pins convert an input
of 0 to 5 V (3.3 Von the 3.3 V Arduinos) into a 10-bit value of 0-1023. The
range can be modified either using an external reference voltage or selecting an
internal reference voltage of 1.1 V. The Arduino Mega also supports an internal
reference voltage of 2.56 V. The Arduino Leo, Mega, and Due each have 12
analog inputs onboard. The Arduino analog 1/0 pins also have an internal
pull-up resistor (normally disabled) that can be enabled via software. On the
Arduino Uno, Mega, and Leo the value of the pull-up resistor is 20 kn to
50 kn. On the Arduino Due, the value of the pull-up resistor is 100 kn.
Serial 1/0
The Arduino Integrated Development Environment (IDE) on your PC
communicates with the Arduino via the hardware serial port. Most Arduinos
communicate with the IDE via the USB connector. However some Arduinos,
such as the Solarbotics Ardweeny, require a USB-to-TTL serial converter
(FTDI module) to access the serial port. The USB port shares the hardware
serial port, located on pins 0 and 1 on the Arduino Uno.
The IDE can be used to upload sketches and also has a Serial Monitor
option that allows you to view the serial port data and to send serial data to the
Arduino. Because the Uno shares the serial port with the USB port, only one of
the two can be active at a time. To get around this limitation, you can use the
Software Serial program library, which allows you to assign any pair of
digital 1/0 pins as a software-driven serial port.
The Digilent chipKIT Uno32 has two hardware serial ports while the
Arduino Mega and Due each have four hardware serial ports onboard.
1 ·Wire Communications
The 1-Wire Interface was designed by Dallas Semiconductor Corp (now
part of Maxim Integrated Products) to provide low-speed data signaling and
power over a single data line. Typically used to communicate with small devices
such as temperature sensors, voltage sensors, current sensors, memory, and
4-2 Chapter 4
other devices, the 1-Wire interface is actually a bus architecture implemented
with a single wire. With a data rate of up to 16.3 Kb/s, the 1-Wire bus can
communicate reliably with devices over 100 meters away from the host.
Each 1-Wire device has its own unique 64-bit serial number embedded
in the device, allowing many 1-Wire devices to be attached to the same bus
without the need to configure the device. Using an advanced algorithm, the host,
also known as the bus master, can quickly identify all of the devices attached
to the bus and determine their type based on the device type embedded in the
lower 8 bits of each device's serial number. This algorithm can scan the 1-Wire
bus and identify up to 75 sensors per second.
A unique feature of the 1-Wire interface is that many 1-Wire devices can be
powered entirely from the data line and do not need a separate supply voltage
to operate. Known as "parasitic power," a small capacitor (typically 800 pF) is
integrated within the device to store enough of a charge to operate the device
interface.
MaxDetect also makes a series of relative humidity and temperature sensors
that use a proprietary 1-Wire interface. The MaxDetect I -Wire interface is not
a bus architecture and the MaxDetect devices do not have embedded addresses,
meaning that you can only have one device attached to the interface at a time.
The MaxDetect 1-Wire interface does not support parasitic power mode and
must be supplied power on a pin separate from the data pin. The MaxDetect
1-Wire interface is not compatible with the Dallas Semiconductor 1-Wire bus,
so care must be taken when mixing these devices in your projects.
Both types of 1-Wire interfaces are supported by Arduino example sketches
and libraries, which makes interfacing and using 1-Wire devices in your
Arduino projects simple and easy.
4-4 Chapter 4
with FC devices on those pins using software-based timing of the FC signals
(also known as bit-banging). With this method, the digital 1/0 pins are turned
on and off manually to simulate the hardware timing needed to communicate
with the device. While this method does work, it requires all of the bit timing
and clocking to be performed in software, which is much less efficient than
the hardware-based FC method. It is far better to design your projects to use
hardware FC and use software FC communication only when required.
Interrupts
While not a true 1/0 method, interrupts allow external conditions and
events to modify the way your sketches execute. The Arduino has two types
of interrupts - hardware and timer. Hardware interrupts are triggered by
an external event, such as a change in voltage level on a digital 1/0 pin. An
interrupt will pause the current program execution and execute a user-defined
function, known as an interrupt handler or interrupt service routine (ISR). When
the ISR is complete, program execution resumes the program at the command
that was executing prior to the interrupt. An interrupt can happen at any time
and allow you to respond to external events without constantly checking to see
if the desired condition exists.
There are four types of interrupt conditions that can be defined: Rising,
Falling, Change, and Low. These interrupts conditions refer to the state of the
digital 1/0 pin. The Rising condition will generate an interrupt when the pin
goes from a low state to a high state; Falling will generate an interrupt when
the pin goes from high to low. Change will generate an interrupt when the pin
changes from either low to high or high to low. The Low condition will generate
an interrupt when the pin is low. The Arduino Due has an additional interrupt
condition, High, which generates an interrupt when the pin is high.
The Arduino Uno has two interrupts, assigned to digital 1/0 pins 2 and 3.
The Arduino Leo has four interrupts, on pins 0, 2, 3, and 7, the Arduino Mega
has six interrupts, on pins 2 and 3 and 18 to 21. The Arduino Due allows you
to configure interrupts on all available pins. The Arduino Uno can also handle
Change interrupts on all 1/0 pins, but unlike the hardware interrupts, the ISR
function must decode the interrupt and determine which pin generated the
interrupt.
The Arduino Uno has three internal timers, defined as TimerO, Timerl,
and Timer2, which can be used to generate Timer interrupts. TimerO is
an 8-bit timer which is used by the Arduino for internal timing functions such
as delay ( ) and mi 11 is ( ) . Since it can affect these functions, modifying
Timer 0 settings is not recommended. Timer 1 is a 16-bit timer which is
used by the Arduino Servo library, and Timer2 is an 8-bit timer used by
the Arduino tone () function. As long as you are aware of any potential
interaction with these functions, you can modify the settings on Timer 1 and
T imer2 for use in your sketches. The Mega2560 has three additional 16-bit
timers- Timer3, Timer4, and Timers - which are not used by any
Arduino internal functions.
You can configure the timers to generate a software interrupt on overflow
or when the timer count matches a desired value. The timers are based on the
References
1-Wire.org - www.1wire.org
Arduino - www.arduino.cc
D&D Engineering - sensorguys.com
Diligent - www.digilent.com
Maxim Integrated - www.maximintegrated.com
NXP Semiconductor - www.nxp.com
Solarbotics - www.solarbotics.com
4-6 Chapter 4
CHAPTER 5
Arduino Development
Environment
..
U) ~··J ~ A $ln~! ~, Jl ;
<
f,Jc(u1!t Jr.j~9l!>_~Y_!'!IDOx~ , C>xft _,_.
. ;- ~:
" ·:·.: .~ . -.:-• ... ~ . _,
Figure 5.1 - Sample screen from the Arduino Integrated Development Environment.
Menus
The FILE menu of the IDE is the usual area where you can create new
sketches, load and save sketches, print sketches, and set your IDE preferences.
The FILE menu also has a quick-access dropdown menu that lists the programs
in your sketchbook (the folder where the IDE stores your Arduino projects).
Another quick-access dropdown menu provides quick access to example
sketches that are typically provided with the various libraries installed in the
IDE. At the time this was written in early 2014, these dropdown menus don't
have scrolling capability due to a bug between the IDE and Java. There is an
enhanced version of the IDE in the Arduino forum (http://forum.arduino.cc/
index.php?topic=ll8440.0) that you can download and install, or you can use
the standard FILE/OPEN menu to select the desired sketch.
In addition to standard editing menu features, the EDIT menu allows you
to copy your sketch to your workstation's clipboard and reformat the text,
including the syntax coloring, in a form suitable for posting in the Arduino
forums and in an HTML format suitable for posting on web pages.
The SKETCH menu allows you to verify and compile your sketch as well
as providing a quick method to display the contents of the sketch folder on
your workstation. The SKETCH menu also allows you to add other code into
your project, which appears on separate tabs in the IDE text editing area. This
allows you to easily merge pre-existing sketches and code into your current
project. These added files can be Arduino code, C code (.c files), C++ code
(.cpp files), or header files (.h files). Also on the SKETCH menu is the IMPORT
LIBRARY function, which will install the selected library into the IDE and add
the #include declaration for the selected library at the start of your sketch.
Starting with IDE Version 1.0.5, you can also import libraries in .ZIP format.
The TOOLS menu is where you select the type of Arduino board you will
5-2 Chapter 5
be programming and which serial port the board is attached to. If you don't
set these to the proper board and port, your sketch will verify and compile, but
the upload will fail. You can also add support for third-party hardware (such as
variant boards) by placing their board definitions, core libraries, bootloaders,
and programmer definitions into a sub-folder in the hardware folder in your
sketchbook. You can create the hardware folder if it does not exist and the IDE
will incorporate the new board into the IDE menus the next time the IDE starts.
A handy feature on the TOOLS menu is the AUTO FORMAT option. This will
reformat the text in your sketch so that the curly braces all line up and the text
within the braces is properly indented, making your programs easier to read,
which will help when troubleshooting your sketches. Another helpful utility on
the TOOLS menu is the ARCHIVE SKETCH option. This will create a copy of your
current sketch and save it in the current sketch folder as a compressed .ZIP file.
Also on the TOOLS menu you will find options to select the hardware
programmer used to upload and save your sketch. You will usually only need
to change this option when you are programming a board or chip that does not
use an onboard USB/serial port. This setting is typically used when burning the
Arduino bootloader. Since most of the Arduino boards you will be working with
already have a bootloader, the only time you will have to bum the bootloader
is if you are trying to recover an Arduino that has lost its bootloader or you are
programming a chip that does not already have a bootloader installed.
One of the most important options on the TOOLS menu is the SERIAL
MONITOR. The SERIAL MONITOR will display serial data sent from the Arduino.
Typically the SERIAL MONITOR is used to show basic program output and provide
debugging information. You can also use the SERIAL MONITOR to send characters
and commands to the Arduino serial port.
Arduino Libraries
Libraries are what make the Arduino so easy to program. Many of the
shields and devices you can attach to the Arduino are supported by program
libraries. By using an existing library, a large percentage of the programming
needed for a project is already done for you. Think of libraries as the core
building blocks of your Arduino sketches. All you have to add is a little "glue"
to tie the libraries into your project and you're done. This will save you hours
and days of deciphering datasheets and writing test code just to interface to a
new device. Now, all you have to do is get the library for the device, look at the
example code that comes with most libraries and start writing your sketch. In
many cases, you can cut and paste parts of the example sketch into your sketch
and have a completed, working project in a matter of hours.
There are many "official" libraries that come integrated with the Arduino
IDE when you install it, as well as a large number of "unofficial" libraries,
created and shared by the vast community of Arduino developers. Herein
lies the true power of the Open Source community. Because the Arduino is
Open Source, there are many hobbyists just like yourself out there, creating
projects with the same devices you are. Many of these hobbyists freely share
their projects and libraries, saving you from having to create your own. Since
everything is Open Source, you can take someone else's library and modify it
Internal Libraries
The Arduino IDE includes 16 libraries when it is installed. These libraries
are:
EEPROM - contains a set of functions for reading and writing data to the
Arduino's internal EEPROM memory.
Esplora - contains a set of functions for interfacing with the sensors and
switches on the Arduino Esplora board.
Ethernet - contains a set of functions for using an Arduino with an
Ethernet shield to connect to the Internet. The library allows you to configure
the Arduino to function as either a web server or as a web client.
Firmata - contains a set of functions to implement the Firmata
communications protocol for communicating between Arduino sketches and the
host computer.
GSM - contains a set of functions for using an Arduino with a GSM
shield. This allows the Arduino to act as a GSM phone, placing and receiving
calls and SMS messages, and connecting to the Internet over the GPRS
network.
Liquid Crystal - contains a set of functions for communicating with
Hitachi HD44780-compatible parallel LCD displays.
Robot_ Control - contains a set of functions to interface with peripherals
and devices on the Arduino robot control board.
Robot_Motor - contains a set of functions to inte1face with the Arduino
motor control board.
SD - contains a set of functions for reading and writing SD memory cards.
Servo - contains a set of functions to control servo motors.
SoftwareSerial - contains a set of functions to allow the use of serial
communications on 1/0 pins other than those normally used for serial
communication.
SPI - contains a set of functions used to communicate with SPI devices.
Stepper - contains a set of functions to control unipolar and bipolar
stepper motors.
TFT - contains a set of functions to draw shapes, lines, images, and text
on a thin-film-transistor (TFT) display.
WiFi - contains a set of functions to allow an Arduino with a WiFi shield
to connect to the Internet. The library allows you to configure the Arduino to
function wirelessly as either a web server or as a web client.
Wire - contains a set of functions to communicate with 12C devices.
Contributed Libraries
These are also a number of contributed libraries available on the Arduino
Playground website (http://playground.arduino.cc). The Playground is where
Arduino users can gather and share their thoughts, ideas, suggestions, and
Arduino code. There is a huge amount of information on the Playground Wiki,
5-4 Chapter 5
including tutorials, how-tos, tips, tools, and libraries. Some of the contributed
libraries you may want to use in your projects are:
Adafruit_GFX - contains a set of functions to draw shapes, lines, images,
and text on Adafruit graphics displays.
AS3935 - contains a set of functions for communicating with the AS3935
Franklin lightning detector.
Bounce - used to debounce digital inputs.
CapacitiveSensor - allows you to tum two Arduino 1/0 pins into a
capacitive touch sensor.
FFT - contains a set of math functions allowing you to perform fast
Fourier transform (FFT) operations on your data.
Flash - contains a set of functions to store static strings, arrays, tables, and
string arrays in flash memory.
GLCD - contains a set of functions to support a large number of graphic
displays, including functions to draw shapes, lines, images, and text.
LCD_12C - contains a set of functions for communicating with Hitachi
HD44780-compatible PC LCD displays.
Messenger - used to parse serial text sent to the Arduino and place the
received data into an array.
Morse - generates Morse code from standard text.
OneWire - used to communicate with devices from Dallas Semiconductor
(now Maxim Integrated) using the 1-Wire protocol.
PCD8544 - contains a set of functions to draw shapes, lines, images, and
text on the Nokia 5110 LCD display.
PString - contains a set of functions to format text for output.
PS2Keyboard - used to interface a PS/2 keyboard to the Arduino.
Streaming - provides a set of functions to implement Java/VB/C#/C++
style concatenation and streaming operations.
Time - contains a set of timekeeping functions to allow your sketches to
keep track of time and dates with or without external hardware timekeeping.
Timer - used to create and manage software Timer interrupts.
TinyGPS and TinyGPS++ - provides a set of functions for
communicating with a serial GPS module.
Webduino - allows you to configure the Arduino with a Wiznet-based
Ethernet shield to function as an extensible web server.
XlO - enables communication with XlO home automation devices.
Xbee - enables communication with Xbee wireless devices.
5-6 Chapter 5
+5V
I- - - - -SCL
,-----SDA R1 3
I AREF 4.7 kO
U2
2
I I GND
U2_1W DS18B20
RESERVED I I D13
IOREF D12
RESET
I I D11
3V I I D10
5V I I U1 D9
GND2
I I Arduino D8 +5V
D1 GND1
I I Uno R3
VIN D7
1N4001 I I D6 +12 Vdc
AO I I D5
LS1
In
A1
I I D4
C1 JP1
A2 D3
A3
I I D2
To
A4/SDA- J I D1
2
12Vdc
Fan
01
A5/SCL- - J DO TIP31
ARRL1169
to the schematic and follow it step-by-step. This helps prevent wiring errors and
helps you to find any circuit design errors you may have overlooked. Having a
schematic has saved me more than once, as I was one wire away from hooking
12 V to a 5 V AID input before a recheck of the schematic diagram showed me
the errors of my ways. I'm sure that $15 AID module was happy I stopped to
draw a schematic.
You don't have to go into every detail, and you don't have to go so far as to
draw a full schematic with every pin labeled (although it does help). Instead,
you can just use block diagrams. You know an FC device will always need the
power, ground, SDA and SCL lines connected, so you can just draw one line
to represent those items. As you build more projects and become familiar with
the components you often use, you can use this form of shorthand to streamline
your creative process.
If you want to use a more formal method to create your circuit diagrams,
you can use the free version of CadSoft's EaglePCB software, or the Open
Source Fritzing program. Both allow you to create schematic drawings, board
layouts, parts lists, and can even generate a file you can use to have your project
commercially etched onto a circuit board. Fritzing has a unique feature that
allows you to create a breadboard image such as the one shown in Figure 5.4,
which will automatically draw a schematic that you can use to wire your circuit
on an actual breadboard. All you have to do is match up the breadboard image
ARRL1099
1!2====·=· -·=·-·------t- -c:-c:_===-====
D1 1 N4001
Figure 5.4 - Fritzing diagram example for the circuit shown in Figure 5.3.
to your real breadboard circuit. When you're ready to start soldering, just print
the schematic image and you 're good to go.
The method you choose to plan your projects is a matter of personal choice,
so use the method that works best for you. The key is to take the time to plan
everything out ahead before you begin constructing your project or coding
your sketch. A little bit of planning and documentation upfront can help keep
you from soldering or coding yourself into a comer and getting frustrated.
Remember, this is supposed to be fun. Using flowcharts and schematics can
help keep things organized and fun.
5-8 Chapter 5
pgmspace. h library in your sketch. The pgmspace library allows you to
store static variables, constants, strings, and arrays in flash memory instead
of RAM. You can also use the FLASH library to store string, array, table, and
string arrays in flash. Finally, you can also use the F ( ) syntax for storing
string constants in flash. Remember, if it goes into flash, it cannot be modified
during program execution, so you can only use these functions for data that
doesn't change.
References
Arduiniana - www.arduiniana.org
Arduino - www.arduino.cc
Arduino Playground - playground.arduino.cc
CadSoft - www.cadsoftusa.com
Firmata - www.firmata.org
Fritzing - www.fritzing.org
Smarthome - www.smarthome.com
XlO - www.xlO.com
Arduino Development
Station
As you begin to create your own Arduino projects, you will quickly find
that connecting all the pieces and parts together with jumper wires on a table
top doesn't quite do the job. It's all too easy for something to move, fall on
the floor, or short out and fry something. In true obedience to Murphy's Law,
that fried component will be the most expensive or irreplaceable part in your
entire project. Fortunately, the Arduino's size makes it ideal to create a mini-
development station that can be set aside without having to tear apart your half-
built projects in between development sessions.
Using a small piece of wood, you can tum your Arduino development
environment into a stable, portable platform that can be moved and put away
in between development sessions without having to take it all apart. Figure 6.1
shows my Arduino development station. Mounted on a 12 inch by 15 inch board,
I have included everything I use on a regular basis when developing my projects.
6-2 Chapter 6
Figure 6.4 - Hot air soldering station
Soldering Tools
For most of my life, I have used the old standard soldering pencil, which
has served me well over the years. When I tried my hand at soldering surface-
mount components, I failed miserably with the soldering pencil and borrowed
a soldering station with a hot air gun. While my first attempt at surface-mount
soldering with the hot air gun is not something that will ever be seen in public,
it became obvious that a temperature-controlled soldering station with a hot
air gun attachment was the way to go. For about $75, I bought a temperature-
controlled soldering iron station (Figure 6.4) with a hot air gun for whenever
I get brave enough to make another attempt at soldering
surface-mount components. The iron has interchangeable tips,
allowing me to quickly switch between tiny circuit board work
and welding coax connectors. Don't get impatient like me;
be sure to allow the soldering iron to cool before changing
tips. The hot air gun also comes with interchangeable nozzles,
allowing you to vary the size and pattern of the hot air. The hot
air gun also does great work on heat-shrink tubing and testing
temperature sensors.
Test Equipment
Regardless of how you create your projects, at some point
you will need to troubleshoot them. You don't have to spend
a ton of money on test equipment, but there is some basic
equipment you will want to have as you start creating your own
circuit designs.
Primarily, you will want a digital multimeter (DMM) such
as the one shown in Figure 6.5, which allows you to read volts,
Figure 6.5 - Digital multimeter. ohms, amps, and check circuit continuity. It doesn't have to be
6-4 Chapter 6
Figure 6.7 - USB oscilloscope [Pat Vickers, KD5RCX, photo]
References
Arduino Playground - playground.arduino.cc
Diligent - www.digilent.com
Instructables - www.instructables.com
1-.
Start
Include Libraries
Define Variables
2
Setup 1 C LCD
I•
,r
Setup
Loop
Arduino Uno
Potentiometer
ARRL 1090
7-2 Chapter 7
Using the Open Source Fritzing design tool, I created a visual representation
of how the project would be laid out on my breadboard (Figure 7.3). One of the
things I like about Fritzing is the way that you can visually create your design
as it would appear in real life, and Fritzing will draw the schematic for you.
Another handy feature of Fritzing is that it can create a Bill of Materials from
your finished diagram, so you'll know what parts you'll need to create your
project without having to keep track of all the individual parts manually.
Once I had created my Fritzing diagram, I printed out the breadboard
diagram and I was ready to begin creating my project. While it takes a while
to get used to laying out a project with Fritzing so things make sense, and
you may have to design some of your own icons for parts not in the Fritzing
component library (it's not that hard to do), Fritzing is a great tool to create
your breadboard diagrams. All you have to do is match your breadboard circuit
up to the diagram and your circuit is ready for testing. Figure 7.4 shows the
schematic diagram and parts list.
For this project, I wanted the Arduino to randomly select a character to
ARRL1091
Piezo Speaker
SPST Switch
..J<(U..0C")N~oaico r-.<0io~"'N~
() 0 w z ~ ~ Ci ~ 0 0 0 0 0 0 0 0 0 o
0
(/) (/) ll'. (!) 0 0 0
I I <
I I
I I U1
I I Arduino Uno R3
I I
-c=--=--=--=--=--=--=--=--=--=--=--=---=; I
@ I I
6:wu..wwI- N~
<(
oo
_J
S1
R2
R1
5000 ~---
SPEED
19V
- BT1
ARRL1092
7-4 Chapter 7
send, use an Arduino library to convert the character into Morse code and play
it as a tone on a speaker. I also wanted to be able to control the sending speed
and to display the sent characters on an LCD display for visual reinforcement
of what I was hearing. A brief Internet search provided me with the Arduino
Morse library by Erik Linder, SM0RVV, and Mark VandeWettering, K6HX.
This library is simple and easy to use. All you have to do is include the library
in your sketch, define the digital 1/0 pin you wish to use, the sending speed,
and whether you want the library to send CW using a tone or a voltage that can
be used to key a relay or transceiver. Once setup, all you do is call the library's
send function with the desired ASCII character and it will output the Morse
code on the assigned pin.
For simple displays, I prefer the PC version of the Hitachi HD44780-
compatible 16-character by 2-line (16x2) display. This display is one of the
least expensive and most commonly used LCDs for the Arduino. I prefer the
PC version because it uses the SDA (A4) and SCL (A5) pins and doesn't tie up
any of the standard digital 1/0 pins. Since most of my projects don't need all six
analog input pins, and the standard version of the LCD needs six digital 1/0 pins
to communicate, the PC version allows me the flexibility to assign the Arduino
digital 1/0 pins to other purposes without sacrificing the simplicity and ease of
use of this display. The Arduino Playground has the LiquidCrysta l _ I2C
library to support the PC version of this LCD. All you have to do is include
this library in your sketch along with the built-in Wire library to support PC
communication and you 're ready to roll.
Once I had figured out all the pieces I would need to create the sketch, and
the electronics I would need to support the sketch, I began laying out the project
on the breadboard for testing. What I love about most Arduino projects is that
the actual wiring is usually simple and easy. The Arduino and libraries do most
of the heavy lifting for you. The key is to have your concept clearly laid out
ahead of time and the rest should go easy.
Code[x] = char(Sl+x);
The last step in the Setup loop is to randomize, or "seed", the Arduino
random number generator we will be using to randomly select the character
to send. The Arduino, like many computers, does not generate a true random
number. Instead, the Arduino random () function returns a pseudo-random
7-6 Chapter 7
number that will repeat the exact same sequence of random numbers every time
the Arduino resets. To add a more realistic randomness to the sequence, you can
seed the random number generator using the randomSeed () function with
a value, thereby altering the starting point in the pseudo-random sequence. A
simple way to randomize the Arduino random number generator is to read an
unconnected analog input pin and use the value returned as the seed value for
the random number generator.
II randomize
randomSeed(analogRead(l) ); II Seed the Random Number Generator
The main loop is where it all comes together. The first thing we do is read
the value of the SPEED potentiometer. The SPEED potentiometer varies the
voltage on the analog input pin from 0 to 5 V. The Arduino 10-bit analog-to-
digital converter (ADC) will convert this voltage into a value from 0 to 1023.
Rather than trying to figure out what voltage equates to the desired speed, we
can use the map ( ) function to do the work for us. For this project, I wanted the
code speed to be variable between 5 and 35 words per minute (WPM).
The map ( ) function translates the value of the SPEED potentiometer analog
input to a number from 5 to 35. This number is used to set the speed used by the
Morse library in words per minute. For this project, the speaker is connected
to digital 1/0 pin 11, so the Morse library is configured to send a tone to the
speaker connected to that pin.
II Set the Code Library to Beep on Pin 11 at the selected Key Spee d
Morse morse(beep_pin, key_speed, 1);
Once we have set up the Morse library for use, we next need to randomly
select the ASCII value of the character we want to send. Since we know we
have 41 elements in the Code [] array, we can have the Arduino random
number generator select a random number between 0 and 40. This value will
be used as the index of the Code [] array and the ASCII value of the selected
character to send is placed in the variable c.
Finally, the character is sent to the Morse library, which will send the
character in Morse code on the speaker.
When the character is sent, the Arduino will repeat the main loop and
continue to send and display random Morse code endlessly.
Finishing Touches
Once I have the project working on the breadboard, I like to move the
finished project into an enclosure so it can be put to actual use. For most of my
projects that use the 16-character by 2-line LCD, I like to put them in the Clear
Enclosure for pcDuino/Arduino from SparkFun (part number: PRT-11797).
This enclosure is designed for the Arduino Uno footprint and also has a handy
Extension Plate (part number: PRT-11798) that adds an extra Ys inch of overall
depth to the enclosure, allowing a little extra headroom for shields and other
components that might not fit inside the standard enclosure.
Before I move the project from the breadboard to the enclosure, I create
the final working version of the project schematic using CadSoft's free EAGLE
Light Edition Schematic Editor. This program allows you to create professional
looking schematics in a matter of minutes. Once your schematic is complete,
you can also create a PC board design file that can be used to have your finished
design etched by a commercial PC board etching service. The free version of
EAGLE Light Edition limits you to noncommercial use; board size is limited to
100 by 80 mm (4 by 3.2 inches), and a maximum of two layers on a single sheet
drawing. EAGLE Light Edition runs on Windows XPNista!Windows 7, Mac OS
X, and Linux.
Using my printed schematic as a guide, I wire up the enclosure and the
Arduino Uno. I like to use a prototyping shield (Figure 7.5) stacked on top of
the Arduino to wire up my projects. I then solder the components and header
pins to the protoshield. The header pins are used to connect to the external
components that are mounted to the enclosure itself using DuPont-style
2.54 mm spaced cable housings and socket pins. This allows me to easily
7-8 Chapter 7
Figure 7.5 - Random Code Practice Oscillator assembled on the prototyping shield.
remove the prototyping shield to correct the inevitable wiring errors and make
any modifications to the project. You will notice that there are white marks on
one end of the board headers and connector sockets. These marks are to indicate
pin 1 on the various connectors to help keep me from connecting things up
backward and letting the smoke out.
After wiring up the prototyping shield, I install it and the Arduino Uno into
the enclosure, build cables (old PC floppy drive cables work great for this) and
connectors for the external components, and mount the external components to
the enclosure.
The clamshell style of the enclosure for this project makes troubleshooting
easier, as you can have your project open to access the various pins and
connections for troubleshooting while the project is powered up and running.
Figures 7.6 and 7.7 show the finished Random Code Practice Oscillator.
When you've finished your wiring and testing, button up the enclosure and
you now have a fully functional Random Code Practice Oscillator in a nice-
looking rugged case. One of the more interesting side effects of this project
came when I was doing some final testing and letting it run on the test bench
while I was soldering another project up at the soldering bench. After about
an hour of hearing random CW in the background, I found myself copying the
code in my head. Leaving the project running, I would turn the speed up a notch
every now and then. At the end of just a few hours, my code speed had gone
from about 10 WPM up to 18 WPM and I was copying it 100%.
Continuing the experiment, I let it run in the background for a day or so,
gradually increasing the speed. At the end of this experiment in mental osmosis,
I was copying about 23 WPM in my head. Since the characters are random, you
can't guess what the next letter will be, which apparently enhances the learning
process, as you have to copy each character as it was sent. Now, if I can get my
sending speed to match my receiving speed, I'll be ready in time for next Field
Day.
Enhancement Ideas
As we discussed in the introduction to this book, the projects are functional
and complete as they are, but there will be room for you to take the existing
project and make it better. As it stands, the Random Code Practice Oscillator is
pretty complete. There's really not a whole lot that I would do to add features to
it. One possible enhancement would be to replace the Arduino Uno with a Nano
or similar version of the Arduino and shrink it all down into a smaller box and
use a smaller display such as the Nokia 5110 or one of the tiny OLED displays.
I'll leave the packaging up to you. Enjoy!
References
Arduino Playground - playground.arduino.cc
CadSoft - www.cadsoftusa.com
Fritzing - www.fritzing.org
SparkFun Electronics - www.sparkfun.com
7-10 Chapter 7
CHAPTER 8
CW Beacon and
Foxhunt Keyer
Start
Include Libraries
Define Variables
Set Beacon or Foxhunt Mode
Setup Morse Library
Define Functions
Setup
Loop
Check Timer
Set the Keying Mode
Send Message
Change LED color while sending
Reset Timer and wait for next interval
ARR L 1093
Keeping the concept as simple as possible, I next created the circuit block
diagram in Figure 8.2. To display the status of the project, I decided to use an
RGB LED (red-green-blue), allowing me to display the various states of the
keying cycle. Since the time intervals, mode, and beacon text would not need
to be switch-selectable, they would be hard-coded within the sketch and could
easily be changed as needed.
8-2 Chapter 8
ARRL1094
RGB LED
1 - - - - - t • Keying Out
Arduino Uno
------Audio Out
Figure 8.3 shows the Fritzing diagram for the project. To keep the beacon
keyer as versatile as possible, a signal relay driven by a 2N2222A transistor was
used to isolate the Arduino keying signal from the transmitter. This circuit is a
good idea anytime you want to drive a relay, as the Arduino digital VO pins can
only drive 40 mA. Using a transistor to key a relay requires much less current
CW Beacon/Foxhunt Keyer
DIP Relay
Keying Out
Next, we define the constants that set the keyer to Beacon or Foxhunt
mode, the beacon message, the size of the message array, the keying speed,
8-4 Chapter 8
the timer interval, and the number of seconds to repeat the message until the
timer interval expires. We also define the digital 110 pins assigned to the keyer
outputs.
The timer ( ) function will return the time in seconds since the timer was
reset by the TimerReset () function. This is how the keyer keeps track of the
various time intervals. When the TimerReset () function is called, it doesn't
actually reset anything. All it does is set the offset variable to the current
mi 1 1 i s ( ) value, which equates to the current time in milliseconds since the
Arduino was last reset. We then use this offset value to calculate our timing
intervals.
II Timer function - returns the time in seconds since last Timer Reset
unsigned long Timer()
void setup ()
In the main loop () , the sketch checks to see if the interval has expired,
or if this is the first pass through the loop since the Arduino was reset. The
sketch then determines if it is in Beacon mode or Foxhunt mode, turns on the
appropriate color LED, turns on the keying relay to use as PTT if in Foxhunt
mode, and sends the message. When in Beacon mode, the keying relay is
used as a CW key and sends the CW directly. If the keyer is in Foxhunt mode,
the sketch will add a space to the CW message and then will repeat the CW
message for the duration of the repeat interval.
II Send if the Timer has expired or if this is the first time through
if (Timer() > interval I first pass)
if (mode== 0) II Set the Key mode and LED for Beacon or Foxhunt
II If in Foxhunt mode, repeat the message until repeat time has exp ired
end time Timer() +repeat;
II Check to make sure repeat timer has not expired (Foxhunt Mode)
8-6 Chapter 8
while(Timer() < end_time)
morse.send(char(32));
else {
end time = Timer()-1;
After the message is sent, the timer is reset, and the keyer will tum the green
LED on again to indicate that it is ready for the next message interval.
When the sketch and prototype were completed, I created the schematic
(Figure 8.4) to use as a guide to move the electronics to an Arduino protoshield
and the finished project was mounted into a Solarbotics Arduino project
enclosure, as shown in Figure 8.5. This enclosure is small enough to be
mounted to the back of a handheld radio to be a self-contained foxhunt keyer.
Enhancement Ideas
There are a number of enhancements you can add to this project. Originally,
as part of the foxhunt keyer, I had planned to add a pushbutton that could be
pressed to indicate that the transmitter had been found and the beacon message
would be changed to a different message. Also, you can use an Arduino Nano
instead of the Uno and shrink the project down to a much smaller size. You
could also use a small OLED display to scroll the actual beacon message as
it is being sent and to indicate when the "found" button was pressed. I would
also recommend using a reed relay instead of a small signal relay to make the
beacon keyer quieter.
The last enhancement I would do is probably the main reason they don't
let me be the fox in foxhunts anymore. Now, since the Arduino is pretty good
at robotics too, mount the handheld and foxhunt keyer on top of an Arduino
quadruped robot and have it move 50 feet in random directions in between
transmissions, install proximity sensors to avoid obstacles, and have motion
detectors to sense when someone is nearby and have it move away from them or
hunker down and go silent. Now that's a real foxhunt.
References
Arduino - www.arduino.cc
RadioShack - www.radioshack.com
Solarbotics - www.solarbotics.com
8-8 Chapter 8
CHAPTER 9 .
l
The finished Fan Speed Controller
While fans may be a necessity with radios and other devices that generate
heat, your typical fan has two speeds, on or off. Noisy fans can be distracting,
especially if you don't need them running at full speed all the time. You could
use a variable speed controller and control the speed of the fan, but what
happens when things get too hot and you forget to tum up the fan speed?
A common method used in basic Arduino projects to control the brightness
of an LED has been to use a digital 1/0 pin with pulse width modulation
(PWM) to control the brightness by varying the duty cycle of the power to the
LED. Using the same concept, we can use the Arduino to control the speed of
a fan. If we add in a simple temperature sensor, we can vary the speed of the
fan according to the temperature and also sound an alarm if things get too hot.
This would have come in real handy two Field Days ago, when they turned me
Figure9.2-
Maxim Inte-
grated DS18820
temperature
sensor. (The
device in the
photo was made
Temperature by Dallas Semi-
Arduino Uno
Sensor conductor, now
a part of Maxim
Integrated.)
ARRL 1097
Starting out with our block diagram (Figure 9.1), you can see that we'll
need a temperature sensor, a Piezo buzzer, an LED, and some method to drive
the fan itself. Since the Arduino can only supply 40 mA of current per 1/0 pin,
we will need to use a transistor between the Arduino digital 1/0 pin and the de
fan. An RGB LED (red-green-blue) was chosen to allow the controller to show
the current fan mode and temperature range.
I feel that it is always best to prototype your circuit before writing your
sketch. As you build and test the electronics, you may find something that you
overlooked in your design. If you had started out with your sketch instead of
the circuit, you could very well end up having to totally rewrite it if your design
doesn't work as intended. In the case of the Fan Speed Controller, the de fan
wouldn't start at very slow speeds due to the PWM square waves being applied
to it. A capacitor was added to smooth out the square wave a bit, and now the
fan is able to start and run quietly at much lower speeds. A simple fix, but one
that might have caused me fits had I not tested the design before writing the
actual sketch. As I am building my circuits and starting out with the sketch, I
often write smaller pieces of sketches to test out each individual function of the
electronics to verify that everything works as intended. This way, if I do have
problems while creating the final sketch, I know the problem is most likely in
the sketch itself since the circuit functionality has already been tested with a
simpler sketch. Often, I am able to cut and paste pieces of code from my testing
9-2 Chapter 9
sketches into the final sketch, so I really
Start don't lose much time in the development
Include Libraries process.
Define Variables
Define Pin Assignments for Before we get into the actual circuit
RGB LED, Buzzer,
Temperature Sensor and Fan
used in the fan speed controller, let's
Control take a look at the Maxim DS 18B20
•
Setup
J2
C1
100µF
35V
M1
Fan Out
12V DC Fan
Q1
TIP31
t:::::::::========:::::::>-fi. .c::::=========~
ARRL1099
D1 1N4001
sound when the temperature reached 120 °F. At temperatures below 80 °F, the
fan and LED would be off. When temperatures get above 80 °F, the fan runs at
a slow speed and gradually increases in speed as the temperature rises. In this
mode, the LED glows blue. When the temperature reaches 100°F, the pulse
width modulation is discontinued and the fan runs at full speed. In this mode,
the LED glows green. Finally, when the temperature reaches 120 °F, the LED
glows red and the alarm buzzer sounds until the temperature drops below
120 °F. Note that there is no special significance to the temperatures chosen
for this sketch. These values were chosen simply for testing purposes. You
should set your temperature and alarm limits to suit your cooling needs.
Figure 9.4 shows the Fritzing diagram for the fan controller prototype. I
chose a 12 V de fan since that is the most commonly available de fan, easily
scavenged from old computer power supplies, and are available in a variety of
sizes and speeds. This circuit can drive a fan up to 40 V de. Higher voltage de
fans can be used simply by replacing the TIP31 transistor with a higher voltage
transistor. If you do use a voltage higher than 20 V, be sure to provide an
alternate method of powering the Arduino, since this design taps off of the
12 V fan power supply to power the Arduino. In this design, I chose to power
the DS18B20 temperature sensor in the standard way, using the recommended
4.7 k.Q pull-up resistor between the power and data lines of the sensor.
9-4 Chapter 9
The Sketch
The actual sketch for this project is a relatively simple one, demonstrating
the power of pre-written libraries and functions . In the top of the sketch, we
include the One Wire library found in the Arduino Playground (playground.
arduino.cc) and define the digital I/O pins and temperature limits used by our
circuit and the OneWire library. The complete Fan Speed Controller sketch and
the OneWire library can be found in Appendix A or downloaded from www.
w5obm.us/Arduino.
int DS18S20 Pin = t e mp_s e nsor ; //DS18S20 Signal pin on temp senso r p in
// Temperature chip I /O
OneWire ds(DS18S20 Pin); //on temp sensor pin
In the setup ( ) loop, we set the pin modes for the digital I/O pins. If you
organize your Arduino digital II 0 into groups of inputs and groups of outputs,
you can simplify the setup process by using a for ( ) loop to set the pin modes
and assign their starting values.
for (int x = 5; x <=9; x ++) // Set the Pi n Modes for Pin s 5 th r o ugh 9
pinMode( x , OUTPUT);
if (x <= 6) // Fo r pin s 5 and 6 sta r t Low , 7 - 9 start High (LED o ff)
digitalWrite( x , LOW);
else {
dig i ta l Wri te(x, HIGH);
In the main loop (),we use the Ge t Temp () function to read the current
temperature from the DS18B20. This function, found in the OneWire library
example sketches, does all the dirty work to read the temperature sensor and
returns the current temperature in Celsius. Since I'm not all that great at conver-
ting Celsius to Fahrenheit in my head, I added the conversion formula to the
Get Temp () function so that it would return the temperature in Fahrenheit instead.
ARRL 1100
ledOff();
digitalWrite(fan, LOW);
digitalWrite(alarm, LOW);
9-6 Chapter 9
II Turn the Fan on full speed
if (temperature > high_temp && temperature < alarm_temp)
When the breadboard prototype and sketch were debugged and complete,
the schematic diagram in Figure 9.5 was used to solder the project onto a
prototyping shield, and the project was mounted inside a Solarbotics project
enclosure for final testing. Figure 9.6 shows the finished project.
' l
Enhancement Ideas
The design of the Fan Speed Controller lends itself very nicely to being
mounted in a much smaller package and controlled by an Arduino Nano or
similar small Arduino. Since the controller is powered by the fan's power, you
can mount everything on a small perfboard attached directly to the fan. Also, as
References
Arduino Playground - playground.arduino.cc
Maxim Integrated - www.maximintegrated.com
Solarbotics - www.solarbotics.com
9-8 Chapter 9
CHAPTER10
Digital Compass
You've got all your gear at that ideal remote site you've been planning to
operate from for years. The gang has the portable tower all set up and ready to
go. Just one minor detail, which way is north? How can you properly align your
antennas if you don't know which way to orient it? Yeah, okay, you've probably
got a compass cell phone app, handheld GPS or even a real compass, but work
with me here. Wouldn't it be cool to just whip out your Arduino-powered
Digital Compass to show the way?
The Honeywell HMC5883L Digital Compass (Figure 10.1) is an PC-based
triple-axis magnetometer combined with a 12-bit analog converter used to read
ARRlllOl
I
2
16x2 1 C LCD
I
J l
I
Compass
Module
...
~
Arduino Uno
10-2 Chapter 1O
Start
Include Libraries
Define Variables
Setup 12 C LCD
Setup Digital Compass Module
, '
Setup
2
Initialize 1 C LCD
Initialize Digital Compass
Loop
Read Compass
Convert Reading to Degrees
Display Heading on LCD
ARRL 1102
devices sharing the FC bus, the HMC5883L compass module and the LCD
module, demonstrating the versatility of the FC bus. With both of the external
components of this project sharing the FC bus, only 8 wires (including power
and ground) are required to build the project.
The HMC5883L and LiquidCr y stal I2C libraries also simplify the
flowchart (Figure 10.3). After the initial setup and initializing the modules, it is
simply a matter of using the library functions and very little in the way of actual
coding is needed. In fact, the logic used to determine the 16 compass points (N,
NNE, NE, and so on) and display the compass bearing on the LCD takes up
more code than the rest of the entire sketch.
As mentioned above, only eight wires, plus the battery connections, are all
that is needed to construct this project. Figure 10.4 shows the Fritzing diagram
of the completed project as it was built on the breadboard to begin coding. You
will notice that this project appears to be missing the recommended 4. 7 kn
pull-up resistors on the FC bus. The HMC5883L module has the FC bus pull-
up resistors on the module itself, so there is no need for the usual external pull-
up resistors.
lXJ.
SPST Switch
. . SW1
The main loop () reads the scaled Gauss values from Digital Compass
module and stores the results in the scaled. XAxis, scaled. YAxis, and
scaled. ZAxis function variables. Since Arduino functions can only return
one value at a time, the MagnetometerScaled Data type is defined in
the library to pass the three Ax is values back to the main loop.
10-4 Chapter 10
IIRetrieve the scaled values (scaled to the configured compass scale) .
MagnetometerScaled scaled= compass.ReadScaledAxis();
Finally, once we have calculated our compass bearing, we have to add in the
magnetic declination that is specific to our location. Magnetic declination, also
known as magnetic variation, is the angular different between the geographic
North Pole, also known as True North, and the magnetic North Pole. This
deviation value needs to be applied to the magnetic compass heading to
calculate True North. You can find the magnetic declination value for your
location at www.magnetic-declination.com.
heading += declinationAngle;
Finally, we convert the heading value from radians to degrees and display
the value on the LCD.
The Output () function displays the heading and direction on the LCD.
The bearing is broken down into 16 directions, (N, NE, ENE, etc.) and the
display is updated once per second.
led.clear();
led.print(" " " ); II Pr i nt an up ar r ow to indi c at e compass p o inter
l cd.print(headingDegrees,1); II Di sp l ay the He ading in degrees
led.print(" Deg");
lcd.setCursor(l 5 ,0);
l ed.print(" " ");
II Calculate Dire c ti o n
Direction = " ";
lcd.setCurs o r(6,l);
Directi o n "NNE";
Construction Notes
Once the Digital Compass was working on the breadboard, the finished
schematic (Figure 10.5) was created and used to solder the finished project
onto a protoshield (Figure 10.6). When you look at the HCM5883L module,
you will see a small circular symbol with X and Y arrows on the board. These
arrows represent the orientation of the magnetic sensors in the HCM5883L
chip. The X arrow on the module should be aligned to point to your desired
heading.
The completed project was mounted in a clear enclosure for pcDuino/
Arduino from SparkFun (Part number: PRT-11797) along with the Extension
Plate (Part number: PRT-11798). Figure 10.7 shows the finished project.
Enhancement Ideas
One thing I discovered while constructing this project is that the
HCM5883L Digital Compass is not tilt-compensated. This means that to get
accurate compass readings, the compass module must be held flat, otherwise
the readings may not be accurate. This can be corrected with the use of an
accelerometer module and calculations can be added to compensate for
compass tilt. There are several libraries and forum topics on the Arduino
Playground (playground.arduino.cc) that add this functionality to the Digital
Compass.
The simplicity of the Digital Compass circuitry lends itself easily to an
Arduino Mini makeover. Using an Arduino Mini and an organic LED (OLED)
10-6 Chapter 1O
ARRL1104
U3 16x2 LCD
_J <!'. (_) 0
u 0 (_) z
(/) (/) > (!)
I I I I I I I I I I I I I I I I I I ......._._ ___.Voe
.____ __. GND
-1---1-----1 SCL
-1-------l SDA U2
HMC5883L
U1 - DRDY
Arduino Uno R3 - 3V3
display, you could miniaturize the digital compass to fit in a much smaller
enclosure, possibly along the lines of the Altoids mint tin or even smaller.
References
Arduino Playground - playground.arduino.cc
bildr.blog - bildr.org/2012/02/hmc58831-arduino/
DFRobot - www.dfrobot.com
Honeywell - www.honeywell.com
Magnetic-Declination - magnetic-declination.com
SparkFun Electronics - www.sparkfun.com
10-8 Chapter 10
CHAPTER 11
Weather Station
As I sit here putting this all together, my weather radio is sounding all sorts
of weather alerts. Almost constant severe thunderstorm, tornado watch, tornado
warnings, and flash flood warnings have been going off for most of the day and
the local ham emergency nets are all active. Perfect timing for a Weather Station
project, wouldn't you say? Hams and weather seem to go hand in hand, from
weather emergency groups and nets to plain old weather watching.
The Arduino has a wide array of sensors that can be used to monitor many
different weather and atmospheric conditions. When I was growing up, our
family had one of the analog wall-mounted weather stations that displayed the
temperature, relative humidity, and barometric pressure on analog dials. For this
project, I decided to revisit my childhood memories and give that wonderful old
weather station an Arduino makeover.
11-2 Chapter 11
not to mix and match your MaxDetect devices and
Maxim devices on the same digital 1/0 pin, you'll
be fine.
The Bosch BMP085 barometric pressure sensor
(Figure 11.2) communicates with the Arduino
using the PC bus. The BMP085 has resolution of
0.01 hPa (hectoPascals) with a typical accuracy
of ± 1 hPa over an operating temperature range of
-40 to 85 °C. (See the sidebar, "Pascals, Millibars,
Inches of Mercury.") As with the RHT03, the
BMP085 also has an embedded temperature sensor
that has a resolution of 0.1 °C with an accuracy
of ± 1 °C over the same operating range as the
Figure 11.2 - The Bosch BMPOBS barometric pressure sensor portion of the module.
barometric pressure and temperature
module. The BMP085 sensor chip requires 3.3 V to operate,
but many of the more recent modules have onboard
5 V regulators . This project uses the 5 V version of
the BMP085 module.
The Nokia 5110 graphic LCD (Figure 11.3)
was originally intended for use as a cell phone
display. Using the PCD8544 display controller, the
Curret1t Wx Nokia 5110 has an 84 x 48 pixel display, which
allows up to six lines of 15 characters of text.
The Nokia 5110 is a graphic LCD, meaning you
can display images, charts, and graphs as well as
text. It uses four small LEDs for backlighting and
is currently available with either a white or blue
backlight. The datasheet recommends powering the
Nokia with 3.3 V; however it can be used at up to
5 V. The Nokia 5110 connects to the Arduino using
Figure 11.3 - Weather Station output five digital 1/0 pins, and the contrast of the display
displayed on the Nokia 511 O LCD
display.
can be adjusted via software.
Starting out with the usual block diagram
(Figure 11.4), I wanted the Arduino to read
the RHT03 and BMP085 sensors and display
ARRL 1105
Nokia 5110 the current temperature, relative humidity, and
I LCD Display I barometric pressure on the Nokia 5110 LCD. Since
j l
both sensors have internal calibration data that has
to be applied to the raw sensor data, the Arduino
RHT03 would also be used to apply this calibration data
Temperature/
Humidity
Sensor
-
~
U4
Nokia 5110 LCD Module
4700
R1
1k0
R2
.......
11111
.....
• • • 8.
11111
I •
U2
RHT03
BT1
9V
1N4001 U3
BMP085
11-4 Chapter 11
there are no pull-up resistors on the FC bus for the BMP085.
The BMP085 module used in this project is the 5 V version
Start
and comes with the FC bus pull-up resistors mounted on the
Include Libraries module itself. You will also note that the datasheet calls for a
Define Variables
Setup Nokia LCD 1 kO pull-up resistor on the RHT03 data line connected to the
Setup Temperature and Relative Arduino digital 1/0 pin. Finally, a 470 n resistor is used on the
Humidity Module
Setup Barometric Pressure Module backlight pin of the Nokia 5110 LCD.
Planning out the sketch flowchart (Figure 11.6), I found
a number of libraries available for the DHT03 and the Nokia
5110 LCD. The libraries I chose to use were the DHTLib
library from the Arduino Playground (playground.arduino.
Setup cc) and the LCD5110_Basic library by Henning Karlsen
(www.henningkarlsen.com/electronics/) although any of
Initialize Nokia LCD
Initialize Temperature and Relative
the other libraries would do just as well. At the time this
Humidity Module project was created, I could not locate a suitable library for
Initialize Barometric Pressure Module
the BMP085 sensor, so the code for the BMP085 does not use
a library and the SparkFun example sketches were used as a
guideline instead. Most of the complex operations are handled
by the libraries or by the functions in the example sketches,
which greatly simplifies the use of these sensors in your
Loop
projects.
Read Temperature and Relative Unlike the previous projects, there is a lot of initialization
Humidity Module needed to get the sensors and display ready for operation.
Read Barometric Pressure Module
Display Temperature, Relative In addition to the standard library #include statements,
Humidity and Barometric Pressure on the addresses and Arduino 1/0 pins must be defined for use
LCD
by their associated libraries. Because we are using PC for
ARRL1107 the BMP085, we also must include the Arduino internal PC
Wire. h library. The complete sketch and required libraries
Figure 11.6 - Weather Station for this project can be found in Appendix A and at www.
flowchart. wSobm.us/Arduino.
II DIN - Pin 11
II DC - Pin 10
II RST - Pin 8
II CE - Pin 9
LCD5110 glcd(12 ,11, 10 , 8,9); II Set the IIO pins used by the Nok ia display
extern uint8 t SmallFont[] ; II Define the Small Font for the Nokia display
long b5;
int chk ; II Status Check variable for RHT03
In the setup () loop, the FC bus and the Nokia 5110 LCD are started. A
startup message is briefly displayed on the LCD display before continuing on
with the rest of the setup ( ) loop.
glcd.InitLCD(65); II Ini tia lize the Nokia 5110 Display, set Contrast to 65
glcd.setFont(SmallFont); II Set the Font to Small Font
glcd.print("KW5GP", CENTER, 0); II Display the Startup screen
glcd.print("Weather", CENTER, 8);
glcd.print("Station", CENTER,16);
glcd.print("Initializing", CENTER,32);
delay(3000);
The last operation performed by the setup () loop is to run the BMP085
calibration function:
In the main loop () , the LCD is set up with a display template and the
RHT03 is read. In case of a read error, the error is displayed on the LCD and
the sensor data is ignored. This portion of the sketch introduces the Arduino
swi tch ... case () statement. The swi tch ... case () statement allows the
selection of different blocks of code to be executed based on the value of a
variable, in this case, the chk variable is used to determine which branch of the
code is executed. The end of each branch of the code is signified by the break
keyword and program execution continues at the end of the swi tch ... case ()
block of code. If no conditions match within the swi tch ...case () statement,
11-6 Chapter 11
the default block of code is executed.
While both sensors are capable of providing temperature data, for this
sketch, the temperature readings from the RHT03 are used.
switch (chk)
case DHTLIB OK :
II Display the RH Data if it 's a va li d r ea d
glcd . printNumF (DHT . humid i ty , 1 , 30 , 16 );
glcd.print( " % ", 55 , 16);
centigrade = DHT . temperature ;
fahrenheit = (centigrade * 1. 8 ) + 32 ; II c onvert to Fa hrenheit
glcd . printNumF(fahrenheit , 1 , 30 , 24 );
default :
glcd.print( " Unk Error" , 25 , 16 );
break ;
Next, the barometric pressure data is read from the BMP085. The BMP085
outputs the barometric pressure in Pascals. The sketch converts this into the
more commonly known inches of mercury. One interesting feature of the
BMP085 is that it can also calculate altitude based on the difference between
standard sea-level atmospheric pressure and the barometric pressure read by the
BMP085.
The real magic for converting the raw barometric pressure data from the
BMP085 happens in the bmp085GetPressure () function. The BMP085
has eleven 16-bit calibration values stored in the BMP085's internal EEPROM
memory. These calibration values are applied using a complex formula to
calculate the actual barometric pressure read by the BMP085. I won't even
attempt to try to understand what this function does other than state that it uses
the formula provided by Bosch in the BMP085 datasheet to convert the raw data
into actual barometric pressure. This is part of the fun of the Arduino. You don't
have to understand how a pre-existing function or library works as long as it
provides you the information you need for a given project.
II Calculate B3
xl (b2 * (b6 * b6)>>12)>>11;
x2 (ac2 * b6)>>11;
x3 xl + x2;
b3 (((((long)ac1)*4 + x3 ) «0SS) + 2)>>2;
II Calculate B4
xl (ac3 * b6)>>13;
x2 (bl * ((b6 * b6)>>12))>>16;
x3 ( (xl + x2) + 2) >>2;
b4 (ac4 * (unsigned long) (x3 + 32768)) >>15;
b7 ((unsigned long) (up - b3) * (50000»0SS));
xl (p »8) * (p»8);
xl (xl * 3038)>>16;
x2 (-7357 * p)>>16;
11-8 Chapter 11
p += (xl + x2 + 3 791)>>4;
long temp = p;
r e turn temp;
Construction Notes
Once the sketch was completed and the project working as advertised on the
breadboard, the schematic diagram for the project (Figure 11.7) was used to
ARRL1108
U4 Nokia 5110
+3.3V
u .:E
tn
er
w u ~ ~
u o o u
u Cl
0
z
> ::::; ('.)
1 2 3 4 5 +5V
R1
470 0 R2
1 kO
Vee
U2 2
~----+-~OUT RHT03
GND
3
U1
Arduino Uno R3
0
w
> <( ....I +5V
eru._t- N~ OU
lw7l erw lw7l > > 0z 0z ~ ~~
erQerMIOC'.l<'.l> ~~~~~~ U3
BMP085
7 3
SDA VDDA
6 4
SCL VDDD
2 5
EOC NC
8
XCLR GND
Enhancement Ideas
This is one of those projects where it can be difficult to choose what you
want it to be as you have so many atmospheric and weather-related sensor
options available. Since many weather-related items involve a trend over a
period of time, adding a real-time clock calendar and datalogging function and
graphic trends on the graphic LCD would be ideal. You can easily add a rain
gauge and an anemometer for wind speed and have a nearly complete picture of
the current weather. A much simpler enhancement would be to use a digital 1/0
pin to control the brightness of the backlight using PWM. You can keep track
of the barometric pressure and add an up or down arrow next to the barometric
pressure reading to indicate that the pressure is rising or falling. Finally, you
could use a text-to-speech module and have the weather station speak the time,
temperature, and other parameters for you.
This project turned out to be a lot of fun for me and it will come in real
handy in just a few short weeks when the club does our annual exercise in
insanity as we compete in the outdoor category of the annual Society for the
Preservation of Ham Radio (SPAR) Winter Field Day event, where temperature
is part of the contest exchange. Hopefully next year, I'll have the Ethernet side
of this project worked out and we can have the contest software automatically
handle the time and temperature side of things for us.
References
Adafruit Industries - www.adafruit.com
Aosong Electronics - www.aosong.com
Arduino Playground - playground.arduino.cc
bildr.blog - www.bildr.org/2011/06/bmp085-arduino/
Bosch - www.bosch-sensortec.com
Henning Karlsen - www.henningkarlsen.com/electronics/
MaxDetect - www.humiditycn.com
Society for the Preservation of Ham Radio - www.spar-hams.org
SparkFun Electronics - www.sparkfun.com
11-10 Chapter 11
CHAPTER12
RF Probe with
LED Bar Graph
One of the cool things about the Arduino is that it is a tool that can be used
to make other tools . If you're like most hams, you don't often have a need for a
lot of test equipment, and when you do need to test something, you can usually
borrow what you need from a fellow ham. The reason for this is primarily
because some test equipment can be rather expensive, or it's just not worth the
investment for something you'll only use once or twice in a blue moon.
In my case, I don't often need an RF probe, but it can come in handy when
you want to know if that QRP transmitter is working and you don't happen to
have a wattmeter or SWR meter handy or you need to track down some stray
RF in the shack. While researching another project, I came across the "RF
Driven On-Air Indicator" article by Keith Austermiller, KB9STR, which itself
is derived from "The 'No Fibbin' RF Field Strength Meter" by John D. Noakes,
VE7NI. 1•2 With a few minor tweaks, those projects could be adapted into an RF
probe that would allow an Arduino to drive an LED bar graph display instead of
a meter to indicate the strength of the RF signal.
J2
Antenna c1 02
~1µF +SV
01
1N5711
1N5711
C2
0.01 µF
R1
10 kO
RF Sense Out
r
~n J1
ToRFProbe
R2 R3
ARRL 1110
12-2 Chapter 12
I The choice of diodes used in the RF sensing unit is critical
and you will need to use either 1N34A germanium diodes
or preferably 1N5711 Schottky diodes. Whatever diode
you choose to use, do not use a silicon diode such as the
1N4001. A silicon diode has a forward voltage drop of
approximately 0.7 V, while a germanium diode has a
forward voltage drop of 0.3 V, and the Schottky diode has
the lowest forward voltage drop of the bunch at 0.2 V. These
small differences in forward voltage drop can significantly
impact the sensitivity of the RF sensing unit.
The RF sensing unit is built on a standard protoboard
cut to fit inside a Radio Shack (part number 270-1802)
4 x 2 x 1 inch project box. The antenna connector and
output jack connect to the circuit board using pin headers
and DuPont-style female headers allowing easy removal of
the circuit board to correct the inevitable wiring error. The
LM358P op amp is mounted in a socket for those times
when you accidentally feed it 100 W and let the smoke out.
A 10 inch piece of AWG #14 solid wire was soldered to
the center conductor of a PL-259 coax connecter to serve
as the RF pickup for the sensing unit. An S0-239 coax
chassis connector mounted to the project box allows you to
use different antennas for the RF pickup antenna. A stereo
Vs-inch mini jack is used to connect between the RF sensing
unit and the Arduino assembly. Figure 12.3 shows the
finished unit.
Breadboard
The next order of business is to wire up the Arduino half
Figure 12.3 - The inside of the RF of the project on your breadboard using the Fritzing diagram
sensing unit.
in Figure 12.4. This project introduces two new 1/0
methods for the Arduino. We will be using the Arduino's
built-in analog-to-digital converter to change the analog voltage output from the
RF sensing unit into a value that is converted to a digital representation of the
signal strength, and then output that to a 10 LED bar graph display. For an RF
probe, you don't necessarily need the power of an LCD display, as all you are
really interested in is a relative RF field strength indication - perfectly suited to
the bar graph-style displays. Since the Arduino will be doing all of the work, all
you really need on the protoshield is the 330 n current-limiting resistors for the
bar graph LED display.
J1
. . . S1
A RRL 1111
Start
Define Variables
-
"
Setup
Figure 12.5 - RF Setup Digital 1/0 Pins
Probe flowchart. Setup Analog Input Pin
I
•
Loop
·- A RRL11 12
12-4 Chapter 12
representation of the input voltage on the bar graph LED.
The bar graph LED requires 10 digital 1/0 pins to drive it directly. Since
we're not planning for the Arduino to do anything other than drive the bar graph
LED, there's no issue with using most of the Arduino's digital 1/0 pins in this
way. Since consecutive pins were used in the design, we can use a for ( ) loop
to set the LED modes as outputs rather than initializing each digital 1/0 pin
separately.
for (int x=2; x<=ll; x++) II Set pins 2 -11 as LED Outputs
pinMode(x, OUTPUT);
In the main loop () the analog voltage is read from the RF sensing unit
and converted into a digital value between 0 and 1023, corresponding to the 0 to
5 V output of the RF sensing unit.
The next thing is to determine how many bars to light on the bar graph LED.
Based on my RF testing, a level of approximately 3.6 V from the RF sensing
unit was determined to be a good indication of maximum RF field strength.
Note that with the 1 kQ resistor between the RF sensing unit and the Arduino,
3.6 V will be the maximum value you can expect to see on the Arduino analog
input pin. This level can be adjusted by varying the 10 kQ potentiometer (Rl)
on the RF sensing unit.
Now would be a good time to introduce the Arduino map () statement.
The map () statement is a great way to modify the scale of your data. In this
case, the 0 to 5 V analog input from the RF sensing unit is mapped from a
possible digital value of 0 to 1023 into a value from 1 to 10, with our maximum
indication occurring at a value of 750 (approximately 3.6 V). This tells us how
many LEDs on the bar graph display need to be lit to indicate the RF field
strength. Using the map () statement in this way, the first LED in the bar graph
will always be lit. This is used as a power indicator to let us know the RF Probe
is powered on and ready to go.
Finally, the mapped value from 1to10 is output to the bar graph LED. A
for ( ) loop is used to light the desired number of LEDs in the bar graph, while
a second for ( ) loop is used to make sure the rest of the LEDs in the display
Enhancement Ideas
This would be an excellent project for an Altoids mint tin and an Arduino
Nano. If you used a BNC connector instead of the S0-239, you could possibly
fit everything inside the Altoids tin with a small cutout for the bar graph LED.
You could also replace the bar graph LED with a small organic LED (OLED)
and calibrate the unit against a real field strength meter and have it provide
a digital representation of the actual field strength. And finally, you could
implement the Maxim MAX7219 LED driver to drive either a bar graph or
7 segment LED, or even display the output as a graph on an 8 x 8 LED array.
12-6 Chapter 12
ARRL1113 R10
'l DS10
'lDS9
'loss
'lDS7
'l DS6
'l DS5
'l DS4
'l DS3
'l DS2
'l DS1
R1-R10, 330 Q
U2
HDSP-4832
d ~ ~ ~ ~ ~ ~ ~ ~ ~
(/)(f)O:::CJoooo
b ~ ~ d 8 ~ 0 8 10 LED Bar Graph
Display
I I <{
I I
U1
I I
Arduino Uno R3
I I
I I
'--- I -=--=--=--=--=--=--=--=--=--=--=--= I
I I
To
RF Sense
Unit
Figure 12.7-
lnside view of
the RF Probe.
Notes
'K. Austermiller, KB9STR, "An RF Driven On-Air Indicator," QST, Aug 2004,
pp 56-57.
2
J. Noakes, VE7NI, "The 'No Fibbin' RF Field Strength Meter," QST, Aug
2002, pp 28-29; Feedback Sep 2002 QST, p 88.
12-8 Chapter 12
CHAPTER 13
Solar Battery
Charge Monitor
Current Monitor
Reading the charging current between your solar array and the battery is
a whole other issue. You really don't want your Arduino anywhere near the
voltages that charge the battery, but you will need to
read the current flowing between the array and the
battery. Fortunately, someone else has faced this issue
and created a module just for this purpose.
The Texas Instruments INA 169 shown in Figure
13.1 is a high-side de current shunt monitor that can
handle up to 60 V de. A high-side monitor can be
inserted anywhere in your circuit, whereas a low-side
device must be inserted between the target ground
and true ground. Since the voltage drop across the
shunt resistor used for measuring is proportional to
the current draw, with a low-side monitor, the ground
reference will change as the current varies. A moving
ground reference can be a bad thing, and is not
something we really want to have to take into account
Figure 13.1 - The INA 169 current sensing in our circuit designs. With a high-side current shunt
module. monitor, we can place it anywhere in our circuit without
fear. The INA169 uses a precision amplifier measuring
differentially across a 0.1 n, 2 W precision sense resistor, allowing you to
read up to 5 A continuously. The output voltage of the module that represents
the current in the circuit under test is in direct proportion to the sense current.
The INA 169 default setting is an output of 1 volt per ampere measured, giving
you an output of 0 to 5 V over the range of 0 to 5 A. The sensitivity of the
current measurement can be changed simply by replacing the onboard 10 kn
measurement resistor with a different value.
The solar panels used for this project are two 150 x 85 mm (5.9 x 3.3 inch)
7 .5 V panels that output up to 220 mA. The idea was to keep this project small,
light, and portable. Taking it to full-scale, I would add two additional sets of
paired panels, giving it a total output of up to 660 rnA, a little more than half
of an amp of solar charging power from a small, portable solar array. The
panels were glued to a small wooden framework and attached to a servo pan/
tilt head assembly. I used a servo pan/tilt mount to allow the addition of servos
and photosensors at a later date to automatically track the sun and maintain
maximum charging rate as the sun moves across the sky. Figures 13.2 and 13.3
show the solar panel assembly.
13-2 Chapter 13
.. "-~~-. ,. . .
Figure 13.2 - The solar panel array mounted on the Figure 13.3 - Rear view of the solar panel array
pan/tilt servo assembly. showing how it is mounted to the pan/tilt servo
assembly.
Circuit Design
Now that we have a solar array that can generate our charging current, and a
sensor that can read the current, we can begin designing the actual circuit. Using
the block diagram (Figure 13.4), we'll want to have the Arduino measure the
charging current and the voltage of both the solar array and the battery. With a
maximum of 220 mA charging current for this project, there's really no need
to regulate the charging current between the solar panels and the 5.0 A/h gel
cell battery. Once you get to charging currents of 1 A or more, you will need to
limit the charging current with additional external circuitry. At charging currents
greater than 3 A, you will also need to beef up the blocking diode between the
solar array and the battery. Since the Arduino only draws about 55 mA, we can
also use the solar array to power the Arduino while having enough current left
over to charge the battery.
Since we have large external components that may be carrying higher currents
at some point, the solar array and battery are connected to the Arduino using
Solar Cells
Current
Sense
Module
. Arduino Uno
ARRL1114
ARRL1115 U3
Nokia 5110 LCD Module
U4
7.SV Solar Cell
U2 Ul
INA169
51
13-4 Chapter 13
AWG #14 wire and Anderson Powerpole connectors (see the sidebar) for quick
disconnecting. If you are planning to use a larger charging current, you will want
to move up to AWG #12 wire or larger, but for my purposes, AWG #14 wiring
can handle anything the solar panels throw at it. Don't forget to beef up the
wiring on the protoboard to the current sensor if you do go higher than 1 A.
Figure 13.5 shows the Fritzing diagram for the project. Since there are
several data points that we'll be monitoring, we'll use a Nokia 5110 LCD
display to show our charging information. With the backlight LEDs off, the
Nokia 5110 also has a very low current drain of about 10 mA, making it the
The Sketch
Once you have the circuit breadboarded, it's time to design the sketch.
Using the sketch flowchart in Figure 13.6, we'll want the Arduino to read the
solar array voltage, the battery voltage, and the charging current. These values
will be displayed and updated every 5 seconds on the Nokia 5110 display, along
with an indication of whether or not charging is occurring. Since the analog
voltages being read are fed to the Arduino from a resistor divider network, we
will also need to define the calibration values needed to determine the actual de
voltages coming from the solar array and the battery as well
as the analog voltage from the current sensor that represents
the charging current. The complete sketch for this project
Start
is found in Appendix A and online at www.w5obm.us/
Define 1/0 Pins and Variables Arduino.
Define Nokia 5110 LCD Display
First, you'll need to define the pins and calibration values
we will use for the analog voltages we'll be providing to the
Arduino. The calibration values are determined by actually
measuring the voltages and current with a voltmeter and
Setup using these values to derive the calibration value needed to
Setup Analog Input Pin convert the raw values to the proper voltage or current. If you
Setup Nokia 5110 Display don't have a voltmeter handy, the values used in the sketch
should do just fine.
13-6 Chapter 13
II Define the ca libration value used to map the charging current to milliamps
#define amp_calibration 5120
Next, we'll define the Nokia 5110 LCD display and define the Small
Font for the display:
#include <LCD5110 Basic . h> II Use the Nokia 5110 LCD Library
I*
It is assumed that the LCD module is connected to
the following pins.
CLK - Pin 12
DIN - Pin 11
DC - Pin 10
CE - Pin 8
RST - Pin 9
*I
LCD5110 g lcd(1 2,11,10 , 8,9); II Assign the Noki a 5110 LCD Pins
The last part of the initialization is used to define the variables holding the
sensor data values:
In the setup () loop, the Nokia display is initialized and a brief startup
message is displayed to let you know the Solar Charge Monitor is ready for
action. After the startup message, the display is set up to display the template
for the data values:
Next the voltage and current values are displayed on the Nokia LCD. The
LCD511 O_Basic. h library has functions to print floating values to the
desired number of decimal points and integers of a fixed length, allowing you to
format the data nicely on the display without having to manually calculate and
add spaces to have all the values line up.
Figure 13.7 shows a sample display during operation. Once the circuit was
fully functional and the sketch debugged, the schematic was created from the
breadboard wiring (Figure 13.8), the project was soldered up on an Arduino
13-8 Chapter 13
Figure 13.7 - Close-up view of
the Solar Charge Monitor display.
~ ~
~ ~ ~
~
a0
0 M N
0 0 0
~ 0 m
o o
00 ~ ~ ~ ~
o o o o o o o o
M N ~ 0
I I <(
I I
U1
I I
02 Ar du i no Uno R3
I I
U2
INA169
I I
IP+
I Vee
'--- I -=--=--=--=--=--=--=--=--=--=--=--=II I
0
UJ
>
~
<( ..J
3 ll'.'.u_f- N~ 0 (.)
VOUT ~UJ~
~<~~~~
00
2 UJa::UJ>>zz~
3.9 kO
GNO a:: Q a::<')"'(!)(!)>
IP-
01
1 kO
1N4001 Power
J_
BT1-=- 12 V
R2 3.9 kO
-~ R3 1 kO
l ARRL 1117
Enhancement Ideas
You've already seen a glimpse of one of the possible enhancement ideas
for this project. It is my ultimate plan to add an additional two sets of solar
panels and add servo tracking capability using the pan/tilt servo head with
phototransistors mounted on the four comers of the solar array to locate and
track the sun across the sky to maintain the maximum charging current. The
Arduino would measure the differences between the four phototransistors and
automatically move the servos for maximum output.
You could also replace the INA169 current sensor with the newer INA219
version. The INA219 communicates with the Arduino using the PC interface
and has program-selectable internal gain settings to select the desired current
sensing range. Since the INA219 uses the PC bus rather than an Arduino
analog input pin, you can have up to four INA219 current sensors in your solar-
powered projects, allowing you to monitor all aspects of your circuits. The
INA219 uses a 12-bit analog-to-digital converter to translate the current into
a digital value send to the Arduino over the PC bus. The INA219 also has an
internal voltage sensor, saving you additional analog input pins.
You could also add a day/night sensing capability using phototransistors to
turn off the Solar Charging Monitor when the sun goes down to reduce battery
drain and turn it back on when the sun comes back up. There's also no reason
that this project could not be scaled up to control a much larger, higher capacity
solar array. All you would need to add is a charging current regulator circuit
and geared stepper motor or worm gear-driven motor to do the positioning on a
larger solar array.
Finally, to make the project even more portable and energy efficient, you
can replace the Arduino Uno with a smaller Arduino, such as a Nano, and
mount everything in the base of the solar panel assembly. Using a Nano instead
of the Uno would save you about 30 mA of charging current, giving you just
that much more charging current to the battery.
I'm really looking forward to using this project to charge and power the
alternative power QRP station we use at ARRL Field Day and I think it would
be neat to watch the solar panels track the sun across the sky all on their own.
References
Adafruit Industries - www.adafruit.com
Anderson Power Products - www.andersonpower.com
Henning Karlsen - www.henningkarlsen.com/electronics/
Texas Instruments - www.ti.com
Solarbotics - www.solarbotics.com
SparkFun Electronics - www.sparkfun.com
13-10 Chapter 13
CHAPTER14
On-Air Indicator
One of the fun things you'll discover about the Arduino is its versatility. It's
like having an adult Erector Set. You can build something, make it work, take it
apart, rearrange the pieces, and you've got something entirely different. Such is
the case with the On-Air Indicator. Using some of the same pieces we built for
the RF Probe in Chapter 12, we can create an entirely different project with an
entirely different purpose.
As I mentioned back when we built the CW Beacon and Foxhunt Keyer,
my friend and fellow Arduino builder, Tim Billingsley, KDSCKP, operates a
finicky 10 meter beacon. Sometimes it just goes dead without warning. Until we
can dig into things and see what exactly is going on, Tim wanted a better way
to tell if the beacon was actually transmitting without having to leave a power/
RF
Sense Arduino Uno Relay
Unit
ARRL1118
SWR meter attached to it, looking at the beacon transmitter's meter, or leaving
a receiver tuned to the beacon frequency all the time. With just a few twists and
a slightly different circuit design, we can tum the RF Probe from Chapter 12
into an On-Air Indicator. Like Tim, you can use it to verify that your beacon is
transmitting, or you can use the relay output to light a sign on your shack door
telling others that you're busy chasing some DX and to enter quietly, or slide
your dinner under the door.
Unlike the RF Probe project, we're not really interested in the signal strength
- we're more concerned with whether or not there is a signal. Since we're only
looking for an on or off indication, as the block diagram (Figure 14.1) shows,
we've replaced the bar graph LED with a single LED and a relay output to
indicate when an RF signal is present.
At the heart of this project is the exact same RF sensing unit we built for the
RF Probe project in Chapter 12. This time around, we'll use the RF sensing unit
to determine the presence of an RF signal rather than read the signal's strength,
and we'll have the Arduino read the probe and trigger the LED and relay if the
signal strength exceeds a threshold value.
If you haven't already built the RF sensing assembly, you can find the
parts list and instructions for building one in Chapter 12. Now you can see the
benefits of using standard connectors for all the pieces of your projects. If you
built the RF Probe project, all you have to do is disconnect the RF sensing unit
from the RF Probe project, connect it to the Arduino protoshield used on this
project and you're almost ready to roll.
Figure 14.2 shows the Fritzing diagram for the On-Air Indicator. You can
see where we've replaced the bar graph LED from the RF Probe project with
an LED and a relay driven by a 2N2222A transistor. Whenever you use a relay
in this manner, be sure that the relay has an internal clamping diode, or add one
externally to prevent reverse voltage from damaging the transistor when the
relay is de-energized. As a general rule, I always include a 1N4001 clamping
diode (D2) in the circuit design and leave it out if the relay I end up using has
an internal clamping diode.
14-2 Chapter 14
On Air Indicator DS1
n-'
U R1
4700
J1
-11·- L 2
I
To RF Sense Unit
Indicator J
Relay
BT1
9V
i Out
1N4001
D1
-- l.ll. S1 K1
... Power HK19F-DC5V-SHG
ARRL 1119
The Sketch
Start
Figure 14.3 shows the flowchart for the sketch used in
Define Variables this project. With projects as straightforward as the On-Air
Indicator, you may not need a flowchart, but I have found
that it helps to flowchart every sketch. It's a good habit to
get into and helps you stay on track as you write the sketch.
'' With a flowchart, even if your sketch building is interrupted,
Setup you can use the flowchart like a checklist and pick right back
up where you left off. In keeping with the Erector Set theme,
Setup Digital 1/0 Pins
Setup Analog Input Pin the sketch for the On-Air Indicator is based on the sketch we
used in the RF Probe project.
Now that you have the circuit wired up and ready to go,
it's time to write the sketch itself. Starting out, we'll define
1'
the 1/0 pins and signal threshold, along with the LED delay
Loop and relay hold delay. You may have noticed that the Arduino
1/0 pins are usually defined at the start of the sketch. This is
Read RF Probe Input
Turn on LED and Relay if done to give the 1/0 pin a name that we can remember. It's a
RF input threshold exceeded whole lot easier to remember that digi talWri te (relay,
ARRL1120
Figure 14.3 - On-Air Indicator flowchart.
We'll also need to define a few variables to keep track of things in the
sketch. Here we've introduced the Boolean variable type. Boolean variables
are used to indicate an on or off, high or low, true or false binary state. Boolean
variables use less memory than other variables and work well in simple yes/no
decision points within your sketch. You will also note that the variable type for
the timeout value is an unsigned long integer. This is needed since we will be
using the Arduino mi 11 is ( ) function to determine when to turn off the LED
and relay. The mi 11 is ( ) function returns an unsigned long integer value,
so we will need to use variables with the matching variable type to be able to
calculate the turn-off time.
int Signal Strength= O; II stores the value coming from the RF sense unit
unsigned long timeout= 0; II stores the timeout time
bool on air false; II indicates that the on air indicator is active
The setup () loop for the On-Air Indicator is used to set the pin mode
for the LED and relay control pins and to make sure they are turned off before
the main loop () begins. As you can see, using the defined names for the pins
rather than the pin number makes it much easier to follow what the sketch is
doing.
In the main loop () , we read the analog signal strength and if the value
exceeds the predefined threshold, the LED and relay are turned on. The hold
delay is then added to the current value of mi 11 is ( ) . As long as the signal
strength exceeds the threshold value, the delay timer continues to be added to
the current mi 11 is ( ) value.
When the signal strength drops below the threshold, the sketch continues to
check for the current mi 11 is ( ) value to exceed the time saved in the timeout
variable. When the current time exceeds the stored value, the LED and relay are
turned off.
14-4 Chapter 14
J2
~w
Indicator
ARRL1121 Relay
Out
K1
HK19F-DC5V-SHG
R2
470 Q DS1
4700
~ ~ ~ 0 M N ~ 0 m 00 ~ W ~ ~ M N ~ 0
u 0 w z ~ ~ ~ ~ 0 0 0 0 0 0 0 0 0 0
rnrna:: 0 o o o o
I I <
I I
U1
I I
Arduino Uno R3
I I
I I
'- I -=--=--=--=--=--=--=--=--=--=--=--: I
I I
To
RF Sense
Unit
digitalWrite(relay, HIGH);
digitalWrite(LED, HIGH);
timeout= millis() +hold time; II set the timeout time
on air = true;
II If we've passed the time out time, turn off the relay and LED
if (millis() >t imeout && on_air)
digitalWrite(relay, LOW);
digitalWrite(LED, LOW);
on air = false;
Once the project and sketch were debugged and working on the breadboard,
the schematic (Figure 14.4) was used to build the Arduino protoshield and the
finished project was mounted in a SparkFun Arduino project case. Figure 14.5
shows the finished project.
Enhancement Ideas
You can tum this project into a wireless On-Air Indicator if you were to
use an Arduino Nano and mount all the components, including the RF sensing
14-6 Chapter 14
unit inside an LED lightbox with a clear front plate and a mask for the On-Air
lettering. You could power everything with batteries, use a small antenna for RF
sensing extending outward from inside the box, and hang it on the wall outside
your shack whenever you're operating.
References
SparkFun Electronics - www.sparkfun.com
K. Austerrniller, KB9STR, "An RF Driven On-Air Indicator," QST,
Aug 2004, pp 56-57.
J. Noakes, VE7NI, "The 'No Fibbin' RF Field Strength Meter," QST,
Aug 2002, pp 28-29; Feedback Sep 2002 QST, p 88.
1. 5917969
0.4174367
1. 7 : 1
One of the fun things about the Arduino is that there are more and more new
devices and modules available for it all the time. This project was originally
designed to be just a standard digital SWR meter. While ordering some of the
enclosures I was planning to use for my projects, I came across the Ernie 2 text-
to-speech module. Suddenly a whole range of new project ideas came to mind.
The first thought was my typical, "How cool would it be to have an SWR
meter that could speak and tell you what the SWR is?" This was quickly
followed by the realization that the Ernie 2 text-to-speech module would open
Nokia
5110
LCD Display
SWR
Arduino Uno Emic2
Sense
Text To Speech
Module
Module
ARR L1122
15-2 Chapter 15
on the fly. The Ernie 2 communicates with the Arduino using a standard TTL
serial port at 9600 baud and works well with the Arduino Software Serial
library, allowing you to use any two digital 1/0 pins to connect the Ernie 2 to the
Arduino. The Ernie 2 is a fully self-contained module that includes a 300 mW
on-board audio power amplifier and a standard 3.5 mm audio jack. The output
volume can also be controlled from within your sketches. Figure 15.2 is a block
diagram of the project.
J1 J2
~--1-----------r
>-../
R1
T1
49.9
R2
49.9 Single-turn windings formed by
short lengths of RG-58 coax
02 through toroid cores.
1N5711 Ground shield at one end only.
chl
1200pF
rc2
l1200pF
NOTE:
T1 and T2 wound on FT50-43 toroid cores .
10 turns for 10 watt unit,
31 turns for 100 watts
VFWD tip ring VREF
tip~ring
~ shield
Stereoiack
rear view
HBK0627 3.5 mm stereo jack
Figure 15.3 - SWR sense head schematic from The ARRL Handbook.
C1 , C2 - 1200 pF, 50 V capacitor. T1, T2 - FT50-43 toroid core; 10 turns
01, 02 - 1N5711 Schottky diode. for 10 W unit, 31 turns for 100 W unit.
J1, J2 - S0-239 coax jack or builder's R1, R2 - 49.9 n, 114 W resistor.
choice. Radio Shack (P/N 270-238) aluminum
J3 - Ya inch mini stereo phone jack. project enclosure
15-4 Chapter 15
Arduino and Related Hardware
Now that we have all the parts and pieces ready, we can use the Fritzing
diagram (Figure 15.6) to start breadboarding up the Arduino side of things.
Whatever you do, don't forget to include the 5.1 V Zener diodes (D2 and D3)
on the SWR sense head inputs to the Arduino. These diodes are there to prevent
any SWR signal input voltages from exceeding 5 V and potentially damaging
the analog inputs of the Arduino. Also, notice that the Ernie 2 module is not
connected to the standard Arduino serial pins 0 and 1. We will be using the
Arduino Software Serial library to communicate with the Ernie 2 on
digital 110 pins 2 and 3.
U3
Nokia 5110 LCD Module
I 1
J1 !=:::::==~====:=;=====! ~~ •. .ii
To SWR Sense Unit
D2
1N4733 1
- - - - . ' Dl
1N4001
BTl
9V
51
frltz.ing
The Sketch
With the circuit ready on the breadboard, we can start putting together the
sketch. While this may seem like a somewhat complicated project, using the
flowchart in Figure 15.7 we can break it down into bite-size pieces. For me,
that is the key to writing Arduino sketches. When you look at them as a whole,
they may seem difficult and complex. When you break the sketch down into
Start
Define Libraries
Define Variables
Define Nokia LCD
Define Text to Speech Serial Port
Setup
Loop
ARRL 1124
15-6 Chapter 15
smaller pieces, you soon realize that it really isn't that difficult at all. They key
is to plan things out ahead of time, and you can use your flowchart like a map to
stay on course. You can find the complete sketch and libraries for this project in
Appendix A and online at www.wSobm.us/Arduino.
In the initialization part of the sketch, we start by defining the Nokia 5110
LCD display and the Software Seria l libraries, assigning the I/O pins,
and initializing the library objects:
Next, we'll define the constants and variables used in the sketch. Since we
want to calculate voltage from the digital values provided by the Arduino's
analog-to-digital (AJD) converter, we define the conversion value for one
AJD count. Since the SWR voltages will be small and we'd like them to be as
accurate as possible, we'll use the float variable type for these variables.
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(audio on, INPUT);
digita l Write(audio on, HIGH); II Enable internal 20K pullup resistor
Next, we'll start the Software Ser ial port and configure it for 9600
baud, which is the default baud rate used by the Ernie 2. We'll also start the
Nokia LCD and show a brief startup message so we can tell that things are
In the final portion of the setup () loop, we'll initialize the Ernie 2
module, select the voice we want to use, and set the volume level. Note that if
your sketch seems to hang at this point, check the connections to the Ernie 2,
as the sketch will not continue until it receives the colon(:) character from the
Ernie 2 to indicate that it is online and ready to accept data.
Now we're ready to start the main lo o p ().First we read the forward and
reverse voltages coming in on the Arduino analog input pins. The values are
then converted to their actual voltages and displayed on the Nokia LCD.
15·8 Chapter 15
glcd .print("Fwd:", 0 , 0 ); II Display the SWR inf ormation on the LCD
glcd.pr i nt ("Ref:",0, 8 );
Next we'll calculate and display the SWR. As an error check, if the reflected
voltage is higher than the forward voltage, the SWR is reported as 0. To protect
your equipment, don't transmit without either an antenna or dummy load
connected to your radio. Also, you should not transmit when the SWR at the
transmitter exceeds 3: 1 unless your transmitter has an internal tuner and can
adjust the SWR to a safe level. Many modem radios also have SWR protection
circuits to limit the transmitter power output when high SWR is detected, but
that is not a good reason to tempt fate. If your SWR exceeds 3: 1, troubleshoot
and repair the problem, and do not transmit at full power until you have the
SWR within a safe range for your transmitter.
For my testing and calibration, I used a TEN-TEC Rebel Model 506 QRP
CW transceiver with the output set to 3 W, and compared the SWR readings
into a 50 n dummy load and my GAP Challenger HF vertical antenna with a
Diamond SX-600 SWR/power meter. The SWR readings between the Diamond
SX-600 and my homebrew SWR sense head were within 5% of each other on
both 20 and 40 meters, and no adjustments or modifications were needed on the
SWR sense head.
Now for the fun stuff. We'll check to see if the Audio Enable switch on
digital I/O pin 7 is turned on. If it is, we'll have the Ernie 2 speak the SWR for
us.
II Send the Ernie 2 the command to speak the text that follows
ernicSerial.print('S');
II Send the Ernie 2 the New Line character to signify end of text
ernicSerial.print('\n');
I*
Wait here until the Ernie 2 responds with a '' ·" indicating it's ready to
accept the next command
*I
while (ernicSerial. read () != ':');
Once the circuit and sketch were tested and debugged, the finished project was
moved onto an Arduino protoshield using the schematic diagram in Figure 15.8.
The completed project was mounted inside a clear Solarbotics Mega S.A.F.E.
enclosure to protect the Arduino and internal components from the elements.
Enhancement Ideas
With proper shielding, you could use a smaller Arduino such as a Nano, and
house the entire project inside the SWR sense head project box. The Ernie 2 text-
to-speech module opens up a wide variety of enhancement options, such as using
the module to provide an alert when the SWR exceeds a preset level. We had
hours of fun coming up with phrases we would have the SWR meter speak when
it encountered alarm conditions, most of which cannot be repeated here. You
could also add an RGB LED to indicate the SWR status for those times when
you don't want the distraction of the speech module. Finally, it would be ideal to
add the forward and reflected transmitter output power to the display and have
the Arduino speak the power as well. All you would need to do is calibrate the
forward and reflected SWR voltages to a known-good power meter, calculate the
power based on the readings, and display them on the Nokia LCD.
References
Diamond Antennas - www.diamondantenna.net
GAP Antenna Products - www.gapantenna.com
Grand Idea Studio - www.grandideastudio.com
Henning Karlsen - www.henningkarlsen.com/electronics/
Parallax- www.parallax.com
15-10 Chapter 15
+5V
R1
LS1
470 Q
ToSWR
Sense Unit
GNO
Forward Power Voltage
Reflected Power Voltage
0µFc~ 1pc2
0.01
1N4733
02
03
1N4733
µF
ARRL1125
RadioShack - www.radioshack.com
Solarbotics - www.solarbotics.com
TEN-TEC - www.tentec.com
Notes
1"A Microprocessor Controlled SWR Monitor'' by Larry Coyle, K1QW, appears in Chapter 24,
Station Accessories, of the 2010 to 2014 editions of The ARRL Handbook for Radio
Communications. In my 2013 edition the project is on pages 24.4 - 24.9.
2 J. Grebenkemper, KA3BLO, "The Tandem Match - An Accurate Directional Wattmeter," QST,
16-2 Chapter 16
Precise Time Signals
Shortly thereafter, I got involved in a team effort to get the JT65-HF digital
communications mode running on the new TEN-TEC Rebel Model 506 QRP
CW transceiver. The Rebel is an Open Source QRP CW transceiver based on
the Digilent chipKit Uno32, an 80 MHz variant of the Arduino Uno. The Rebel
uses a Texas Instruments AD9834 direct digital frequency synthesis (DDS)
integrated circuit to generate the transmitted signal as well as the IF mixing
signal for the receive side of the Rebel. Through the use of some serious magic
and some absolutely amazing coding by Joe Large, W6CQZ, the team came up
with a method to actually command the chipKit Uno32 in the Rebel to shift the
AD9834 DDS transmit frequency on the fly to generate the 64 tones necessary
for JT65 .
Since the Rebel is an ideal portable QRP transceiver that can go with you
just about anywhere, we wanted a way to acquire accurate time anywhere for
the JT65-HF mode to function correctly. The JT65 -HF protocol requires that a
transmission must start at precisely 1 second into a new minute. If you 're out in
the middle of nowhere with no Internet access to NTP (Network Time Protocol)
time servers, your only option is to set the time manually on the workstation
running the JT65-HF software. We wanted the JT65 operations on the Rebel to
be totally self-sufficient and not rely on any external time source for the time
synchronization. The light bulb came on, and a GPS interface was quickly built
on a modified Arduino protoshield and mounted on the chipKit Uno32's shield
expansion pins inside the Rebel. Our Rebel prototype can now provide accurate
time and location, and as an added treat, it can also calculate and display your
current Maidenhead grid locator. (Hams usually just call these "grid squares."
See the sidebar, "Maidenhead Grid Locators.")
Ok, so what if you don't use JT65 or don't have a Rebel? Well, many of
the contests, particularly the VHF contests, use your grid square as part of the
contest exchange. If you're into mobile operating, it's difficult to keep track
of your grid square as you travel down the road. It's also cool to have this
project around for Field Day and other portable events, providing accurate time,
altitude, and grid square information.
.. '.~""""·-, ·~T
®sl(YLAB
SKM53
16-4 Chapter 16
150028.000 - UTC Time in hhmmss.sss
3458.8015 - Latitude in degrees and minutes ddmm.mmmm
N-North Latitude
09001.3496 - Longitude in degrees and minutes ddmm.mmmm
W - West Longitude
1 - Position Fix Indicator. A "l" indicates the reading is in GPS SPS mode
and the fix is valid
9 - The number of GPS satellites used to determine the position fix
0.90 - The Horizontal Dilution of Precision (HDOP) of the fix
93.7 - Altitude above mean sea level
M - Altitude reading is in meters
-30.0 - The Geoids Separation value (correction for tidal influences)
M - Geoids reading is in meters
*55 - Message Checksum
And the answer to your next question is yes, if you plug these numbers into
your GPS, you will find yourself on top of the work table in my lab, give or
take a few meters. As you can see, there is a lot of valuable information packed
into an NMEA sentence. Fortunately, there is a pair of excellent libraries for
the Arduino that handle the decoding of the GPS messages, without us having
to parse out all that data manually. The Arduino T in yGPS and TinyGPS++
libraries from www.arduiniana.org are outstanding for any sketches needing
to extract data from your GPS module. For this project, we will be using the
TinyGPS library.
To kick things up a notch, we'll also be using the Ernie 2 text-to-speech
module we used in the last project to have our GPS project speak the time and
our current Maidenhead grid locator. This can come in real handy for those
times you're operating mobile and don't want to take your eyes off the road.
Figure 16.3 shows the block diagram for the Talking GPS/UTC Clock and
Grid Square Indicator. For this project, we'll have the Arduino read the GPS,
Nokia
5110
LCD Display
Speaker
ARRL 1126
0 0
U4
Nokia 5110 LCD Module
0
Rl
470Q
U3
GPS Module
Ernie 2
Text To Speech Module
U2
BTl LSl
9V
1N4001
01
Sl
fdtz:.ing
16-6 Chapter 16
The Sketch
With everything wired up and ready to go, we can now begin to write the
sketch. Using the flowchart in Figure 16.5, we have all the steps laid out in
the order that we need to do them. As you will see as we get into the sketch,
it really is as easy as the flowchart makes it look. The libraries do most of the
work for us; all we have to do is "glue" the various pieces together. The entire
sketch and libraries can be found in Appendix A and online at www. wSobm.
us/Arduino.
Starting off with the sketch, you will see that we include a library we
haven't discussed yet. The Arduino ma th. h library is a library of extended
math functions that is included with the Arduino IDE, so all we have to do is
define it to gain access to its features. For this sketch, we need the ability to
calculate the absolute value of a floating variable. The basic Arduino math
functions do not have this ability, so we add that functionality using the
ma th . h library.
#inc lude <math.h> II so we can get absolute va lue of floating point number
Start
Include Libraries
Define Pins and Variables
Define Nokia LCD
Define Text to Speech Serial Port
Define GPS Serial Port
Setup
Loop
Read GPS
Extract Lat, Long , Time , Altitude
Check Speech Enable Switch
Speak GPS info if enabled
ARRL 1128
Now, we'll include the Software Serial library for the Ernie 2 and
GPS modules. You will note that the RX pin on the Ernie 2 module and the TX
pin on the GPS module are defined as -1. This tells the library that these pins
will not be active when we initialize the modules later in the sketch. The reason
we don't enable these pins is because the Software Serial library doesn't
like to share time between the two modules. Since we have data coming in from
the GPS constantly, we can't sit in a loop waiting for the Ernie 2 to respond
with its usual":" ready for input prompt after we send it data. We'll have to
assume the Ernie 2 is ready and accepting data as we send it. Again, you could
use an Arduino Leonardo to work around these issues and place one of the two
modules on the Leonardo's hardware serial port, but since we've standardized
on the Arduino Uno for now, we'll do it the hard way. In actual operation, you'll
see that everything comes together and plays well with each other.
Here we include the Tin yG PS . h library, assign the GPS 110 reset pins,
and define the GPS object:
16-8 Chapter 16
Next, we'll declare the gpsdump () , feedgps () , and getgps ()
TinyGPS . h library functions. They are declared here so the set u p () loop
can find and use these functions.
long lat, lon; II long integer for latitude and longitude function
float LAT, LON; II floating integer for latitude and longitude values
int year; II Variable to hold the year value
int gps_altitude; II Variable to hold the altitude value
int gps_tick = 0, gps timeout= 120; II GPS startup timer variables
byte month, day, hour, minute, second; II variables to hold date and time
unsigned long fix age, time, date, chars;
String s date, s time, s_month, s year, s day, s hour, s_minute, s second,
II Variable arrays of characters and numbers for the Grid Square function
char A_Z[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
a z[27] = "abcdefghijklmnopqrstuvwxyz";
grid[7];
In this sketch we have a lot going on in the setup () loop. First, we'll set
up the Arduino pins used by the Nokia LCD, Ernie 2, and the GPS. We'll also
set up the input pin for the Audio Enable switch and turn on its internal
20 kn pull-up resistor.
II set up the serial IIO pins for the Text to Speech module
pinMode(emic_rxPin, INPUT);
pinMode(emic txPin, OUTPUT);
Next, we'll wait for the GPS to acquire the satellites. The sketch will wait
for up to 2 minutes to acquire a location fix. From a cold start, the SKM53 data
sheet says that the maximum time for a satellite fix from a cold start takes a
maximum of 36 seconds. Indoors in my lab, I have seen the satellite fix take up
to a minute and a half, so the timeout is set for 2 minutes. From a warm restart,
the SKM53 will usually acquire the GPS satellites in 30 seconds or less. The
LCD will display a message indicating that we are acquiring the satellites and
show the timeout timer as it counts down.
gps. g et_posi t ion ( &lat , &lon , &fix age ); II Read the GPS
getGPS ();
gl cd . p rin t (" No Sat . Fi x ", CENTER , 16 );
II Di sp la y the timeout timer
glcd.prin t ((" "+ St r i n g( gps t i meout - gps tick ) +" "), CENTER,40);
dela y (l OOO);
gps ti c k+ + ; //Wa i t a second and decrement the t i meout t i me r
16-10 Chapter 16
In the last portion of the setup ( ) loop, we'll configure and start up the
Ernie 2. Remember, because we're running two Software Serial ports,
we're not checking the Ernie 2 status, assuming everything is okay and it is
accepting data, but we'll add a half-second delay when we send data to the
Ernie 2 to ensure it has time to process the commands.
II Read GPS Latitude and Longitude into lon, lat and fix_age variables
gps.get_position(&lat, &lon, &fix_age);
II Read the GPS Data and Time into data, time and fix age variables
gps.get_datetime(&date, &time, &fix_age);
Once we have the GPS data, we'll convert the date and time into strings so
we can format them for the LCD display:
Next we'll display the latitude, longitude, the number of satellites used
to calculate the position fix, along with the date and time on the LCD . The
LCDS 11 O_Basic. h library has some handy formatting functions when
displaying floating numbers. Here, the glcd. printNumF () library function
is used to select the length, number of decimal places, and the separator
character when it outputs floating type variable data.
glcd.print("S",78,0);
glcd.print("W",7 8 , 8 );
16-12 Chapter 16
II Display the Time
glcd.print(s_hour + ":" + s_minute + ":" + s second,36,32);
Next, we'll use a function to calculate the Maidenhead grid locator from
the latitude and longitude, and display it along with our altitude. The SKM53
can determine altitude up to 18,000 meters, so even if you do your next Summit
On The Air (SOTA) operation from the Himalayas, you'll still have an accurate
altitude reading.
emicSerial.print(grid_ text[x));
emicSerial . print(" ");
If we did not acquire valid GPS data, we'll display that on the LCD and also
speak it if the audio output is enabled:
II We did not get valid GPS before the startup timed out
glcd.clrScr();
glcd . print("NO GPS Data",CENTER,40); II Display No GPS Data message
if (digitalRead(audio on) LOW) II Only speak if Audio is enabled
if ( feedgps () )
{
newdata = true;
if (newdata)
gpsdump(gps);
while (GPS.available())
if (gps.encode(GPS.read()))
return true;
return 0;
16-14 Chapter 16
Lastly, we have the Gr idSquare () function used to calculate our
Maidenhead grid locator:
grid[4) =a z[grid_long 3) ;
grid[5) a z [grid_la t 3) ;
return;
Once the project was fully debugged and operational on the breadboard, the
protoshield, consisting mainly of connectors for the Nokia display,
Ernie 2 and GPS modules, Audio Enable switch, and speaker connections
was constructed using the schematic in Figure 16.6, and the finished assembly
mounted into a Solarbotics Mega S.A.F.E. enclosure.
Enhancement Ideas
This is one project I would really love to downsize with an Arduino Nano
to fit inside an Altoids mint tin, turning it into a true shirt-pocket GPS and grid
square display. It will be a tight fit, but I think it can be done. You could also
upgrade to the TinyGPS++ library, which allows you to extract data from
anywhere within the NMEA sentences, allowing you much more flexibility
with the data you have available to display. You could also add code to provide
course and velocity output, as well as adding in "course to" code so you can use
the GPS as a navigational aid. This project turned out to be a lot of fun to design
and construct, and I can see a great many uses for it in the future .
16-16 Chapter 16
U4 Nokia 5110
0 +3.3 v
SCL ~ () w ~
:Joooocr: u~
u Cl z
> :.J Cl
SDA 5 4 3 2 1 6 7 8
AREF
R1
GND
RESERVED D13
IOREF D12
RESET ,
)>
D11
+5V
3V
a. D10
s::
5V ...... D9 vcc
:l c U3
GND2 0 ..... DB GND
GND1 c Speech Enable NC
4
Skylab
:l
VIN 0 D7 RST SKM53 GPS
5
D6 RXD
~r
:::0 Module
LLJ 6
AO D5 TXD
A1 D4
1N4001 D1 A2 D3 +5V
A3 D2
GND
J_
9V -=-BT1
A4/SDA
A5/SCL
D1
DO 3
5V
SOUT
U2
EMIC2
4
-J, 5
6
SIN
SP+
SP-
Text to Speech
Module
I
LS1
ARRL1 129
References
American Radio Relay League - www.arrl.org/digital-modes
Arduiniana - www.arduiniana.org
Arduino - www.arduino.cc
Grand Idea Studio - www.grandideastudio.com
Henning Karlsen - www.henningkarlsen.com/electronics/
Parallax - www.parallax.com
Skylab Technology Company - www.skylab.com.cn
SparkFun Electronics - www.sparkfun.com
Solarbotics - www.solarbotics.com
Summits on the Air - www.sota.org.uk
TEN-TEC - www.tentec.com
Iambic Keyer
---- ----
It really can't be said enough: the Open Source world is a wonderful place.
It's like having a whole Internet full of developers working side by side with
you and sharing everything they do. When you start out working with a new
module or project, take some time to look for similar projects and ideas on
the Internet. While you may not find exactly what you have in mind for your
project, there's a good chance you can find someone who has been where you
are now and has a similar project you can adapt or that can help you on your
way.
Such is the case with the Iambic Keyer project. Electronic CW keyers have
been around for decades, using technologies ranging from vacuum tubes to
microprocessors. I remember way back when the Curtis keyer chips were hot
off the press, and I built my first electronic keyer with the Curtis 8044 chip
in 1977. Naturally, I had to build an electronic keyer project for the Arduino.
Having been away from the CW world for a while, before I started out with this
project, I did some searching on the Internet to see how far keyers have come
since my last keyer project.
Keyer Design
Now that I had a good idea of what I was going to do, the next step was
to figure out how to do it. Turning to the Open Source community, I did some
searching and came across a nice little keyer project for the Arduino that, with
minor adaptation, would be perfect for the task. "The Arduino Iambic Keyer"
by Steven T. Elliott, KlEL (see the References) had almost everything I wanted
in my Iambic Keyer project for the Arduino; it just needed a few things added
to make it into exactly what I had in mind. Rather than reinvent the whole
wheel, now all I have to do is add my features to the nice foundation Steve has
provided. This is the power of the Open Source community and I thank Steve
for allowing me to adapt his work into this project.
ARRL11 30
Nokia
5110
LCD Display
Speed ~ Sidetone
Potentiometer -----11._ Out
In "-:::==============~
17-2 Chapter 17
Starting out, we'll create our block diagram (Figure 17.1) to determine the
basic functions in our keyer. We'll be using a SPDT center-off switch to choose
the keyer mode. In one direction the switch will select Iambic Mode A, and in
the other direction it will select Iambic Mode B. The center-off position will
allow us to use either paddle as a straight key. We'll also add a potentiometer to
adjust the keying speed. For this project, we'll have the keying speed variable
between 5 and 35 WPM. For outputs, we'll have our keyer send a tone to the
speaker or key a relay to drive a rig. We'll also have an LED to indicate when
the keyer is sending. Lastly, we'll use a Nokia 5110 LCD to display mode and
speed settings.
As you can see from the Fritzing diagram in Figure 17.2, we have quite
a few external components on this project, and we'll be using most of the
Arduino Uno's digital I/O pins, as well as one of the analog pins. Even with the
number of external components, wiring this project up on the breadboard should
not take much time at all.
I
0 0 U2
ARRL1131
DS1 Nokia 5110
LCD Module
Key Oo
S2
Mode Switch
R2 L
4700
J1
U1
LS1
Sidetone
BT1
9V
~ 1N4001
R1
' 01 1k0
--- JJ.!. S1
. . . Power
LCD5110 glcd(l2,ll,10,8,9);
extern uint8 t SmallFont[];
17-4 Chapter 17
Start
Include Libraries
Define Pins and Variables
Define Nokia LCD
Setup
Loop
No
Iambic Mode A
Paddle Keying
Complete code
element when
paddle released
No
Iambic Mode B
Paddle Keying
Send Opposite code
element when
paddle released
ARRL11 32
In the setup ( ) loop, we start out by defining all of the digital 1/0 pin
modes we'll need to use to interface with all the external pieces we have on the
breadboard. You will see how much more readable all this setup is by defining
the pins with an understandable name. This also allows you to easily switch
your pins around if you would prefer to connect the external components to
different pins, or you make a wiring error and would rather change the pin
assignments than rewire your circuit.
17-6 Chapter 17
Next, we'll initialize the Nokia 5110 LCD and output a startup message.
With this sketch, you'll see that we have assigned a string variable for each line
of text on the LCD display and use a function to update the display. This will
allow us to update multiple lines on the display simultaneously without having
to print to every line of the LCD every time we want to update the display.
glcd .I n i t LCD( 60 );
gl cd .se t Fo nt( SmallF o nt);
In the next part of the set up ( ) loop, we initialize the keyer state machine
and the control byte. We also read the SPEED potentiometer and map the analog
voltage input from the SPEED potentiometer to a value between 5 and 35 WPM.
We then call the loadWPM () function to set the keyer speed to the value read
from the SPEED potentiometer.
keyerState = I DLE;
keyerContro l = O;
II Rea d t he p oten tiometer to determine code speed
key_speed = map (ana l o g Read (Spee d_Pi n),1 0 ,10 0 0,5, 3 5);
l oadWPM( key_ s p e ed) ; II Set the ke ying speed
In the final section of the set up ( ) loop, we clear and display the starting
status of the keyer on the Nokia display:
In the main loop () , the first thing we do is read the current setting on the
SPEED potentiometer and update the keyer sending speed and the speed display
on the LCD if the speed has changed.
Next we check to see if the keying mode has been changed and update the
LCD display only if the mode has changed:
key_mode = 0;
text3 = "Mode: Iambic-A";
key_mode = l;
text3 = "Mode: Iambic - B";
key_mode = 2;
text3 = "Mode: Straight";
II Update the LCD and save the new mode only if it has changed
i f (key_mode != last_mode)
17-8 Chapter 17
Next, we check to see if we are in straight key mode or iambic keying mode.
If we're in straight key mode, we just use either paddle as a keying input, turn
on the LED, key the keying relay, and play the sidetone as the paddles are
pressed.
Here is where Steve Elliott's keyer code comes into play. Using a switch ...
case () statement, we check the various conditions of the state machine and
set the keyerControl variable's bits accordingly.
break;
break;
break;
17-10 Chapter 17
The last state of the state machine is to set the inter-element spacing
between the code elements:
break;
The Functions
There are four functions used in this sketch. The first, update
PaddleLatch (), is used to update the status of the keyerControl byte
when a paddle is pressed:
The loadWPM () function calculates the desired dit timing from the
selected words per minute:
ditTime = 1200lwpm;
void updatelcd() II clears LCD display and writes the LCD data
glcd.clrScr();
glcd.print(textl,CENTER,0); II Line 0
g l cd.print(text2,CENTER,8); II Line 1
glcd.print(text3,CENTER , 16); II Line 2
glcd.print(text4,CENTER,24); II Line 3
glcd.print(textS,CENTER,32); II Line 4
g l cd.print(text6,CENTER,40); II Line 5
text2 textl;
text3 textl;
text4 textl;
text3 textl;
text4 textl;
texts textl;
text6 textl;
As you can see, there is a lot going on inside the iambic keyer portion of
the sketch, but because Steve had already done this part of the sketch, we saved
a lot of time and effort by utilizing his sketch as a foundation and wrapping
our modifications around it. This is part of the fun of the Arduino and Open
Source; you're rarely totally alone and as this sketch proves, there's most likely
someone out there doing something similar to what you're wanting to do and
sharing their work to help you with your project.
Once you have everything working on the breadboard, you can use the
schematic in Figure 17.4 to build your keyer on an Arduino protoshield and
mount the finished project into a Solarbotics Mega S.A.F.E. enclosure.
Enhancement Ideas
Between Steve Elliott's keyer sketch and my enhancements, there's really
not much more I can think of adding to this project. The one idea that does
come to mind is to shrink the project down using an Arduino Nano, rearranging
the controls, fitting everything into a single-height enclosure, and mounting
your keyer paddles on top, turning it into a self-contained portable keyer for that
next Field Day or other portable operating event.
17-12 Chapter 17
U2 Nokia 5110
J2
+3.3V Cl :c
2~
z Ol
u
u ~ u w ti
:JUClClUO:::
CJ ::::; >
8 7 6 5 4 3 2 1 1 Out
""""'
R3
D2
1N4001
L __ J Keying Relay
R2
~
J1 DS1 4700
MODE
1
Right Paddle
2
Gnd
3
Left Paddle
o~ < ~ Q
a w z M~ ~ """" """" om c00
N """" 0
cncna:::CJoooo
<(
LS1
U1
Arduino Uno R3
<( -'
Cl u
0
<(
""""
<(
N
<(
~ ~ ~
<( <( <(
+5V
R1
'----+<SPEED
1 kO
ARRL 1133
17-14 Chapter 17
CHAPTER18
Waveform Generator
20 kQ
8 bit Digital to
Bit7 Analog Output
10 kQ
20 kQ
Bit6
10 kQ
20 kQ
Bit5
10kQ
20 kQ
Bit4
Digital 1/0 Pins 10 kn
from Arduino
20 kQ
Bit3
10 kQ
20 kQ
Bit2
10 kQ
20kQ
Bit 1
10 kQ
20 kQ
BitO
10 kQ
ARRL 1134
18-2 Chapter 18
Figure 18.2 - The resistor ladder Figure 18.3 - The resistor ladder
digital-to-analog converter output at digital-to-analog converter output
200 Hz. It doesn't look bad at all here. at 6 kHz. You can see where the
waveform is starting to show
stairstepping.
Figure 18.4 - The resistor ladder Figure 18.5 - The resistor ladder
digital-to-analog converter output digital-to-analog converter output
at 13 kHz. You can see where the at 27 kHz. The waveform is so badly
waveform is getting badly distorted distorted now that we can't really tell
with noticeable stairstepping. if it's a sine or a square wave.
was so distorted that it was more like a bad square wave than a sine wave as
seen in Figure 18.5. It was the same way with a triangle wave, except the
distortion was very noticeable at 8 kHz, and at 12.5 kHz the triangle wave
was distorted to where it began to look more like a very bad sine wave than a
triangle wave.
I tried multiple versions of the sketch and did all that I could think of to
optimize the waveforms, including direct calculation of the sine wave rather
than using a pre-defined table. The results were every bit as bad, if not worse.
Even using the Arduino's digital I/O port register I/O method that outputs to
eight digital I/O pins with a single digi talWri te () didn't improve things
very much. It was pretty obvious that for any frequency above 800 Hz, this
design wasn't going to provide a clean, stable waveform unless I moved up to
a faster Arduino such as the Due. I felt that was a bit too big of a step for what
should be a simple waveform generator project, so it was time to fall back and
regroup.
18-4 Chapter 18
Figure 18.7-The Analog Devices AD9833 waveform
generator module.
generate clean and stable waveforms up to 37 .5 MHz, perfect for use in amateur
HF transmitter or receiver designs. The AD9850 can generate signals up to
62.5 MHz and the AD9851 can generate signals up to 90 MHz. However, since
the AD9834, AD9850 and AD9851 don't generate triangle waves, and this
project's initial design called for generating sine, square, and triangle waves,
with no requirement for generating waveforms higher than 20 kHz, the AD9833
seemed to be the best candidate for the job.
The Analog Devices AD9833 is a digitally programmable waveform
generator, capable of generating sine, square, and triangle waveforms from 0 to
12.5 MHz. It has dual 28-bit frequency registers and can achieve a resolution
of 0.1 Hz with a 25 MHz reference clock rate. Even higher resolutions can be
achieved by using a lower frequency for the reference clock. The AD9833 also
has two 12-bit phase registers, allowing the phase of the output signal to be
shifted from 0 to 720° (0- 2n). The AD9833 uses a 10-bit DIA converter to
generate the output waveform. Sine waves are generated using an on-chip sine-
wave lookup table in internal read-only memory (ROM), requiring no external
calculations to generate smooth, 10-bit sine waves across the entire frequency
range. The output signal from the AD9833 is approximately 0.6 V peak-to-
peak.
The AD9833 is controlled through a single 16-bit multi-function control
resister. The upper two bits of the control register are used to determine if the
command is a control command, frequency register 0 or 1 command, or a phase
register command. Since the frequency registers are 28 bits each, two 16-bit
writes are required to load the frequency registers. Command register options
allow you to control how the frequency registers are loaded, giving you a
number of options for frequency control and selection.
Final Design
Finally, we have a circuit that looks like it can do what our design calls
for. Using the block diagram (Figure 18.8), we'll use an AD9833 to generate
the waveforms, an SPDT center-off switch to select among sine, square, and
triangle waves, and a 1 kQ potentiometer to control the output frequency. We'll
use an LM386 audio amplifier chip to boost the output of the DDS module to
provide an output signal strong enough to drive a speaker. We'll also have a
potentiometer on the LM386 to control the output level.
Now that we finally have all the pieces in the right order, we can create our
prototype circuit using the Fritzing diagram in Figure 18.9. In spite of all the
difficulties determining the best way to build this circuit, the actual hardware
involves only a handful of wires and external components. We'll have the
AD9833 attached to the Arduino's SPI bus and the 16-character by 2-line LCD
display connected to the FC bus.
ARRL1135
Speaker
AD9833
DDS Arduino Uno Output 1.------1._ Signal
Amplifier Out
Module
Square if(
SPOT Switch _ _/__
Off= Sine Triangle~ c~----'
Frequency
18-6 Chapter 18
Waveform Generator
Figure 18.9
-Waveform -""l i c1
,., 10µF
Generator
U2 R2
Fritzing diagram. AD9833 10k0 11
- U3
LM 386
• ii
S2
Waveform Select U4
16x2 LCD
BT1 9V
..
S1 ARR L 1136
The Sketch
Figure 18.10 shows the flowchart we will use to design
Start our sketch. After initialization and setup, the sketch will read
Includ e Libraries the sine/square/triangle WAVEFORM SELECT switch, read the
Define Pins and Variables
FREQUENCY potentiometer, and set the output waveform and
Define LCD
frequency of the DDS module accordingly.
As I mentioned earlier, most of the Analog Devices DDS
chips are interfaced using the same 1/0 methods and register
Setup control bits, so I was able to adapt an existing sketch designed
for the AD9837 DDS that I found online to use as the core
Setup Digital 1/0 Pins
Initialize LCD functions in the Waveform Generator sketch.
Initialize DDS Starting out with creating the sketch, we'll need to include
the SPI. h library for the AD9833, and the Wire.hand
LiquidCrystal _ I2C. h libraries for the 16x212C LCD,
along with our pin and other definitions. The complete sketch
Loop
can be found in Appendix A and online at www.wSobm.us/
Read Sine/Square/Triangle Switch Arduino.
Read Frequency Potentiometer
Set DDS Frequency/Wave Type
A RRL 1137
Figure 18.1 O - Waveform Generator flowchart.
Next we'll define the variables we'll need and create the LCD object:
II set the LCD I2C address to Ox27 for a 16 chars and 2 line display
LiquidCrystal I2C lcd (l cd_address ,l cd_end ,l cd_lines );
In the set up ( ) loop, the majority of the work is spent setting up the 16x2
LCD and displaying a brief startup message so you know everything is going
well to this point.
In the last part of the setup ( ) loop, we define the pin modes for the
AD9833 and the WAVEFORM SELECT switch, enable the 20 kn internal pull-up
18-8 Chapter 18
resistors on the WAVEFORM SELECT switch pins, initialize the AD9833, and start
the SPI bus. Note that the AD9833 requires SPI Mode 2 to communicate via
the SPI bus. SPI Mode 2 will clock the data from the Arduino to the AD9833
on the falling edge of the SCK signal. Failure to select SPI Mode 2 will cause
communication issues with the AD9833, since the default mode for SPI is
Mode 0, where the data is clocked out on the rising edge of the SCK signal.
II Enable the Internal Pullup Resistor on the Square wave Control Pin
digitalWrite(Square_wave, HIGH);
II Enable the Internal Pullup resistor on the Triangle wave Control Pin
digitalWrite(Triangle_wave, HIGH);
delay(lOO); llA little set up time, just to make sure everything's stable
The main loop () for the sketch is relatively short and to the point. The
majority of the work dealing with the AD9833 is handled by two function calls.
Next, we'll update the AD9833 frequency and mode settings if anything
has changed. We "debounce" the FREQUENCY SELECT potentiometer to
There are two functions used to communicate with the AD9833. The
Wri teFrequencyAD 9833 () function is used to set the selected frequency
and waveform type:
II
int MSB; //variable for the upper 14 bits of the frequency
int LSB; //variable for the lower 14 bits of the frequency
int phase O; II variable for phase control
18-10 Chapter 18
float AD9833Val = 0.00000000; II variable to calculate frequency word
AD9833Val = AD9833Val * 2;
II
Finish calculating the frequency word
calculated_freq_ word = AD9833Val*Oxl0000000;
WriteRegis terAD9833 (wave data ); //Write the Waveform type to the AD9833
The Wri teReg ist erAD9833 () function is the part of the sketch that
performs the actual SPI bus transfer of data from the Arduino to the AD9833.
Once the Waveform Generator was finally up and running on the breadboard,
the output amplifier circuit was added. I chose to use a Texas Instruments
LM386 audio power amplifier chip. The LM386 is a single power supply
voltage, self-contained audio power amplifier, with a selectable gain from 20
to 200, bandwidth of 300 kHz, and an output of 325 mW. I chose the LM386
over a standard op amp because the LM386 does not require a feedback resistor
or any other external components to operate at its default gain of 20. The 300
kHz bandwidth of the LM386 was more than adequate for what the design of
the Waveform Generator called for. If you desire your Waveform Generator to
operate up to the full 12.5 MHz bandwidth of the AD9833 DDS module, you'll
need to replace the LM386 circuit with an op amp circuit capable of handling the
higher frequencies .
Once the LM386 was added to the breadboard, along with a IO-tum IO kQ
potentiometer on the input to the LM386 for level control, we could create the
finished schematic for the Waveform Generator (Figure 18.11). The finished
project was soldered up on an Arduino protoshield and mounted in a SparkFun
clear pcDuino/Arduino enclosure. The external switches, FREQUENCY SELECT
potentiometer and output jack were mounted to the enclosure shell (Figure 18.12).
18-12 Chapter 18
Vee U2
AD9833
+5V
6
Voo OUT
3 Output > 4 - -- --o
7 FNC 7 C1 Output
t-:--o--v
vn
REF Level
CLK
4 Select Waveform 5 +
2
GND DAT
5
Center Off= Sine Wave
1 8 10µF o--A J1
LM386 ~
U1
Arduino Uno R3
U4 16x2 LCD
_J 0
u z
Cf) (.'.)
+5V
R3 R4
4.7 kO 4.7 kO
ARRL 1138
Figure 18.12 -
Inside view of
the finished
Waveform
Generator.
Enhancement Ideas
Since this project ended up way beyond being just
an audio frequency waveform generator, there's a lot
Figure 18.14 - Square wave output
of the AD9833 at 10 kHz.
you can do with it. The potentiometer used to control the
waveform generator has set limits, and if you increased the
range of the potentiometer, you would lose your ability to
accurately set a frequency. Replacing the potentiometer
with a rotary encoder and an SPDT center-off switch
would allow you to use the switch to select three different
frequency stepping sizes (for example 1 Hz, 100 Hz
and 10 kHz), and you could tum the rotary encoder
continuously until you dialed in the exact frequency
without having to tum it forever across the entire
12.5 MHz range. You could also add a control to adjust the
phase shift of the output waveform. You could add a five
position band switch and use this as the basis for an HF
Figure 18.15 - Triangle wave output
of the AD9833 at 1o kHz. band VFO, or even a QRP transmitter. This is one of those
projects that is only limited by your imagination. I started
out being somewhat leery of the DDS modules, and now
that I know how easy they really are to use, I can think of a
whole list of projects I want to use with them.
18-14 Chapter 18
Figure 18.16 - Measuring the accuracy of the Waveform
Generator.
References
Analog Devices - www.analog.com
Arduino Playground - playground.arduino.cc
RadioShack - www.radioshack.com
SparkFun Electronics - www.sparkfun.com
Texas Instruments - www.ti.com
PS/2 CW Keyboard
As I've said earlier, CW has always been one of my first loves. However,
over the years I've gotten away from it in favor of the digital modes, unless it's
ARRL Field Day, then I'm planted somewhere on 20 or 40 meter SSB . But,
I've recently wanted to get back into CW, and while my CW receiving speed is
getting there, my sending "fist" leaves much to be desired. I don't get the usual
"QLF" (Try sending with your left foot) reports. If there was such a thing, I'd
more likely get something more like "QSF" (Are you sending with someone
else's foot?) signal reports. I mean, my CW fist is bad, really, really bad.
Still, I enjoy working CW when I can, so I came up with the PS/2 CW
Keyboard. This was actually one of the very first Arduino projects that I built.
Originally, the project was built with an Ardweeny, but, as all early projects go,
I wanted to upgrade it to an Arduino Uno in version 2 to make it look nicer, and
to take advantage of the built-in voltage regulator on the Uno. Also, this was my
16x2 I2 C LCD
Reed Relay
Key
...,_,__.,.....,....>----out
Arduino Uno
Keyboard
Piezo Speaker
PS/2 CW Keyboard
LS1 D2
Key Out
1N4001
----=--=-n
To PS2 Keyboard
DIN Connector
R1
4.?kO
~ U2
Power
9V
ARRL1140
19-2 Chapter 19
chance to clean up the circuit board, as the Ardweeny version had been built on
a standard piece of perfboard and was shoehorned into the project enclosure.
Now, the new version of the project fits on an Arduino protoshield and looks
much nicer.
For the PS/2 CW Keyboard, I wanted to use a standard PS/2-style keyboard,
with variable sending speeds, and the ability to send either an audio tone to
a speaker or plug into the standard key jack of a transmitter. I also wanted to
be able to experiment with the EEPROM onboard the Arduino, so the PS/2
CW Keyboard would have five user-programmable 40 character memories
that retain their information, along with the last selected sending speed and
keying mode, after a reset or power-off. Finally, I also wanted to be able to tum
the LCD backlight on or off via the keyboard. Figure 19.1 shows the block
diagram.
Now that we know what we want our PS/2 CW Keyboard to do, the
next step is to assemble a circuit prototype on the breadboard as shown in
Figure 19.2. The older PS/2-style keyboard was chosen for its simple interface
and availability. For the PS/2-style keyboards, all you need to do is connect the
Data and Clock lines, along with power and ground, from the PS/2 keyboard
to the Arduino. The communication between the Arduino and the keyboard is
handled by the PS2Keyboard. h library found in the Arduino Playground.
For use with the PS/2 CW Keyboard sketch, the PS2Keyboard. h library had
to be modified to support the Fl-Fl2 keys, so when you compile your sketch, be
sure to use the library in Appendix A, or download the modified library from
www.wSobm.us/Arduino.
Include Libraries
Define EEPROM Data Format
Define Pins and Variables
Define LCD
Setup
Loop
Read Keyboard
Save Macro to
Selected Function Key
Yes
(F1-F5)
Insert = Create
End= Done
F10 =Save
No
19-4 Chapter 19
entering the message, press the END key, and the message will be assigned to the
selected function key and saved in the Arduino's onboard EEPROM. When you
save an entry to any memory function key, the current sending speed and keying
mode are also saved to the EEPROM. Since the CW memory data, the sending
speed and keying mode are stored in the Arduino's onboard EEPROM, they will
be reloaded automatically any time you reset or power cycle your Arduino.
Also, if you want to save the current sending speed and keying mode at any
time, just press the FlO key. This will store all of the current CW memories and
operating parameters to the Arduino's onboard EEPROM.
Since the Arduino's EEPROM isn't part of the storage normally used
for variable data, we have to manually handle the reading and writing of
information to the EEPROM. The eeprom. h library does a lot of the work
for us, but we still have to manually define the format needed for the data we'll
be storing in the EEPROM. We'll also be defining our own command, the MI N
statement, used to determine the minimum of two values.
Next we'll define all the constants and variables used in the sketch:
19-6 Chapter 19
,,,, ,.
String F3 data
String F4 data "''.,
String F5 data "".,
Next, we'll define the structure of the data we'll be storing in EEPROM:
/*
* ~eeprom_data
is the magic name that maps all of the data we are
* storing in our EEPROM
*/
struct ~eeprom_data II The structure of the EEPROM data
II set the LCD address to Ox27 for a 16 chars and 1 line display
II The display is a 2 line display, but we only want scrolling on one line
LiquidCrystal I2C lcd(lcd_address,lcd_end,lcd_lines);
//default to beep on pin 11, key speed to 15wpm and enable the speaker output
Morse morse(beep_pin, key_speed, beep_on);
In the last portion of the set up () loop, we'll read the contents of the
EEPROM and save them into RAM:
II Read the EEPROM data for the current mode (Beep or Key)
eeprom_read(morse_beep,e_beep);
19-8 Chapter 19
In the main loop, we wait for a key to be pressed on the PS/2 keyboard, then
use a swi tch ... case () statement to determine what to do with the incoming
characters. The first thing we do is check to see if it is a command that needs
special handling. You'll notice that the logic is already included to decode most
of the keyboard characters, but only a few are actually used.
II Check Macro select and select this key if not already selected
if (macro select)
else
break;
break;
19-10 Chapter 19
We then duplicate this operation for the F2 thru F5 keys:
if (create_macro)
II Check Macro select and select this key if not already selected
if (macro select)
else
break;
break;
if (create macro)
II Check Macro select and select this key if not already selected
if (macro_select)
else
break;
break ;
if (create_macro)
II Check Macro select and select this key if not already selected
if (macro select)
else
break;
break;
if (create_macro)
19-12 Chapter 19
II Check Macro select and select this key if not already selected
if (macro select)
else
break;
break;
Again, the F6 through F9 keys are decoded, but do not have any actions
assigned to them:
We can use the Fl 0 key to save our current CW memory data, sending
speed and keying mode to the EEPROM at any time:
We use the Fl 1 and F12 keys to switch between the beep and keying modes:
lcd.noAutoscroll();
led.clear();
led.home();
l cd.print("Select" +macro+" Key"); II Display F-Key Selection Message
lcd.setCursor(lcd_end,lcd_home);
lcd.autoscroll();
create macro = one; II Set the Create macro flag
macro data -"''
- ,· II Clear the macro data
break;
19-14 Chapter 19
save_macro(); II Save the Macro data to EEPROM
lcd.print(macro +"Saved"); II Display "Saved" on the LCD
else {
II Aborting - Don't save and display "Aborted" on the lCD
lcd.print(macro +"Aborted");
II We're all done with the Macro, clear the screen and reset the flags
lcd.setCursor(lcd_end,lcd_home);
lcd.autoscroll();
create macro zero;
macro select zero;
break;
As the last step in the swi tch ... case () statement, the default action is to
do nothing and continue on through the loop:
As the last step in the main loop ( ) , we handle the building of the CW
memory entry if we are creating one, check to see if we've ended the creation of
a CW memory entry, or just send the character normally.
lcd.noAutoscroll();
led.clear();
led.home();
II Display that we're ready to enter Macro data for the selected key
lcd.print("Enter" +macro);
c = toupper(c); II convert the character to uppercase
lcd.setCursor(lcd_end,lcd_home);
lcd.autoscroll();
else {
II Select the Macro Key
if (c == PS2_END) II Check to see if we want out
{
macro select zero; II Reset the Macro Flags
create macro zero;
if (morse_ beep)
return key_speed;
if (morse_beep) {
Morse morse(beep_pin, key_speed, one); II beep
else {
Morse morse(key_pin, key_speed, zero); II keyer
return key_speed;
II Trim the function key data if longer than the memory key buffer
if (macro_data.length() > (buflen - 1))
19-16 Chapter 19
case PS2 Fl:
Fl data macro data;
break;
II The EEPROM ID byte is used to signify the EEPROM has valid dats
id= 18; II set the EEPROM ID Byte
morse_speed = key_speed; II set the keying speed
morse_beep = l ; II set the beep mode
fdata = Fl data;
m data() ; II Format the data for writing to EEPROM
eeprom_write from(xF, eFl ,buflen); II Write the Data to EEPROM
fdata = F2 data;
m_data(); II Format the data for writing to EE PROM
eeprom_write from (xF, eF2,buflen); II Write the Data to EEPROM
fdata = F3 data;
m_data(); II Format the data for writing to EE PROM
eeprom_write from(xF , eF3 ,buflen); II Write the Data to EEPROM
fdata = F4 data;
m_data (); II Format the data for writing to EE PROM
eeprom_write from(xF , eF4,buflen) ; II Write the Data to EEPROM
fdata = F5 data ;
m_data(); II Format the data for writing to EEPROM
eeprom_write from (xF , eF5,buflen); II Write the Data to EEPROM
The m_data ( ) function is used to convert our memory key variable data
to a format that can be written to and read from the EEPROM.
II This routine figures out where to write the variable data in the EEPROM
char yFl[buflen];
int i = 0;
if (fdata.length() > (buflen - 1)) II trim the data to the right size
{
fdata = fdata.substring(O, (buflen - 1));
yFl[i] fdata.charAt(i);
i++;
yFl [i] O;
i = 0;
II place the data in the variable one character at time
II to write to the EEPROM
while (yFl [ i] != 0)
{
x F[i] = yFl [i];
i++;
xF [i] 0;
19-18 Chapter 19
void send_ma cro ( String F Key data ) II Function to Send the Macro data
char send_data[buflen);
int i = 0;
The mode set () function is used to select either audio tone or keying
mode:
if (morse_beep)
int free_memory;
if((int) brkval == 0 )
free_memory ((int) &free_memory ) - ((int)& bss end );
else
free_memory ( (int) &fr ee_memory) - (( int ) brkval );
return free_memory;
LS1 To PS/2
Keyboard
DIN
Connector
~ < ~ 0 M N ~ 0 m ro ~ ID ~ ~ M N ~ 0
~ ~ ~ 0 0 0 o o o o o o o o o o
60
I I <!:
I I
U1
I I
Arduino Uno R3
I I
I I
'-- I --=---=---=---=---=---=---=---=---=---=---=--= I U2 16x2 LCD
I I
_J 0
0 z
(!)
CJ)
R3 R4
+5 v ,__4.7 kO 4.7 kO
_______ ____.
19-20 Chapter 19
PS2Keyboard. h libraries. They were also the first libraries I had to dig
into and modify. The Morse. h library had a couple of encoding errors
with some of the Morse code characters, which were easily resolved. The
PS2Keyboard. h library did not support some of the extended characters
such as INSERT, END, and the Fl through F12 Keys. It was relatively easy to
Figure 19.6 - The flexible keyboard I use with the PS/2 CW Keyboard for
portable operation.
Enhancement Ideas
With the low number of external components, this project would easily fit
inside a smaller enclosure such as a mint tin or similar small enclosure. You
could use an Arduino Nano and an organic LED (OLED) display to shrink this
into a project you could carry in your pocket. If you'd prefer not to use a PS/2-
style keyboard, you could use an Arduino Uno with the USB host shield and a
standard USB keyboard. You could also optimize the memory utilization and
give yourself more CW memory function keys by moving all of the constant
variables into the Arduino flash memory using the F ( ) macro or the PROGMEM
statement with the avr /pgmspace. /h library.
And the best part of this whole project: now I can send near-perfect CW and
nobody has to know how bad my CW sending ability really is. I've had a lot of
fun with the PS/2 CW Keyboard in contests, where I've had a lot of the required
contest exchange and CQs stored in the memory function keys, allowing me
time to log the contact on the computer while the keyboard is off sending CQ,
looking for the next contact.
References
Arduino - www.arduino.cc
Arduino Playground - playground.arduino.cc
CadSoft - www.cadsoftusa.com
Fritzing - www.fritzing.org
SparkFun Electronics - www.sparkfun.com
19-22 Chapter 19
CHAPTER 20
\.
:\'
.. .,,......
..
:\,
·::\
The Field Day Satellite Tracker was the second major Arduino project I
attempted. The Satellite Tracker described here provides azimuth and elevation
rotation for a pair of model satellite antennas to demonstrate how the tracking
software and automatic antenna positioning work. The Satellite Tracker uses
SatPC32 satellite tracking software and follows actual amateur satellites, just
like a real antenna system. It was originally created as a proof-of-concept
prototype for a full-scale satellite azimuth and elevation controller for my Yaesu
G5400 satellite antenna rotator. Somewhere along the way, the project took on a
life of its own and our club has used it at many of our outdoor and public events
such as ARRL Field Day and ARRL Kids Day.
At our club's last ARRL Kid's Day event, we had both the Satellite Tracker
and a full-size satellite antenna array up and running with its own Arduino-based
I 16x2 I 2 C LCD
I
'l
Azimuth I
Servo
PC ~~
--
Ardweeny
RS232 In
-,.
---~--'"'--'"-
I Elevation
Servo
ARRL1143
20-2 Chapter 20
rotate and tilt our antenna model. Servos are small, powerful, geared motor
assemblies often used in robotics and radio controlled models that use the
width of a pulse on a digital I/O pin to determine how far they should rotate.
Servos are very accurate and move quickly to the desired position. Your typical
servo has a range of travel from 0 to 180°. This is fine for elevation rotator
positioning, but we need a range of 0 to 360° for azimuth rotation if we're going
to get the PC to think we're a real rotator. Since the standard servos don't have
that range of motion, we'll use a model sailboat multiple tum "sail winch"
servo. The sail winch servo works on the same principle as a regular servo,
except that it can tum up to seven full rotations, which makes it perfect for the 0
to 360° rotation we'll need for the azimuth portion of the Satellite Tracker.
Circuit Highlights
This project is built using a Solarbotics Ardweeny, shown in Figures 20.3
and 20.4. The Ardweeny uses the same Atmel ATmega328 processor used
in the Arduino Uno, except the supporting components are mounted on a
backpack-style circuit board that is soldered directly to the pins on the ATmega.
This gives you the equivalent of an Arduino Uno that has a very small footprint
and fits in a standard 28 pin IC socket. The Ardweeny does not have a USB
U4
J2 16x2 12C LCD
RS232
Z1 Z2
TxD
C2
1µF/16V
cs
1 µF/16V
U1
C3
-
Ardweeny
1µF/16V
C4
1µF/16V
C1
1µF/16V C7
0.1µF
J1 16V
+12Vdcln
Satellite Tracker
01 ARRL 1144
1N4001
20-4 Chapter 20
serial converter that attaches to the hardware serial port on the Ardweeny. For
power, a small 12 V, 5 Ah gel cell battery attaches to the bottom of the project
enclosure using hook-and-loop fastener strips and plugs into a de power jack
on the side of the enclosure. This makes the entire project portable and self-
powered, which is perfect if you use a laptop PC to run the tracking software.
The servos are controlled by a 5 V pulse on the data line, so they can be driven
directly from the Ardweeny's digital I/O pins. We'll finish things up using a
16-character by 2-line LCD display with an PC "backpack" that communicates
with the Ardweeny using the PC bus.
The Sketch
With everything assembled on the breadboard, we can begin to write the
sketch. When you break the sketch down into a flowchart (Figure 20.7), you'll
see this really isn't a difficult sketch to create. Since the Satellite Tracker looks
exactly like a Yaesu GS-232A azimuth/elevation rotator controller as far as
the PC software is concerned, the key is determining the format of the RS-232
commands the PC will send to the Ardweeny. The Ardweeny will decode the
desired azimuth and elevation information from the RS-232 commands and
translate the commands into servo positioning information. This is done by
mapping the desired azimuth and elevation from degrees into pulse widths to
drive the servos. The Arduino IDE's built-in Servo. h library will handle the
actual positioning of the servos based on the pulse width needed to rotate the
Start l
Include Libraries
Define Pins and Variables
I
Define LCD
Define Servos
- -
'
Setup
Loop
__
Decode Command String
Move Azimuth and Elevation Servos
,
ARRL 1145
LiquidCrystal I2C lcd(Ox27,16,2); II set the LCD address to Ox27 for a 16 chars
and 2 line display
Next we'll define the variables and constants we'll need for the sketch.
The values used for the servo positions are determined manually and will be
different from one servo to another. Adjust these values until your servos are
positioning correctly. The SatPC32 software has the ability to send positioning
commands manually, so you can command the servos to go to 0 and 360° and
modify the values accordingly.
int byte count= O; II the number of bytes received on the Serial port
char az_buffer[4]; II Holds the decoded azimuth command
char el_buffer[4]; II Holds the decoded elevation command
char rotor_buffer[lO]; II The incoming Rotor command data
int set az, set el; II Holds the desired azimuth and elevation data
20-6 Chapter 20
In the setup () loop we initialize the LCD and have it display a brief
startup message so we know everything is working. Then we'll initialize the
servos, start the serial port for communication with the PC, and then move both
servos to the 0° "home" position.
led.clear();
lcd.setCursor(O, 0);
lcd.print("Homing Servos ");
set azimuth(O) ; II Set the Servos to 0 degrees
set elevation(O);
l cd . setCursor(0 ,1);
lcd.print("Elevation: 0,,) ; II Display the current Elevation
lcd.setCursor(O, 0) ;
lcd.print("Azimuth 0,,) ; II Display the current Azimuth
delay(delay2);
In the main loop () , we wait until a character is received on the serial port
connected to the PC:
inByte =Serial.read();
Serial . write(inByte);
We then check to see if the first character is a "W," which is the Yaesu
GS-232A command to move the rotator to the desired azimuth and elevation.
The full command we'll be decoding is "Waaa eee," where aaa is the desired
azimuth in degrees, and eee is the desired elevation in degrees. If it is a "W," we
enable the sketch logic to decode the rest of the command string.
If it is not a "W," we'll start building the strings for the azimuth and
elevation data from the incoming characters if we have already received a "W."
If not, the character is ignored and the sketch continues to monitor the serial
port waiting for the "W" command. We continue to build the azimuth and
elevation strings until we have received a total of eight characters, the length of
the complete move command.
20-8 Chapter 20
move command false; II Indicate we're done with this move command
II Map the desired position to the correct Azimuth servo pulse width
move_azimuth = map(desired_az,360, O,min servo_pulse,max_servo_pulse);
II Send the Servo position pulse to the Azimuth servo
myservoAZ.writeMicroseconds(move_azimuth);
delay(delayl); II Wait for move to comp l ete
Once everything was working on the breadboard, the schematic for the
circuit (Figure 20.8) was drawn up, the circuit was soldered up on a perfboard,
and the finished board was mounted inside a 2 x 4 x 6 inch RadioShack project
enclosure as shown in Figures 20.9 and 20.10. The 16-character by 2-line LCD
is mounted inside the top lid of the enclosure along with the sail winch servo
for the azimuth rotation. The pan/tilt servo assembly for elevation is mounted
to the sail winch servo using a 4 inch section of threaded aluminum tubing I
found at a local hobby shop. A model of a satellite antenna array was built out
of wooden dowels and toothpicks, painted silver to make it look like the real
thing, and mounted on top of the pan/tilt servo assembly. Figure 20.11 shows
the completed Satellite Tracker with its model antennas.
20-10 Chapter 20
Figure 20.9 - Inside view showing the Ardweeny and support
components.
SDX\SDXParam.SQF file to change the settings manually. The first line in this
file is the COM port number and the second line is the baud rate, which must
be 9600 unless you change the baud rate setting in the sketch to match the PC
baud rate setting.
Enhancement Ideas
When this project was originally designed, I was unaware that the Arduino
Nano had an onboard voltage regulator. The Ardweeny could easily be replaced
with a Nano, or even an Uno with a protoshield mounted inside the enclosure,
and the external 5 V regulator portion of the circuit eliminated entirely. You
could also replace the RS-232 interface and use the Nano or Uno's onboard
USB port for the serial link to the software.
The sketch for this project was written for SatPC32 and will not work with
Ham Radio Deluxe (HRD) as it is currently coded. This is due to the fact that
SatPC32 doesn't look for any response from the Ardweeny; it just sends the rotator
control commands and assumes the controller executed them. HRD does a two-
way handshake with the controller and expects a response to the rotator control
commands. The sketch could be easily modified to respond back to HRD with the
positioning information, allowing you to use the satellite tracking portion of HRD
to control the Tracker. One thing to keep in mind, when HRD initially connects
to the rotator controller, it toggles the DTR signal line on the USB interface. The
Arduino Uno and Nano interpret this as a RESET command and resets the Arduino.
As you will see in the full-scale rotator controller projects, adding a capacitor and
a jumper block to the reset line will allow you to enable the auto-reset for loading
your sketch and then disable it for use with Ham Radio Deluxe.
References
Atmel Corp - www.atmel.com
RadioShack - www.radioshack.com
SatPC32 software - www.dkltb.de
Solarbotics - www.solarbotics.com
Yaesu - www.yaesu.com
20-12 Chapter 20
CHAPTER 21
Azimuth/Elevation Rotator
Controller
Based on the success of the Field Day Satellite Tracker prototype, the next
logical step is to build a full-scale Arduino controller for the actual Yaesu
G5400/5500 series azimuth/elevation (az/el) rotator using either SatPC32 or
Ham Radio Deluxe (HRD). For automatic operation, the Yaesu G5400/5500
series rotator controllers are designed to work with the Yaesu GS-232 rotator
computer interface. There are several different models of the GS-232 with slight
differences among them. For this project, shown in Figure 21.1, we will be
emulating the Yaesu GS-232A interface.
The Yaesu G5400/5500 series dual rotator controllers have a built in 8-pin
DIN connector labeled EXTERNAL CONTROL (Figure 21.2). This connector
provides an analog voltage output for the azimuth and elevation values, and
relay control inputs for azimuth and elevation control. Ordinarily you would
connect the Yaesu GS-232 rotator computer interface unit to this connector,
but we're going to replace the GS-232 with an Arduino and have the Arduino
emulate the GS-232 interface. We'll use the Arduino's USB port to interface
with SatPC32 or Ham Radio Deluxe on the PC side of things. We'll also be
using the Arduino's onboard EEPROM to save our calibration settings. This
way, the Azimuth/Elevation Rotator Controller will remember the calibration
data even after a reset or power-off.
•
ADJ ADJ
0 0
Figure 21.3 shows the block diagram for this project. The external hardware
needed is minimal, comprising six resistors, four transistors, a capacitor, and
a Texas Instruments ADSll 15 4-channel, 16-bit 12C analog-to-digital (AID)
converter. You could use the Arduino's built in 10-bit AID converter instead of
the ADS 1115, but you will not have the resolution that the extra six bits of the
ADS1115 provides. The Arduino's AID converter would only read three AID
counts per degree of rotation, versus the 148 AID counts per degree with the
ADSl 115. Any noise on the positioning signals could cause positioning errors.
Since we're tracking satellites, it's worth using the 16-bit AID to get the extra
accuracy.
21-2 Chapter 21
ARRL1147
Yaesu
G5xxx
Rotator
Rotator Drive
~
Position Sense
Yaesu 1 USB
Port PC
G5xxx
Rotator
Arduino Uno
-- -- Running
HRD orSatPC
Control Box
'
Rotator Drive J
. Position Sense l
r-1 I
~
R4
4700
04
2N2222A
03
2N2222A
~·-······- -~ --- - -- ~
-~oe-::::0:::;===11
R3
02
4700
2N2222A
R2
4700
I
R5
4.7k0 ----~""---=
_.....,.. R1
Disable 4700
R6
4.7k0 J2
C1
- - - - - - - _..J.__
1µF
To Yaesu
to do to drive the rotator is use a transistor for each rotator control pin. From
your breadboard, you can build an 8-pin header-to-DIN-plug adapter cable
to connect to the external control socket on the Yaesu controller. When you
move the project to the protoshield, you can use an 8-pin header on the board
to connect the DIN plug adapter cable you've already built. We'll power the
Azimuth/Elevation Rotator Controller from the Arduino's USB connector that
attaches to your PC, so we won't need an external source of power for this
project.
Do not connect the Yaesu rotator controller to your breadboard circuit until
you have calibrated the output voltages on the external control pins. First, use
the Yaesu rotator controller to manually position the antenna to full scale for
azimuth and elevation. Using a voltmeter, measure the voltage between the
ground pin (pin 8) and elevation voltage pin (pin 1). Adjust the ELEVATION OUT
VOLTAGE ADJ potentiometer on the back of the rotator controller for 5 V. Do
the same for the azimuth voltage pin (pin 6) and the AZIMUTH OUT VOLTAGE ADJ
potentiometer. Do not connect the DIN connector to your breadboard until you
have completed this procedure, otherwise you could send a voltage higher than
5 V to the ND converter and damage it. When you have completed the output
21-4 Chapter 21
voltage calibration, you should be able to rotate your azimuth and elevation
rotators and see the output change from 0 to 5 V on each of the voltage output
pins as you rotate the antenna from zero to full scale on the front panel meters.
The Sketch
When I initially began working with the TI ADS 1115 AJD converter, the
ADS 1115 . h and I 2 Cdev. h libraries did not handle the 16-bit data coming
from the ADSl 115 correctly. I had to modify these libraries to correct this
issue. Be sure to use the ADS 1115 . h and I 2 Cdev. h libraries in Appendix A
or download them from www.wSobm.us/Arduino.
Before you can load your sketch, you will need to be sure that the jumper
that ties the 1 µF capacitor (Cl) to the Reset pin is off. This capacitor is used
to block the Reset command that Ham Radio Deluxe accidentally sends to the
Arduino when it toggles the DTR signal line as it begins a connection attempt
to the rotator controller. If you forget to short this jumper after loading your
sketch, Ham Radio Deluxe will not be able to connect to the controller since
the controller will be resetting while HRD is trying to connect to it. However,
you do want to enable the DTR Reset when you load sketches, so be sure and
remove the jumper before trying to load your sketch.
Next it's time to plan out the sketch. Figure 21.6 shows the flowchart for
the sketch and Table 21.1 shows the actual Yaesu GS-232A commands that we
will be implementing. This sketch will use many of the tools and techniques
we've learned from the previous projects. For example, we'll be using the
Texas Instruments ADSl 115 to read the position voltages and we will be saving
the position calibration values in the Arduino's onboard EEPROM. Using the
Arduino's USB port, we will communicate with the satellite tracking software
on the PC. To aid in troubleshooting, we will also implement a debug mode
in the sketch, that when set, will return diagnostic information to the Arduino
IDE's Serial Monitor.
Table 21.1
Azimuth/Elevation Rotator Controller Commands
(Subset of Yaesu GS-232A Commands)
A Stop Azimuth Rotation
B Return Current Elevation Value in Degrees (format +Oeee)
C Return Current Azimuth Value in Degrees (format +Oaaa)
C2 Return Current Azimuth and Elevation (format +Oaaa+Oeee)
D Rotate Elevation Down
E Stop Elevation Rotation
F Set Azimuth Full Scale Calibration
F2 Set Elevation Full Scale Calibration
L Rotate Azimuth Counter-Clockwise
Maaa Rotate Azimuth to aaa degrees
0 Set Azimuth Zero Calibration
02 Set Elevation Zero Calibration
R Rotate Azimuth Clockwise
s Stop All Rotation
u Rotate Elevation Up
Waaa eee Rotate Azimuth to aaa degrees and Elevation to eee degrees
Include Libraries
Define Pins and Variables
Define ADC
Setup
Loop
ARRL11 49
21-6 Chapter 21
From the flowchart, you can see that in the main loop () we decode the
command string from the tracking software on the PC into three basic groups
of functions: status requests, calibration commands, and movement commands.
By using this divide and conquer method, we break the sketch down into
manageable chunks that can be independently created and debugged. The
complete sketch and libraries can be found in Appendix A or online at www.
w5obm.us/Arduino.
Starting out in the sketch, we'll define the libraries and the ADSl 115 object.
We also include a definition for the debug mode. When this definition is set to a
"1", debug information will be sent to the Arduino IDE's Serial Monitor.
Next, we'll define the Arduino digital 1/0 pins used to control the antenna
rotation and the baud rate for the serial port used to interface with the tracking
software on your PC. The baud rate in the sketch must match the baud rate you
have set in the tracking software on your PC.
#define BAUD RATE 9600 II Set the Serial Port Baud rate to 9600
21-8 Chapter 21
int AZ - To; II Requested AZ Move
int EL To; II Requested EL Move
int AZ Distance; II Distance to move AZ
int EL- Distance; II Distance to move EL
In the setup () loop, we'll initialize the digital 1/0 pins and make sure that
all the position control outputs are off:
Now we'll initialize the serial port, the PC bus, and the ADS 1115 AID
converter:
II Connect to adc and send two bytes - Set Config Reg to all Ones
II We do this so when we read the ADC we can be sure we're
II communicating correctly
Wire.write(Oxl);
Wire.write(Ox7F); // MSB
Wire.write(OxFF); II LSB
Wire.endTransmission(); II End the direct ADC Communicat i on
As the final step of initializing the AID converter, we'll set it to free-running
single-ended mode at 4 7 5 samples per second, with a range of 0 to 6.144 V.
As the last step in the setup () loop, the move flag variables are set to -1
to indicate that there is no active rotation command, and the calibration values
(if any) are loaded from EEPROM.
The main loop () for this sketch is rather unique. It consists of only two
statements. The divide and conquer design strategy for this project resulted in
the majority of the work being handled by functions . All the main loop does
is continually check for incoming commands on the serial port, decode and
execute any commands it receives, and handle any commands involving move
commands. Each decoded command will call a function to perform the action
called for by the incoming command.
21-10 Chapter 21
EL_CAL_MAX + l),DEC);
}
if (debug_mode)
II You may need to comment out the following line if your PC software
II will not communicate properly with the controller
II SatPC32 wants the command echoed, Ham Radio Deluxe does not
Serial . print(char(inByte)); II Echo back to the PC
21-12 Chapter 21
serial_buffer[serial_buffer_index] = inByte;
The "C" command will send the current azimuth in degrees back to the
tracking software on the PC. However, this command may actually be a "C2"
command, which needs to send the current azimuth and elevation back to the
tracking software. The length of the command string as determined by the
serial buffer index variable is used to decide what information needs
to be sent back to the tracking software.
if (debug_mode)
break;
The "F" command is another command that can have a secondary function.
The "F" command by itself will read and save the azimuth full scale calibration
value, while the "F2" command will read and save the elevation full scale value.
21-14 Chapter 21
if (debug_mode)
{
break;
The "O" command is used for the zero calibration settings. An "O"
command by itself will save the azimuth zero calibration value, while an "02"
command is used to save the elevation zero calibration value.
if (debug_mode)
break;
When the command has been decoded and executed, the incoming serial
character buffer is cleared and the buffer index is set to 0. The function will then
return to the main loop () to wait for the next command.
II Clear the Serial Buffer and Reset the Buffer Inde x Pointer
serial buffer index = O;
serial_buffer [OJ 0;
21-16 Chapter 21
aaa is the azimuth value in degrees. This function will read the AID converter
and map the value to degrees based on the current azimuth calibration values. A
string is then built using the Yaesu GS-232A format that the tracking software
is expecting, and then sent back to the tracking software via the USB serial port.
Because the G5400/5500 rotators have 0°/360° at midscale, the data has to be
adjusted to return the correct azimuth value.
Seria l .println(current_AZ);
if (debu g_mode)
Serial.println(AZ Degrees);
Serial.println(current_AZ);
Serial . println(current_EL);
II
Map the Elevation to Degrees
EL_Degrees = map(current_EL, EL 0, EL_MAX, 0, 180);
if (debug_ mode)
{
Serial.println(EL_ Degrees);
Serial.println(AZ Degrees);
21-18 Chapter 21
if (AZ Degrees < 10)
The set_max_ az _cal () function is used to save the azimuth full scale
value to the Arduino's onboard EEPROM:
if (debug_mode)
Serial.println(current_AZ);
The set - max- el - cal () function is used to save the elevation full scale
value to the Arduino's onboard EEPROM:
if (debug_mode)
Serial.println(current_ EL);
Therotate_az_ccw(),rotate_az_ cw(),rotate_el_up(),
and rotate_ el_ down () functions control the relays inside the Yaesu
G5400/5500 rotator controller to perform the actual rotation functions. The a z
rotate_ stop() andel rotate stop() areusedtotumofftherelays
and stop rotation.
21-20 Chapter 21
digitalWrite(rotate_down, LOW); II Make sure the Rotate Down Pin is Low
if (debug_mode)
AZ To 0;
AZ To = 360;
AZ To = AZ To - 180 ;
e l se {
AZ To = AZ To + 180;
if (debug_mode)
{
Serial.println(Requested_AZ);
Ser ial .pri ntl n (AZ_To);
II Map it to degrees
if (debug_mode)
21-22 Chapter 21
az rotate stop(); //Stop the Azimuth Rotation
set AZ= -1; // Turn off the Move Command
else { // Move Azimuth - figure out which way
if (AZ Distance > 0) //We need to move CCW
if (debug_mode)
if (debug_mode)
AZ To = 0;
AZ To 360;
21-24 Chapter 21
AZ To = AZ To - 180;
else {
AZ To AZ To + 180;
if (debug_mode)
Serial.println(Requested_AZ);
Serial.println(AZ To);
Serial.println("Value in [5] to [7]?");
EL To = O;
EL To 180;
if (debug_mode)
Serial.println(Requested_EL);
Serial.print ln(EL_To);
II Set Elevation
II No move needed if we're within tolerance range
if (abs(EL Distance) <= EL_Tolerance)
The set - 0- az - cal () function is used implement the "O" command and
saves the azimuth zero calibration value to the Arduino's EEPROM:
if (debug_mode)
21-26 Chapter 21
II save current az and el values to EEPROM - Zero Calibration
if (debug_mode)
The set_ O_el_ cal () function is used implement the "02" command
and saves the elevation zero calibration value to the Arduino's EEPROM:
if (debug_mode)
The read_ adc () function is used to read the analog azimuth and
elevation voltages coming from the rotator controller and converts these values
to raw, uncalibrated, 16-bit digital values using the ADS 1115 AID. The values
are stored in the global variables c urrent_EL and current_AZ, and used
by the other functions to determine the current azimuth and elevation of the
rotators.
if (debug_mode)
{
Ser ial.printl n("Read ADC Function ");
Serial.println(current_AZ);
21-28 Chapter 21
II Map EL to degrees
if (debug_mode)
Serial.println(current_EL);
R4
470 Q R3
R2 470 Q
470 Q R1
4700
I I <
I I
I I J3
I I U1 8-pin DIN
I I Arduino Uno R3
I I
II I- - - - - - - - - - - - - - - - - ,
----~-------------r1
w I I
> <( --'
ffiu..tu
{/) w {/)
N~
0 0
0()
{/) {/)
wO::W>>ZZ~ o~"l<'>;a:lO
o::Qo:: <') l{)C!)C!)> • <(<(<(<(<(<(
U2
ADS1 115
J1 16-bit I 2 C ADC J2
8
DTR Vee -------+--+-___.. Voo AINO 4
R5,R6
Reset 2 10
SCL + C2
Disable 4.7 kQ 9
SDA 147
µF
ADDR
2
ALERT
3
GND A IN1 5
AIN2 + C3
AIN3 47µF
ARRL1150
1
Figure 21.7 - Azimuth/Elevation Rotator Controller schematic diagram.
C1 - 1 µF, 25 V capacitor. Q1-Q4 - 2N2222A NPN transistor.
C2, CJ - 47 µF, 25 V capacitors. R1-R6 - 470 n, Va W resistor.
J1 - 2 pin header. U1 - Arduino Uno.
J2 - 8 pin header. U2 - Tl ADS1115 16-bit analog-to-digital converter.
J3 - 8 Pin DIN female connector. Arduino Uno Enclosure
21-30 Chapter 21
Figure 21.8- The finished Azimuth/Elevation Rotator
controller mounted in a Zigo Arduino Mega enclosure.
to set the zero calibration points. Then, manually rotate the azimuth and
elevation rotators to full-scale and use the "F" and "F2" commands to set
the azimuth and elevation full-scale values. Once you have done that, your
controller is calibrated and the calibration values are stored in the Arduino's
onboard EEPROM. You can recalibrate your controller at any time by repeating
the calibration process. You can now send the various OS-232A controller
commands listed back in Table 21.1 to test all the functions on your controller.
When you're finished, define the debug mode to 0 and upload the sketch with
the debug mode changes. This turns off the diagnostic messages and you're
ready to go.
Now that your controller is calibrated, you're ready to use the controller
with the SatPC32 or Ham Radio Deluxe satellite tracking software on your PC.
Don't forget to short the jumper on capacitor Cl to disable the DTR Reset, and
have the sketch loaded with the debug mode turned off. Configure your tracking
software to use the Arduino's COM port and select the Yaesu OS-232A az/el
rotator controller in your tracking software. Now your 05400/5500 rotator
should move and track the selected satellite.
Once you have everything working on the breadboard, you can build the
circuit on an Arduino protoshield using the schematic diagram in Figure 21.7.
Since this is a project that will be penp.anently located in my shack, I went for
a classier look with the enclosure. I mounted my finished Azimuth/Elevation
Rotator Controller in a Zigo Mega Enclosure (Figure 21.8) and mounted the
8-pin DIN connector on the side of the enclosure. The Zigo Arduino enclosures
are available on eBay and at Amazon.com. I built an 8-pin DIN-to-DIN patch
cable to interface to the Yaesu 05400/5500 rotator controller. We won't need
to connect any source of external power to the Arduino since we'll be using the
power provided by the PC and the Arduino's USB connector.
Enhancement Ideas
There's really not much left to do with this project in the way of
enhancements. Looking at my Yaesu 05400 controller box, there may be just
References
Amazon - www.amazon.com
Ebay - www.ebay.com
Ham Radio Deluxe - www.ham-radio-deluxe.com
SatPC32 software - www.dkltb.de
Yaesu - www.yaesu.com
21-32 Chapter 21
CHAPTER 22
CW Decoder
How many times have you been working CW, gotten distracted and asked
yourself "What did they just send?" It's times like that I wish that I had a
CW decoder handy to double-check myself. Sure, I can fire up the PC with a
soundcard interface and have the PC do the decoding for me, but that can be
cumbersome, especially if I'm operating a portable station in the middle of
nowhere without any ac power.
By now you've seen some projects that can send CW, but what about
receiving and decoding CW? If they can write a computer program for the
PC that uses a soundcard interface to decode CW, then surely we can do
it with an Arduino. All we have to do is convert the CW signal to a digital
pulse and measure the pulse widths to decode the CW. Now for the really
cool part, someone has already created an Arduino library to do just that. The
CW Decoder 22-1
MorseEnDecoder. h library will decode a digital CW signal into the actual
letters and numbers; all we have to do is convert the CW audio tone into a
digital signal that the MorseEnDecoder. h library can use.
Tone Decoder
To do this, we'll use a Texas Instruments LM358 op amp to buffer the CW
audio, and a Texas Instruments LM567 tone decoder chip to convert the CW
tone into a digital signal. By using the LM567 tone decoder, we also have the
ability to limit the decoder bandwidth to help prevent interference from adjacent
CW signals. The LM567 can be used to decode a tone and the output of the
LM567 will go high when the desired frequency is present on the input. The
center frequency and bandwidth of the decoded tone are controlled by the value
of a resistor and two capacitors. To calculate the desired center frequency, you
can use the formula
f,,= 1/(1.1 x RC)
where
R is the resistance (in ohms) across pin 5 and pin 6 on the LM567
C is the capacitance (in farads) on the capacitor between pin 6 on the
LM567 and ground.
The bandwidth of the tone decoder can be determined with the formula
I 16x2 I 2 C LCD
I
••
11
-
11
•Ir
~
Rx LED
cw
Speed ARRL1151
22-2 Chapter 22
Fortunately, there is an online LM567 tone decoder calculator at www.
vk2zay.net to make these calculations much easier for us. Using the online
calculator, a variable center frequency of 455 Hz to 909 Hz, with a bandwidth
of 217 Hz to 300 Hz, was chosen for the CW Decoder project. With the
potentiometer (R6) for the LM567's center frequency at a mid-range value of
5 kn, the center frequency will be approximately 600 Hz, with a bandwidth of
270 Hz.
Now that we know how we can convert the CW audio into a digital signal
the Arduino can use, we can plan our project. The CW Decoder block diagram
(Figure 22.1) shows that we will use the LM358/LM567 circuit to decode the
CW audio signal, and we'll scroll the decoded CW on a 16-line by 2-character
(16x2) LCD display. We will also use an LED on the output of the LM567 as
a tuning indicator. Finally, we'll use a potentiometer to adjust the CW decode
CW Decoder R11
C3 RS 4700 081
10µF 10k0
Level Adj CB
R8
0.1 uF
R2 10k0
R9 1k0 C1 }I ,.
10k0 02
1NS711 U3
01 .L I
1Ns?11 I ,. cs
2.2uF
R4 0.1uF
100k0 R6 10k0
Frequency Adj
Speed
R10
1k0
BT1 R13
9V
ARRL 1152
.,.
. 03
I
S1
I
1N4001
U4
CW Decoder 22-3
speed range. The MorseEnDecoder. h library doesn't handle automatic CW
decode speed adjustments, so we'll need to use the SPEED potentiometer to
adjust the CW decode speed manually.
Now that we have our block diagram, we can start putting all the pieces
together on a breadboard. The majority of this project involves the LM386/
LM567 circuit. Figure 22.2 shows the Fritzing diagram used to build the CW
decoding circuit. Potentiometer R9 will be used to adjust the audio input to the
LM358 op amp we're using to amplify and buffer the audio input to the LM567.
Potentiometer R5 is used to adjust the audio input level to the LM567. The
LM567 requires an input signal level of 200 m V or less to decode properly, so
two 1N5711 Schottky diodes are used as clamping diodes to limit the LM567
input voltage to a maximum of 200 m V. Potentiometer R6 is used to adjust the
center frequency of the CW tone to be decoded. As a starting point, adjust this
resistor to its mid-range point of 5 kQ.
Once you have the CW audio decoding circuit on the breadboard, you can
test and adjust the center frequency. Connect the audio from your receiver to
the audio input of the CW Decoder circuit and tune to a CW signal. You can
also use the waveform generator we built back in Chapter 18 to precisely tune
the center frequency of the LM567. Using an oscilloscope or voltmeter, adjust
potentiometer R9 until the audio input on pin 2 of the LM358 is about 50 m V
ac. The gain of the LM358 is controlled by the values of resistors RI and R2.
For the CW Decoder project, the gain was selected to be 10, which is calculated
using the simple formula Rl/R2. This will provide an output of up to
500 m V on pin 1 of the LM358. Once you have the input on pin 2 of the LM358
adjusted to 50 m V, you can adjust R5 to control the audio level into the LM567.
You'll want to adjust this level to be around 200 mV on your voltmeter.
Next, tune your receiver to output the pitch of the CW
tone that you prefer to listen to. Alternatively, you can use the
Start waveform generator, and adjust its output to the frequency your
Include Libraries ears like best, usually a frequency around 600 to 700 Hz. Adjust
!'
Define Variables potentiometer R6 to find the center of the point where the LED
Setup r2c LCD
(DSI) on pin 8 of the LM567 comes on. Your CW tone decoder
circuit is now tested and tuned to the desired CW pitch.
1J
The Sketch
Setup
Finish hooking the rest of the circuit on your breadboard and
-.-
Initialize r2c LCD we're ready to write the sketch for the CW Decoder. Using the
flowchart in Figure 22.3, you can see that the LM358/LM567
- does most of the work for us, and the MorseEnDecoder. h
library will handle the rest of the work on the Arduino side of
Loop things.
Set CW Decode Speed
Starting out in the sketch, we'll define the libraries we'll
Read CW Input need for the CW Decoder project. You'll note that the sketch
Decode CW Input
Update Scrolling LCD Text
defines the a v r / pgmspace. h library, but you don't see where
it is used in the sketch. The MorseEnDecoder. h library
...___ _ _ _ _ _ _ _A_R_RL_11_53__, stores its CW conversion tables in the Arduino's flash memory,
. CW so the library itself uses the avr / pgmspace. h library. So,
F1gure 22 .3 - 0 ecoder flowchart. . . . .
you effectively have the case of a library usmg a library to
22-4 Chapter 22
get the job done. It doesn't get much more efficient than that. To display the
decoded CW characters, we'll use a 16x2 LCD display with an PC "backpack"
to communicate with the Arduino using the PC bus. The complete sketch can
be found in Appendix A and online at www.wSobm.us/Arduino.
Next, we' ll define the Arduino I/O pins and the variables used in the sketch:
CW Decoder 22-5
In the main loop () , we'll first read the value of the CW receive SPEED
potentiometer. If the receive speed potentiometer value has changed, the
new receive speed will be displayed on the LCD and the receive decode
speed will be updated in the MorseEndecoder. h library. Since the
MorseEnDecoder. h library doesn't auto-detect the speed of the received
CW, the SPEED potentiometer must be adjusted manually to match the receive
speed. This adjustment does not have to precise. Once you start listening
to the incoming CW, you can approximate the speed and adjust the receive
speed accordingly. Since this is a coarse adjustment, you'll find that it's not as
ff'+
C5
IN R11
470 Q
2
C6 2 ~
0.22 µF U3
0.1 DS1
LM567
µF
R5
Adjust 10 kO 1N5711
CB 4 5 R7 10 kQ
02
01
C4 F eq
1N5711
l 1 µF dj
U1
Ar du i no Uno R3
U4 16x2 LCD
--' 0
u z
<fl (.9
R13 R12
4.7 kQ 4.7 kQ
Vee ~-----+-~
ARRL 1154
22-6 Chapter 22
cumbersome as it may seem to be at first. The MorseEndecoder. h library
can handle some variation in the receiving speed internally, so you'll just need
to set the receiving speed close to the actual speed and the library will take it
from there.
II If the Speed Pot has changed, update the speed and LCD
if (current speed != read_speed)
'
a
II Display the incoming character - Set the text to display on line 0 only.
II When length= 15, trim and add to new character so display
II appears to scroll left
if (text.length() >15)
Once you have the circuit and sketch working on the breadboard, you can
use the schematic diagram in Figure 22.4 to build the finished project on an
CW Decoder 22-7
Figure 22.5 - Inside view of the CW Decoder.
Enhancement Ideas
Naturally, the first enhancement that comes to mind is to downsize
everything with an Arduino Nano and a small piece of perfboard, which would
allow you to build the CW Decoder in a much smaller enclosure that would fit
22-8 Chapter 22
in a shirt pocket or mount to your portable QRP CW rig using hook-and-loop
fasteners. You could also modify the MorseEnDecoder. h library, add in the
code needed to implement the auto-speed detection, and have the CW decoder
automatically adjust to the speed of the incoming CW signal. And, since the
MorseEnDecoder. h library also has the ability to send CW, you could add
in the code for an iambic keyer, and use the MorseEnDecoder. h library to
tum the project into a complete CW keyer and decoder all in one small, portable
package.
References
Google - code.google.com/p/morse-endecoder/
LM567 Tone Decoder Calculator - www.vk2zay.net/calculators/lm567.php
Texas Instruments - www.ti.com
CW Decoder 22-9
CHAPTER 23
Lightning Detector
consensus that a lightning detector that did all that would be cool, but existing
lightning detectors were too expensive.
That led to some research on the Internet about lightning detectors, and I
stumbled across the Austriamicrosystems AS3935 Franklin lightning sensor
chip. Not only that, but I found a fully assembled module that would connect
directly to the Arduino. The Embedded Adventures MOD-1016 module (Figure
23.1) incorporates the AS3935 chip and all the support components onto a
module that connects to the Arduino via either the SPI or PC bus. The AS3935
lightning sensor can detect lightning up to 40 km away and provide distance
and strength of the lightning strike. And the best part, the module only cost
$21. Now that we had cleared the "too expensive" hurdle, it was time to get my
hands on one of these modules and start playing.
Around the same time, I was invited by Craig Behrens, NM4T, to present
a forum on the Arduino at the Huntsville Hamfest in Alabama. Craig asked
me to come up with a couple of new and unique ham-related projects for the
presentation. Since I had never seen a lightning detector anywhere, much less
an affordable one, this would be the perfect project for the forum.
Austriamicrosystems AS3935
Franklin Lightning Detector
The Austriamicrosystems AS3935 is a programmable lightning sensor
chip that can detect the presence and approach of lightning, both cloud-to-
ground and cloud-to-cloud. The module can detect lightning at a distance of up
to 40 km and estimates the distance to the leading edge of the storm in steps
of 16 ranges. The AS3935 does this by analyzing the RF signals it receives
23-2 Chapter 23
at approximately 500 kHz. The module has a
Nokia programmable internal capacitor that is used to
5110 tune a small external loop antenna for resonance
LCD Display at 500 kHz. It uses a sophisticated on-chip
algorithm to validate the incoming signal and
can distinguish between man-made noise and
lightning. If a valid lightning strike is detected,
the AS3935 will calculate the energy of the
strike, and then perform a statistical estimate
AS3935
of the distance of the strike. The module can
Lightning l'----- Arduino Uno communicate with the Arduino using either the
Sensor SPI or FC bus.
Figure 23.2 shows the block diagram for
the Lightning Detector. Since you can't always
get lightning to show up when you need it for
testing, a LIGHTNING SIMULATE switch is added so
Lightning - ./'_
Simulate~ ( ARRL 1155 that we can test the sketch logic and simulate a
lightning strike for demonstrations.
Figure 23.2 - Lightning Detector block diagram. I went back and forth over what type of
display to use with this project. The
Lightning Detector 0 0 small 128 x 32 pixel organic LED
(OLED) display I originally used
U3 for the Huntsville Hamfest Arduino
forum was really nice and allowed
me to experiment with bitmap
graphic images, but for demonstration
purposes, the display proved to be
Lightning u2 MOD-1016 a little on the small side. Instead,
Simulate we'll use the larger Nokia display,
which will allow us to show more
information on the LCD and is much
more readable.
When you stop and think about
what this project is actually doing,
it's amazing that it can be built using
just nine signal wires (not including
power and ground connections). Once
again, this shows that you can create
some pretty sophisticated projects
with the Arduino without the need for
81
9V
a lot of external components. Figure
I
I 23.3 shows the Fritzing diagram for
i I D1
1N4001 the Lightning Detector project. You'll
notice that we don't have any pull-
up resistors on the FC connection
ARRL 11 56
to the lightning sensor module. The
Embedded Adventures MOD-1016
Figure 23.3 - Lightning Detector Fritzing diagram. has the necessary FC pull-up resistors
The Sketch
Writing the sketch for the Lightning Detector is almost as easy as wiring it
up. The hardest part was finding an Arduino library for the PC version of the
AS3935. The Embedded Adventures MOD-1016 is pre-wired to use the PC bus
for communication. You can change the soldered jumpers on the board to use
the SPI bus, but I prefer to use the PC bus when possible, and I really didn't
want to solder on the only lightning detector module I had. Most of the libraries
I found online used the SPI bus to communicate with the Arduino. Once again,
the Open Source community rides to the rescue. I was able to locate a modified
version of the SPI-based library that works with the PC version of the AS3935,
and the sketch was good to go.
With the circuit wired up on the breadboard, we can get started on the
sketch. Using the flowchart in Figure 23.4, you can see that the plan is to wait
for a lightning event and display the information about the lightning strike on
the Nokia LCD. We'll keep track of the time since the last lightning strike and
display that also. We'll be using libraries for the AS3935 and the Nokia display,
which will help to simply the work we have to do to create this sketch. The
complete sketch for the Lightning Detector project can be found in Appendix A
and online at www.wSobm.us/Arduino.
As we start out with the sketch you'll see that we use the debug mode to
provide extra diagnostic information as we test and debug the sketch:
Include Libraries
Define Variables
II I 2C a nd AS393 5 Lib r a ries
Setup Lightning Detector #incl u de " I2C . h " II Use th e I2 C Library
Setup Nokia LCD #i n clude <AS3935 .h> II Use the AS4935 Library
#i nclude <LCD5110 Bas i c .h > II Use the Nokia 5110
i
Setup 11
LCD Li bra r y
# i nclude <Wire .h > II I nc lude the Wire
Commun i ca t io n Li b ra ry
Setup 1/0 pins
Initialize Lightning Detector
Initialize Nokia LCD Next, we'll define the Nokia LCD and the AS3935 objects
-' for the library.
+ I*
Loop
23-4 Chapter 23
LCD5110 glcd(12,11,10,8,9); II Assign the Nokia 5110 LCD Pins
AS3935 AS3935(2,3);
Note that we've defined the AS3935 address as 3. The AS3935 is jumper
selectable to one of four different PC address, but we'll be using the default
address that the MOD-1016 module is preset to. Next, we'll define the Arduino
1/0 pins and AS3935 internal registers and settings we'll be using:
#define IRQ_PIN 2 II Define Pin 2 for the Interrupt from the Detector Module
#define SIMULATE PIN 7 II Define Pin 7 for the Lightning Simulation switch
II Defines the Register for the High order bits of the lightning energy
#define AS3935_ENERGY HIGH Ox6,0xlf
II Defines the Register for the Middle order bits of the lightning energy
#define AS3935 ENERGY_MID Ox5, Oxff
II Defines the Register for the Low order bits of the lightning energy
#define AS3935_ENERGY_LOW Ox4,0xff
In the last part of the initialization portion of our sketch, we'll define all the
variables we'll need:
In the setup () loop, we'll start the serial port so we can use the Arduino
IDE's Serial Monitor to see the diagnostic information as we test the sketch.
Then we'll start up the FC bus and set the bus speed to the default speed of
100 kHz. We need to be sure we're at the standard FC bus speed of 100 kHz
to ensure the operating frequency of the bus is not near the 500 kHz receive
frequency of the Lightning Detector. If we were to run the FC bus in Fast Mode
at 400 kHz, we run the risk of interfering with the Lightning Detector's receiver,
potentially causing missed lightning events. Since we go through a tuning test
and verification as part of the setup ( ) loop, this portion of the sketch is a
little more involved than usual.
Next, we'll start the Nokia 5110 LCD and display a brief startup message so
we know everything is working to this point:
23-6 Chapter 23
In my early tests of the AS3935 communications, I had some problems
verifying that the AS3935 was communicating correctly with the Arduino. The
I 2 C . h library incorporates a bus scan function that will display a list of all the
PC devices on the Arduino IDE's Serial Monitor. If the debug mode is enabled,
it will run the PC bus scan function.
Serial.println("Tune Error");
Once we have verified the tuning capacitor value, we'll set it to the
recommended value, and read it back from the AS3935 to verify that the setting
is correct:
Next, you will see a block of code that has been commented out. The
AS3935 uses three internal oscillators to generate clocking signals. The LC
oscillator (LCO) runs at the resonant frequency of the antenna and tuning
capacitor, which should be around 500 kHz. The system RC oscillator (SRCO)
typically runs at 1.1 MHz and the timer RC oscillator (TRCO) runs at 32.768
kHz. The AS3935 has the ability to send the output of these three internal
oscillators to the IRQ pin for monitoring. The AS3935 library uses the output
of the LCO as part of the function to calculate the tuning capacitor value.
You can use an oscilloscope or a frequency counter to measure and fine-tune
these settings if desired. In normal operation these oscillators are calibrated
at initialization by the AS 3 9 3 5 . h library and you'll find that the library
calibration settings work just fine.
I*
Serial.println("Set Disp LCO Reg 8 Bit 7");
AS3935.registerWrite(AS3935_DISP_LCO,l);
delay(lOOOO);
AS3935.registerWrite(AS3935 DISP LC0,0);
Serial. println ( "LCO disp complete") ;
23-8 Chapter 23
Serial . println("Set Disp SRCO Reg 8 Bit 6");
AS3935.registerWrite(AS3935 DISP SRCO,l);
delay(lOOOO);
AS3935.registerWrite(AS3935 DISP SRC0,0);
Serial . println("SRCO disp complete");
*I
In the last portion of the set up () loop, we'll finish setting up the AS3935,
set the receiver gain for indoor use, disable the Disturber (EMI) interrupts since
we're only looking to see lightning and not man-made noise events (more on
this later), and print the contents of the important AS3935 registers to the Serial
Monitor one last time to ensure everything is set up correctly. We'll then clear
the interrupts on the AS3935 to be sure we have a clean start with no false
lightning events, and display a "No Activity" message on the Nokia LCD.
time = timel60;
text6 = String(time);
i f ((time >= 1) && (time <60))
II 1 to 59 minutes ago
{
text6 = text6 + " min ago";
else {
if (time >=60)
time = timel60;
II convert to hours
text6 = String(t ime);
if (time >=l)
if (time == 1)
23-10 Chapter 23
II Delay the start for a few seconds to let everything settle
if (holddown == 1)
if ((millis()llOOO) > holddown time) II If we've passed the hold down time
{
holddown = 0; II Turn it loose
Now we're ready and waiting for a lightning or simulation event. First, we'll
check and see if the LIGHTNING SIMULATE switch has been pressed:
Next, we'll check to see if the AS3935 has generated any interrupts:
Serial.print("IRQ: ");
Serial .print(i rqSource);
Serial.pr int(" ");
Now we'll process the interrupt type. The AS3935 has four types of
interrupts. An interrupt value of 0 (no IRQ register bits set) indicates that the
AS3935 has purged its internal statistics. This is a normal event that occurs
about 15 minutes after the last interrupt event occurs. An interrupt value of 1
(IRQ register bit 0 is set) indicates that a Noise High interrupt has occurred,
while an interrupt value of 4 (IRQ register bit 2 is set) indicates that a Disturber
Now we'll start decoding the interrupts and displaying the results to the
Nokia LCD. The first two interrupts are the Noise High and Disturber (EMI)
interrupts. We don't do anything with this other than display the type of
interrupt and how long ago the last event occurred:
Here's where the fun starts. We'll handle the interrupt for lightning. This
can either be an actual lightning interrupt from the AS3935, or it can be a
simulated lightning event. The AS3935 will report the estimated distance of the
strike in 16 ranges.
23-12 Chapter 23
text2 = "Detected";
if (simulated) II make up a distance if we're faking it
strokeDistance = l;
Once we get the distance, we'll format this information for display at the
next Nokia LCD update:
if (strokeDistance > 40 )
Next, we'll get the energy of the detected strike. If this is a simulation,
we'll make up the numbers. Once we have calculated the estimated energy
of the strike, we'll scale the energy value from 1 to 10 to create an arbitrary
"Lightning Intensity Factor." We'll then format this information to display the
next time we update the Nokia LCD.
There are four functions used to support the Lightning Detector sketch.
The printAS3 935Registers () function is used to display the contents
of the key AS3935 registers. The times tamp () function is used to create a
times tamp to keep track of the time of an event. The update l c d ( ) will clear
the Nokia LCD and display the current contents of the LCD text variables. The
cleartext () function is used to clear the contents of the LCD text variables
in preparation for the next display update.
23-14 Chapter 23
II Read the Noise Fl oor setting
int noiseFloor = AS3935.getNoiseFloor();
II clears LCD display and writes the current LCD text data
void updatelcd ()
glcd.clrScr();
glcd.print(textl,CENTER,0);
glcd.print(text2,CENTER,8);
glcd.print(text3,CENTER,1 6 );
glcd.print(text4,CENTER,24);
glcd.print(text5,CENTER,32);
glcd.print(text6,CENTER,40);
U3 Nokia 5110
i· 'f
+3.3 v :E 0 ~ f-
z -' ~ u w (/)
"'
:.J l? u 0 0 u a:::
6 7 8 5 4 3 2 1 +3.3 v
R1
220 0 Vee
2 U2
cs
S2 3
IRQ MOD-1016
Lightning 4 SCL AS3935
Simulate
5 Lightning
MISO
6 Sensor
SDNMOSI
7
GND
d ~ ~ ~ ~ ~ ~ ~ ~ ~
CIJCfJa:::l?oooo
b 8 ~ d 8 ~ 0 8
I <(
I
I
I
I
I U1
I
1 Arduino Uno R3
I
I
I
--------------------------
--------------------------+-,
[jJ I I
> I I
ffiLLGJ
(/) w (/)
N~
00
~d
(/) (/)
W O:::Q W > > Z Z ~ O ~ ~ M ~ ~
0::: - 0::: M ~ (.? (.? > <( <( ~ <( <( <(
ARRL1158
23-16 Chapter 23
Careful Packaging is Needed
Using the schematic diagram in Figure 23.5, the finished project was built
on an Arduino protoshield, mounted on top of the Arduino Uno, and everything
was mounted in a Solarbotics Arduino Mega S.A.F.E. enclosure. Then it
was back to waiting for the next thunderstorm to test the finished project.
Unfortunately, it was weeks before the next storm, and the discovery of the last
little glitch in the project.
I had originally placed everything inside the enclosure, mainly to protect the
Nokia LCD and the fragile-looking antenna on the AS3935 module. Let's back
up and review how the AS3935 actually works. For all
intents, it is a narrowband receiver tuned for 500 kHz.
In my initial design, I had mounted the AS3935 module
inside the enclosure near the Arduino Uno. As it turns
out, the Uno generates your typical low-grade RF noise
from its 16 MHz oscillator and various clock signals,
including the PC bus. The Nokia 5110 LCD display also
generates some RF noise as it scans and displays the
pixels on the LCD. These factors combined to interfere
with the reception on the AS3935 module, and it would
not detect lightning very well at all. The performance
was nowhere near as good as it had been when it was
on the breadboard. I tried various types of displays and
configurations, having to wait for thunderstorms after
each new design was mounted in the enclosure.
As a last resort, I moved the AS3935 outside the
Arduino enclosure onto a small wooden mast to provide
some added distance from the noisemakers inside the
enclosure. At one point, I had three different versions of
the Lightning Detector sitting around the house waiting
for a storm. As luck would have it, a fairly rare winter
thunderstorm came rolling through one morning, and
I was finally able to verify my suspicions about the
RF noise and determine which design worked best.
The winning design can be seen in Figure 23.6. As a
final touch, we'll use a ping-pong or plastic golf ball to
provide some measure of protection and make the project
look like it has a little radome to add to the cuteness
factor.
Enhancement Ideas
Now that we have a working Lightning Detector,
there are all sorts of interesting features we can add.
After building this project, I discovered the Parallax/
Grand Idea Studios Ernie 2 text-to-speech module we
used in previous projects in this book. Adding voice
output to the Lightning Detector project opens up a
Figure 23.6 - The finished Lightning
Detector module mounted on its mast.
world of possibilities. You can drive a PA system at Field
References
Arduino PC Master Library - www.github.com/rambo/12C
AS3935 Arduino Library - www.github.com/SloMusti/AS3935-
Arduino-Library
Austriamicrosystems AG - www.austriamicrosystems.com
Embedded Adventures - www.embeddedadventures.com
Solarbotics - www.solarbotics.com
B. Smith, K04NR, "A Low-Cost Remote Antenna Switch," QST, Apr 2005,
pp 38-41. This project also appears in the Station Accessories chapter of recent
editions of The ARRL Handbook.
23-18 Chapter 23
CHAPTER 24
COE/Hy-Gain Rotator
Controller
How many times have you come across an antenna rotator at a hamfest that
didn't have the control box? Or maybe lightning zapped your rotator control
box and now you have a working rotator motor, but no way to turn it. Replacing
an antenna rotator control box can get expensive, assuming you can even find a
working one.
Not long ago, a friend of mine, Shawn Braddock, W5SMB, was faced with
this very dilemma. Shawn had acquired a tower with a rotator, but the rotator
controller had long since gone missing. Since I've done a lot of tinkering with
the Arduino and the Yaesu rotator controllers, I offered to build an Arduino-
based controller for his CDE/Hy-Gain HAM-III rotator. This was going to
be a fun challenge. I would have to build the controller completely from
scratch based on the original HAM-III schematics I managed to find online,
and adapt the rotator for Arduino control. (HAM series rotators have been
used by amateurs for decades. They were originally made by Cornell Dubilier
Electronics - CDE - and are now made by Hy-Gain, which is now part of
MFJ. The HAM-M, HAM-II, HAM-III, HAM-IV, HAM-V and Tailtwister
models all will work with this Rotator Controller project.)
I really didn't want to just duplicate the existing controller with an analog
position meter and some switches. If there's an Arduino under the hood, why
not use it and kick things up a notch? The plan is to use an analog-to-digital
Rotator
Rotator Drive
and
Relay Control Position Sense
and Arduino Uno RGB LED
Postion Sense
ARRL1159
Direction~
Control
(AID) converter to sense the rotator position, and have the Arduino drive
relays to control the rotator brake and activate the drive motors. Because we're
controlling all this with an Arduino, let's add in a brake delay that's not in the
standard CDE/Hy-Gain rotator controller. We'll replace the analog meter with
a 16-character by 2-line (16x2) LCD display, plus we'll add an RGB LED to
show the drive motor and brake status.
Now that we know what we're planning to have our rotator controller
do, we'll start out with the block diagram in Figure 24.1. We'll use a two-
position center-off switch to tell the Arduino which way to tum the rotator. To
do the actual motor and brake control, we'll have the Arduino drive three 5 V
relays with 10 A contacts. For the rotator position sensing, we'll use a Texas
Instruments ADSl 115 4-channel 16-bit PC AID converter to read the voltage
coming in from the 500 Q variable resistor mounted inside the rotator housing.
Finally, we'll display the antenna heading on a 16x2 LCD in place of the analog
meter used in the CDE/Hy-Gain control box. We'll have the Arduino display the
antenna bearing in degrees and for fun, we'll also have it display direction arrows
when the rotator is turning, and display a message when the rotator is braking.
We'll also use an RGB LED to indicate the drive relay status just for kicks.
Packaging
Since we're going to need an enclosure for the main rotator power
transformer and all the rest of the goodies, we can't use a standard Arduino
enclosure like we've been using. Putting all this in an Altoids mint tin is
certainly out of the question. For this project, we're going to need a bigger box.
The HAM-III rotator brake solenoid and motors run on 26 V ac at about 3 A. I
bought a used HAM-III controller power transformer online from C.A.T.S. for
$25 since there wasn't much hope of finding one locally. That turned out to be
the most expensive part of the whole project. That's part of the fun about the
24-2 Chapter 24
Arduino. You can create some very complex projects and they're not going to
cost you an arm and a leg. The total cost for this entire project ended up around
$80. That's less than the cost of a used CDE/Hy-Gain controller, and you won't
have anywhere near the fun and sense of accomplishment. Not to mention, the
standard CDE/Hy-Gain controllers don't have a brake delay or PC interface,
so computer control isn't even a possibility without spending a whole lot more
money. Once we have the basic controller up and running, all it takes is a little
extra software to add in the interface for Ham Radio Deluxe or other rotator
control software for your PC.
The next order of business was to find an enclosure large enough to house the
transformer and everything else mounted inside. All of the enclosures available
locally were just a little too short to house the power transformer. After searching
around for an enclosure big enough to hold everything, but not so big as to put
a dent in my budget, I found the perfect selection of enclosures on TEN-TEC's
website. As it turns out, not only does TEN-TEC make radios, they also sell a
complete line of very affordable enclosures. For this project, I chose the TP-49
enclosure in the aluminum finish at a cost of $12. The TP-49 measures 3.25 x
7.75 x 6.25 inches (height, width, depth), perfect for what we've got in mind.
Now that we've got all the major pieces figured out, it's time to start
building our rotator controller. This will be a two-pronged approach. We'll
need to mount everything inside the enclosure, but, since the enclosure is a
plain box, we're going to need to cut some holes and figure out how to mount
things. Before we can start to build the rotator controller, we'll need to design
the circuit and wire everything inside the enclosure. Because we're dealing with
high voltage, we're not going to test this project on the breadboard. Instead,
we'll build everything directly in the enclosure, and do all our testing with the
actual finished controller.
Circuit Details
Even though we're not going to use the breadboard for this project, I still
like to create both a schematic diagram and a Fritzing diagram. Since a Fritzing
diagram is more of a physical representation of the circuit, I find it easier to use
the Fritzing diagram as a wiring guide and check things off on it as I go. I like
to use the schematic diagram in the final steps of construction to verify all the
connections and do any circuit troubleshooting that may be needed.
Figure 24.2 shows the Fritzing diagram for the CDE/Hy-Gain Rotator
Controller project. Don't let the apparent complexity fool you. Many of the
components will be mounted on an Arduino protoshield that will be plugged
onto the Arduino expansion shield headers, and we' ll use header pins and
sockets for wiring that connects to the external relays, LCD, switch, and other
parts. Since we want this to be a standalone rotator controller, we'll also add in
a small 12 V power supply to provide the current needed to power the Arduino
and drive the relays . The circuit may look daunting, but you'll find that the
actual wiring of the project goes smoothly and easily. The hardest part is cutting
all the holes and mounting everything in the enclosure.
Since we're going to be wiring everything in the enclosure, we'll also want
to have the schematic diagram (Figure 24.3) handy. Before we can begin the
actual wiring, we'll need to figure out how and where we're going to mount
.
S4
360 Cal
"'tr
'I
COE Rotator Controller
D2
CCW (Left) Drive 1N4001
02
2N2222A K2
_..,__
R2 CW (Right) Driv
4700 01 l!I
2N2222A ffi
,, D1
--~
R1 1N4001
4 on
J3
To Rotator
U3
16x2 Serial 12C LCD
l!!IJ;;-
T2 h1 F1 03
t1:j 3A K3 2N2222A
I Brake Drive
J1 D3
AC Power 1N4001
24-4 Chapter 24
+5V K2 Left(CCW)
,---,I
ZERO
CALI BRATE
360
~ R2
Po ?o
CALI BRATE
I I I 470
R1
Q2
~25Vac
470
R3
J3
'VY-
470
Q1 r----
R5
470 M m
~
u
~
0
U..
w z
0
C/J(/)Cl'.'.(.?oooo
~
N
~
~
~
0
~ 0
00
0 b (3 ~ 3 8 ~ 0 8
I I <{
Q3
I I
U1
I I 1
Ar du i no Uno R3 I
I I S1
I I
'- I -=--=--=--=--=--=--=--=--=--=--=--=II I
0
w
>
Cl'.'. <{ -'
(") w U.. tLi N ~ 0 u
Cf) w Cf) 0 0 Cf) Cf)
c w Cl'.'.W>>ZZ~
Cl'.'. QCl'.'.MLOl?l?> ~ :;: ~ ~ ~ ~ U5 U4
[!! 7812
:c I I I I I I I
'<I
G) DTR 1
J2 _,._D4
• • • I I I OutREG
Gnd
In I • I
12.6
Vac
II> 1 N4001
Reset 2
:::s + C5 ;+;0.01
µ'l
Disable C6 ...._ ...._C4
:D
s. +5V 1000 ].01 +5 v +5V
-...
U2
II>
0
R9
Ra I ADS1115
16-bit r2 c ADC
R4~4.7 k
(")
4.7 k
47
. k 8 VDD A INO 1
4
l I
-
0 (.) <{ -'
u 1
:::s ~ 0
Cf) Cf) '-----f!----<l>-----0; SCL A IN1
'-------<~----9-t SDA +
0
ADDR
AIN2
AIN3
C311
00 µF
...
CD'
ARRL1 161
U3 16x2 I C LCD 2
~ALERT
3 IGND
N
. -
~
I
(11
everything in the enclosure. Since this involves cutting holes, we'll start by
preparing the enclosure.
First, we'll cut out a hole for the 16x2 LCD and find a place to mount the
big power transformer. I used a drill and a nibbler to cut out the holes to the
approximate shape and then filed the area smooth. Fortunately, the aluminum
enclosure was easy to work with and the hole-cutting went smoothly. Figure
24.4 shows the results.
~ - ~
.i
I . 2·(. .
JJ. .,:..
~sE
-!'
."'"'"-...
14,}1'< '
~
24-6 Chapter 24
On the rear of the enclosure (Figure 24.5), we'll need to cut out the holes
for the ac power socket, fuse holder, rotator connector, and the Arduino's USB
connector. We'll want the Arduino's USB connector brought out to the back of
the box so we can hook up a PC to upload the sketch and for interfacing with
Ham Radio Deluxe or other rotator control software at a later date.
Now that we have the locations of the big parts laid out, the next step is to
mount the LCD, POWER switch, ROTATE switch, and RGB LED holder to the
front of the chassis. Four 2 mm socket head screws were used to mount the
LCD in its front panel cutout. For the ROTATE switch, a large
double-pole double throw center-off momentary switch was
mounted below the LCD assembly. Figure 24.6 shows the
finished front panel.
The large power transformer is mounted on the rear panel
flange of the chassis itself, along with the ac power socket,
fuse holder, and the AMPffYCO CPC circular socket for the
rotator connector. The rotator connector will connect to a male
circular connector on a short pigtail cable that has Anderson
Powerpole connectors to connect to the rest of rotator cable
(Figure 24.7). Since I use Powerpoles to standardize all my
rotator connections, the pigtail allows for quick and easy
swapping between the Arduino project and a standard CDE/
Hy-Gain rotator controller during test and setup.
Figure 24.7- Pigtail cable used Figure 24.8 shows all of the external components
between rotator controller and the
mounted inside the chassis with the Arduino Uno mounted to
COE/Hy-Gain rotator.
the bottom of the chassis with standoffs. The four standoffs
Figure 24.8 - Rotator Controller chassis showing the Arduino mounting point.
Figure 24.9 - The relay board mounted behind the front panel
underneath the power switch.
24-8 Chapter 24
The 12 V power transformer and voltage regulator are installed on a square
piece of perfboard and mounted on top of the standoffs in front of the Arduino
(Figure 24.10). The ZERO and 360° CALIBRATION SET pushbutton switches are
also mounted on the low voltage power supply board. This board will connect
to the Arduino using the right-angle header pins located on the lower right side
of the board.
Now that all the major components have been mounted, it's time to build
the Arduino protoshield that will be used to interface between the all of the
Software Design
Just as with the chassis construction, the sketch for this project looks
complex, but when you break it down into small functional chunks, you'll see
that it's really not that difficult. In fact, some of the sketch came directly from
the Azimuth/Elevation Rotator Controller project and other sketches we've
created to this point. This is yet another aspect that helps make developing
projects fun. If you build your sketches in a modular fashion, often you can
re-use that code in another sketch, saving you a lot of time by not having to
reinvent the wheel.
Figure 24.13 shows the flowchart we'll use to create the CDE/Hy-Gain
Rotator Controller sketch. When you put aside the thoughts of all that complex
wiring you just did, you'll see that we don't need the Arduino to do all that
much actual work. Once we have everything initialized, the Arduino will read
the rotator position and wait for the ROTATE switch to be pressed. Once the
ROTATE switch has been pressed, the Arduino will energize the rotator brake
release and the appropriate drive motor relay. As the rotator is turning, the
current heading is updated on the LCD, along with an arrow to indicate the
direction of rotation.
When the ROTATE switch is released, the motor relay is de-energized, but
the brake solenoid is held energized for an additional three seconds to allow the
rotator and antenna to coast to a stop. The brake solenoid is then de-energized
and the brake locks the rotator into position.
While the Arduino is waiting for the ROTATE switch to be pressed, it will
also check to see if one of the CALIBRATION SET pushbutton switches has been
pressed. These switches are used to save the AID converter's values for the
current rotator position in the Arduino's EEPROM for the 0° and 360° rotator
position.
24-10 Chapter 24
Start
Rotator Controller Flowchart
Include Libraries
Setup
Loop
24-12 Chapter 24
position potentiometer. After some quick testing to get the feel for how the
Arduino software timer interrupts worked, I incorporated the time and rotational
distance calculations into the interrupt handler function in the sketch and began
my tests. Once I got a few minor bugs ironed out in the sketch, my first run had
the rotator controller tracking the real position within 3° of the actual position
over a 360° rotation. Fine tuning brought that down to less than 1° of difference
between the calculated position and the actual position of the rotator. Further
testing determined that a 250 ms interrupt was the optimum interrupt time to
update the front panel LCD display and accurately calculate the rotator position
while it was turning. So, now we had a design that worked and met all the
design criteria.
The Sketch
Now it's time to create the final sketch we're going to use to finish up the
Rotator Controller. The complete sketch and libraries used in this project can be
found in Appendix A or online at www.w5obm.us/Arduino. Starting out in the
sketch, we'll include all the libraries we'll need. Note that the libraries for the
ADS1115 AID converter and the I 2 Cdev library that supports the ADS1115
did not correctly handle the 16-bit data from the AID and had to be modified.
When you create your sketch, be sure to download the modified version of these
libraries from www.w5obm.us/Arduino.
Next, we'll define the PC LCD. We'll also define the speed for the Serial
Monitor so that we can use it to help debug the sketch and watch what's going
on while the rotator is turning.
In order to get the AID converter to read the rotator position potentiometer
accurately, a 4.7 kn pull-up resistor is attached to one side of the potentiometer
that comes in on pin 3 of the rotator connector. We want to feed a low current
into the position potentiometer so we don't cause it to bum out when it's at the
lower resistance positions. Due to the way the current in the pull-up/position
potentiometer circuit will vary as the resistance of the position potentiometer
changes, we'll need a pull-up resistance value of approximately 10 times the
highest resistance of the 500 n potentiometer to prevent any distortion of
the position voltage coming in from the position potentiometer. This results
in a position-sensing voltage that will vary from 0 to approximately 400 m V
depending on the rotator position.
This is another reason why I prefer to use the ADS 1115 AID module instead
of the Arduino 's onboard AID converter. The ADS 1115 has six programmable
gain settings. For this project, we'll set the gain for a maximum of 0.512 V
(512 mV).
Next, we'll define the brake delay. We'll allow three seconds after the
motors have been turned off for the rotator and antenna to coast to a stop before
we engage the brake solenoid to lock the rotator in place.
#define brake delay 3000 II Set the Brake Delay to 3 seco nds
Now we'll define the data format we'll use to store the calibration values
in the Arduino's EEPROM and define the default AID values if there is no
calibration data saved:
The next step is to define all the variables needed in our sketch. You will
note that there are separate rotation speed values for when the rotator is turning
24-14 Chapter 24
clockwise (right) or counterclockwise (left). On the HAM-III rotator used in my
testing, there was enough variation in the rotational speeds that I felt the need
for different values for each direction to maintain position accuracy while the
rotator was turning.
int tickEvent ;
II Integer variable for position calculation while moving
int derived_degrees;
String direction;
In the last part of the initialization portion of our sketch, we'll initialize the
objects for the LCD, the ADS 1115 and the software timer interrupt.
II set the LCD I2C address to Ox27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(lcd_address ,lcd_end,lcd_lines);
Starting out in the se tup () loop, we'll start the Serial Monitor port and
the LCD. We'll then display a brief startup message to let us know everything is
good to this point.
Next, we'll set all the Arduino I/O pin modes and make sure that everything
is turned off before we start.
Now we'll read the Arduino's EEPROM to load the 0° and 360° calibration
data. If the debug mode is enabled, we'll output the calibration values to the
Serial Monitor.
Finally, in the last part of the setup () loop, we'll configure and start the
ADS1115:
24-16 Chapter 24
adc.setMultiplexer(ADSlllS_MUX_PO_NG);
delay(lOO); II adc settling delay
Starting out in the main loop () of the sketch, we'll update the software
timer interrupt so it can handle the next interrupt if the rotator is moving:
If the rotator is not moving, we'll read the current rotator position and
display it on the LCD:
II Read the ADC normally as long as the motor or brake are not energized
if (!moving)
AZ Degrees = 0;
if (AZ Degrees > 360) II Set position to 360 degrees if above 360
AZ Degrees = 360;
led.print("");
e ls e {
II We're moving, ADC reading is useless - too much noise
if (!timing) II Check to see if we're already timing the event
Since the software timer interrupt can happen at any time in the loop and
can take care of itself, we can move on in the loop () and check the rotate
switch to see if it has been released. If the rotator is not turning, we'll read the
rotate switch to see if it has been pressed and determine which direction we
need to tum the rotator.
II Rotate CW
move right(); II Call the Move Right function
}
II Rotate CCW
move left(); II Call the Move Left function
else {
if (moving) II If we were moving, time to stop
In the last portion of the main loop (),we'll check to see if either of the
CALIBRATION SET pushbuttons have been pressed. If a CALIBRATION SET button has
been pressed, we'll save the AID value for the current position in the Arduino's
EEPROM.
24-18 Chapter 24
II Read the Zero Degree Calibrate Switch
if (digitalRead(cal zero) == LOW)
There are 12 functions used in this sketch. By moving the actual control
activities into functions, the sketch can be assembled in a building block
fashion. This allows you to debug your Rotator Controller one piece at a time.
It also gives you a functional building block that you can use in future sketches,
saving you the time of having to rewrite the same block of code over and over
agam.
The a 11 st op ( ) function is used to tum off the motor drive relays, wait
three seconds, then engage the rotator brake. A message indicating we are in the
brake delay cycle will be displayed on the front panel LCD and the RGB LED
will be turned red during the braking cycle.
The move_ left ( ) and move_ right ( ) functions activate the brake
solenoid and the motor drive relays to tum the rotator. The moving flag is
turned on and an arrow indicating the direction of rotation will be displayed on
the LCD. If we're turning left, the RGB LED will glow green; if we're turning
right it will glow blue.
The next block of functions controls the RGB LED. Since there are
three digital VO pins controlling the RGB LED, it makes sense to move the
LED controls into functions, rather than have to repeat the sequence of three
digi talWri tes () inside the sketch to set the appropriate LED color or tum
the LED off.
24-20 Chapter 24
digitalWrite(red , LOW) ; // Set all RBG LED pins High (Off)
digita l Write(green , LOW);
digita l Write (b lue , LOW) ;
digitalWrite(red , LOW) ;
dig i talWrite(green , HIGH) ; II Turn on the RGB Green LED On
dig i talWrite (blue , LOW) ;
II Wh i te LED function
vo i d l edWhite() //Turn on all LEDs to get white
d i g it alWrite(red , HIGH );
digitalWrite(green , HIGH) ;
dig i ta l Wr i te (b l ue, HIGH ) ;
Next, we have the rea d_ a dc () function to read the 16-bit AID converter.
If debug mode is enabled, the value of the current rotator position is sent to the
Serial Monitor.
else {
II EEPROM has no Calibration data - initialize eeprom to default values
if (debug_mode)
{
II
Send status message in debug mode
Serial . println("Read EEPROM Calibration Data Invalid ID - setting to
defaults");
24-22 Chapter 24
AZ_ MAX = AZ CAL_MAX DEFAULT;
write eeprom_cal data(); II Write the data to the EEPROM
if (debug_mode)
Our last function is the interrupt handler function that is called when a
software timer interrupt occurs. Whenever a timer interrupt occurs, the Arduino
pauses execution of the main lo op () and executes this function. When the
function is completed, the Arduino resumes the main loop () right where it
left off before it received the interrupt.
Serial.print(" ");
Serial.print("Rotating ");
Serial.print(direction);
Serial.print(" ");
Serial.println(calculated_degrees);
derived_degrees = 0;
derived_degrees = 360;
led.print(" ");
Since every rotator controller turns at a slightly different speed, you'll need
to tune the left and right rotate speed variables to get your rotator controller to
accurately display the current position while moving. You will need to do this
with the debug mode disabled, as the slight delay introduced by sending data to
the Serial Monitor can affect the timing for the position calculations.
To tune the right rotation speed variable, I turned the rotator from 0° to
approximately 340° and compared the final estimated value to the actual
position displayed when the brake cycle completed. I used 340° in case we were
estimating too high, and our sketch modifies any values higher than 360 to be
360°. I then repeated the process from 360° to 20° to adjust the left rotation
speed variable. Be sure to let the rotator cool after a few full rotations. It's not
made for constant duty and may overheat if you tum it too much while you're
tuning the rotation speed variables.
24-24 Chapter 24
Enhancement Ideas
The 0° /360° position on our rotator controller starts at the far left
(counterclockwise) rotation point. The standard CDE/Hy-Gain Rotator
Controller has the 0° /360° position at mid-scale on the meter. If you prefer the
0/360° point to be at the midpoint of the rotation, you can modify the sketch
to mirror the values of the standard controller by using the same method we
used in the Azimuth/Elevation Rotator Controller project to modify the position
values.
The sketch for this project does not include the Yaesu GS-232A azimuth-
only rotator emulation code to allow your PC to automatically control the
rotator. You can add that functionality if you want to use Ham Radio Deluxe
or other antenna positioning software on your PC to automatically control the
rotator. The Reset Disable jumper needed to interface with Ham Radio Deluxe
has been included in the design for this project, in case you want to add that
code in. To upload your sketch, the Reset Disable jumper must be removed,
otherwise the Arduino IDE can't automatically reset the Arduino using the
DTR signal to enter the sketch upload mode. Since Ham Radio Deluxe toggles
the DTR signal line when it initially attempts to connect to the rotator, it
inadvertently resets the Arduino and the rotator controller will never connect
to Ham Radio Deluxe. If you are adding the interface for Ham Radio Deluxe,
remember to add the Reset Disable jumper after uploading your sketch.
References
Rotor Parts by C.A.T.S - www.rotor-parts.com
TEN-TEC - www.tentec.com
Modified COE/Hy-Gain
Rotator Controller
-
OFF ON
25-2 Chapter 25
ARRL 1163
Rotator
Rotator Drive
Position USB
CDE Sense Port PC
Rotator Arduino Uno Running
Control Box Rotator HRD
Control
•
the cutout for the Arduino
Uno's USB port.
Figure 25.5 - The brake and motor relays mounted in the chassis.
25-4 Chapter 25
available space is that the cutout for the USB port is also where the control box
chassis has a double layer of metal, which makes the hole cutting just a slightly
more difficult (Figure 25.3). Fortunately it's only a small hole we need to cut
out, so it goes fairly quickly. Figure 25.4 shows the Arduino Uno mounted to
the underside of the control box chassis.
Next, we'll use epoxy to glue the three miniature relays to a strip of perfboard
and mount it to the ends of two existing screws in the control box chassis (Figure
25.5). You can mount the relay board anywhere you want on the underside of the
chassis, but the two existing screws were just too convenient to ignore.
Now it's time to wire everything together. Because we need to wire in the
switches and position sensing circuit inside the rotator control box, we won't
build a test circuit on the breadboard. Instead, we'll wire everything in place in
the rotator control box and hope for the best. Be sure and unplug your control
box, as there is 120 V ac all over the inside. Figure 25.6 shows the Fritzing
diagram for modifying your CDE/Hy-Gain rotator controller. As with the Yaesu
Azimuth/Elevation Rotator Controller, only a couple of components are needed
to build this project. We'll mount the resistors and transistors used to drive the
relays, along with the ADS 1115 AID converter, and the Reset Disable jumper
on an Arduino protoshield. We'll then use the DuPont-style header and socket
Brake Drive
D3
CCW (Left) Drive
1N4001 I K3
02 - - - - - - To Brake Switch
I
to---- 2N2222A
CCW (Left) Drive
CW (Right) Drive
K2
01
_ _ _ _ I, --0~ 2223~ t------ To Left (CCW) Switch
CW (Right) Drive
D1 ,d.
1N4001 I K1
j 47~~-F
~~~~~~~ J2
-- To Front Panel
Meter
ARRL 1164
ARRL1165
Lt)
...
C\I
Cl)
Q.
Figure 25.7 - Modified COE/Hy-Gain Rotator Controller schematic diagram. cu
.c
CJ
co
I
Lt)
C\I
connectors to connect up the relays and rotator position sensing. Figure 25.7
shows the schematic diagram for this project.
Finding a way to read the rotator position accurately with the AJD converter
proved to be difficult. Reading the position sensor directly through a voltage
divider to reduce the 12 V position sense voltage to 5 V brought the same noise
issues that we had with the previous CDE/Hy-Gain rotator controller project.
Searching through the rotator control box with a voltmeter and oscilloscope
showed that the voltage across the front panel meter did not have as much ac
noise, and we could have the AJD read the voltage across the analog meter
differentially. By adding a 470 µF filtering capacitor across the meter, the
ac hum was all but filtered out, and we had a usable position sense voltage.
Since we're reading across the meter, the position sense voltage is very low
(0 to 55 mV), so we'll need to set the ADSl 115 gain to its most sensitive
setting of 256 m V for a full scale reading. When you attach the wire coming
from the analog meter, the meter lug closest to the center of the chassis is the
higher potential (positive) side, which should be connected to AJD channel 0.
The lower potential side (negative) is connected to AJD channel 1. This will
allow the ADS 1115 to read channel 0 and 1 differentially. Since we're reading
differentially, the ac hum is no longer such a factor, and the input capacitor
filters out whatever ac hum is remaining. A ferrite bead choke was also added to
the position sense input to the AJD for added noise protection.
The relays are wired across the contacts on the motor and brake switches
on the front panel. Be careful with the brake switch wiring. The brake switch
actually controls the 120 V ac power to the 26 V ac power transformer, and
the brake is released by applying power to the motor drive circuit. Figure 25.8
shows the completed modifications to the CDE/Hy-Gain rotator control box.
Figure 25.8 - The finished controller modifications with all the wiring
complete and the protoshield mounted on top of the Arduino Uno.
Start
Include Libraries
Define Pins and Variables
Define ADC
Loop
Return Requested
:>-.----~ Position Information i-+--~
Via Serial Port
No
Perform Requested
Yes Calibration
Save Calibration Data
to EEPROM
ARRL1166
25-8 Chapter 25
GS-232A in azimuth-only mode. This will allow us to use most of the same
sketch we used for the Yaesu Azimuth/Elevation Rotator Controller project.
All we have to do is make a few minor changes and remove the portions of the
sketch that deal with elevation control. The Yaesu GS-232A command codes
needed to communicate with Ham Radio Deluxe are listed in Table 25.1. Since
the Yaesu GS-232A command set includes the commands needed to calibrate
the zero and maximum azimuth values, we won't need the calibration switches
we used in our previous CDE/Hy-Gain rotator controller project.
The complete sketch for the Modified CDE/Hy-Gain Rotator Controller
can be found in Appendix A and online at www.w5obm.us/Arduino. Starting
out with the sketch, we'll include the libraries we need, enable the debug mode
for troubleshooting, and initialize the ADS 1115 AID converter object. The
ADS1115. hand I2Cdev. h libraries have been customized to correct an
error when handling 16 bit data. Be sure to use the modified libraries in your
sketch. When your sketch is tested and debugged, don't forget to add the Reset
Disable jumper on the protoshield and tum debug mode off, otherwise the Ham
Radio Deluxe rotator controller software will not connect to the Arduino.
The next thing we need to do is define the relay pins, the default positioning
calibration data, and the speed on the serial port. You need to be sure whatever
speed you choose to define matches the settings you plan to use in Ham Radio
Deluxe. We'll also define the format for the calibration data that will be kept in
the Arduino's onboard EEPROM.
Table 25.1
COE/Hy-Gain Rotator Controller Commands
(Subset of Yaesu GS-232A Commands)
A Stop Azimuth Rotation
C Return Current Azimuth Value in Degrees (format +Oaaa)
F Set Azimuth Full Scale Calibration
L Rotate Azimuth Counter-Clockwise
Maaa Rotate Azimuth to aaa degrees
0 Set Azimuth Zero Calibration
R Rotate Azimuth Clockwise
S Stop All Rotation
#define BAUD RATE 9600 II Set the Serial Port Baud rate to 9600
As the last step in the initialization portion of our sketch, we'll define all of
the variables we'll be using in this sketch:
In the setup () loop, we'll start out by setting the digital 1/0 pin modes
for the brake solenoid and motor drive relays. Then we'll tum off the relays to
make sure everything is turned off before we begin.
25-10 Chapter 25
II Turn off all the relays just to be sure
digitalWrite(rotate left, LOW); II Turn off the rotate l e ft relay
dig it alWrite(rotate right, LOW); //Turn off the rotate right relay
digitalWrite(brake , LOW) ; II Turn off the brake sole noid relay
Next, we'll start the serial port, the PC bus, and the ADS1115. We'll then
configure the AID to run continuously at 32 samples per second. We'll also set
the AID gain to 256 m V and have the AID read differentially between input
channels 0 and 1.
II set the ADC gain to 0.256 Volt range, 0 .007 813 Volts/step
adc.setGain(ADSlllS PGA_OP256);
In the last portion of the setup () loop, we'll tum off the flag we use to
indicate rotator movement and read the rotator position calibration data from
the Arduino's EEPROM. If there are no calibration values saved, the sketch will
use the defined default calibration values.
The functions in this sketch handle most of the work. The first function,
read_ eeprom_cal_data (),reads the calibration data stored in the
Arduino's onboard EEPROM and places it into the variables we use to map the
raw rotator position data into the actual azimuth in degrees. If there is no valid
calibration data, the default values are used and also saved in the Arduino's
EEPROM.
25-12 Chapter 25
The write_ eeprom_cal _ data function is used to write the calibration
data to the Arduino's onboard EEPROM:
The check_ serial () function will read the incoming characters from
the PC, then decode and execute the Yaesu GS-232A command. If you are not
using Ham Radio Deluxe to control your rotator, you may need to uncomment
the statement that echoes the received data back to the PC. Ham Radio Deluxe
will not connect to the rotator controller if debug mode is on or if the received
characters are echoed back to the PC.
void check serial() II Function t o check for data on the Seria l port
return;
Once the command has been received, we'll use a swi tch ...case ()
statement to decode and execute the command:
if (debug_mode)
if (debug_mode)
25-14 Chapter 25
case 77 : II M - Rotate to Set Point
if (debug_mode)
if (debug_mode)
if (debug_mode)
if (debug_mode)
After the decoded command has been executed, the serial data buffer is
cleared and the sketch is ready to receive the next command:
II Clear the Serial Buffer and Reset the Bu ffer Index Pointer
serial buffer index = O;
ser ia l_buffer[O] O;
The send current az () function will read the AID converter and
convert the raw AID value to a calibrated azimuth value. The azimuth data is
Serial.println(current AZ);
if (debug_mode)
Serial.println(AZ Degrees);
The set _ma x _ a z _ca 1 ( ) function is used to set the calibration value
for the maximum azimuth rotation. This value is then saved to the AZ MAX
calibration variable, and to the Arduino's onboard EEPROM.
25-16 Chapter 25
void set_max_az cal() II Set the Max Azimuth Calibration Function
The az _rotate stop () function is used to stop all rotation. The motor
drive relays are de-energized, and a one second delay is added to allow the
rotator and antenna to coast to a stop. After the one second delay expires, the
brake solenoid is de-energized and the brake is engaged.
if (debug_ mode)
if (debug_mode)
AZ To = 0;
AZ To = 360;
AZ To = AZ To - 180;
e l se {
AZ To = AZ To + 1 8 0;
if (debug_mode)
{
Serial.println(Requested_AZ );
Serial.println(AZ To );
II
set the move flag a nd s t ar t
read_ adc(); II Read the ADC
II Map it to degree s
if (debug_mode)
25-18 Chapter 25
Serial.println(current_AZ);
The set - 0 - az - cal () function is used to set the azimuth zero calibration
value. This value is then stored to the AZ 0 calibration variable and saved to
the Arduino's onboard EEPROM.
if (debug_ mode)
{
Serial.println("Read ADC Functi o n ");
Serial.println( current_AZ) ;
if (debug_ mode)
{
25-20 Chapter 25
if (a bs(AZ Distance) <= AZ_Tolerance)
You can see how much of the Yaesu Azimuth/Elevation Controller sketch
that we were able to re-use. This is one reason why working with the Arduino
is so much fun. Once you have built your own Arduino sketch and library
collection, you can re-use them endlessly in your future projects, greatly
reducing your sketch development time. Being able to re-use huge blocks of
code made this a very easy sketch to create, since all that we had to do was a
little modification here and there. Once you have the sketch ready for testing
and debugging, you can use the Serial Monitor to send the Yaesu GS-232A
commands to the rotator controller.
Once you have everything debugged and working, don't forget to upload the
sketch with the debug mode turned off, and the Reset Disable jumper installed
on the Arduino protoshield, before trying to control the rotator with Ham Radio
Deluxe.
Now we're ready to have some real fun. With the sketch complete, we're
ready to test the interface and set the azimuth calibration values. For this test,
you can use the Arduino IDE's Serial Monitor to send the Yaesu GS-232A
commands directly to the Arduino. Manually rotate the azimuth to zero (the
front panel analog meter at minimum deflection) and use the "O" command to
set the zero calibration point. Then, manually rotate the azimuth to full-scale
on the front panel analog meter and use the "F" command to set the azimuth
full-scale value. Once you have done that, your controller is calibrated, and
the calibration values are stored in the Arduino's onboard EEPROM. You can
recalibrate your controller at any time by repeating the calibration process. You
can now send the various Yaesu GS-232A controller commands listed back in
Table 25 .1 to test all the functions on your controller.
Now that your controller is calibrated, you're ready to use the controller
with the Ham Radio Deluxe rotator controller software on your PC. Don't forget
to install the Reset Disable jumper and have the sketch loaded with the debug
mode turned off. Configure the Ham Radio Deluxe rotator controller to use the
Arduino 's COM port, set the baud rate to match the serial port speed setting in
the sketch, and select the Yaesu GS-232A/Az rotator controller in Ham Radio
Deluxe. Now your rotator can be controlled by Ham Radio Deluxe, and the
-
Figure 25.10 - Screen shot of Ham Radio Deluxe controlling the modified COE/Hy-Gain
rotator controller.
current rotator position will be displayed on the HRD rotator controller screen
as shown in Figure 25.10. If the rotator turns correctly, but Ham Radio Deluxe
doesn't show anything on the rotator dial, you need to verify that the Arduino
does not have the command echo statement uncommented in the check
serial () function. Ham Radio Deluxe doesn't like it when you echo the
command back to it. If everything went well, you now have a fully operational
CDE/Hy-Gain rotator controller that can be controlled by Ham Radio Deluxe or
other software on your PC.
Enhancement Ideas
Because this needed to be a fully functional project, there's not a whole lot
left for you to enhance. You could use an Arduino Nano and shrink everything
to a perfboard mounted inside the CDE/Hy-Gain rotator control box, or you
could even put the Arduino in a small external enclosure and run the rotator
sense and relay control wires through a small hole drilled in the rotator
controller chassis to save you the fun of having to cut out a square hole in the
rotator controller chassis for the Arduino's USB connector. You might also want
to add an RGB LED to the front of your CDE/Hy-Gain control box so you can
tell when the PC is controlling the rotator. One final enhancement would be
to add an infrared LED detector and use an infrared controller to control your
rotator wirelessly. This would allow you to move your rotator control box off
your desk, and clear up some space for more stuff.
References
Ham Radio Deluxe - www.ham-radio-deluxe.com
Texas Instruments - www.ti.com
Yaesu - www.yaesu.com
25-22 Chapter 25
CHAPTER 26
In Conclusion
The previous chapters in this book have shown many ways to use the Arduino
Uno to enhance your ham radio capabilities. Look at these projects as the
beginning of your Arduino experience.
In this book, we've only been able to scratch the surface of what the
Arduino can do. There are so many more shields and modules that can be used
in ham radio projects that we haven't gotten to play with yet, but that too is part
of the fun of the Arduino. Like the Erector Set from my childhood, there is no
end to the things that can be built, especially with new add-ons coming out all
the time. In this book, I have tried to cover the broad spectrum of ham radio,
creating projects that briefly touched as many aspects as possible. You know as
well as I do that can't be done entirely in a single book. This is where you come
in. Hopefully, this book has given you the spark of inspiration and knowledge
you need to go out and create your own projects.
If you need to learn more about the Arduino and what it can do, there
are several websites that have excellent tutorials and projects. The Arduino
Playground, Instructables.com, SparkFun.com and Adafruit.com are just
several that come to mind, but there are many others to choose from.
In Conclusion 26-1
So where do you start? Well, how about starting with the things that are not
in this book. For example, the Arduino can be web-enabled with the Ethernet
shield. With the Ethernet shield, you can create Arduino projects that can be
accessed via the Internet, and control and monitor your shack remotely.
Another area that could prove quite interesting is the linking of an Android
phone to the Arduino. There are numerous Android apps available that allow
your Arduino to communicate with an Android device via Bluetooth. Now you
can create telemetry and control applications for the Arduino. To help you along
this path, take a look at Android apps such as ArduDroid, ArduinoCommander,
Arduino Uno Communicator, and Arduino Total Control, just to name a few. For
the PC side, there are programs such as Processing and Ardulink that will allow
you to create applications on your PC that can communicate with the Arduino.
Voice Recognition
While I was wrapping up this book, I bought an EasyVR voice recognition
shield shown in Figure 26.1. This shield can respond to 28 speaker-
independent, and 32 speaker-specific user-defined commands. It comes
complete with a software library for the Arduino, so how hard can it be
to get this new toy working? I doubt it will be very hard at all. We've had
voice-operated (VOX) transmitters for years, but now, we can take that to a
whole new level and make our entire shack voice-controlled. I am sitting here
thinking my usual phrase, "Wouldn't it be cool if you could just sit back, give
your antenna rotator a voice command, and have it tum your antennas for
26-2 Chapter 26
you automatically?" Why stop there? You can connect an Arduino to your
transceiver's computer interface and do everything by voice commands. For me,
the possibilities are endless with this new shield.
With motion and infrared sensors, you could use your Arduino to tum on
everything in your shack when you walk in, and tum everything off when you
leave. Sure you can use a plain old power switch, but that's just not that same as
creating your own Arduino project to do it for you.
And we've only scratched the surface of what can be done with the direct
digital frequency synthesis (DDS) modules. If you link a DDS module with an
SWR sensing unit, you can build your own antenna analyzer. If you link that to
your PC or Android phone, or use one of the color TFT displays on the Arduino
itself, you can graph the entire SWR curve for your antennas. Going further,
you can use a DDS module and create your own Arduino-based transceiver.
Figure 26.2 - The TEN-TEC Rebel Model 506 Open Source QRP CW transceiver.
In Conclusion 26-3
Figure 26.3 -
Inside view of
theTEN-TEC
Rebel showing
an Arduino
protoshield
mounted on the
chipKit Uno 32
shield expansion
pins.
So, as you go out and start creating your own magic with the Arduino, please
remember to share back to the Open Source community so that others can follow
in your footsteps. And by all means, please feel free to share with me what you
have done, both with the projects in this book and the projects you create on your
own. Who knows, you may end up creating that one enhancement that I would
love to have and didn't even think about, or provided the spark for my next
Arduino adventure.
73, Glen Popiel, KW5GP
References
Adafruit Industries - www.adafruit.com
Android Apps - play.google.com/store/apps
ArduinoCommander - arduinocommander.blogspot.com
Arduino-Communicator - github.com/jeppsson/Arduino-Communicator
Arduino Playground - playground.arduino.cc
Ardulink - www.ardulink.org
Instructables - www.instructables.com
Processing - www.processing.org
SparkFun Electronics - www.sparkfun.com
TEN-TEC - www.tentec.com
TEN-TEC Rebel User's Group - groups.yahoo.com/neo/groups/
TenTec506Rebel
VeeaR EasyVR - www.veear.eu
26-4 Chapter 26
APPENDIX A
This is a list of all of the sketches and libraries used to create the projects
in this book. You can download a PDF file with the complete sketches and
libraries from the ARRL website at www.arrl.org/arduino. You can also
download the sketch and library files themselves from www.wSobm.us/
Arduino. Links to the original libraries are also provided to allow you to
download the current version of the libraries if desired.
Appendix 1
Chapter 11 - Weather Station
Libraries Required:
dht
LCD5110_Basic
Sketch Required:
Weather_Station.ino
2 Appendix
Chapter 18 - Waveform Generator
Libraries Required:
LiquidCrystal_I2C
Sketch Required:
Waveform_ Generator.ino
Chapter 22 - CW Decoder
Libraries Required:
LiquidCrystal_I2C
MorseEnDecoder
Sketch Required:
CW_Decoder.ino
Appendix 3
Chapter 24 - COE/Hy-Gain Rotator Controller
Libraries Required:
ADS 1115 (customized)
I2Cdev (customized)
LiquidCrystal_I2C
Timer
Sketch Required:
Rotor_ Controller.ino
Libraries
All libraries used for the projects in this book can be downloaded either
from the link provided or from www.w5obm.us/Arduino. In the case of
the LCD5110 _ Basic library used for the Nokia 5110 display, the library
developer has requested that you download the library directly from their
website to ensure the latest version.
Library Links
LiquidCrystal_I2C - hmario.home.xs4all.nVarduino/LiquidCrystal_I2C
OneWire - www.pjrc.com/teensy/td_libs_OneWire.html
HMC5883L - bildr.org/2012/02/hmc5883l_arduino
dht - arduino.cc/playground/Main/DHTLib
LCD5110_Basic - www.henningkarlsen.com/electronics/library.
php?id=44
TinyGPS - www.arduiniana.org
I2C - github.com/rambo/12C
MorseEnDecoder - code.google.com/p/morse-endecoder
AS3935 - www.github.com/SloMusti/AS3935-Arduino-Library
Timer - www.github.com/JChristensen/Timer
4 Appendix
APPENDIX B
There are two primary tools that I use to design and document my Arduino
projects, Fritzing and CadSoft EaglePCB. Documenting your projects is
very important. Sometimes you'll revisit a project that you built months ago
(or longer), and need to be able to pick up where you left off. Without good
documentation, you'll lose a lot of time trying to remember how and why you
did something the way it was done.
Fritzing
Fritzing is a free Open Source design tool I use to produce drawings of
how the circuit will look on a breadboard. Fritzing produces a realistic-looking
layout of the breadboard design and all you have to do is match your actual
breadboard wiring to the Fritzing drawing to construct your prototype.
Fritzing comes with a parts library that contains many of the components
you will be using to design your projects. Fritzing will run on Windows, Mac
OS X, and Linux. New parts definitions are constantly being added to the
Fritzing distribution and their website for download. The parts in Fritzing are
customizable, and you can modify existing parts templates, or create your own.
The Fritzing website, www.fritzing.org, has a series of excellent tutorials to
help you learn how to use Fritzing in your circuit designs. Fritzing can also be
used to draw schematics and create the actual printed circuit board patterns for
etching circuit boards of your finished projects.
lnkscape
Fritzing graphics for new parts are easily created using another free Open
Source program called Inkscape. Inkscape is a free, Open Source graphics
editor that can create the scalable vector graphics (SVG) files used by Fritzing.
Inkscape will run on Windows, Mac OS X, and Linux. The Inkscape website,
www.inkscape.org, has a number of excellent tutorials to help you along your
way when you need to design your own parts for Fritzing.
EaglePCB
Cadsoft's EaglePCB is my tool of choice for creating schematic drawings.
Eagle is used commercially by many companies to produce schematics and
Appendix 5
printed circuit boards. EaglePCB will run on Windows, Mac OS X, and Linux.
As with Fritzing, EaglePCB comes with an extensive library of components. If
the component you need is not in a library, you can easily create or download
a new component, or modify an existing one to get what you need. EaglePCB
will also produce the Gerber data files used to create etched circuit boards.
While Fritzing does an excellent job creating the breadboard layouts, I prefer to
use EaglePCB to create my finished schematic diagrams.
EaglePCB has several levels of licensing. The freeware Eagle Light Edition
will do just about everything the average hobbyist needs. The Eagle Light
Edition limits you to a circuit board size of 100 x 80 mm (4 x 3.2 inches), two
signal layers and a single design sheet. The Light Edition also limits you to
a single user and nonprofit applications. If you are planning to create circuit
boards for your projects, the layout and autorouting features can be added to the
Light Edition for $69.
The Eagle Hobbyist version allows you to create circuit boards up to 160
by 100 mm (6.3 x 3.9 inches), six signal layers and up to 99 design sheets. The
Hobbyist version also includes the layout and autorouting features. A single-
user license for the Eagle Hobbyist version currently costs $169 and you are
restricted to noncommercial use.
If you plan to sell your finished products and designs, you can purchase
either the Eagle Standard or Professional versions starting at $315 for a single-
user license.
As with Fritzing and Inkscape, the CadSoft website (www.cadsoftusa.
com) has an excellent series of tutorials and videos to help you learn how to use
EaglePCB to create your schematic diagrams.
6 Appendix
APPENDIX C ·
4D Systems -www.4dsystems.com.au
Adafruit Industries - www.adafruit.com
Amazon - www.amazon.com
Austriamicrosystems AG - www.austriamicrosystems.com
Crisp Concept - www.crispconcept.com
DFRobot - www.dfrobot.com
Diligent - www.digilentinc.com
eBay - www.ebay.com
Embedded Adventures - www.embeddedadventures.com
MFJ - www.mfjenterprises.com
Midnight Design Solutions - www.midnightdesignsolutions.com
Pololu Robotics and Electronics - www.pololu.com
RadioShack - www.radioshack.com
Smarthome - www.smarthome.com
Solarbotics - www.solarbotics.com
SparkFun Electronics - www.sparkfun.com
TEN-TEC - www.tentec.com
Tindie - www.tindie.com
West Mountain Radio - www.westmountainradio.com
XlO - www.xlO.com
Yaesu - www.yaesu.com
ZiGo - www.zigo.am
Appendix 7
NOTES
NOTES
NOTES
NOTES
INDEX
A B
AD9833 programmable waveform generator: ....... 18-4 Bluetooth module: ....... ... .... ..... ........ .... ... ..... .......... 3-25
AD98xx series DDS module: ... ... .......... ... ......... .... 3-21 BMP085 barometric pressure sensor: ... ...... 3-21, 11 -3
ADS1115 AID converter module: ... ..... ..... ..... ........ 21-3 Breadboard shield: ... ... ............. ........ ............ .. 3-1 0, 6-2
Analog input: ...... ... ... .. ............... ..... ... .. ..... .... ... ... ..... 4-2
Analog switch chip: ........ ... ................... ......... ... ...... 3-31
Analog-to-digital converter module: .......... ... ....... .. 3-27
c
Anderson Powerpole connectors: .... ................. .... 13-5 COE/Hy-Gain rotator controller
Android apps: .. ......... .. ...... ................. .. ..... ............. 26-2 commands (Table): ...... ... ... ........ ..... .... .. .......... 25-9
COE/Hy-Gain rotator controller
Arduino
History: ........................... .... ..... ..... .... ....... ........... 1-3 modification project: .... ..... ... ..... ..... .... ....... .. .. 25-1 ff
Uno: ..... ............... ...... ............. ..... ..... .. ............ 1-2 COE/Hy-Gain rotator controller project: ..... ..... .. .. 24-1ff
Code practice generator project: ..... ..... ... ..... .... ..... 7-1 ff
Arduino boards and variants: ................................ 2-1ff
Color TFT display: .......... ......... .. ... ..... ... ..... ... .. 3-3, 3-16
Bluetooth: .................... ............................ ........ ... 2-2
Comparison chart: ............................ .. ... .. ....... .. 2-12 Creative Commons License: ......... ... .. ... ..... .. ..... ... ... 1-6
DC Boarduino: ........ .. .... ... ..... ... ... .......... ..... ... ... ... 2-4 Current sensor module:.... ... ..... .... ..... ........ ... .... .... . 3-24
Diecimilia: .. ................... ... ..... .......... .. .... ........ ... .. . 2-2 CW beacon and foxhunt
Digilent chipKIT Max32: .. .... .. ... .. ....... ........... .... 2-11 keyer project: ........ .. ...... ........ ... ... ... .. ..... ........ .. 8-1 ff
Digilent chip KIT Uno32: ...... ........... ... ..... ... ..... .. 2-10 CW decoder project: ................ ......... ..... ...... ....... 22-1 ff
Due: ................................ .......... .... .. ... ..... ..... .. 2-8 CW iambic keyer project: .... .. ..... .. .................. ..... 17-1ff
Duemilanove: .......................... ....... ... .. ..... .. ...... .. 2-2 CW keyboard project: .......... .... .... .... .. ....... ... ........ 19-1 ff
Esplora: ..................... ... ................................. ... .. 2-7
Extreme: ............................................. ................ 2-2 D
lduino Nano: ...... .. ...... ... ...... ........ ........... ...... 2-2, 2-3 DC Boarduino: ... ........... ........... ....... .... ... .... ... ..... ...... 2-4
Leonardo: ..... .. ... ..... ............................. .... ... ..... ... 2-7 Debugging: .................... ... .......... .... .. ..... ......... 5-9, 21-7
LilyPad: ....... ........... .. ... .... ......... ....... .. ........... 2-2, 2-4 Development station: ..... ...... .. ....... ..... .... ..... ........... .. 6-2
Mega: ..................... ... .... .... .. ......... ........ ........ .... 2-6 DFRobot Graphic LCD4884 display shield: .. .......... 3-2
Mini: ...... ........ ..... ... .... ..... .... ............. ........... .... 2-2 dht library:.......... .... ... ... .... ........ .......... .. ....... ........... 11-5
NG: .................................. ... ... .. ...... ....... ........ 2-2 Digital compass module: ..... ... ... .. .. ........ ...... ... ....... 3-24
Pro Mini: ... ........ ........... ..... .. ..... .. .. ..... ......... .. ....... 2-3 Digital compass project: .. ..... .. ...... ...... ........ ...... ... 10-1 ff
Solarbotics Ardweeny: ....... ... ..... ..... ... ... ....... ..... . 2-4 Digital 1/0:..... ... ..... ........... ... ..... .... .. .. ... ..... ..... ... ... ..... 4-1
Tre: ...... .. ............ .. .. ........... ......... ........ ... ..... ... 2-9 Digital 1/0 expander: .... ..... ........... ..... ........ ............ 3-30
Uno R3: ... .......... .. .. ...... ....... .. ....... ...... .. .... .. ......... 2-3 Digital potentiometer chip: ... ... ........ ... ...... .... .......... 3-31
USB: ................ .... ....... .. .............. .... ........... ..... 2-2 Digital-to-analog converter module: .... ... ..... ........ .. 3-29
Yun: ..... ......... .......... .... .... .. ... ........... ..... ... ....... 2-8 Digilent chipKIT Max32: ... ... .. ........ ........... ... .. ... ... .. 2-11
Arduino Integrated Development Environment Digilent chipKIT Uno32: ..... ................ ... ... ..... ... ..... 2-10
(IDE): ..... ...... ........ ... .... ......................... ........... 5-1 ff Direct digital synthesizer (DDS) module: .. .. .. .. ...... 3-21
Argent Radio Data shield: .................. ..................... 3-8 AD98xx series: ... ................ ..... ... ........ ........... ... 3-21
ATmega1210: .... ........ .... ................................ ..... ..... 2-6 Display: ...... ..... ...... ...... ..... ...... .... ... ... ..... ... ..... ... .... 3-12ff
ATmega 168: ........... .. ....... .. ........... .... ..... ... ....... .. .... .. 2-2 Color TFT: ...... ........ ........ ............... ............ 3-3, 3-16
ATmega328: ..... ... .. .............. ....... ... ... ..... .. ... ... ....... .. . 2-3 DFRobot Graphic LCD4884: .. ........ ..... ........... ... . 3-2
ATmega32u4: ...... ....... ........ ..... ... ... ..... ..... ... ... ......... . 2-7 Graphic LCD: ..... .. .... ... ........ ...... ... ........ ........... .... 3-2
ATmega8: ....... ..... ...... ........ .... .... ... ........................ ... 2-2 Hitachi HD44780: ........... ... .................... .... 3-2, 3-12
Audio shield: ... .. ... .. ......... ... ......... ..... ....... ... ............ .. 3-4 LCD: ....... ...... .. .... ... ...... ... ........ ... ........ ... .......... 3-2
Azimuth/Elevation rotator controller project: ..... .. 21-1 ff LED: ...... .... .... .. ... .. ... .. .. .... .................. ... ..... ... 3-32
LED driver: .. ............... ............... ....................... 3-32 Integrated Development Environment (IDE): ........ 5-1ff
Nokia 5110: ...... ......... ...................... 3-2, 3-14, 11-3 Inter-Integrated Circuit (12C) bus: ........................ .. .. 4-4
Organic LED (OLEO): ... .. .... ....... ..... ... ..... ......... 3-15 Interrupts: ..... ............... ................................ ..... ....... 4-5
Vacuum fluorescent display (VFD): .......... .. .. .... 3-13
VGA module (40 Systems): .................. .. .... ... .. 3-16 L
DS18820 temperature sensor: .... .. .. ... ... ........ 3-19, 9-3
LCD display: ................................................... 3-2, 3-12
LCD5110_8asic library: .... ... ...................... 11-5, 16-12
E LED display: ... ........... ... ................................. .. ...... 3-32
EaglePCB software: ...... ................... .... .... 5-7, 7-8, A-5 LED driver: .............. ....................................... ...... . 3-32
EasyVR shield: ...................................... ................ 26-2 Lesser GNU GPL (General Public License): ..... .. ... 1-6
EEPROM library: ........................ ................... ... ..... 19-5 Level converter module: .. ................ .. .................... 3-18
EEPROM module: .............. ..... .............................. 3-30 Library: ................................... .... ............. 5-3ff, A-1, A-4
Elliott, Steven, K1EL:. ..... .. ................................ ..... 17-2 dht: ........... .. ..... ........................................... 11-5
Ernie 2 text-to-speech module: ........... 3-23, 15-2, 16-5 EEPROM: ..................................... ..... .. ... .... ...... 19-5
Enclosures: .... .... ... ... ............. ... .............. .............. 3-34ff HMC5883L: ............... ....................................... 10-3
Ethernet shield: ..... .... .............................................. 3-5 LCD5110_8asic: ........ .. .. .. ...... ...... ... ... .. . 11-5, 16-12
LiquidCrysta1_12C: ............................... ...... 7-5, 10-3
F Math: .............................. ...... ..... ......... .. ......... 16-7
Morse: ............. ..... .. .... .... ... ......................... 7-6, 8-4
Fan speed controller project:. ........................ ..... ... 9-1ff MorseEnDecoder: .... .... ........................ .. .......... 22-4
Flow chart: ... ...... ..... ..... ... ..... ..... .. ................... .. ... ..... 5-6 One Wire: ... ... ... .... ........... .. ..... ................ ... .......... 9-5
Franklin AS3935 lightning detector: .................. .... 23-2 PS2Keyboard: .................................................. 19-3
Franklin AS3935 lightning detector module: ... ..... . 3-24 SoftwareSerial: ... ..................................... 15-5, 16-8
Fritzing software: .................................... .. 5-7, 7-3, A-5 TinyGPS: .............................. ... .. ..... .................. 16-5
FTDI US8 interface: ...................... ..... .. 2-4, 3-18, 20-4 License, Open Source: .................................... ...... 1-4ff
Lightning detector module: .......................... .. ...... .. 3-24
G Lightning detector project: ..... .... .............. ............ 23-1ff
GNU GPL (General Public License): .......... .. ... ....... 1-5 LilyPad Arduino: ... ... ... .... .................................. 2-2, 2-4
GPS (Global Positioning System): .. ...... .. ... ........... 16-3 LiquidCrysta1_12C library: .......................... ..... 7-5, 10-3
GPS logger shield: .. ........................ ........................ 3-8 LM567 tone decoder: .................. ...... ..... ... ............ 22-2
GPS module: ........ .. .. .... .. .................................... ... 3-23
Graphic LCD shield: ..................... ........... .. .............. 3-2 M
Maidenhead grid locators: ............................. ........ 16-2
H Math library: ..... .................... ... ............ ................... 16-7
H-bridge chip: ....................... ....................... .... ...... 3-32 MAX7219 LED driver: ............................ .... ..3-32, 12-2
Ham Radio Deluxe (HRD) software: ... .. .. ..20-11, 21 -1, MaxDetect 1-Wire interface: ... ........................ 4-3, 11-2
21-31, 24-25, 25-2, 25-21 Maxim 1-Wire interface: .. ...... .. .................... ... .. 4-2, 9-3
HAM series rotator: ...................... .......... ..... .... ...... 24-1 MCP4725 D/A module: ...................... ............ ....... 18-4
Hitachi HD44780 display: ..... ... ....................... 3-2, 3-12 Memory management: ...... ....................... .... ........... 5-8
HMC5883L digital compass module: ........... 3-24, 10-1 Memory tracking :................................................... 19-5
HMC5883L library: .............. ...... ... ......................... 10-3 Millibars: .......... ..... .. ................ ............................... 11-2
Hy-Gain rotator controller modification project: .. 25-1 ff MIT License: ............................................................ 1-6
Hy-Gain rotator controller project: ..... .................. 24-1 ff MOD-1016 lightning detector module: ... .. .. .. .. ....... 23-4
Module: ... ...... ....................................................... 3-11ff
Analog-to-digital converter: .................... ... ...... . 3-27
81uetooth: ....... ...................................... ............ 3-25
1/0 methods: .............................. ... ... .......... .... ........ 4-1 ff 8MP085 barometric pressure sensor: .... 3-21, 11-3
Analog input: ........ .. ................. ... ..... ..... .............. 4-2 Current sensor: ............... ................................. 3-24
Digital 1/0:.............. ... ................................ .... ...... 4-1 Digital compass: ............................ ................... 3-24
Inter-Integrated Circuit (12C) bus: ...................... .4-4 Digital-to-analog converter: .............................. 3-29
Interrupts: ........................... ................................ 4--5 Direct digital synthesizer (DDS): .. .................... 3-21
MaxDetect 1-Wire interface: .......... .. ................... 4-3 DS18820 temperature sensor: ............... ..3-19, 9-3
Maxim 1-Wire interface: ........ .. ..................... ...... 4-2 EEPROM: ... ................................................ ...... 3-30
Pulse width modulation (PWM): .......... .. ............. 4-2 Ernie 2 text-to-speech: .. ... ................................ 3-23
Serial 1/0: ..................... ...... ............ .... ..... .. ......... 4-2 Franklin AS3935 lightning detector: .............. ... 3-24
Serial Peripheral Interface (SPI) bus: ....... ... ....... 4-3 GPS: .............. ...................... ......................... 3-23
1/0 shield: ... .... ........ ...................... ..... .. ............. ..... 3-10 HMC5883L digital compass: ............................ 3-24
Iambic keyer modes: ............................................. 17-1 INA 169 current sensor: ............................ .. .. .... 3-24
lduino Nano: ......... .. ......................... .......... .............. 2-3 Level converter: ............................. ................... 3-18
INA169 current sensor module: ...... ....... .... .. 3-24, 13-2 Motion detector: .............. ................ ................. 3-32
Inches of mercury: ............. .. ................. ................. 11-2 Motor driver: ....... .. .. ........ .. ................... .. .......... . 3-27
lnkscape software: .. ...... ................................. ... ...... A-5 Real-time clock/calendar (RTCC): ................... 3-26
RHT03 humidity/temperature sensor: ..... 3-19, 11-2 Color TFT display: ...................... ........ ................ 3-3
SD card: .. .................... .............. .... .. ................. 3-27 OF Robot Graphic LCD4884 display: ................. 3-2
Skylab SKM53 GPS: ... .... .... ............................. 3-23 EasyVR: ... ........................................................ 26-2
Text-to-speech: ......................... .... .... ..... ..... ... ... 3-23 Ethernet: .. ........................................................... 3-5
TinyRTC clock/calendar: .................................. 3-26 GPS logger: ........................................................ 3-8
Vibration sensor: ..... ... ... .. ..... .... .......... ...... ........ 3-32 Graphic LCD display: ............................ ............. 3-2
Morse library: .. ... ..... .. ...................... .................. 7-6, 8-4 Hitachi HD44780 display: ................................... 3-2
MorseEnDecoder library: ............ ... ............ .... ... .. .. 22-4 1/0: ................... ..... ..................................... 3-10
Motion detector module: ...... ... .. ................ .. ... ... ... .. 3-32 LCD display: ....................................................... 3-2
Motor driver module: ............ ... .. .......... .................. 3-27 Motor driver: .................... ..... ... ........................... 3-4
Motor driver shield: .. ...... .... .... .... .............................. 3-4 Nokia 5110 display: ................. ........................... 3-2
Multimeter: .... ...... .... ...... .... .. ........ .............. ...... ... ...... 6-3 Prototyping (protoshield): .......................... 3-11, 6-2
Relay: ............................................................... 3-3
N SD card: ................ .... ..... .. ..... ..... .... .......... .......... 3-7
USB Host:. .......................................................... 3-6
NMEA protocol: .... ................ ................... ..... 16-1, 16-4 WiFi: ..... ................ ... .. ..... .. .. ................ ............ 3-6
Nokia 5110 display: .... ... .. ..... .... .... ........ 3-2, 3-14, 11-3 Xbee: .. .................. .. ................ ... ...................... 3-8
Skylab SKM53 GPS module: .. ..... .. .............. 3-23, 16-3
0 SoftwareSerial library: ... ........... .................. .. 15-5, 16-8
On-air indicator project: .. ............. ... .. ... .. ...... ........ 14-1ff Solar battery charge monitor project: .................. 13-1ff
One Wire library: .... ... .. ... ... .. ... .................................. 9-5 Solarbotics Ardweeny: ................................... 2-4, 20-3
Open Source: ............................. ... ........................ 1-4ff Soldering tools: ... ... ..... ... .. ...... .. ........................... ..... 6-3
Creative Commons License: ...... ........................ 1-6 Switches: ........................ .. ..................................... 3-32
GNU GPL (General Public License): ................. 1-5 SWR sense head: ....... .. .. .. .................................... 15-3
Lesser GNU GPL: ..... .. ....................................... 1-6
MIT License: .................. ..... ... ................... .......... 1-6 T
Organic LED (OLEO) display: ............................... 3-15 Talking GPS/UTC time. grid square indicator
Oscilloscope: ... ...... ...... ............ ...... ...... .. .... .............. 6-4 project: ............................. ............................. 16-1 ff
Talking SWR meter project:.. .. .. ........................... 15-1ff
p TEN-TEC Rebel Model 506 transceiver: .... ..... .. ... 26-3
Pascals: ....................... ...... ..... ..... ........ .. ... ............. 11-2 Test equipment: ..... .. .... ..................................... ... .... 6-3
Prototyping shield (protoshield}: .................... 3-11, 6-2 Text-to-speech module: .. ........................ .... ....... .... 3-23
PS2Keyboard library: ....... ...... ......... .. ...... .... .... ...... 19-3 TinyGPS library: ................... ..... ............ ................ 16-5
Pulse width modulation (PWM): ..... ..... .............. ... ... 4-2 TinyRTC clock/calendar module: .......................... 3-26
R u
Real-time clock/calendar (RTCC) module: ... ..... .. . 3-26 USB Host shield: ... .. .................. ..... ... ..... ..... .. .. ........ 3-6
Relay shield: ...... ...................................................... 3-3
Resistor to resistor ladder network: ...................... 18-2 v
RF probe with LED bar graph project: ........ ........ 12-1ff Vacuum fluorescent display (VFD): ... .. ... .... .... .... ... 3-13
RHT03 humidity/temperature sensor: .... .. ... .3-19, 11 -2 Vendor links: ............................................................A-7
VGA display: .......................................................... 3-16
s Voice recognition: ..... ............................................. 26-2
Satellite tracker project: .. .. ........... ... ............. .. ...... 20-1 ff
SatPC32 software: ....................... .... 20-2, 21-1 , 21-31
Schematic diagram: ... .... .................. .. ...... .. ...... ... ..... 5-6
w
Waveform generator project: ............................... 18-1 ff
SD card module: .. ......... .... ..... ...... .... ... .. .... ... ......... 3-27
Weather sensors: .. .............................................. 3-19ff
SD card shield: ...... ... .. .... ........ ...... ..... .................... .. 3-7
Weather station project: ....................... .. ............. 11-1ff
Sensor
WiFi shield: .............................................................. 3-6
BMP085 barometric pressure sensor: .. .. 3-21, 11-3
DS18820 temperature sensor: .. ... ...... .... ..3-19, 9-3
RHT03 humidity/temperature sensor: .... .3-19, 11 -2 x
Vibration sensor: ......................................... .... . 3-32 Xbee shield: ............................................................. 3-8
Serial 1/0: ........... ........ ........... ... .. ............................. 4-2
Serial Monitor: .............. ... ..... .. ............. ....... ....... .... 21-7 y
Serial Peripheral Interface (SPI) bus: ............. ..... .. .. 4-3
Servo: ...... .. .... ............... .... ..... ............... ................. 20-2 Yaesu G5400/5500 rotator: ................................... 21-1
Shield: .. ........... .... ....... .. ... .... ..... .. ...... ............ ... 1-2, 3-1 ff Yaesu GS-232A rotator controller
Argent Radio Data: .... ....... ... ............ .. ................. 3-8 commands (Table): .... ... .... .......... .... .... ..... .... ... 21-5
Audio: ............... .... ... ... ...... ................. ... ..... ....... 3-4 Yaesu GS-232A rotator interface: .... 20-2, 21-1, 25-21
Breadboard: ....... .. ...... ......... .. .................... 3-10, 6-2