You are on page 1of 393

Arduino Tutorials

Arduino is a fascinating and very easy way to make the world of electronics fun and
interesting. Scroll down to read what were up to!
But what is it? From their web page:
Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use
hardware and software. Its intended for artists, designers, hobbyists, and anyone
interested in creating interactive objects or environments.
Arduino can sense the environment by receiving input from a variety of sensors and can
affect its surroundings by controlling lights, motors, and other actuators. The
microcontroller on the board is programmed using the Arduino programming language
(based on Wiring) and the Arduino development environment (based on Processing).
Arduino projects can be stand-alone or they can communicate with software on running
on a computer (e.g. Flash, Processing,MaxMSP).
The boards can be built by hand or purchased preassembled; the software can
be downloaded for free. The hardware reference designs (CAD files) are available under
an open-source license, you are free to adapt them to your needs.
Arduino received an Honorary Mention in the Digital Communities section of the 2006
Ars Electronica Prix. The Arduino team is: Massimo Banzi, David Cuartielles, Tom
Igoe,Gianluca Martino, and David Mellis. Credits

Arduino Uno (Duemilanove is fine as well)


If you are shopping for your first Arduino board, please dont use an Arduino Leonardo
the pinouts vary and for some chapters of this tutorial the board will not work and is not
supported here. There isnt anything wrong with the Leonardo, it just isnt fully

backwards compatible with Uno/Duemilanove boards. A much better solution is the


improved upon the original, 100% Arduino Uno-compatible board with built-in
prototyping space the Freetronics Eleven.

Freetronics Eleven 100% Uno-compatible


Absolute genius!
Over semi-regular intervals you will find a new instalment of my tutorials. If you have
not used the system before, please start with Chapter Zero! In the first few chapters of the
tutorials we refer to the book Getting Started with Arduino by Massimo Banzi.
Furthermore, readers who submit interesting photos, videos or links to their work based
off our tutorials may win a prize! Technical support for the tutorials is available by
asking a question in the Google Group. Please note that video clips in the tutorials do not
have any voice, but some later ones may have a musical track. (I dont like the sound of
my own voice at all).
After a few weeks I would hope that you have enough building blocks of knowledge to
be able to bring your ideas to life!
Files and sketches from each chapter can be downloaded directly from the file repository.
Update 16th June 2012: I have written these tutorials in a period spanning over two
years. During this time several versions of the Arduino IDE have been published. Over
the next month I am endeavouring to update the tutorials so that they work with the
latest Arduino v1.0.1 IDE. In the meanwhile, you can run both v23 (old) and v1.0.1 on
the same machine. If a particular tutorial requires v23, it will state at the top. Any
questions email john at tronixstuff dot com.
All the original material in these tutorials, unless noted otherwise, is published
under a Creative Commons Attribution-Non Commercial-Share Alike v3.0 license. If you

would like to use the work in other situations, please email me at john (at) tronixstuff dot
com.
A quick summary of where we are up to so far:
Chapter Zero

Introduction to the Arduino system


Basic digital outputs
Lots of blinking LEDs!

Chapter One

learn about electricity


the for loop
random numbers
pulse-width modulation
fun with RGB LEDs
reading analogue inputs
building a voltmeter

Chapter Two

sensing temperature with the Analog Devices TMP36


sending data back to the host PC with the serial outputs
libraries
building a digital thermometer
LCD modules- please see chapter 24

Chapter Three

controlling relays to switch heavy current loads


creating your own functions
interrupts
having lots of fun with servos
building an analogue electronic thermometer

Chapter Four

learning about binary numbers


getting more output pins using the 74HC595 shift register
making noises with buzzers and sounds with speakers
understanding arrays
building a temperature data logger

Chapter Five

Controlling more than one 74HC595 shift register


Using 7-segment LED displays
We examine and hack a remote control toy car in order to control it with an
Arduino
learn some more functions
build a binary quiz game testing your ability to convert binary to base-10

Chapter Six

Using 4-digit 7-segment LED display modules with shift registers


Examining the Sharp infra-red distance sensor
Making our first protoshield
build a device to display values from an analogue sensor

Chapter Six (addendum)

more about using 4-digit 7-segment LED display modules

Chapter Seven

Hexadecimal numbers
Binary-coded decimal numbers
the switchcase function
introduction to the I2C bus (two wire interface)
Using the Maxim DS1307 real time clock IC
make our own digital clocks!

Chapter Eight

Some more timing with the Maxim DS1307


receive user input via the serial monitor box
control physical movement with the serial input data
make our own analogue clock!

Chapter Nine

Blink more LEDs with an 88 LED matrix display module


Spend some time considering user interfaces with our projects
create a function to use a potentiometer to return a number in a desired range of
numbers (0~x)
implement a user-interface on the digital clock from Chapter Seven
build our own digital alarm clock!

Chapter Ten

Creating a minimal Arduino board using a bootrom


Using Arduino to control a relay with an on/off timer
build our own dual timer control system with various timing options

Chapter Eleven

Start using wireless data link modules


Control digital pins remotely using wireless
Investigate rotary encoders

Chapter Twelve

More about rotary encoders


Using common-anode LED display modules
Create a button board
Start the series of making a prototype into a product

Chapter Thirteen

examine piezoelectric buzzers


continue with our alarm clock, adding a snooze function
using wireless radio modules to create some remote control systems and sending
various data over the airwaves.

blinky the one eyed clock

an Arduino-based project of interest

Chapter Fourteen

A detailed yet simple introduction to using the XBee wireless data transceivers
with Arduino projects by reader request

Chapter Fifteen

A beginners guide to RFID with Arduino! We build RFID tag/card readers, RFID
control systems, and an RFID data logger with time, date and so on by reader
request

Chapter Sixteen

Getting started with using ethernet and Arduino by reader request

Chapter Seventeen

Getting started with using GPS receivers and Arduino by reader request

Chapter Eighteen

Start playing with RGB LED matrix units

Electronic Dice

An Arduino-based project of interest

Adding a real-time clock to the TwentyTen Arduino-compatible board


Chapter Nineteen

More about GPS

Chapter Twenty

Arduino and the I2C bus. We learn the basics of reading and writing data to
various I2C devices, in preparation for future tutorials.

Chapter Twenty-one

More on Arduino and the I2C bus, including I/O expanders and EEPROM use

Chapter Twenty-two

Arduino and the AREF pin

Chapter Twenty-three

Arduino and the touch-screen

Chapter Twenty-four

Arduino and monochrome LCDs (both character and graphical)

Chapter Twenty-five

Using analog input to read multiple buttons

Chapter Twenty-six

Arduino and GSM cellular part one

Chapter Twenty-seven

Arduino and GSM cellular part two

Chapter Twenty-eight

Arduino and a colour LCD shield

Chapter Twenty-nine

Arduino and a colour TFT LCD

Chapter Thirty

Arduino and twitter.

Chapter Thirty-one

Arduinos inbuilt EEPROM

Chapter Thirty-two

Arduino and infra-red remote control

Chapter Thirty-three

Control AC power outlets via SMS

Chapter Thirty-four
Arduino and the SPI bus (part one)
Chapter Thirty-five
Arduino and video out
Chapter Thirty-six
Arduino and the SPI bus (part two)
Chapter Thirty-seven
Timing applications with millis()

Chapter Thirty-eight
Thermal printer!
Chapter Thirty-nine

How to use the NXP SAA1064 4-digit LED display driver IC with our Arduino
systems

Chapter Forty
Arduino and single thumb-wheel switches.
Arduino and four-digit thumb-wheel switch combinations
Chapter Forty-One
Using one Microchip MCP023017 to add 16 digital I/O ports to your Arduino
Chapter Forty-Two
Arduino and Numeric Keypads
Chapter Forty-Two addendum
Arduino and Numeric Keypads II
Chapter Forty-three
I/O Port Manipulation
Chapter Forty-four
Using an ATtiny45/85 with Arduino software
Chapter Forty-five
Parallax Ping))) Ultrasonic Sensor
Chapter Forty-six
Using an analog input pin to read four buttons
Chapter Forty-seven
Follow me on twitter to find out when the next article is published
Subscribe to keep up to date see top-right of this page.
The content of these tutorials are often decided in part by the readers, suggestions and
votes on future posts are conducted in the Google Group.
All the original material in these tutorials, unless noted otherwise, is published
under a Creative Commons Attribution-Non Commercial-Share Alike v3.0 license. If you
would like to use the work in other situations, please email me at john (at) tronixstuff dot
com. Feedback, comments, and constructive criticism is always welcome dont be shy!

Getting started with Arduino! Chapter Zero


Hello world!
Please join with us as we learn about electronics and the Arduino! Together through this
series of articles I would like to share with you a journey of learning, exploration and fun
with the Arduino system, and make some enjoyable, useful, interesting, useless and
practical things. These posts will be published on a regular basis, on top of the other nonmicro controller posts.
Whew! So much to read and so much fun to have!
The index of articles is to your right. During the first few posts, we will refer to the book:

Getting Started with Arduino (Massimo Banzi)

and also assume a basic knowledge of electronics. For support or to have your questions
answered, post your enquiry in our Google Group a friendly place for such discussions

First of all, lets breakdown the whole system into the basic parts. From there we can
build an understanding of what Arduino is all about.
Arduino is an open source physical computing platform based on a simple input/output
board and a development environment that implements the Processing language
(www.processing.org). Arduino can be used to develop standalone interactive objects, or
be connected to software on your computer. [1]
So, we have hardware and software. Our hardware will be a personal computer that can
run the Arduino IDE (integrated development environment) software; and the Arduino
itself and the electronics to go with it.
Our software is the IDE software very similar to a word-processor, but can send the
Arduino program (or sketch) to the micro controller. These sketches are programs that
are written in the processing language which is similar to C. These are interpreted by a
boot loader software in the chip that allows it to understand your sketch. As the Arduino
system is open source, anyone can purchase a blank micro controller and put the boot
loader on it, or even write their own boot loader or modify the original one.
Now for the Arduino itself. But what do we mean by that? Lets have a look

What we have is a microcontroller installed into a circuit board with a USB interface, a
DC power socket, and many input and output lines (more about them later). Plus some
LEDs for status reports, and other miscellaneous components. This board is the Uno , and
uses the ATMega328 micro controller.
There are also larger, smaller, older and in the future newer boards each different by
their physical size, interface type, and available sketch and data memory. A very good
improvement on the Arduino boards are available from Freetronics. The purpose of the
board is to simplify to a great degree access to the micro controller, and allow you to
easily interface with inputs, outputs, add power supply, connect to a PC for programming,
and talk to other circuits. However the board is more for your convenience, you can
actually use the programmed micro controller in your own designs without the board.

To summarise at this point with an Arduino you can connect various forms of input
and output, and create a program to process and respond to the inputs and outputs. For
example, you could create a temperature alarm when your room temperature rises
above a set amount, the Arduino could sound an alarm.
Forms of input can include: buttons, switches, movement sensors, temperature sensors,
light sensors, gas sensors (!), dials that you can turn (e.g. like a volume knob), wireless
data receivers, etc. Forms of output can include: lights, noise-makers, motors, pumps,
other circuits, liquid-crystal displays, etc. Basically anything that can be switched on or
off, or controlled by electricity, can be controlled by an Arduino.
To make things easier, you can buy or make what is called a shield. This is an interface
board that sits on top of your Arduino, and has various types of circuitry you can
interface with. For example, an ethernet network connection, a joystick for games or
controlling a robot, or an LCD.

So that means with the right sketch, and the right hardware interface, and maybe a shield,
you can do almost anything.
Great!
Thankfully thats about all we need to learn at the moment. Now it is time to actually do
something. You are going to need three things:

A personal computer running Linux, MacOS or Windows with a USB port, with
Internet access. Then again, if youre reading this youre on the net
a USB cable that matches your board socket
an Arduino or compatible board. Most boards should come with a USB cable,
check before buying.

And now for the initial preparation please install your Arduino IDE software using the
instructions here. If you are running Ubuntu, here is an excellent installation guide.
How did you go? Did your LED blink? Were you mesmerised by it, staring blankly at all
the blinky goodness? Its ok, you can admit it we all were the first time.
When working through this series of tutorials, some of the files you download will end
with .pde or .ino. Theyre both fine, the .pde extension was used for sketches written
before Arduno IDE v1.0. You can load these and work with them as normal.
At this point I hope you realised that the Arduino can be powered by your computers
USB port. However, if you want to use your programmed Arduino away from the
computer, you will need a nice regulated plugpack or another source of power.
There is some really basic things to get started, however with respect to the Arduino
creators, please refer to the book Getting Started with Arduino book until the end of page
38. You should be able to get that LED to blink on your own!
Exercise 0.1
Now lets have some more blinky fun. Do you remember Knight Rider with David
Hasselhoff? The hoff drove a tricked-up Trans Am with some cool lights in the bonnet, a
horizontal row with each light blinking in sequence from left to right to left
Your mission, is to simply recreate this with your Arduino, using not one but eight LEDs.
Blink them in an endless loop in the sequence 1-2-3-4-5-6-7-8-7-6-5-4-3-2-1-2-3- with
a delay of one second.
You will need:

Your standard Arduino setup (computer, cable, Uno or compatible)


8 light emitting diodes (LEDs). Anything as long as they draw less than 40mA.

8 560 ohm 0.25 W resistors. They are to reduce the current to protect the LEDs
a breadboard and some connecting wire
a camera (optional) to document your success!

Hint make the delay a variable so you can alter it easily.


From your original flashing LED project in the book, the digital pin 13 was used. This
time, you can use digital pins 2 to 9. The hardware side is easy run a wire from each
digital output pin to the anode of an LED, then put a 560 ohm resistor from the cathode
back to ground. See the diagram below:

And this is what the result should hopefully look like:

And of course, here it is in action:


Now it is your turn to do something write the code! But before you do that, plan what
you want to do first (some old-schoolers would call the plan an algorithm). For example,
for this exercise you might write something like
exercise 0.1 plan
set all the pins I want to use as outputs
create a variable to store the delay duration in milliseconds

start an infinite loop


turn on pin 2, wait for delay duration, turn it off
turn on pin 3, wait for delay duration, turn it off
repeat for pins 4 to 9
then do the same thing but backwards down to pin 3
end of infinite loop
So how did you go? Did it work first time? Its ok if it didnt, as you learn by doing and
fixing your mistakes. Remember if you have any questions, leave a comment at the
bottom of this post and I will get back to you. But to save you time, here is the sketch:
/*
exercise 0.1 - KITT emulator!
Created 02/04/2010
By John Boxall
http://tronixstuff.wordpress.com...
http://wp.me/pQmjR-3i
Blinks LEDs from output pin 2~9 in a forwards<>backward motion
The circuit:
an LED is connected to each output pin from 2 to 8, thence to a 560 ohm
resistor, then to ground (pin 4 on the bottom left of the Arduino
Duemilanove).
based on an orginal by H. Barragan for the Wiring i/o board
*/
// The setup() method runs once, when the sketch starts
int del=100; // sets a default delay time, 1000 milliseconds (one
second)
void setup()
{
// initialize the digital pins as outputs:
// later on there will be easier ways to do this
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
// the loop() method repeats indefinitely until you turn off the power
void loop()
{
digitalWrite(2, HIGH);
// turn on LED on pin 2
delay(del);
// wait (length determined by value of 'del')
digitalWrite(2, LOW);
// turn it off
digitalWrite(3, HIGH);
// turn on LED on pin 3
delay(del);
// wait
digitalWrite(3, LOW);
// turn it off
digitalWrite(4, HIGH);
// turn on LED on pin 4
delay(del);
// wait
digitalWrite(4, LOW);
// turn it off
digitalWrite(5, HIGH);
// turn on LED on pin 5

delay(del);
digitalWrite(5,
digitalWrite(6,
delay(del);
digitalWrite(6,
digitalWrite(7,
delay(del);
digitalWrite(7,
digitalWrite(8,
delay(del);
digitalWrite(8,
digitalWrite(9,
delay(del);
digitalWrite(9,
digitalWrite(8,
delay(del);
digitalWrite(8,
digitalWrite(7,
delay(del);
digitalWrite(7,
digitalWrite(6,
delay(del);
digitalWrite(6,
digitalWrite(5,
delay(del);
digitalWrite(5,
digitalWrite(4,
delay(del);
digitalWrite(4,
digitalWrite(3,
delay(del);
digitalWrite(3,
}

LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//

wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn

it off
on LED on pin 6
it off
on LED on pin 7
it off
on LED on pin 8
it off
on LED on pin 9
it off
on LED on pin 8
it off
on LED on pin 7
it off
on LED on pin 6
it off
on LED on pin 5
it off
on LED on pin 4
it off
on LED on pin 3
it off

So there you have it. Today you have learned how to set up a computer to program your
Arduino, and written some sketches to create outputs based on your design. Although it
wasnt that much, we have to start somewhere but great things will follow.

Getting Started with Arduino! Chapter One

This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
microcontrollers, to be read with the book Getting Started with Arduino (Massimo
Banzi). The first chapter is here.
Welcome back fellow arduidans!
I hope you have been enjoying your new-found skills with the Arduino system, and
enjoying Massimos book. There are many interesting tasks for you to complete in this
weeks instalment: finish chapter four and five of the book, which contains some vital
information about electricity; well look at a new command or two for your sketches that
will save you time and a lot of sketch memory; take a look at pulse width modulation
(huh?); go random!; receive inputs from analogue sources; make some decisions; and
finally complete a project as an exercise for you to test your new knowledge.
First of all, please continue on from page 38 until the end of chapter four. This contains
excellent instuctions on how to deal with switch-bounce, which is vital for future use.
See you soon!
Hello again.
Recall from the previous instalment that your exercise involved a lot of repeated
commands to light each LED in sequence for example:
digitalWrite(2,
delay(del);
digitalWrite(2,
digitalWrite(3,
delay(del);
digitalWrite(3,
digitalWrite(4,
delay(del);
digitalWrite(4,
digitalWrite(5,
delay(del);
digitalWrite(5,
digitalWrite(6,
delay(del);
digitalWrite(6,
digitalWrite(7,
delay(del);
digitalWrite(7,
digitalWrite(8,
delay(del);
digitalWrite(8,
digitalWrite(9,
delay(del);
digitalWrite(9,

HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);
HIGH);
LOW);

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//

turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn
turn
wait
turn

on LED on pin 2
(length determined by value of del)
it off
on LED on pin 3
it off
on LED on pin 4
it off
on LED on pin 5
it off
on LED on pin 6
it off
on LED on pin 7
it off
on LED on pin 8
it off
on LED on pin 9
it off

That seemed repetitive and time consuming the nemesis to the reasoning for the
existence of Arduino! However the solution can be found by using the for command. The

purpose of the for command is to repeat a section of your sketch a number of times (of
course this number is an integer you cannot repeat a loop 3.141 times!).
Below is a very basic example that blinks an LED on pin 9 five times: (download)
/* Example 1.1 using the for command

Created 02/04/2010 --- CC by-sa v3.0 Share the love!


By John Boxall --- http://tronixstuff.wordpress.com
Blinks LED on digital port 9 five times...
Based on an orginal by H. Barragan for the Wiring i/o board
*/
void setup()
{
pinMode(9, OUTPUT);
// initialise the digital pin 9 as an output
}
void loop()
{
for (int wow = 1; wow <= 5; wow++)
{
digitalWrite(9, HIGH); // turn on digital pin 9
delay(1000);
// wait a moment
digitalWrite(9, LOW); // turn off digital pin 9
delay(1000);
// wait a moment
}
delay(10000); // wait 10 seconds, then the whole thing will start again
}

What is happening here is this:

the integer wow is set to have a value of one


the code in the curly brackets is executed
the code checks to ensure wow is less than or equal to five, then increments
wow by one

You can also use wow to subtract one from the value of wow, or another variable.
Anyway, if wow <=5 the looping continues; and if wow>5 it stops and the sketch moves
on.
Hopefully by this stage you have recognised how this can simplify the code for exercise
0.1 from the last instalment. No? Lets try that now. So instead of that huge block of code
to light the LEDS in order up and down, rewrite it to use two loops one for the up
direction, and one for the down.
How did you go? Heres what we came up with: (download)
/*
exercise 1.1 - using the 'for' command in exercise 0.1
Created 02/04/2010 --- CC by-sa v3.0 Share the love! - By John Boxall
--- http://tronixstuff.wordpress.com
Based on an orginal by H. Barragan for the Wiring i/o board

*/
int del=100; // sets a default delay time, 1000 milliseconds (one
second)
void setup()
{
// initialize the digital pins as outputs:
for (int i = 2; i<=9 ; i++)
{
pinMode(i, OUTPUT);
} // end of for loop
} // end of setup
void loop()
{
for (int i = 2; i<=9; i++) // blink from LEDs 2 to 9
{
digitalWrite(i, HIGH);
delay(del);
digitalWrite(i, LOW);
}
for (int i = 8; i>=3; i--) // blink from LEDs 8 to 3
{
digitalWrite(i, HIGH);
delay(del);
digitalWrite(i, LOW);
}
}

Well, wasnt that better? Those for loops saved us a lot of time, and the use of variables
also allows for sketch modifications to be much easier that hunting for each value to
change within the sketch.
Groovy. Time for a quickie:
Hey, do you need a random integer? Easy!
random(x) returns a random integer between 0 and x-1. For example, if you need a
random number between 0 and 255, use random(256). However, using random() is
not entirely random, you need to seed the random number generator inside your
Arduino chip. Use randomSeed(analogRead(0)); or another open analogue pin. You
can also specify a range, for example random(10,20) will produce a random number
between 10 and 19 (the minimum of the range is inclusive, the maximum exclusive
that is why the range is 10~19.

Next on the agenda is pulse-width modulation. Instead of reinventing the wheel, you will
now work through chapter five of the book until the end of page 62.
Now that you have emulated a popular cults computer, its time to have some real fun
with PWM and colours. Massimo mentioned about using red, green and blue LEDs to
make any colour in the spectrum. This can be done quite easily (like most things) with
your Arduino! When you were in school in art classes, you may remember that red +
yellow = orange, red + green = blue, and so on. You can achieve the same effect using
LEDs, and also vary the brightness between them to create the entire colour spectrum.

First, lets look at how the primary colours can be used to create all sorts of colours. This
example demonstrates briefly the possibilities of experimenting with red, green and blue.
You will need:

Your standard Arduino setup (computer, cable, Uno or compatible)


A diffused (not clear plastic) common-cathode RGB light emitting diode. A
diffused LED will shine like a light bulb, where a clear one will just look like a
5mm dot.
2 50 ohm 0.25 W resistors. They are to reduce the current to protect the green and
blue LED section
1 150 ohm 0.25W resistor. This is to reduce the current to the red LED section
a breadboard and some connecting wire
a camera (optional) to document your success!

The circuit is quite simple, however the pins of the LED can be tricky. Here is the
explanation of their layout:

The resistors are between the PWM output pins and the colour anode of the LED. See the
board layout below:

And here is the code oops sketch: (download)


/*
example 1.2 - fun with PWM and RGB LED - Created 07/04/2010 --sa v3.0 Share the love!
By John Boxall --- http://tronixstuff.wordpress.com
*/
int red = 11; // the pins for the LED
int green = 9;
int blue = 10;
int i = 0; // for loops
int j = 0;
void setup()
{
pinMode(red, OUTPUT); // tell Arduino LED is an output
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
}
void loop()
{
// first, cycle up each primary colour twice
for (j = 1; j < 6; j++)
{ // loop 5 times
for (i = 0; i < 255; i++)
{ // loop from 0 to 254 (fade in)
analogWrite(red, i);
// set the LED brightness
delay(20); // Wait 10ms because analogWrite isn't instant
}
analogWrite(red,0);
delay (20);
for (i = 0; i < 255; i++)
{ // loop from 0 to 254 (fade in)
analogWrite(green, i);
// set the LED brightness
delay(20); // Wait 10ms because analogWrite isn't instant
}
delay (20);
analogWrite(green,0);
for (i = 0; i < 255; i++)
{ // loop from 0 to 254 (fade in)
analogWrite(blue, i);
// set the LED brightness

CC by-

delay(20); // Wait 10ms because analogWrite isn't instant


}
delay (20);
analogWrite(blue,0);
}
// psychadelic time
for (j = 1; j < 10000; j++)
{
analogWrite(red,random(255)); // set red at random brightness between 0
and 254
delay (random(10,31));
// wait for a random duration between
10 and 30 milliseconds
analogWrite(green,random(255));
delay (random(10,31));
analogWrite(blue,random(255));
delay (random(10,31));
}
}

And here it is in action! Mesmerising


Wasnt that fun? I hope you enjoyed that as much as I did writing about it for you.
Dont stare at the LED for too long though were moving on to analogue sensors!
Follow the book until the end of page 69.
Now for something completely different. It is time to learn about a new command: if
else
More often than not your sketch will need to make a decision. Is a switch on? Or is it off?
If the variable ph equals 8657309 I will send that number to the GSM module to dial the
number! Once again, with Arduino its ardueasy!
Example: if the value of temperature is greater than 100, turn off pin 13, otherwise turn it
on.
if ( temperature > 100 )
{
digitalWrite(13, LOW); // turn off kettle
}
else
{
digitalWrite(13, HIGH); // leave kettle on
}

You can also extend this with else if


Example: if the value of temperature is greater than 100, turn off pin 13; otherwise if
value of humidity > 80, turn on pin 7.
if ( temperature > 100 )

{
digitalWrite(13, LOW); // turn off kettle
}
else if (humidity > 80 )
{
digitalWrite(7, HIGH); // turn on pin 7
}

With the ifelse statement you have a choice of six operators:

== equals
> greater than
< less than
>= greater than or equal to
<= less than or equal to
!= not equal to

At this point go and have a break and some fresh air. Because after that, its time for
Exercise 1.1
Now we want to put together all the things learned so far and make something that has
analogue inputs, digital outputs, and lots of LEDs a voltmeter! Imagine a bar graph of
ten LEDs, each one represents a voltage range. The range of the voltmeter will be
between 0 and 10 volts DC ideal for testing batteries and cells before they head to the
garbage bin.
That sounds like a lot of work (the sketch, not throwing away batteries), but it isnt when
you break it down into smaller tasks. Lets have a think about it
We know that analogRead() can measure between 0 and 5 volts, and return an integer
between 0 and 1023 relative to the measurement. Ah, but we want to measure up to 10
volts. Easy use a voltage divider. (Need a refresher? Check this post here). Use two
small resistors of equal value (e.g. 560 ohm 0.25 watt).
Next, how to convert that analogRead() value to represent a voltage we relate to an LED.
We know that it will return a value between 0 and 1023, in our case that relates to 0~10
volts. So each LED will relate to one-tenth of the maximum reading. So the first LED
will need to be illuminated if the analogRead() returns between 0 and 102.3 (actually 102
as it returns integers, not real numbers). The second LED will need to be illuminated if
analogRead() returns between 103 and 205. Etcetera.
Now the rest should be easy use your new sketch decision-making skills to decide
which LED to light up (and dont forget to turn it off as well) and youre away
You will need:

Your standard Arduino setup


ten LEDs of your choice. Standard ones are fine, or perhaps a mixture of colours?
3 x 560 ohm 0.25 W resistors. One to reduce the current to protect the LED
indicator in use, and two for the voltage divider
1 x 10k ohm 0.25 W resistor. For use with the analogue input
a breadboard and some connecting wire
a camera (optional) to document your success!

So here is our layout diagram:

And here it is in real life:

and the action movie! We connected a variable power output to the voltmeter for the
sake of the demonstration
however due to resistor tolerance and other analogue electrical problems caused by
using a breadboard, our voltmeter was a little overenthusiastic. So like any quality piece
of test equipment, it required some calibration. There are two ways this could be
achieved:

put a variable resistor in the voltage divider. Then feed a known source, such as
5V from an LM7805 regulator, then adjust the variable resistor until LED 5 was
constantly on;

put another voltmeter (e.g. a multimeter) over the voltage input to measure the
voltage being measured by our voltmeter; use the serial.begin and serial.println()
functions (from page 69) to send the value of voltage to the screen. Adjust the
voltage being measured until you hit 1, 2, 10V noting the serial output. Then
substitute these values into the ifthen decision tree for the LEDs.

The second method is more accurate and easier to accomplish, so I have inserted the
serial code into the example sketch below.
Here is a clip showing the results of the second calibration option:
So how did you go? Did it work first time? Its ok if it didnt, as you learn by doing and
fixing your mistakes. Remember if you have any questions, leave a comment at the
bottom of this post and I will get back to you. But to save you time, here is the sketch. So
there you have it. Today you have learned many more useful things to help you on your
Arduino journey.

Getting Started with Arduino! Chapter Two


This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
microcontrollers, to be read with the book Getting Started with Arduino (Massimo
Banzi). The first chapter is here.
Welcome back fellow arduidans!
I hope you have been enjoying these posts and learning and creating and making many
things. If not, you soon should be!
Todays post has several things: taking temperatures, sending data from the arduino back
to your PC, opening a library, and some exercises that will help to consolidate your
previous knowledge and help revise it.
Note Using LCD screens has moved to Chapter 24.
First of all, we shall investigate another analogue sensor a temperature sensor. As you
can imagine, there are many applications for such a thing, from just telling you the
current temperature, to an arduino-based thermostat control system. And it is much easier
to create than most people would think so get ready to impress some people!
Lets say hello to the Analog Devices TMP36 Low-voltage temperature sensor:

Tiny, isnt it? It looks just like a standard transitor (e.g. a BC548) due the use of the same
TO-92 case style. The TMP36 is very simple in its use looking at the flat face, pin 1 is
for +5V supply (you can connect this to the 5V socket on your arduino), pin 2 is the

output voltage (the reading), and pin three is ground/earth (connect this to the GND
socket on your arduino). Furthermore, have a look at the data sheet, it is quite easy to
read and informative. TMP36 data sheet
The TMP36 will return a voltage that is proportional to temperature. 10 mV for each
degree Celsius, with a range of -40 to 125 degrees.
There isnt any need for extra resistors or other components this sensor must be the
easiest to use out there. However there is one situation that requires some slight
complexity remote positioning of the sensor. It is all very well to have the sensor on
your breadboard, but you might want it out the window, in your basement wine cellar, or
in your chicken coop out back As the voltage output from the sensor is quite low, it is
susceptible to outside interference and signal loss. Therefore a small circuit needs to be
with the sensor, and shielded cable between that circuit and the home base. For more
information on long runs, see page fifteen of the data sheet.
At this point were going to have some mathematics come into the lesson sorry about
that. Looking again at page eight of the data sheet, it describes the output characteristics
of the sensor. With our TMP36, the output voltages increases 10 millivolts for every
degree Celsius increase; and that the output voltage for 25 degrees Celsius is 750 mV;
and that there is an offset voltage of 500 mV. The offset voltage needs to be subtracted
from the analogRead() result, however it is not without vain having the offset voltage
allows the sensor to return readings of below freezing without us having to fool about
with negative numbers.
Quick note: A new type of variable. Up until now we have been using int for integers
(whole numbers) but now it is time for real numbers! These are floating point decimals,
and in your sketches they are defined as float.
Now we already know how to measure an analogue voltage with our arduino using
analogRead(), but we need to convert that figure into a meaningful result. Lets look at
that now
analogRead() returns a value between 0 and 1023 which relates to a voltage between 0
and 5V (5000 mV). It is easier on the mind to convert that to a voltage first, then
manipulate it into temperature. So, our raw analogRead() result from the TMP36
multiplied by (5000/1024) will return the actual voltage [we're working in millivolts, not
volts] from the sensor. Now its easy subtract 500 to remove the offset voltage; then
divide it by 10 [remember that the output is 10 mV per degree Celsius]. Bingo! Then we
have a result in degrees Celsius.
If you live in the Fahrenheit part of the world, you need to multiply the Celsius value by
1.8 and add 32.
Quick note: You may have seen in earlier sketches that we sent a value to the serial
output in order for the arduino software to display it in the serial monitor box. Please

note that you cannot use digital pins 0 or 1 if using serial commands. We used
Serial.begin(9600); in the void setup(); part of the sketch. You can also send text to the
serial monitor, using Serial.print(); and Serial.println();. For example, the following
commands:
Serial.print("The temperature is: ");
Serial.print(temperature, 2);
Serial.println(" degrees Celsius");

would create the following line in the serial monitor (assuming the value of temperature
is 23.73):
The temperature is 23.73 degrees Celsius
and send a carriage return to start a new line. That is the difference between the
Serial.print(); and Serial.println(); commands, the extra -ln creates a carriage return
(that is, sends the cursor to the start of the next line. Did you notice the 2 in the
Serial.print(); above? You can specify the number of decimal places for float variables;
or if you are using an integer, you can specify the base of the number being displayed,
such as DEC, HEX, OCT, BIN, BYTE decimal, hexadecimal, octal, binary, or byte
form. If you dont use the second paramater of Serial.print();, it defaults to decimal
numbers for integers, or two decimal places for floating-point variables.
Now lets read some temperatures! All you need to do is connect the TMP36 up to the
arduino board. pin 1 to 5v, pin 2 to analog 0, pin 3 to GND. Here is a shot of the board
setup:

And here is the sketch:


/*
example 2.1 - digital thermometer
Created 14/04/2010 --- By John Boxall --http://tronixstuff.wordpress.com --- CC by-sa v3.0
Uses an Analog Devices TMP36 temperature sensor to measure temperature
and output values to the serial connection

Pin 1 of TMP36 to Arduino 5V power socket


Pin 2 of TMP36 to Arduino analog 0 socket
Pin 3 of TMP36 to Arduino GND socket
*/
void setup()
{
Serial.begin(9600);
// activate the serial output connection
}
float voltage = 0; // setup some variables
float sensor = 0;
float celsius = 0;
float fahrenheit = 0;
void loop()
{
// let's get measurin'
sensor = analogRead(0);
voltage = (sensor*5000)/1024; // convert raw sensor value to millivolts
voltage = voltage-500;
// remove voltage offset
celsius = voltage/10;
// convert millivolts to Celsius
fahrenheit = ((celsius * 1.8)+32); // convert celsius to fahrenheit
Serial.print("Temperature: ");
Serial.print(celsius,2);
Serial.println(" degrees C");
Serial.print("Temperature: ");
Serial.print(fahrenheit,2);
Serial.println(" degrees F");
Serial.println("_ _ _ _ _ _ _ _ _ _ _ _ _ _ ");
delay (1000); // wait a second, otherwise the serial monitor box will be
too difficult to read
}

And theres nothing like a video, so here it is. The measurements start at room
temperature, then an ice cube in a plastic bag is pushed against the TMP36 for a moment,
them held between two fingers to warm up again
Quick note: the while() command. Sometimes you want a sketch to wait for user input, or
wait for a sensor to reach a certain state without the sketch moving forward. The solution
to this problem is the use of the while() command. It can cause a section of a sketch to
loop around until the expression in the while command becomes true.
For example:
while (digitalRead(3) == LOW)
{
Serial.writeln("Button on digital pin 3 has not been pressed");
}

Anyhow, back to the next exercise its now your turn to make something!
Exercise 2.1
Recently the cost of energy has spiralled, and we need to be more frugal with our heating
and cooling devices. Unfortunately some members of the family like to use the air

conditioner or central heating when it is not really necessary; many arguments are caused
by the need for the heating/cooling to be on or off. So we need an adjudicator that can sit
on the lounge room shelf and tell us whether its ok to use the heating or cooling.
So, create a device that tells us when it is ok to use the air conditioner, heater, or
everything is fine. Perhaps three LEDs, or a single RGB LED. Red for turn on the heat,
blue for turn on the air conditioner, and green or white for Youre fine, you dont need
anything on. You will need to define your own temperature levels. Living here in northeast Australia, Im going to have the air conditioner on above 28 degrees C; and the heat
can come on at 15 degrees C.
Hopefully you are thinking about the voltmeter we made in chapter one, that should give
you a starting point. If not, go back now and have a look. Otherwise, hop to it
Anyway, here is my board layout

You will need:


Your standard Arduino setup (computer, cable, Uno or compatible)
Either three LEDs or an RGB LED
3 x 560 ohm 0.25 W resistors. They are to reduce the current to protect the LEDs.
a breadboard and some connecting wire
a camera (optional) to document your success!
And a sketch to solve the exercise: (download)
/*
exercise 2.1 - Climate Control Judge
Created 14/04/2010 --- By John Boxall --http://tronixstuff.wordpress.com --- CC by-sa v3.0 Share the love!
Measures temperature with Analog Devices TMP36 and compares against
minimum temperature to use a heater or air conditioner
*/
int redLED = 13; // define which colour LED is in which digital output
int greenLED = 12;
int blueLED = 11;
float voltage = 0; // set up some variables for temperature work
float sensor = 0;
float celsius = 0;
float heaterOn = 15; // it's ok to turn on the heater if the temperature
is below this value

float airconOn = 26; // it's ok to turn on the air conditioner if the


temperature is above this value
void setup()
{
pinMode(redLED, OUTPUT);
// set the digital pins for LEDs to outputs
pinMode(greenLED, OUTPUT); // not necessary for analogue input pin
pinMode(blueLED, OUTPUT);
}
void loop()
{
digitalWrite(redLED, LOW);
// switch off the LEDs
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);
// read the temperature sensor and convert the result to degrees Celsius
sensor = analogRead(0);
// TMP36 sensor output pin is connected to
Arduino analogue pin 0
voltage = (sensor*5000)/1024; // convert raw sensor value to millivolts
voltage = voltage-500;
// remove voltage offset
celsius = voltage/10;
// convert millivolts to Celsius
// now decide if it is too hot or cold.
if (celsius>=airconOn)
{
digitalWrite(blueLED, HIGH); // ok to turn on the air conditioner
} else if (celsius<=heaterOn)
{
digitalWrite(redLED, HIGH);
} else
{
digitalWrite(greenLED, HIGH); // everything normal
}
delay(1000); // necessary to hold reading, otherwise the sketch runs too
quickly and doesn't give the LEDs enough time to
// power up before shutting them down again
}

And of course a video. For demonstration purposes, I have altered the values by making
them very close, so its easier to show you the LEDs changing. The plastic bag used in
the video is full of ice water.
Well that was interesting, I hope you enjoyed it and have some ideas on how to put
temperature sensors to use. But now it is time to look at a library or two
Quick note: As you know, there are several commands in the processing language to
control your arduino and its thoughts. However, as time goes on, people can write more
commands and make them available for other arduino users. They do this by creating the
software that allows the actual Atmel microcontroller interpret the authors new
commands. And these commands are contained in libraries. Furthermore, as Arduino is
open-source, you can write your own libraries and publish them for the world (or keep
em to yourself) In the arduino IDE software, have a look at the Sketch>>Import
Library menu option. Also, check out here for more libraries! Now to put one to good
use

Update LCDs were orginally explaned at this point, however they are now
explained in their own article chapter 24. Dont forget to return to try out the
examples and the rest of this chapter!
Exercise 2.2
This is our most complex project to date, but dont let that put you off. You have learned
and practised all the commands and hardware required for this exercise. You only need a
little imagination and some time. Your task is to build a digital thermometer, with LCD
readout. As well as displaying the current temperature, it can also remember and display
on request the minimum and maximum temperatures all of which can be reset.
Furthermore, the thermometer works in degrees C or F.
First of all, dont worry about your hardware or sketch. Have a think about the flow of
the operation, that is, what do you want it to do? For a start, it needs to constantly read
the temperature from our TMP36 sensor. You can do that. Each reading will need to be
compared against a minimum and maximum value. Thats just some decision-making and
basic maths. You can do that. The user will need to press some buttons to display and
reset stored data. You can do that its just taking action if a digital input is high. I will
leave the rest up to you.
So off you go!
You will need (this may vary depending on your design, but this is what we used):

Your standard Arduino setup (computer, cable, Uno or compatible)


Water (you need to stay hydrated)
2 x 10k 0.25 W resistors. They work with the buttons to the arduino
Analog Devices TMP36 temperature sensor (element-14 part number 143-8760)
2 little push buttons
a breadboard and some connecting wire
162 character LCD module and a 10k linear potentiometer or trimpot (For LCD
contrast)
a camera (optional) to document your success!

For inspiration, here is a photo of my board layout:

and a video clip of the digital thermometer in action.


And here is the sketch for my example Exercise 2.2 sketch example. I hope you had
fun, and learned something. Now its time for Chapter Three.

Getting Started with Arduino! Chapter Three


This is chapter three of a series originally titled Getting

Started/Moving Forward with


Arduino! by John Boxall in what feels like an endless series of articles on
the Arduino universe. The first chapter is here, the complete series is detailed here. Any
files from tutorials will be found here.
Welcome back fellow arduidans!
In this chapter we will be looking at relays, becoming more functional, getting
interrupted, and finally being served up some servos. So lets go!
First on the agenda to day are relays.
What is a relay? Think of it as two things that are very close together: a coil that
sometimes has a current passing through it; and a switch, that defaults in one direction.
When a current passes through the coil, it generates an electromagnetic field which
causes the switch to change state. The beauty of a relay is this: you can use a small
current and voltage to switch on and off a very large current and/or voltage and the
switch and coil current are isolated from each other. Here is an example of a relay:

If you look closely you can see the coil and the internals of the switch. This particular
model has a double-pole, double throw switch. That means two inputs can be switched in
either of two directions. The coil needs 12 volts to activate; and the switch can handle
250 volts AC at 5 amps; and the coil resistance is 200 ohms. Ohms law (voltage =
current x resistance) tells us the coil current is 60mA. No way you can get that sort of
current out of an arduino hence the need for a relay. (Though if anyone wants to try,
stand back and film it for us!) The only problem with relays is that they contain moving
parts (the switch) and hence will wear out over time. So if you design a relay into a

project, be sure to document a maintenance schedule for the end-user or maintenance


people.
How will we use this with our arduino? Once again very easily. But we need a partner
in our relay quest a switching transistor. A simple, garden-variety NPN model will do,
such as the BC548. However, when selecting your transistor you need to ensure that it
can handle the current of the relay coil. The data sheet for your transistor (e.g. our
BC548) will mention a value called Ic collector current. For our BC548 this is 100mA,
and greater than the 60mA of our relay coil. Perfect!
Almost there when a coil switches off, all the electromagnetic radiation in the coil
needs to go somewhere, otherwise it could pulse down into the transistor. Therefore a
simple 1A power diode (such as a 1N4004) is placed across the coil, allowing current to
flow through the coil and the diode as a loop until it dissipates.
The last thing to verify is the relay coil voltage. If you have a 5V relay, with a low coil
current, you can use the arduino power. However in most cases your coil voltage will be
12V, so it will require its own power supply.
Here is the schematic for what you should end up with, using a 12V relay and a low
current transistor. Since writing this article I have found some 5V relays are available,
negating the 12v power supply requirement:

So now for a simple test to get a feel for the operation of a relay here is our sketch:
(download)
// example 3.1
// relay test - John Boxall - http://tronixstuff.wordpress.com
void setup()
{
pinMode (2, OUTPUT); // set pin 2 as an output pin
}
void loop()
{
for (int i = 1; i<=20; i++) // loop 20 times
{
digitalWrite (2, HIGH); // turn on pin2 for 1 second, then off for one
second

delay (1000);
digitalWrite (2, LOW);
delay (1000);
}
delay (2000);

Our hardware is exactly as the schematic above. Here is a photo:

And of course a video. Here you can see in detail the coil causing the switch to change
poles.

From here on you understand and can use an arduino to switch a very high current and/or
voltage. Please exercise care and consult an expert if you are working with mains voltage.
It can KILL you.
So now it is time to get more functional.
There are three main components to an arduino sketch: the variables, the structure and the
functions. Functions are the commands that request something to happen, for example
analogRead();. You can also define your own functions to improve the structure and flow
of your sketch. If you have previous programming experience, you may think of these as
sub-procedures, or recall using GOSUB in BASIC all those years ago. An ideal candidate
for a custom function would be exercise 2.2 from our last instalment we could have

written functions to organise the min/max display or reset the memory. However, first we
must learn to walk before we can run
Do you remember void loop(); ? I hope so that is the function that defines your sketch
after the setup. What it really does is define the code within into a loop, which runs
continuously until you reset the arduino or switch it off. You can simply define your own
functions using the same method. For example:
void blinkthree() // the name of my function is "blinkthree"
{
for (int i = 0; i <3; i++) // loop three times
{
digitalWrite(8, HIGH); // turn on LED connected to digital pin 8
delay (1000);
digitalWrite(8, LOW); // turn off LED connected to digital pin 8
delay (1000);
}
}

Now that function has been defined, when you want to blink the LED on pin 8 three
times, just insert void blinkthree(); into the required point in your sketch. But what if you
want to change the number of blinks? You can pass a parameter into your function as
well. For example:
void blinkblink(int blinks) // the name of my function is "blinkblink",
and receives an integer which is stored in the variable blinks
{
for (int i = 0; i <blinks; i++) // loop "blinks" times
{
digitalWrite(8, HIGH); // turn on LED connected to digital pin 8
delay (1000);
digitalWrite(8, LOW); // turn off LED connected to digital pin 8
delay (1000);
}
}

So to blink that LED 42 times, execute blinkblink(42); Want to specify your own delay?
Try this:
void blinkblink(int blinks, int del) // the name of my function is
"blinkblink", and receives an integer which is stored in the
variable blinks, and another del ...
{
for (int i = 0; i<blinks; i++) // loop "blinks" times
{
digitalWrite(8, HIGH); // turn on LED connected to digital pin 8
delay (del);
digitalWrite(8, LOW); // turn off LED connected to digital pin 8
delay (del);
}
}

So to blink that LED 42 times, with an on/off period of 367 milliseconds


execute blinkblink(42,367);. It is quite simple, dont you think?
Ok, one more. Functions can also function as mathematical functions.

For example:
float circlearea (float radius)
{
float result = 0;
result = 3.141592654 * radius * radius;
return result;
}

Do you see what happened there? If our sketch determined the radius of a circle and
placed it in a variable radius2, the area of the circle could be calculated by:
area2 = circlearea(radius2);

Easy.
So now you can create your own functions. Not the most colourful of sections, but it is
something we need to know.
Time for a stretch break, go for a walk around for five minutes.
Now it is time to interrupt your break with some interrupts.
An interrupt is an event that occurs when the state of a digital input pin changes, and
causes a specific function to be called and its contents to be executed.
For example, a robot while it is happily wandering about a sensor is monitoring a
proximity sensor pointing to the ground, which changes state when the robot is lifted off
the ground and triggers an interrupt which could switch off the wheels or sound an
alarm (Help, Im being stolen!). I am sure your imagination can think of many other
things.
So how do we make an interrupt interrupt? It is relatively easy, with a couple of
limitations. You can only monitor two pins (for a normal arduino board) or six with an
Arduino mega. Furthermore, you cannot use the function delay() in your interrupt
function. Now, you need to decide three things: the pin to monitor (digital 2 or 3, referred
to as 0 or 1), the function to run when the interrupt occurs, and what sort of behaviour to
monitor on the interrupt pin that is, the change of state of the pin. Your pins also need to
be set to output using pinMode();.
There are four changes of state: LOW (when the pin becomes low), CHANGE (when the
pin changes state, from high or from low), RISING (when pin goes from low to high) and
FALLING (when pin goes from high to LOW). Initially that looks like a lot to
remember, but it is quite simple when you think about it.
Crikey that was a lot to take in. So instead of theory, it is time for some practice.

Example 3.2 interrupt demonstration.


In this example, we will have our random number generator from example 2.2, but with
two interrupts being monitored. These will be triggered by push buttons for simplicity:
(download)
/*
Example 3.2 interrupts
Created 21/04/2010 By John Boxall http://tronixstuff.wordpress.com
CC by-sa v3.0
Just send some data to the LCD, whilst monitoring two interrupts
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
float noisy = 0;
void setup()
{
lcd.begin(16, 2);
// need to specify how many columns and
rows are in the LCD unit
lcd.setCursor(0,0);
lcd.println('* example 3.2 * ');
lcd.setCursor(0,1);
lcd.println('tronixstuff.com ');
lcd.setCursor(0,1);
delay(4000);
lcd.clear();
randomSeed(analogRead(0)); // reseed the random number generator with
some noise
attachInterrupt(0, panicone, RISING); // so when interrupt zero (digital
pin 2) changes state, it will trigger the interrupt and go to function
'panicone'
attachInterrupt(1, panictwo, RISING); // so when interrupt one (digital
pin 3) changes state, it will trigger the interrupt and go to function
'panictwo'
}
void loop()
{
noisy=random(1000);
lcd.setCursor(0,0);
lcd.print('Random Numbers!');
lcd.setCursor(0,1);
lcd.print('Number: ');
lcd.print(noisy,0);
delay(1000);
}
void panicone()
{
lcd.clear();
lcd.println('Interrupt one
');
}
void panictwo()
{
lcd.clear();
lcd.println('Interrupt two
');

Of course it wouldnt be right without a photo of the board layout we have just reused
the LCD set-up from example 2.2, and added two standard push-buttons and 10k resistors
(as per page 42 of the book) for the interrupts. Here you are:

And the video those switches could really have used a de-bounce circuit, but for the
purpose of the demonstration they are not really necessary.
Finally its servo time! I really hope you went through the other sections before heading
here although they may not have been that interesting, they will certainly be useful.
What is a servo?
Think of a little electric motor that is connected to a variable resistor. An electric pulse or
command is sent to the motor, and it rotates until it reaches a position that matches a
value of the potentiometer. Yes, that sounds a little crazy.
A much simpler explanation is this: a servo is an electric motor that can be commanded to
rotate to a specific angular position. For example, they are commonly used to control the
steering in a remote-control car. Thankfully once again with arduino and friends, using a
servo is very easy, and allows your imagination to go nuts, limited only by the amount of
spare time and money you have.
When considering the use of a servo, several factors need to be taken into account. These
include:

rotational range, that is the angular range it can rotate. 180 degrees, 360 degrees
(full rotation), etc.
the speed at which it can rotate (usually measured in time per degrees)
the torque the servo can generate (how strong it is)
the amount of current it draws under load
weight, cost, and so on

One of the first things that came to mind was Wow how many can I use at once? And
the answer is 12 on the Duemilanove/Uno, and 48 (wow) on the Arduino Mega. Please
note you cannot used analogWrite(); on pins 9 and 10 when using the servo library. For
more details, please see the Arduino servo library page.
For our examples and exercises today, I am using the Turnigy TG9. It is quite
inexpensive and light, good for demonstration purposes and often used in remote control
aircraft. It can rotate within a range of almost 180 degrees (well it was cheap).

I hope you noticed that there are three wires to the servo. One is for +5V, one is for GND,
and one is the control pin connect to an arduino digital out. Which colour is which pin
may vary, but for this adafruit servo, the darkest is GND, the lightest is control, and the
middle colour is the +5V. This servo is very small and doesnt draw much current, so its
ok to power from your Arduino board. However, if using something larger, or putting
your servo under load you will need to run it from a separate power supply that can
deliver the required current. If working with more than a couple of these light-duty
servos, you should get an external power supply and a motor shield.
When working with angles, you should have a protractor handy. Such as:

Now how do we control our servo? First of all, we need to use the servo library. In the
same manner as we did with the LCD screen in chapter two, place the following line at
the start of your sketch:
#include <Servo.h>

So now we have access to a range of servo commands.


Then you need to create the servo object in your sketch, so it can be referred to, such as
Servo myservo;

Then finally, attach the servo to a digital pin for control (within your void(setup); )
myservo.attach(9);

// attaches the servo on pin 9 to the servo object

That is the setting up out of the way. Now all you need to do is this
myservo.write(pos);

where pos is a value between 0 and 180. (or more or less, depending on the rotational
range of your servo).
Now, the proof is in the pudding so to speak, so here once more is an example of it all
coming together and rotating. The following example moves from left to middle to
right and repeats, to give you an idea of what is happening: (download)
/*
Example 3.3 servo examination
Created 21/04/2010 By John Boxall http://tronixstuff.wordpress.com
CC by-sa v3.0
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0;
// variable to store the servo position
int del = 100; // delay in micoseconds
void setup()
{
Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
for (int loopy = 0; loopy<=3; loopy++)
{
for (pos = 180; pos >=0; pos--) // from left to right with Hextronik
HXT900
{
myservo.write(pos);
delay(del);
}

delay(1000);
}
for (int loopy = 0; loopy<=3; loopy++)
{
myservo.write(180);
delay (1000);
myservo.write(90);
delay (1000);
myservo.write(0);
delay (3000);
}
}

The board layout is quite simple, just the three servo wires to the arduino board.

And the video. I am sorry that my camera does not record audio, as you cannot hear the
cute buzz of the servo.
Ok then thats enough reading and watching from your end of the Internet. Now it is
time for you to make something; using all the knowledge that we have discussed so far
Exercise 3.1
We can use our digital world to make something useful and different an analogue
digital thermometer, with the following features:

analogue temperature display over a 180-degree scale. The range will vary
depending on your home climate. My example will be 0~40 degrees Celsius
analogue meter showing whether you can have the heater or air-conditioner on, or
off. A rendition of exercise 2.1 in analogue form.
minimum and maximum temperature display, displayable on demand, with
indicators showing what is being displayed (LEDs would be fine); and a reset
button

You will need to combine your own functions, working with temperature sensors; a lot of
decision-making, digital and analogue inputs, digital and analogue outputs, and some
creativity. To reproduce my example of the exercise, you will need the following:

Your standard Arduino setup


Water (you need to stay hydrated)
Analog Devices TMP36 temperature sensor (element-14 part number 143-8760)
2 little push buttons
2 x 10k 0.25 W resistors. They work with the buttons to the arduino
a breadboard and some connecting wire
two LEDs to indicate minimum/maximum
2 x 390 ohm 0.25 W resistors. They are to reduce the current to protect the LEDs.

Off you go if you have any questions, leave a comment at the end of the post, or email
john at tronixstuff dot com.
And now for the results of the exercise. Here are photos of my board layout:

Here you can see the buttons for displaying minimum/maximum temperature, and the
reset button. The LEDs indicate the right servo is display minimum or maximum

temperature, or illuminate together to ask if you want to reset the memory. And of course,
our video:
And here is the sketch for my example board layout.
Wow. Congratulations to all those who took part and built something useful. Now to
move on to Chapter Four.

Getting Started with Arduino! Chapter Four


This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
microcontrollers. The first chapter is here, and the complete index is here.
Welcome back fellow arduidans!
In this chapter will be looking at getting more outputs from less pins, listening to some
tunes, saying hooray to arrays, and even build a self-contained data logger!
So lets go!
More pins from less sounds too good to be true, doesnt it? No, it is true and we can
learn how to do this in conjunction with a special little IC, the 74HC595 Serial In/Parallel
Out 8-bit Shift Register. Lets say hello:

Before we get too carried away, we need to understand a little about bits, bytes and binary
numbers.
A binary number can only uses zeros and ones to represent a value. Thus binary is also
known as base-2, as it can only use two digits. Our most commonly used number types
are base-10 (as it uses zero through to nine; hexadecimal is base-16 as it uses 0 to 9 and A
to F). How can a binary number with only the use of two digits represent a larger
number? It uses a lot of ones and zeros. Lets examine a binary number, say 10101010.
As this is a base-2 number, each digit represents 2 to the power of x, from x=0 onwards.

See how each digit of the binary number can represent a base-10 number. So the binary
number above represents 85 in base-10 the value 85 is the sum of the base-10 values.
Another example 11111111 in binary equals 255 in base 10.

Now each digit in that binary number uses one bit of memory, and eight bits make a
byte. A byte is a special amount of data, as it matches perfectly with the number of output
pins that the 74HC595 chip controls. (See, this wasnt going to be a maths lesson after
all). If we use our Arduino to send a number in base-10 out through a digital pin to the
595, it will convert it to binary and set the matching output pins high or low.
So if you send the number 255 to the 595, all of the output pins will go high. If you send
it 01100110, only pins 1,2,5, and 6 will go high. Now can you imagine how this gives
you extra digital output pins? The numbers between 0 and 255 can represent every
possible combination of outputs on the 595. Furthermore, each byte has a least
significant bit and most significant bit these are the left-most and right-most bits
respectively.
Now to the doing part of things. Lets look at the pinout of the 74HC595: (from NXP
74HC595 datasheet)

Pins Q0~Q7 are the output pins that we want to control. The Q7 pin is unused, for now.
595 pin 14 is the data pin, 12 is the latch pin and 11 is the clock pin. The data pin
connects to a digital output pin on the Arduino. The latch pin is like a switch, when it is
low the 595 will accept data, when it is high, the 595 goes deaf. The clock pin is toggled
once the data has been received. So the procedure to get the data into a 595 is this:
1) set the latch pin low (pin 12)
2) send the byte of data to the 595 (pin 14)
3) toggle the clock pin (pin 11)
4) set the latch pin high (pin 12)
Pin 10 (reset) is always connected to the +5V, pin 13 (output enable) is always connected
to ground.
Thankfully there is a command that has parts 2 and 3 in one; you can use digitalWrite();
to take care of the latch duties. The command shiftOut(); is the key. The syntax is:
shiftout(a,b,c,d);

where:
a = the digital output pin that connects to the 595 data pin (14);
b = the digital output pin that connects to the 595 clock pin (11);
c can be either LSBFIRST or MSBFIRST. MSBFIRST means the 595 will interpret the
binary number from left to right; LSBFIRST will make it go right to left;
d = the actual number (0~255) that you want represented by the 595 in binary output
pins.
So if you wanted to switch on pins 1,2,5 and 6, with the rest low, you would execute the
following:
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST,102);
digitalWrite(latchpin, HIGH);

Now, what can you do with those 595 output pins? More than you could imagine! Just
remember the most current you can sink or source through each output pin is 35
milliamps.

For example:

an LED and a current-limiting resisor to earth you could control many LEDs
than normally possible with your Arduino;
an NPN transistor and something that draws more current like a motor or a larger
lamp
an NPN transistor controlling a relay (remember?)

With two or more 595s you can control a matrix of LEDs, 7-segment displays, and more
but that will be in the coming weeks.
For now, you have a good exercise to build familiarity with the shift-register process.
Exercise 4.1
Construct a simple circuit, that counts from 0~255 and displays the number in binary
using LEDs. You will require the following:

Your standard Arduino setup (computer, cable, Uno or compatible)


8 LEDs of your choosing
One 74HC595 shift register
8 x 560 ohm 0.25 W resistors. For use as current limiters between the LEDs and
ground.
a breadboard and some connecting wire

The hardware is quite easy. Just remember that the anodes of the LEDs connect with the
595, and the cathodes connect to the resistors which connect to ground. You can use the
Arduino 5V and GND.
Here is what my layout looked like:

and of course a video I have increased the speed of mine for the sake of the
demonstration.

How did you go? Here is the sketch if you need some ideas.
Next on the agenda today is another form of output audio.
Of course you already knew that, but until now we have not looked at (or should I say,
listened to) the audio features of the Arduino system. The easiest way to get some noise is
to use a piezo buzzer. An example of this is on the left hand side of the image below:

These are very simple to use and can be very loud and annoying. To get buzzing, just
connect their positive lead to a digital output pin, and their negative lead to ground. Then
you only have to change the digital pin to HIGH when you need a buzz. For example:
/* Example 4.1
Annoying buzzer!
CC by-sa v3.0
http://tronixstuff.wordpress.com */
void setup()
{
pinMode(12, OUTPUT);
}
void loop()
{
digitalWrite(12, HIGH);
delay(500);
digitalWrite(12, LOW);
delay(2000);
}

You wont be subjected to a recording of it, as thankfully (!) my camera does not record
audio
However, you will want more than a buzz. Arduino has a tone(); command, which can
generate a tone with a particular frequency for a duration. The syntax is:
tone(pin, frequency, duration);

where pin is the digital output pin the speaker is connected to, frequency in Hertz,
duration in milliseconds. Easy!
If you omit the duration variable, the tone will be continuous, and can be stopped with
notone();. Furthermore, the use of tone(); will interfere with PWM on pins 3 and 11,
unless you are using an Arduino Mega.
Now, good choice for a speaker is one of those small 0.25w 8 ohm ones. My example is
on the right in the photo above, taken from a musical plush toy. It has a 100 ohm resistor
between the digital output pin and the speaker. Anyhow, lets make some more annoying
noise hmm a siren! (download)
/* Example 4.2
Annoying siren
CC by-sa v3.0
http://tronixstuff.wordpress.com */
void setup()
{
pinMode(8, OUTPUT); // speker on pin 8
}
int del = 250; // for tone length
int lowrange = 2000; // the lowest frequency value to use
int highrange = 4000; // the highest...
void loop()
{
// increasing tone
for (int a = lowrange; a<=highrange; a++)
{
tone (8, a, del);
}
// decreasing tone
for (int a = highrange; a>=lowrange; a--)
{
tone (8, a, del);
}
}

Phew! You can only take so much of that.


Array! Hooray? No Arrays.
What is an array?
Lets use an analogy from my old comp sci textbook. Firstly, you know what a variable is
(you should by now). Think of this as an index card, with a piece of data written on it.
For example, the number 8. Lets get a few more index cards, and write one number on
each one. 6, 7, 5, 3, 0, 9. So now you have seven pieces of data, or seven variables. They
relate to each other in some way or another, and they could change, so we need a way to
keep them together as a group for easier reference. So we put those cards in a small filing
box, and we give that box a name, e.g. Jenny.

An array is that small filing box. It holds a series of variables of any type possible with
arduino. To create an array, you need to define it like any other variable. For example, an
array of 10 integers called jenny would be defined as:
int jenny[10];

And like any other variable, you can predefine the values. For example:
int jenny[10] = {0,7,3,8,6,7,5,3,0,9};

Before we get too excited, there is a limit to how much data we can store. With the
Arduino Duemilanove, we have 2 kilobytes for variables. See the hardware specifications
for more information on memory and so on. To use more we would need to interface with
an external RAM IC thats for another chapter down the track.
Now to change the contents of an array is also easy, for example
jenny[3] = 12;

will change our array to


int jenny[10] = {0,7,3,12,6,7,5,3,0,9};

Oh, but that was the fourth element! Yes, true. Arrays are zero-indexed, so the first
element is element zero, not one. So in the above example, jenny[4] = 6. Easy.
You can also use variables when dealing with arrays. For example:
for (int i = 0; i<10;
{
jenny[i] = 8;
}

i++; i<10)

Will change alter our array to become


jenny[] = {8,8,8,8,8,8,8,8,8,8}

A quick way set set a lot of digital pins to output could be


int pinnumbers [] = {2,3,4,5,6,7,8,9,10,11,12,13}
for (int i= 0; i++; i<12)
{
pinMode(pinnumbers[i],OUTPUT);
}

Interesting very interesting. Imagine if you had a large array, an analogue input sensor,
a for loop, and a delay. You could make a data logger. In fact, lets do that now.

Exercise 4.2
Build a temperature logger. It shall read the temperature once every period of time, for 24
hours. Once it has completed the measurements, it will display the values measured, the
minimum, maximum, and average of the temperature data. You can set the time period to
be of your own choosing. So lets have a think about our algorithm. We will need 24
spaces to place our readings (hmm an array?)

Loop around 24 times, feeding the temperature into the array, then waiting a
period of time
Once the 24 loops have completed, calculate and display the results on an LCD
and (if connected) a personal computer using the Arduino IDE serial monitor.

I know you can do it, this project is just the sum of previously-learned knowledge. If you
need help, feel free to email me or post a comment at the end of this instalment.
To complete this exercise, you will need the following:

Your standard Arduino setup (computer, cable, Uno or compatible)


Water (you need to stay hydrated)
Analog Devices TMP36 temperature sensor (element-14 part number 143-8760)
1 little push button
1 x 10k 0.25 W resistor. For use with the button to the arduino
a breadboard and some connecting wire
one LCD display module

And off you go!


Today I decided to construct it using the Electronic Bricks for a change, and it worked
out nicely.
Here is a photo of my setup:

a shot of my serial output on the personal computer:

and of course the ubiquitous video. For the purposes of the demonstration there is a much
smaller delay between samples
(The video clip below may refer to itself as exercise 4.1, this is an error. It is definitely
exercise 4.2)
And here is the sketch if you would like to take a peek. High resolution photos
are available in flickr.
Another chapter over! Im already excited about writing the next instalment Chapter
Five.

Getting Started with Arduino! Chapter Five


This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
microcontrollers. The first chapter is here, and the complete index here.
Welcome back fellow arduidans!
Hello once again to our weekly Arduino instalment. This week are up to all sorts of
things, including: more shiftiness with shift registers, more maths, 7-segment displays,
arduinise a remote control car, and finally make our own electronic game! Wow lets
get cracking
In the last chapter we started using a 74HC595 shift register to control eight output pins
with only three pins on the Arduino. That was all very interesting and useful but there is
more! You can link two or more shift registers together to control more pins! How? First
of all, there is pin we havent looked at yet pin 9 on the 595. This is data out. If we
connect this to the data in pin (14) on another 595, the the first shift register can shift a
byte of data to the next shift register, and so on.
Recall from our exercise 4.1, this part of the sketch:
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, loopy);
digitalWrite(latchpin, HIGH);

If we add another shiftOut(); command after the first one, we are sending two bytes of
data to the registers. In this situation the first byte is accepted by the first shift register
(the one with its data in pin [14] connected to the Arduino), and when the next byte is
sent down the data line, it pushes the byte in the first shift register into the second shift
register, leaving the second byte in the first shift register.
So now we are controlling SIXTEEN output pins with only three Arduino output pins.
And yes you can have a third, fourth if anyone sends me a link to a Youtube clip
showing this in action with 8 x 74HC595s, I will send them a prize. So, how do we do it?
The code is easy, here is the sketch.
On the hardware side, it is also quite simple. If you love blinking LEDs this will make
your day. It is the same as exercise 4.1, but you have another 74HC595 connected to
another 8 LEDS. The clock and latch pins of both 595s are linked together, and there is a
link between pin 9 of the first register and pin 14 of the second. Below is a photo of my
layout:

and a video:
Can you think of anything that has seven or eight LEDs? Hopefully this photo will
refresh your memory:

Quickie if you want to find out the remainder from a quotient, use modulo %. For
example:
a = 10 % 3;
returns a value of 1; as 10 divided by 3 is 3 remainder 1.
and
If you need to convert a floating-point number to an integer, it is easy. Use int();. It does
not round up or down, only removes the fraction and leaves the integer.
Anyhow, now we can consider controlling these numeric displays with our arduino via
the 74HC595. It is tempting to always use an LCD, but if you only need to display a few
digits, or need a very high visibility, LED displays are the best option. Futhermore, they
use a lot less current than a backlit LCD, and can be read from quite a distance away. A 7segment display consists of eight LEDs arrange to form the digit eight, with a decimal
point. Here is an example pinout digram:

Note that pinouts can vary, always get the data sheet if possible.
Displays can either be conmmon-anode, or common-cathode. That is, either all the LED
segment anodes are common, or all the cathodes are common. Normally we will use
common-cathode, as we are sourcing current from our shift register through a resistor
(560 ohm), through the LED then to ground. If you use a common-anode, you need to
sink current from +5v, through the resistor and LED, then into the controller IC. Now
you can imagine how to display digits using this type of display we just need to
shiftout(); a byte to our shift register that is equavalent to the binary representation of the
number you want to display.
Huh?
Lets say we want to display the number 8 on the display. You will need to light up all
the pins except for the decimal point. Unfortunately not all 7-segment displays are the
same, so you need to work out which pinout is for each segment (see your data sheet) and
then find the appropriate binary number to represent the pins needed, then convert that to
a base-10 number to send to the display. I have created a table to make this easier:

And here is a blank one for you to print out and use: blank pin table.pdf.
Now lets wire up one 7-segment display to our Arduino and see it work. Instead of the
eight LEDs used in exercise 4.1 there is the display module. For reference the pinouts for
my module were (7,6,4,2,1,9,10,5,3,8) = (a,b,c,d,e,f,g,DP, C, C) where DP is the decimal
point and C is a cathode (which goes to GND). The sketch: example 5.2. Note in the
sketch that the decimal point is also used; its byte value in this example is 128. If you
add 128 to the value of loopy[] in the sketch, the decimal point will be used with the
numbers.

and the video:


There you go easily done. Now it is time for you to do some work!

Exercise 5.1
Produce a circuit to count from 0 to 99 and back, using two displays and shift-registers. It
isnt that difficult, the hardware is basically the same as example 5.1 but using 7-segment
displays.
You will need:

Your standard Arduino setup (computer, cable, Uno or compatible)


Two 7-segment, common-cathode displays
Two 74HC595 shift registers
16 x 560 ohm 0.25 W resistors. For use as current limiters between the LED
display segments and ground
a breadboard and some connecting wire
some water

You are probably wondering how on earth to separate the digits once the count hits 10
a hint: 34 modulo 10 = 4. 34 divided by 10 = 3.4 but 3.4 isnt an integer. While you
are thinking, here is the shot of my layout:

and the ubiquitous video:


And here is the sketch for my interpretation of the answer.
I hope you have gained more of an understanding of the possibilities available with shift
registers. We will contiunue with more next week.
However, next on our agenda is some real-world hacking. This section of the chapter is
more of a commentary than the usual format, but I hope you find it interesting and you
receive some inspiration or ideas after reading it.
Although we have been having fun (well I have been, hopefully someone else is as well)
making things on our desks or work benches, it is time to slowly enter the real world and
hack something up. The other day I was in a variety store to buy some glue, and
happened across a very cheap remote-control car. After noticing it had full directional
control (left/right, forwards/backwards) it occured to me that we could control it with an
arduino. So $9 later here it is on my desk:

Naturally I stopped everything else and had a play with it. But by crikey it was very fast:
The first thing to do would be slow this baby down. Due to the cheapness of the
product it did not have variable speed control. So the first thing to do was pull the body
off to see what we had to work with:

The design is very simple, with one motor controlling the steering, and one for the speed.
Luckily for me there were four wires heading to the motor from the PCB, and the were
very easy to get to.

Normally we could use pulse-width modulation to slow motors down, but I dont think
we could send a PWM signal over radio control. Instead, it would be easier to reduce the
voltage going to the drive motor in order to slow it down. So with the car up on blocks,
the motor was set to forward with the remote and I measure the voltages across the four
wires. Black and green was +3.7 in forwards, nothing in reverse, black and red was the
same in reverse, and nothing forwards. Easy just find out how much current the motor
draws at full speed and then we can use Ohms law (voltage = current x resistance) to
calculate the value of a resistor to slow it down about 70% or so.

The motor initially drew ~500 mA to start up and then reduced to ~250 mA once it got
going after around one second. However, a various range of resistors from 10 to 120 ohm
didnt really seem to have much effect, and a 560 ohm knocked it out all together. So
instead of trying to control speed with a hardware method, we will try with a software
method perhaps try PWM after all, or create our own.
But now, time to get the arduino interfaced with the transmitter unit. Firstly I reassembled
the car, then started on the transmitter:

After cutting my finger trying to get the transmitted open, it eventually gave in and
cracked open. But the effort was worth it the control buttons were very simple rubber
pads over the PCB spots:

Excellent each controller was basically a SPDT switch, and there is plenty of space on
the PCB to solder in some wires to run to the Arduino and a breadboard. The push
buttons could be replaced with BC548 transistors controlled by our Arduino the same
we we controlled a relay in Chapter Three.
Next was to solder some wires from the PCB that could run to my breadboard:

The green wire is a common return, and the yellow wires are forwards, reverse, left and
right. Now to set up the breadboard. Four digital out pins, connected to the base of a
BC548 transistor via a 1k resistor. The emitters are connected to GND, which is also
connected to the GND of the transmitter.

Just as I had finished making up the breadboard, after turning around to close a window
my arm brushed the transmitter and it made a crack noise.

My soldering had come unstuck. Oh well, it was only reverse! Time to get moving
anyhow. Once again, I put the car up on blocks and uploaded the following sketch:
(download)
/*
Example 5.3
Control a toy remote control car with arduino
Chapter Five @ http://www.tronixstuff.com/tutorials
*/
int forward = 12;
int left = 9;
int right = 7;
int del = 5000;
void setup()
{
pinMode(forward, OUTPUT);
pinMode(left, OUTPUT);
pinMode(right, OUTPUT);
}
void loop()
{
digitalWrite(right, HIGH);
delay(1000);
digitalWrite(right, LOW);
delay(1000);
digitalWrite(left, HIGH);
delay(1000);
digitalWrite(left, LOW);
delay(1000);
digitalWrite(forward, HIGH);
delay(del);
digitalWrite(forward, LOW);
delay(1000);
}

It cycles throgh the three (working!) function of the car. Lets see what happens:

Thats a good start, things are moving when we want them to move. However the cars
motors seem to be pulsing. Perhaps the resistor-transistor bridge to the arduino had
something to do with that. So I threw caution to the wind and connected the digital output
pins directly to the transmitter. Wow! That fixed it. The motors are going at full speed
now
Using our knowledge of Arduino sketches it will be east to make this car to drive around.
Lets try that now here is our sketch:
/*
Example 5.4
Control a toy remote control car with arduino - figure eight
Chapter Five @ http://www.tronixstuff.com/tutorials
*/
int forward = 12;
int left = 9;
int right = 7;
int del = 5000;
void setup()
{
pinMode(forward, OUTPUT);
pinMode(left, OUTPUT);
pinMode(right, OUTPUT);
}
// to make creating the car's journey easier, here are some functions
void goleft(int runtime)
{
digitalWrite(left, HIGH); // tell the steering to turn left
digitalWrite(forward, HIGH); // move the car forward
delay(runtime);
digitalWrite(forward, LOW);
digitalWrite(left, LOW); // tell the steering to straighen up
}
void goright(int runtime)
{
digitalWrite(right, HIGH); // tell the steering to turn right
digitalWrite(forward, HIGH); // move the car forward
delay(runtime);
digitalWrite(forward, LOW);
digitalWrite(right, LOW); // tell the steering to straighen up
}
void goforward(int runtime)
// run the drive motor for "runtime" milliseconds
{
digitalWrite(forward, HIGH); // start the drive motor forwards
delay(runtime);
digitalWrite(forward, LOW); // stop the drive motor
}
void loop()
{
goforward(1000);
goleft(1000);
goright(1000);
}

For some reason now forwards made the car go backwards. And only when I removed the
GND wire from the Arduino to the breadboard. Interesting, but perhaps a problem for
another day.
There we have it. Our first attempt at taking over something from the outside world and
arduinising it. Now it is back to our normal readings with an exercise!
Exercise 5.2
Once again it is your turn to create something. We have discussed binary numbers, shift
registers, analogue and digital inputs and outputs, creating our own functions, how to use
various displays, and much more. So our task now is to build a binary quiz game. This is
a device that will:

display a number between 0 and 255 in binary (using 8 LEDs)


you will turn a potentiometer (variable resistor) to select a number between 0 and
255, and this number is displayed using three 7-segment displays
You then press a button to lock in your answer. The game will tell you if you are
correct or incorrect
Basically a Binary quiz machine of some sort!

I realise this could be a lot easier using an LCD, but that is not part of the exercise. Try
and use some imagination with regards to the user interface and the difficulty of the
game. At first it does sound difficult, but can be done if you think about it. At first you
should make a plan, or algorithm, of how it should behave. Just write in concise
instructions what you want it to do and when. Then try and break your plan down into
tasks that you can offload into their own functions. Some functions may even be broken
down into small functions there is nothing wrong with that it helps with planning and
keeps everything neat and tidy. You may even find yourself writing a few test sketches, to
see how a sensor works and how to integrate it into your main sketch. Then put it all
together and see!
You will need: (to recreate my example below)

Your standard Arduino setup (computer, cable, Uno or compatible)


Three 7-segment, common-cathode displays
eight LEDs (for binary number display)
Four 74HC595 shift registers
32 x 560 ohm 0.25 W resistors. For use as current limiters between the LED
display segments and ground
a breadboard and some connecting wire
10k linear potentiometer (variable resistor)
some water

For inspiration here is a photo of my layout:

and a video of the game in operation. Upon turning on the power, the game says hello.
You press the button to start the game. It will show a number in binary using the LEDs,
and you select the base-10 equivalent using the potentiometer as a dial. When you select
your answer, press the button - the quiz will tell you if you are correct and show your
score; or if you are incorrect, it will show you the right answer and then your score.
I have set it to only ask a few questions per game for the sake of the demonstration:
And yes here is the sketch for my answer to the exercise.
Now this chapter is over. Hope you had fun! Now move on to Chapter Six.

Getting Started with Arduino! Chapter Six


This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
microcontrollers. The first chapter is here, and the complete index is here.
Welcome back fellow arduidans!
Hello once again to our regular Arduino tutorial instalment. In this chapter we are up to
all sorts of things, including: distance sensing, using prototyping shields, even more
shiftiness with shift registers and 4-digit 7-segment displays, and some exercises to
refresh and expand your knowledge. Wow lets get cracking
Do you know how to keep your distance? Some people do, some do not. The same goes
for mechatronical things (i.e. robots, those little autonomous vacuum cleaners, etc). So to
solve that problem you can integrate a distance sensor into your design. Hopefully by
following this section you will gain an understanding of such sensors, and be able to
make use of them later on in your own projects. Anyhow, today we are looking at
the Sharp GP2Y0A21YK0F infra-red distance sensor. What a mouthful The funny
thing is that it looks like a robot head:

That white JST connector is for three leads, +5V, GND, and analogue out. When
purchasing it you should also get a matching lead to save time and mucking about.
How it works is quite simple (I must stop writing that, some things are not as simple as
they seem) the sensor contains an infra-red transmitter and a receiver. It returns a
voltage that is relative to the distance between itself and the object in front of it. This
output voltage is inversely proportional to the distance; which is explained better with
this graph from the data sheet:

However it is always fun to test these things out yourself. So I placed a sensor up over
my desk, measured out 80cm, and attached the multimeter to the analogue output of the
sensor.

A crude setup but effective. I held a white piece of cardboard in front of the sensor,
starting from more than one metre away, then moved closer to the minimum, then back
out again. As shown in this video clip:
Although watching that multimeter may not have been too interesting, hopefully the next
task will be!
Exercise 6.1
Using the values from the graph from the Sharp data sheet (above), make yourself a
distance-measuring device. Use an LCD module to display the measurements. Metric and
imperial! This shouldnt be too hard at all, youre just using one analogue input from the
sensor, some basic maths, and displaying some data on an LCD. Furthermore, to make it
truly portable, you could wire up a 9v PP3 battery to a DC plug and use it for power. A
hint before calculating distances, run a sketch to just return the analogRead() value

from the sensor. Then you can make your own judgement on voltage-distance
calculations. To save time I used the Electronic Bricks to rapidly construct this prototype.
You will need:
Your standard Arduino setup (computer, cable, Uno or compatible)
One parallel LCD display module
One Sharp infra-red distance sensor and sensor cable
a breadboard and some connecting wire
Anyhow, here is a photo of what I came up with:

and the ubiquitous video clip


Finally, my sketch for the solution. You may have to adjust the values in the decision tree
for more accuracy. After spending some time with this sensor, I wouldnt rely on it for
exact distance calculations, however it would be very useful for general item detection,
air switches and so on. In the next week or two we will examine another type of distance
sensor.
What else could this be used for? Robotics sensors, burglar alarms, switching things on
and off. Hopefully you have gained some knowledge about this sensor and have some
ideas for implementation.

Now that we have spent a few weeks constructing our prototypes on breadboards and
electronic bricks, it is now time to look at how we can do this in a more compact, and/or
permanent method. As you already know, the Arduino system allows for shields, PCBs
that plug on top of your Arduino board to add some sort of extra functionality. One of
these was the Electronic Brick chassis, another popular shield is the ethernet shield.

Well thats all very nice, but can we do this ourselves? Of course. You need a prototyping
shield. There are two main types of protoshield, one that contains a small solderless
breadboard that can be used on the shield:

or a shield that is plainly a PCB, ready to solder a circuit onto it. This one below is great,
it includes two extra LEDs and a button. Furthermore, the yellow PCB makes things
easier to see:

As you can imagine, one is more permanent than the other. In this chapter you can follow
me create my own circuit on the plain PCB protoshield.

Recently I purchased a couple of blank protoshields (the yellow one above) in order to
make a shield with two 7-segment LED displays and 74HC595 shift registers as it takes
a long time to wire these up on a breadboard. So after composing a diagram of which pins
are connected to which pins, it was time to place the components and start soldering.

The board basically a matrix of through-plated holes, so you can solder into them from
both sides. Which makes linking them together very simple:

However you really need to be careful planning your board, top and bottom, to avoid
things getting messy:

Another trap to look out for is trying to squeeze too much in at once. This can cause you
to do some very creative soldering:

The plan was to have two wires in the one hole, a lead and a resistor tail. Very difficult
for me to do neatly. However at the end it all came together somehow!

With this example, some wires have been soldered on the read. In fact, most of them were
on the rear. Anyhow, the last thing to do is solder in the header pins in order for our new
protoshield to stack on top of our Arduino. You can either solder on full header sockets,
just like the Arduino, or pins if you dont need to stack another shield on top of yours. In
this case you would not cover up the displays, so only pins will be used. The best way to
solder the pins is to place them into your Arduino, put your shield on top, then solder.
Example:

And once it came time to set my shield down on the pins, a very amusing (to me) thing
happened it would not sit straight! All those wires underneath the PCB interfered with
the microcontroller on the Arduino itself:

So there is a useful tip for you: always plan your protoshields in all three dimensions!
Otherwise things may not go as planned, and you dont want a leaning tower of shields.
But finally, it did work with some careful wire repositioning:

So there you have it, a quick demonstration of what to do and not do when using a blank
prototyping shield. In the near future we shall make more use of these.
Moving on
In previous instalments we have worked with 7-segment LED displays, using up to three
at once, being controlled by 74HC595 shift registers. As you may have realised by now
that involved a lot of wiring, resistors, time and effort. But what if you need four or more
digits? Use an LCD Maybe. Sometimes you need to use LED displays for aesthetic
reasons, price, clarity, or just because you love that LED look. Thankfully you can find
four digit displays, instead of having to use 2 x 2 or 4 x 1 digit displays. Lets have a look
at one now:

For the newcomer there would be a surprising lack of pins on this display module. That is
a good thing, and a slightly tricky thing but we can overcome the obstacles and use it
very easily. How? Again, with two 74HC595 shift registers and some brainpower. Firstly,
lets have a look at the pins from left to right they are: E, D, C, G, F, B, A, C1, C2, C3,
C4, decimal point, unused, unused. This display is common cathode, so to display (for
example) the number 1 on digit 3, you would apply ~+2 volts to pins 6 and 7, and attach
ground to pin 10. Very much the same as using a single-digit display, except you need to
choose the cathode that corresponds with the digit you wish to use. In this tutorial we are
using a Common Cathode unit. Out of curiositys sake, here is the data sheet for the
module used in this chapter: data sheet.pdf.
Secondly, how are we going to control the cathodes with out Arduino? Current comes out
of a cathode, so it would not accept a signal from our digital out pins. What we need to do
is have a simple switch on each cathode between the display pin and ground, so we can
control which digit we want to use. How can we do this with our Arduino? Easy we
can use a simple NPN transistor as a switch. Remember we did this with a relay in
chapter three!
But using 4 digital out pins for cathode control is a waste of pins, we can use our trusty
shift register again to control the cathodes. So that means we need two shift registers in
total, the first to control the digit (0~9), and the second to switch on the cathode of the
position we wish to display our digit in. Time to do it!
The first (left-hand) shift register from the Arduino controls the segments on the display,
via 560 ohm resistors. Just like last time. The second (right-hand) shift register controls
the cathodes. Pins Q0~Q3 connect to the base of a BC548 transistor via a 1k ohm resistor.
The collector of the transistor is connected to the cathode on the display, and the emitter
to ground. For example:

Note that the schematic above is a guide only. But here it is in real life, below:

After a few projects, wiring up displays and shift registers should be a lot quicker for you
now. Here is the matching sketch I came up with for the demonstration video below.
Youd have to admit, even in the year 2010, LED displays still look mesmerising. Or
maybe thats just me! Here is the data sheet display.pdf for the LED display I used. You
can use other ones,as long as they are common cathode; just match the LED element pins
with your first shift register, and the cathode pins with the second shift register.
But on to making something useful
Exercise 6.2
Using the hardware from example 6.1 above, create a device that displays the value of an
analogue sensor. For example, if we connect a 10k variable resistor to an analogue input,
the Arduino will return a reading of between 0 and 1023. From a hardware perspective,
all you need to do is add an analogue sensor (e.g. LDR, 10k variable resistor, the infra-

red sensor from earlier on, etc.). The software will be a little tricky, but if you completed
exercise 5.1, or 5.2 you shouldnt have a problem at all. As you will be displaying one
digit at a time, but very quickly, try to minimise the number of times you clear the display
in doing so you will keep the brightness at a maximum.
You will need:

Your standard Arduino setup (computer, cable, Uno or compatible)


One 4-digit, 7-segment LED display, common cathode
Two 74HC595 shift registers
Four BC548 or equivalent NPN transistors
8 x 560 ohm 0.25 W resistors. For use as current limiters between the LED
display segments and ground
One 10k variable resistor
a breadboard and some connecting wire

For motivation, here is a video clip of my result. There are two examples, one with
leading zeroes, and one without:
And the sketch as well.
That wasnt too hard was it? Now that you can use such a display, it will become easier to
display output from your various projects. Now on to Chapter 6A.

Getting Started with Arduino! Chapter Six addendum


Welcome back fellow arduidans!
After reviewing Chapter Six of our tutorials, I felt that there was some important
information missing about the section regarding driving 4-digit 7-segment LED display
modules. Although we have discussed displaying numbers using the module, and
hopefully you have done this yourself with exercise 6.2, those numbers were constantly
being written to the display as the sensor was being repeatedly read.
But how do we send a number to the display and hold it there? We need a function that
can accept the number to display and the length of time (in cycles) to hold it there. I
have rewritten the function displaynumber() from the solution to exercise 6.2 now it
accepts another value, cycles. This is the number of times the number will be shown on
the display.
void displaynumber(int rawnumber, int cycles)
// takes an integer and displays it on our 4-digit LED display module
and HOLDS it on the display for 'cycles' number of cycles
{
for (int q=1; q<=cycles; q++)
{
if (rawnumber>=0 && rawnumber<10)
{
onedigitnumber(rawnumber);
}
else if (rawnumber>=10 && rawnumber<100)
{
twodigitnumber(rawnumber);
}
else if (rawnumber>=100 && rawnumber<1000)
{
threedigitnumber(rawnumber);
}
else if (rawnumber>=1000)
{
fourdigitnumber(rawnumber);
}
}
}

Here is a sketch to demonstrate this function, the hardware is the same as exercise 6.2,
except there is no need for the variable resistor.
And my day wouldnt be complete without another video demonstration. This example
has cycles set to 500.
So there you have it! Now you have the knowledge to use these multi-digit displays
effectively. And now that we have mastered them, we can move onto more interesting
and useful display types. In the meanwhile, off to Chapter Seven.

Getting Started with Arduino! Chapter Seven


This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
microcontrollers. The first chapter is here, the complete index is here.
Welcome back fellow arduidans!
This week is going to focus around the concept of real time, and how we can work with
time to our advantage. (Perhaps working with time to our disadvantage is an
oxymoron) Once we have the ability to use time in our sketches, a whole new world of
ideas and projects become possible. From a simple alarm clock, to complex timing
automation systems, it can all be done with our Arduino and some brainpower. There is
no time to waste, so lets go!
First of all, there are a few mathematical and variable-type concepts to grasp in order to
be able to understand the sketch requirements. It is a bit dry, but I will try and minimise
it.
The first of these is binary-coded decimal.
Can you recall from chapter four how binary numbers worked? If not, have a look then
come back. Binary coded decimal (or BCD) numbers are similar, but different each
digit is stored in a nibble of data. Remember when working with the 74HC595 shift
registers, we sent bytes of data a nibble is half of a byte. For example:

Below is a short clip of BCD in action counting from 0 to 9 using LEDs:


However, remember each digit is one nibble, so to express larger numbers, you need
more bits. For example, 12 would be 0001 0010; 256 is 0010 0101 0110, etc. Note that
two BCD digits make up a byte. For example, the number 56 in BCD is 0101 0110,
which is 2 x 4 bits = 1 byte.
Next, we will need to work with variables that are bytes. Like any other variable, they can
be declared easily, for example:
byte seconds = B11111;
B11111 is 31 in base 10, (that is, 2^4+2^3+2^2+2^1+2^0

or

16+8+4+2+1)

However, you can equate an integer into a byte variable. Here is a small sketch
demonstrating this.

And the result:


If you printed off the results of the sketch in example 7.1, it would make a good cheat
sheet for the Binary Quiz program in Chapter Five.
Anyhow, moving forward we now take a look at hexadecimal numbers. Hex numbers
are base-16, in that 16 digits/characters are used to represent numbers. Can you detect a
pattern with the base-x numbers? Binary numbers are base-2, as they use 0 and 1;
decimal numbers are base-10, as they use 0 to 9 and hexadecimal numbers use 0 to 9
then A to F. Run the following sketch to see how they compare with binary and decimal.
Below is a screenshot of the result: the left column is binary, the centre decimal, and the
right hexadecimal.

Unfortunately the IC we use for timing uses BCD, so we need to be able to convert to and
from BCD to make sense of the timing data.
So now we have an understanding of BCD, binary, base-10 decimal, bytes, hexadecimal
and nibbles. What a mouthful that was!

Coffee break.
Before we head back to timing, lets look at a new function: switch case. Say you
needed to examine a variable, and make a decision based on the value of that variable,
but there were more than two possible options. You could always use multiple ifthen
else if functions, but that can be hard on the eyes. That is where switch case comes in.
It is quite self-explanatory, look at this example:
switch (zz) {
case 10:
//do something when variable zz equals 10
break;
case 20:
//do something when variable zz equals 20
break;
case 30:
// do something when variable equals 30
break;
default:
// if nothing else matches, do the default
// default is optional
}

OK, were back. It would seem that this chapter is all numbers and what not, but we are
scaffolding our learning to be able to work with an integrated circuit that deals with the
time for us. There is one last thing to look at then we can get on with timing things. And
that thing is
The I2C bus.
(There are two ways one could explain this, the simple way, and the detailed way. As this
is Getting Started with Arduino, I will use the simple method. If you would like more
detailed technical information, please read this document: NXP I2C Bus.pdf, or read the
detailed website by NXP here)
The I2C bus (also known as two wire interface) is the name of a type of interface
between devices (integrated circuits) that allows them to communicate, control and share
data with each other. (It was invented by Philips in the late 1970s. [Philips spun off their
semiconductor division into NXP]). This interchange of data occurs serially, using only
two wires (ergo two wire interface), one called SDA (serial data) and the other SCL
(serial clock).

I2C bus image from NXP documentation


A device can be a master, or a slave. In our situation, the Arduino is the master, and our
time chip is the slave. Each chip on the bus has their own unique address, just like your
home address, but in binary or in hexadecimal. You use the address in your sketch before
communicating with the desired device on the I2C bus. There are many different types of
devices that work with the I2C bus, from lighting controllers, analogue<> digital
converters, LED drivers, the list is quite large. But the chip of interest to us, is the:
Maxim DS1307 Serial I2C real-time clock. Lets have a look:

This amazing little chip, with only a few external components, can keep track of the time
in 12-and 24-hour formats, day of week, calendar day, month and year, leap years, and
the number of days in a month. Interestingly, it can also generate a square wave at 1Hz,
4kHz, 8kHz, or 32 kHz. For further technical information, here is the DS1307 data
sheet.pdf. Note the DS1307 does not work below 0 degrees Celsius/32 degrees
Fahrenheit, if you need to go below freezing, use a DS1307N.
Using the DS1307 with our Arduino board is quite simple, either you can purchase a
board with the chip and external circuitry ready to use, or make the circuit yourself. If
you are going to do it yourself, here is the circuit diagram for you to follow: (click on
image to enlarge)

The 3V battery is for backup purposes, a good example to use would be a CR2032 coin
cell however any 3V, long-life source should be fine. If you purchase a DS1307 board,
check the battery voltage before using it. my board kept forgetting the time, until I
realised it shipped with a flat battery. The backup battery will not allow the chip to
communicate when Vcc has dropped, it only allows the chip to keep time so it is accurate
when the supply voltage is restored. Fair enough. The crystal is 32.768 kHz, and easily
available. The capacitor is just a standard 0.1uF ceramic.
Now to the software, or working with the DS1307 in our sketches. To enable the I2C bus
on Arduino there is the wire library which contains the functions required to
communicate with devices connected to our I2C bus. The Arduino pins to use are
analogue 4 (data) and analogue 5 (clock). If you are using a Mega, they are 20 (data) and
21 (clock). There are only three things that we need to accomplish: initially setting the
time data to the chip; reading the time data back from the chip; and enabling that 1Hz
square-wave function (very useful if you were making an LED clock, you could have a
nice blinking LED).
First of all, we need to know the I2C address for our DS1307. It is 068 in hexadecimal.
Addresses are unique to the device type, not each individual device of the same type.
Next, the DS1307 accepts or returns the timing data in a specific order

seconds (always set seconds to zero, otherwise the oscillator in the DS1307 will
stay off)
minutes
hours
day of week (You can set this number to any value between 1 and 7, e.g. 1 is
Sunday, then 2 is Monday)
day of month
month
year
control register (optional used to control the square-wave function frequency
and logic level)

but it only accepts and returns this data in BCD. So were going to need some
functions to convert decimal numbers to BCD and vice-versa (unless you want to make a
BCD clock )
However, once again in the interests of trying to keep this simple, I will present you with
a boilerplate sketch, with which you can copy and paste the code into your own creations.
Please examine this file. Note that this sketch also activates the 1Hz square wave,
available on pin 7. Below is a quick video of this square wave on my little oscilloscope:
This week we will look at only using 24-hour time; in the near future we will examine
how to use 12-hour (AM/PM) time with the DS1307.
Here is a screen capture of the serial output box:

Now that you have the ability to send this time data to the serial output box, you can send
it to other devices. For example, lets make a simple LCD clock. It is very easy to modify
our example 7.3 sketch, the only thing to take into account is the available space on the
LCD module. To save time I am using the Electronic Brick kit to assemble this example.
Below is a short clip of our LCD clock operating:
and here is the sketch. After seeing that clock fire up and work correctly, I felt really
great I hope you did too.
Update for more information on the DS1307 real-time clock IC, visit this page.
Now lets head back in time, to when digital clocks were all the rage

Exercise 7.1
Using our Arduino, DS1307 clock chip, and the exact hardware from exercise 6.2 (except
for the variable resistor, no need for that) make a nice simple digital clock. It will only
need to show the hours and minutes, unless you wish to add more display hardware. Have
fun!
Here is my result, in video form:
and the sketch. Just an interesting note after you upload your sketch to set the time;
comment out the line to set the time, then upload the sketch a second time. Otherwise
every time your clock loses power and reboots, it will start from the time defined in the
sketch!
As mentioned earlier, the DS1307 has a square-wave output that we can use for various
applications. This can be used from pin 7. To control the SQW is very easy we just set
the pointer to the SQW register then a value for the frequency. This is explained in the
following sketch:
/*
DS1307 Square-wave machine
Used to demonstrate the four different
square-wave outputs from Maxim DS1307
See page nine of data sheet for more information
http://tronixstuff.wordpress.com
CC by-nc-sa v3.0
*/
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus
address, the DS1307 is 0x68
void setup()
{
Wire.begin();
}
void sqw1() // set to 1Hz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary)
Wire.endTransmission();
}
void sqw2() // set to 4.096 kHz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x11); // sends 0x11 (hex) 00010001 (binary)
Wire.endTransmission();
}
void sqw3() // set to 8.192 kHz
{

Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x12); // sends 0x12 (hex) 00010010 (binary)
Wire.endTransmission();
}
void sqw4() // set to 32.768 kHz (the crystal frequency)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary)
Wire.endTransmission();
}
void sqwOff()
// turns the SQW off
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x00); // turns the SQW pin off
Wire.endTransmission();
}
void loop()
{
sqw1();
delay(5000);
sqw2();
delay(5000);
sqw3();
delay(5000);
sqw4();
delay(5000);
sqwOff();
delay(5000);
}

And here it is in action we have connected a very old frequency counter to pin 7 of the
DS1307:
And there we have it another useful chapter. Now to move on to Chapter Eight.

Getting Started with Arduino! Chapter Eight


This is part of a series titled Getting Started with Arduino! by John Boxall A tutorial
on the Arduino microcontrollers. The first chapter is here, the complete index is here.
Welcome back fellow arduidans!
In this chapter we will continue to examine the features of the DS1307 real time clock,
receive user input in a new way, use that input to control some physical movement, then
build a strange analogue clock. So lets go!
Recall from chapter seven, that the DS1307 is also has an inbuilt square wave generator,
which can operate at a frequency of 1Hz. This is an ideal driver for a seconds indicator
LED. To activate this you only need to send the hexidecimal value 010 after setting the
date and time parameters when setting the time. Note this in line 70 of the solution for
exercise 7.1. This also means you can create 1Hz pulses for timing purposes, an overengineered blinking LED, or even an old-school countdown timer in conjunction with
some CMOS 4017 ICs.
For now, lets add a seconds LED to our clock from Exercise 7.1. The hardware is very
simple, just connect a 560 ohm resistor to pin 7 of our DS1307, thence to a normal LED
of your choice, thence to ground. Here is the result:
Not that exciting, but it is nice to have a bit more blinkiness.
Finally, there is also a need to work with 12-hour time. From the DS1307 data sheet we
can see that it can be programmed to operate in this way, however it is easier to just work
in 24-hour time, then use mathematics to convert the display to 12-hour time if necessary.
The only hardware modification required is the addition of an LED (for example) to
indicate whether it is AM or PM. In my example the LED indicates that it is AM.
Exercise 8.1
So now that is your task, convert the results of exercise 7.1 to display 12-hour time, using
an LED to indicate AM or PM (or two LEDs, etc)
Here is my result in video form:
and the sketch.
OK then, thats enough about time for a while. Lets learn about another way of accepting
user input
Your computer!

Previously we have used functions like Serial.print() to display data on the serial monitor
box in the Arduino IDE. However, we can also use the serial monitor box to give our
sketch data. At first this may seem rather pointless, as you would not use an Arduino just
to do some maths for you, etc. However if you are controlling some physical hardware,
you now have a very simple way to feed it values, control movements, and so on. So lets
see how this works.
The first thing to know is that the serial input has one of two sources, either the USB port
(so we can use the serial monitor in the Arduino IDE) or the serial in/out pins on our
Arduino board. These are digital pins 0 and 1. You cannot use these pins for non-serial
I/O functions in the same sketch. If you are using an Arduino Mega the pins are different,
please see here. For this chapter, we will use the USB port for our demonstrations.
Next, data is accepted in bytes (remember 8 bits make a byte!). This is good, as a
character (e.g. the letter A) is one byte. Our serial input has a receiving buffer of 128
bytes. This means a project can receive up to 128 bytes whilst executing a portion of a
sketch that does not wait for input. Then when the sketch is ready, it can allow the data to
serially flow in from the buffer. You can also flush out the buffer, ready for more input.
Just like a well lets keep it clean.
Ok, lets have a look. Here is a sketch that accepts user input from your computer
keyboard via the serial monitor box. So once you upload the sketch, open the serial
monitor box and type something, then press return or enter. Enter and upload this sketch:
// Example 8.1
int character = 0; // for incoming serial data
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
character = Serial.read();
{
Serial.write(character);
}
}
}

Here is a quick video clip of it in operation:


So now we can have something we already know displayed in front of us. Not so useful.
However, what would be useful is converting the keyboard input into values that our
Arduino can work with.

Consider this example. It accepts a single integer from the input of serial monitor box,
converts it to a number you can use mathematically, and performs an operation on that
number. Here is a shot of it in action:

If you are unsure about how it works, follow the sketch using a pen and paper, that is
write down a sample number for input, then run through the sketch manually, doing the
computations yourself. I often find doing so is a good way of deciphering a complex
sketch. Once you have completed that, it is time for
Exercise 8.2
Create a sketch that accept an angle between 0 and 180, and a time in seconds between 0
and (say) 60. Then it will rotate a servo to that angle and hold it there for the duration,
then return it to 0 degrees. For a refresher on servo operation, visit chapter three before
you start.
Here is a video clip of my interpretation at work:
So now you have the ability to generate user input with a normal keyboard and a PC. In
the future we will examine doing so without the need for a personal computer
Finally, lets have some fun by combining two projects from the past into one new
exercise.
Exercise 8.3
Create an analogue clock using two servos, in a similar method to our analogue
thermometer from chapter three. The user will set the time (hours and minutes) using the
serial monitor box.

Here is a photo of my example. I spared no expense on this one

Here is a video demonstration. First we see the clock being set to 12:59, then the hands
moving into position, finally the transition from 12:59 to 1:00.
If you had more servos and some earplugs, a giant day/date/clock display could be
made Nevertheless, we have had another hopefully interesting and educational lecture.
Or at least had a laugh. Now onto chapter nine.

Getting Started with Arduino Chapter Ten


This is part of a series titled Getting Started with Arduino! by John Boxall A tutorial
on the Arduino universe. The first chapter is here, the index is here.
Welcome back fellow arduidans!
This week we will minimise an Arduino Uno board, use time to control, and then find
some synergy between the two.
As time goes by, you will want to build projects to use away from the bench, or that are
permanent. Although doing so is infinitely fun, it can become expensive if you keep
buying Arduino boards for each project or proof-of-concept prototype, or even finished
products. However, as always, the Arduino team have solved this problem for us as well.
The actual microcontroller integrated circuit (e.g. ATmega328P-PU) can operate with a
lot less circuitry than that is contained on your Duemilanove or compatible board. In fact,
you can have a functioning Arduino system with three components and a 5V power
supply.
How?
To start, please download the Uno schematic from here. Upon glancing at it for the first
time, there seems to be a lot of things required. However if you just want to use the
digital and analogue pins, you can cut that schematic down to a lot less, however you
need to make a couple of changes to how you upload the sketch. Here is what you can get
away with:

X1 is the 16 MHz resonator. Using only the main circuit on the left, to upload your sketch
you need to place the ATmega chip in your Arduino board, upload the sketch, then very
carefully remove the chip and place it into your circuit, breadboard, etc. Please make sure
to observe anti-static precautions, and always use a chip puller (below).

Furthermore, if you only have one chip, it would be very wise to have a second or third as
a backup. A programmed ATmega with the Arduino bootloader can be had for less than
US$6. Below is a shot of my barebones Arduino system at work. It is setup to run this
basic example.

The blue and yellow wires run off to a 5 volt power supply. And here is it working:
To recreate this at home, you will need:

One ATmega328P-PU microcontroller with Arduino bootrom


solderless breadboard
10k ohm resistor
16 MHz resonator
(optional for USB cable) 6-pin header pin
(optional for USB cable) 0.1 uF ceramic capacitor
(optional for USB cable) FTDI cable (the 5 volt version!)

A note about the resonator. Your Arduino board will most likely have a metal crystal,
however a resonator is a little cheaper and easier to use, as it has the capacitors in built. If
you look at the Arduino schematic, they use a crystal and two 22 picofarad capacitors. So

if you use the resonator, pins 1 and 3 go to chip pins 9 and 10, and resonator pin 2 goes to
GND. Here is the data sheet for the resonator. They should be easily available, for
example from here or here. The USB cable option will make life a lot easier. The cable is
called an FTDI cable, and contains the electronics within to interface between the USB
port on your computer and the TX/RX pins on the microcontroller. The wiring details are
in the schematic above.
The cable also supplies power whilst programming, or leaving the cable plugged in. Here
is my board with the extra wiring connected:

So if you have this kind of setup, you can just plug the cable into the computer USB port
and upload sketches as normal. However there are some modifications that may need to
be done with your computers operating system to make it work. If you are running Linux
or MacOS, please visit here; if you are running windows of some sort, go to device
manager, right click the USB serial port you are using, select properties, port-settings tab,
advanced, and turn on set RTS on Close.
When purchasing an FTDI cable make sure you get the 5 volt version!
So now you can integrate the Arduino chip into your prototypes much easier and cheaper.
However, if you are going to use SPI or I2C devices, more circuitry will be required. We
will examine creating these interfaces in more detail later. A good compromise in this
situation is a miniature Arduino-compatible board such as the Freetronics LeoStick.
If you are interested in a project using such a barebones setup, please have a look at
blinky the clock.

Next on the agenda is a small project to consolidate some previous learning. At the end of
chapter nine, we made a (relatively) user friendly clock with an alarm. And in chapter

three, we controlled a relay with our arduino. So now we have the ability to create our
own on/off timer of which possible uses could be limitless.
In doing so, we can start by modifying the sketch from exercise 9.3. It has the ability to
set an alarm time (lets call it a start time from now on), so we can add the ability to set
an end time it just requires some more variable to store the end time data, and another
menu function to set these. Finally, another function is required to check if it is time to
turn off (basically identical to the checkalarm() function.
The hardware side of things for the example will be quite simple as well, below is my
schematic, and the basic board:

I am using 12v relays as currently that is all I have in stock. The 12V power supply is just
an LM7812 regulator from a 20V DC plugpack. For demonstration purposes any lowvoltage relay would be fine. A 5V relay such as this would be perfect as you could run it
from the Arduinos 5V rail.
Note: From here on you understand that one can use an Arduino to switch a very high
current and/or voltage with some relays. Please exercise care and consult a qualified,
licensed person if you are working with mains voltage (100~250V AC the stuff that
comes out of power points/outlets). They can KILL you!

So for this example, I have modified the sketch as described earlier to accept a start time,
end time, and display relevant data on the screen. It will switch on and off the relay,
which controls a light globe drawing 100mA 5 times the current an Arduino digital out
pin can deliver. It only operates using 24-hour time, to save user confusion. You could
control anything as long as you do not exceed the current and voltage maximums for your
particular relay.
So here it is in action. The time has already been set previously, so you can watch the
setting of the on/off time, and watch it in action. You can skip ahead from 01:03s to
01:48s to save time.
and here is the sketch for your perusal.
As as example the user interface wasnt that flash, but naturally it can be worked on to be
more intuitive. So now it is your chance to do so, with
Exercise 10.1
Create a timing system for a hypothetical lighting system that controls two independent
circuits. Each timer can turn on or off at a specified time, either daily, only on weekdays,
only on a certain day of the week (e.g. only Fridays) or only on weekends. The menu
system should be easy and quick to use.
For the purpose of the exercise, you can switch on or off an LED to represent each
lighting circuit you already know how to use the relays.
You will need:

Your standard Arduino setup (computer, cable, Uno or compatible)


Two usual LEDs of your choice
2 x 560 ohm 0.25 W resistors. For use as current limiters between the LEDs and
ground
1 x 10k resistor
one push button
a breadboard and some connecting wire
some water
DS1307 timer IC circuit components (see this schematic from chapter seven) or a
pre-built module
one 10k linear potentiometer
LCD module as per chapter two

Here are some videos of my interpretation. To save time I have not connected the LEDs,
however timer running status is indicated on the second line of the display an ! is
shown when a circuit has been activated. The first video shows setting the real time, timer
data and displaying the results and the sketch.

How did you go? With a little more hardware this exercise could become a real product
you could control sprinkler systems instead of lights, thermostats, anything is really
possible. Having a larger LCD screen would help with the user interface, perhaps a 20
character by 4 line unit. As long as such a screen has the standard HD44780 interface,
you would be fine.
Now on to Chapter Eleven

Getting Started with Arduino Chapter Eleven


This is part of a series titled Getting Started with Arduino! A tutorial on the Arduino
universe. The first chapter is here, the index is here.
Welcome back
In this instalment we will start to investigate radio data transmission; then introduce
rotary encoders.
As technology has marched along and generally improved on the past, things have been
getting small and relatively cheaper. What was once jaw-droppingly amazing is now just
meh. But as you are reading this, you know differently. We can now take control of this
technology for our own devices. What has been in the past quite unapproachable is now
relatively the concept of wireless data transmission. But no just sending a signal, like a
remote-control garage door opener but sending actual, useful data numbers and
characters and so on.
How is it so? With this pair of tiny devices:

Quite small indeed the pins are spaced 2.54mm apart, and the graph paper is 5mm
square. The transmitter is on the right. This pair operates at 315 kHz, over up to a
theoretical 150 metres. The data transmission speed is 2400 bps (bits per second). These
units are serial passthrough, that is they can replace a link of wire between the serial TX
(pin 1) from one Arduino, and the RX of another Arduino (pin 0). They dont need aerials
for very short distances, but the use of one will extend the range towards the maximum.
And finally, the transmitter needs between 2 and 10 volts; the receiver 5. Here is the data
sheet for these modules: 315MHz.pdf. Normally they are sold individually, for example
the transmitter and receiver. You can also find faster (data speed) modules, however we
will use these ones today.
In preparation to use these modules, another library needs to be installed the
VirtualWire library. Download the latest revision from the following
location: http://www.open.com.au/mikem/arduino/.
There is also a guide to using the library in .pdf format as well. Please note the library
authors instructions with regards to licensing on the last page of the guide. For a

refresher on how to install a library, please head back to chapter two. This library will
save us a lot of time, it takes care of checking for errors, and only allows complete,
correct data (i.e. what is received matches what is sent) to be used in the receivers
sketch.
However, as wireless is not 100% reliable, you need to take into account that
transmissions may not be received, or erroneous ones will be ignored by the receivers
sketch. You can reduce the data speed to improve reliability and range. Furthermore, you
cannot use PWM on D9 and D10 if you are using VirtualWire.
Therefore if you are using this for some important communications, have the transmitter
repeatedly sent the message. Later on in this series we will investigate more powerful
solutions. Anyhow, moving along
Example 11.1
First of all, we will demonstrate the use of these modules with a basic sketch. It sends
some text from one Arduino to another. The receiving Arduino sends the data to the serial
monitor box. Of course you could always use an LCD module instead. In my own
inimitable style the sketches are very simple, yet allow you to use their contents in your
own work. Here is the sketch for the transmitter tx.pdf and the receiver rx.pdf.
When working with two sketches at the same time, you can have two Arduinos connected
to your PC simultaneously, just remember to select the correct USB port for the correct
Arduino. Do this with the tools > serial port menu option in the IDE. Otherwise you will
become very frustrated if you upload the rx sketch to the tx Arduino.
Furthermore, you will need to remove the wire from digital 0 to the data pin on the
receiving units before uploading the sketch. And finally, remember to set the serial
monitor window at 9600 baud.
Here are my two boards in action:

Although having both boards connected to the one computer is only useful for
demonstration purposes, in real life this is obviously useless. Remember that once you
upload your sketch the Arduino doesnt need a computer, only a power supply. You can
feed yours between 7 and 12 volts DC through the socket. A nice switchmode power pack
will do nicely, or if you are a cheapskate like me, a PP3 battery and clip soldered to a DC
plug:

You may find that when you use a battery powered Arduino that it basically does not
work. Arduino genius Jon Oxer (co-author of Practical Arduino) has found a solution for
this issue place a 10k resistor between GND and digital 0 (RX), or between digital pins
0 and 1. The next thing to consider it improving the reception range. This can be done
using two methods the first by connecting an external antenna, either a length of wire,
or perhaps a purpose-built aerial. The second method is to increase the supply voltage of
the transmitter up to 12 volts.
Now it is your time to do some work:
Exercise 11.1
You now are able to send characters using the radio link from one Arduino to another.
Now it is time to control things remotely. For the purpose of the exercise, we will just
control three LEDs, turning them on and off. You already know how to control other
things with digital output pins, so we just need to focus on getting the switching on and
off. Hint you can send characters via the wireless link, so create your own codes.
You will need:

Two standard Arduino setups (computer, cable, Uno or compatible)


two breadboards and some connecting wire
One transmitter and one receiver unit
three LEDs
3 x 560 ohm 0.25 W resistors. They are to reduce the current to protect the LEDs

Here is the schematic of my interpretation:

the transmitter:

the receiver:

and the video:


So how did you go? Hopefully this exercise was easier than you had first expected. If
not, here are the example sketches: exercise 11.1 tx and exercise 11.1 rx. A basic

transmit/receive system like this would also be handy for testing the range that wireless
modules can operate over, or testing a particular site to see if you could implement such
wireless modules. Its always better to test before agreeing to make something for
someone.
That concludes our work with radio wireless links for now.
Next on the agenda is the rotary encoder. Recall how we used a potentiometer in the
previous chapters as a dial, to select menu options using the readdial() function. It was
simple, cheap and it worked, but some may say it was a kludge. There must be a better
way! And there is, with the rotary encoder. A rotary encoder looks like a potentiometer,
but it is a knob that can be rotated in either direction infinitely. Furthermore, the knob is
also a normally-open button. The encoder we will be using in this chapter is a 12-step
encoder, in that you can feel it physically resist rotation slightly twelve times over the
360 degrees of rotation.
Here is our example:

On one side there are three pins, and two on the opposing side. On the perpendicular
sides are legs for strength, that is they are meant to be soldered into a PCB to lock it in
nicely. The problem for us is that those legs interfere when trying to use the encoder in a
breadboard, so I have bent them up and cut them off:

The pins are easy to understand. The two pins on one side are the button contacts, just
like any simple button. The other side with the three pins the centre goes to ground, and
the outside pins are the forwards and backwards output pins. The data sheet for our
encoder is here. After fooling about with this all afternoon, the quickest way to get a feel
for how it works is with a simple demonstration. So first we will test it out, then see how
we can use it in our user-interfaces.
Example 11.2
This example is very easy to assemble. You only need an encoder, and the usual Arduino
setup. Here is the sketch, and the schematic:

and in real life:

and finally a snapshot of the output. Dont forget to set the speed in your serial monitor
box to 115200 baud:

So as you can see, this is a much better solution that then potentiometer that we used in
the past. Plus having the button integrated in the encoder is very convenient, you can
really create a user interface with only one control. In the next instalment of this series
we will implement the encoder in an existing design. So on to Chapter Twelve.

Getting Started with Arduino Chapter Twelve


This is part of a series titled Getting Started with Arduino! by John Boxall A tutorial
on the Arduino universe. The first chapter is here, the complete series is detailed here.
Welcome back
This chapter we will spend some more time with the rotary encoder by using it to control
a clock, look at ways of driving a common-anode LED display with Arduino, and make a
usable alarm clock with which we can start to move from the prototype stage to an actual
finished product something you would be proud to give to someone.
So off we go
In chapter eleven, we looked at getting some values from the rotary encoder. Not the
easiest way of receiving user input, but certainly interesting. This week I have an
example for you where the encoder is used for setting the time of a digital clock.
Example 12.1
This example is basically two previous projects mashed together. It consists of the LED
digital clock from exercise 7.1, and the rotary encoder sketch from example 11.2. The
sketch was quite simple in theory, but somewhat complex in execution. The idea was to
read the decoder, and after every read, display the time. However, if the encoders button
was pressed, the time set function would be activated. At this point, you turn the encoder
in one direction to set the hours, and the other direction to set the minutes. Then press the
button again to set that time and return to normal operations.
To recreate it you will need:

Your standard Arduino setup (computer, cable, Uno or 100% compatible)


Seven 560 ohm 1/4 watt resistors
Four 1 kilo ohm 1/4 resistors
Four BC548 NPN transistors (if you cannot find these, you can use 2N3904)
Two 74HC595 shift registers
DS1307 timer IC circuit components (see this schematic from chapter seven) or a
pre-built module
Solderless breadboard and connecting wires

Here is the sketch for your perusal, and the matching schematic (sorry, I forgot to add the
DS1307 module see example 12.2 schematic below for how to do this):

in real life:

and a video clip:


After watching that clip you can soon see that there is an issue with the encoder. As a
normal switch can bounce (turn on and off very very quickly in the latter part of
operation), so can a rotary encoder. That is why it would sometimes return a result of
clockwise, instead of anti-clockwise. Furthermore, they are right little pains when trying
to use in a breadboard, so if you were going to use one in greater lengths, it would pay to
make up your own little breakout board for it. Therefore at this stage we will leave the
encoder for a while.

You may also have noticed the extra shield between the real time clock shield (yellow)
and the arduino board. It is the Screwshield for Arduino reviewed here. It is very useful
to making a stronger connection to the I/O pins, or using normal multi-core wires.

Next on the agenda is the common-anode LED display. Normally the LED display we
have demonstrated in the past has been common-cathode, and very easy to use. Current
would flow from the power supply, through the shift registers outputs (for example the
74HC595), through current-limiting resistors, into the LED segment, then off to earth via
the cathode. Current flows through a diode from the anode to the cathode, and finally
back to earth/ground. For a refresher on diodes, please read this article.
The other month I found this style of useful LED display:

Absolutely perfect for our clock experimentations. A nice colon in the middle, and
another LED between the third and fourth digit which could make a good indicator of
some sort. However the one catch (always a catch) is that is was common-anode. This
means that current starts from the power supply, through the common anode pin for the
particular digit, then the LED segment, the LEDs individual cathode pin, through the
current-limiting resistor and then to ground. With the current flowing in the opposite
direction via a common anode, we cant just hook the display up to our 74HC595 shift
register.
Therefore, we will need the shift register to control switches to allow the current to flow
through each segment, just like we have done previously controlling the cathodes of a
common cathode display (see example 12.1). So to control the digits of this new display,
we will need twelve switches (eight for the segments of the digit, and four to control the
anodes). That would mean twelve BC548 transistors and 10k ohm resistors, and a lot of
mess.
Example 12.2
Instead we will now use the 74HC4066 quad bilateral switch IC. I have reviewed this
chip being used with Arduinos in a separate article here. The 74HC4066 is quite a
common chip, available from many suppliers including: element14/Newark (part number
380957), Digikey (part number 568-1463-5-ND) or Mouser (771-74HC4066N). If you

cannot find them, email me and I can sell you some at cost plus postage. Once you have a
understanding of this IC, please consider the following circuit:

Most of this should be easily understood. One shift register is controlling the anodes,
turning them on and off via a 74HC4066. In past examples this shift register would have
turned off common cathodes via a 10k resistor and an NPN transistor. The other shift
register is controlling the individual LEDs for each digit via a pair of 74HC4066s (as they
only have four switches per IC).
Here is the sketch, it should be quite a familiar piece of code for you by now.
To recreate it you will need:

Your standard Arduino setup (computer, cable, Uno or 100% compatible)


Seven 560 ohm 1/4 watt resistors
DS1307 timer IC circuit components (see this schematic from chapter seven) or a
pre-built module
Two 74HC595 shift registers
Three 74HC4066 quad bilateral switch ICs
Solderless breadboard and connecting wires
LED clock display module

And here is the result, with red and a blue display.

And the usual board layout:

The blue looks really good in a dark background. You can also get them in yellow and
green.

Moving along. Now and again, you often want to have a few buttons in use for user input,
however the cheap ones dont really like to sit in a breadboard. Naturally, you could make
your own button shield, which would be very admirable, but then it would be preset to
certain pins, which could interfere with your project. I had the same problem in writing
this chapter, so came up with this example of an external button panel to make life
easier.
Example 12.3
Here is the schematic, nothing complex at all just four buttons and the required 10k
ohm pull-down resistors:

and the finished product:

This was a quick job, as I will need to use a few buttons in the near future. Have also put
some rubber feet on the bottom to stop the solder joints scratching the surface of the
bench. Originally I was going to chop off the excess board at the top, but instead will add
some LEDs to it after finishing this article. However using this button board will save a
lot of frustration by not trying to jam the buttons into a breadboard.

Exercise 12.1
Now it is time for you to do some work. From this chapter onwards, we will be working
on making a small alarm clock something you could use. Just like the six million dollar
man, we have the capability, the technology, and so on except for Steve Austin. So this
chapter, your task is to create and breadboard the circuit and the underlying sketch.
Using the LED display from example 12.1, your clock will have a menu option to set the

time, alarm time, turn on and off the alarm, a snooze button and also switch the display
on and off (so you dont stare at it when you should be trying to sleep).
You could either use a DS1307 module, or the raw parts. For an explanation of the
circuitry, please see this post about making a RTC shield. You can always change it when
we get to making a real prototype. The same with the Arduino but for this exercise just
stick with the normal board. Later on we will use a bare circuit the same as in chapter ten.
With regards to user input, its up to you. A rotary encoder could be a real PITA, my
example below just uses buttons. Anyhow, off you go!
Parts you will need:

Your standard Arduino setup (computer, cable, Uno or 100% compatible)


Seven 560 ohm 1/4 watt resistors
DS1307 timer IC circuit components (see this schematic from chapter seven) or a
pre-built module
Two 74HC595 shift registers
Three 74HC4066 quad bilateral switch ICs
Four normally open buttons or a board as described in example 12.3
Solderless breadboard and connecting wires
LED clock display module

Here is my interpretation of the answer to the exercise. Although this is a particularly


long sketch for our examples, it is broken up into many functions which are quite
modular, so you can easily follow the flow of the sketch if you start at void loop(). All of
the types of functions used have been covered in the past tutorials. In then next chapters
we will add more functions, such an an adjustable snooze, selectable blinking colon, and
so on. If you have any questions, please ask.
The buttons have several functions. In normal clock display mode, button one is for
menu, two turns the alarm on, three turns it off, and four turns the display on and off. If
you press menu, button two is to select time set, three for alarm set, and four is like an
enter button. When in the time/alarm set modes, button one increases the hour, button
two increases minutes in units of ten, and button three increases minutes in ones, and four
is enter. When the alarm activates, button four turns it off.
The schematic is just example 12.2 and example 12.3 connected together, however the
first button on the external board is connected to digital pin 8 instead of 1.
So here is a photo of our work in progress:

And a video clip showing the various functions of the clock in operation:
I hope you found success and inspiration in this chapter. Now to Chapter Thirteen.

Getting Started with Arduino Chapter Thirteen


Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is part of a series titled Getting Started with Arduino! by John Boxall A tutorial
on the Arduino universe. The first chapter is here, the complete series is detailed here.
Welcome back fellow arduidans!
This chapter we will examine piezo buzzers, continue with our alarm clock, and then
spend more time with the wireless radio modules by creating some remote control
systems and sending various data over the airwaves. So lets go!
Sometimes you would like to make some noise. For warnings, fun, or to annoy people. A
very simple and inexpensive way to do this is with a piezoelectric buzzer. In simple
terms, it contains a disc of metal that can deform when a current is applied to it. If you
apply an alternating current at a high enough frequency, the disc will move fast enough to
create a sound wave, something we can hear.
This is an example of a small piezo buzzer:

bzzzzz
This example was very cheap, less than $2. Here is the data sheet: PS1240.pdf. It can run
from between 3 and 30 volts AC which thankfully the output from our Arduino falls
between. But how do you output AC from an Arduino? There are several ways, however
the easiest is using pulse-width modulation (PWM). If you look at your Arduinos digital
output sockets, some are labelled PWM. Using the function analogWrite(); you can send
a PWM signal to the buzzer. For example:

/*
Example 13.0
Drive a piezoelectric buzzer with Arduino
http://tronixstuff.wordpress.com/tutorials > Chapter 13
*/
void setup()
{
pinMode(11, OUTPUT);
// sets the pin as output
}
void loop()
{
analogWrite(11,128);
delay(500);
digitalWrite(11, LOW);
delay(500);
}

The sketch above will beep the piezo on and off, and be somewhat annoying. Perfect.
However with the analogWrite(); function it is impossible to use the full frequency range
of the piezo buzzer. With a value of 254 for the duty cycle, the frequency generated is
around 1500 Hz:

Later on we will explore ways to create a better range of sounds. But now to use that
buzzer in our alarm clock to help wake people up.

Continuing on from exercise 12.1, this chapter we will add some more features to the
clock. First of all is the piezo buzzer. As we just discussed above, using it is quite simple.
On the hardware side of things, we can replace the resistor and LED connected between
digital pin 6 and ground with our piezo buzzer. On the software side of things, instead of
digitalWrite(6, HIGH); we use analogWrite(6,128);. Very easy. And here is a short video
with sound!
Moving on, its time to clean up the alarm function in general. Most alarm clocks have a
snooze function, so lets add one as well. When the alarm sounds, the user presses button

four to turn off the buzzer, and is then asked if they want to snooze. Button one is yes and
four is no. If yes, add ten minutes to the alarm time and carry on as normal. When adding
the ten minutes be sure to check for increasing the hour as well, and also take into
account the jump from 2359h to 0000h (or 2400h). If the user presses no, the alarm is
switched off and the user warned with the flashing OFF.
Example 13.1 Here is a demonstration of what I came up with:
The hardware is the same as exercise 12.1, except the LED and resistor from digital pin 6
to GND has been replaced by the piezo buzzer as described earlier. You will find the
snooze function is controlled in the checkalarm(); function in the sketch.

In chapter eleven we started to examine the inexpensive serial data transmitter/receiver


pairs. In this chapter we will continue working with them, to create the backbone of
various remote control and data transmission ideas for you to use.
Example 13.2
First of all, a simple remote control with four channels. That is, it has four buttons, and
the transmitter will send out the state of the four buttons, high or low. This would be
useful for a remote control toy or a perhaps robot. The sketches are quite simple. The
transmitter reads the buttons with digitalRead(); then transmits a single letter a~h
which is code for a button and its state. For example, a means button 1 is low, h means
button 4 is high. The receiver just decodes that a~h code and sends the result to the serial
monitor window. Here is the sketch for the transmitter and receiver.
To save time I will use the button board created in example 12.3. Here are the schematics
for the transmitter and receiver sections:

And set up:

And finally a video of the serial monitor showing the button states:
Now that we have the data being sent across, lets get some switching happening.
Example 13.3
Using the same transmitter system as example 13.2, we will turn on or off four LEDs at
the receiving end. Of course you could use relays, transistors, 74HC4066s, etc instead.
Our sketch decodes the transmitted data once more, but sets the digital pins high or low
depending on the received code. Here is the schematic for the new receiver:

and the board laid out:

And again a quick demonstration video:


Now that you can turn the LEDs on or off with a push of a button, there are a few other
ways of controlling those digital outputs with the remote control rig without altering the
hardware.
Example 13.4
This time, we will control two digital outputs with the four buttons, as each output will
have an on and off button. Consider this sketch; and the following demonstration video:
So there you have various ways to control digital outputs and send basic data across a
wireless radio serial data link.

Moving Forward with Arduino Chapter 14


XBee introduction
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is part of a series originally titled Getting Started with Arduino! by John Boxall
A tutorial on the Arduino universe. The first chapter is here, the complete series is
detailed here.
Welcome back fellow arduidans!
From this chapter on, the title of this series will now be Moving Forward with Arduino, as
we are well past the Getting Started stage There is also a new Arduino-based project in
another article blinky the clock.
This instalment is by user request we will examine the XBee wireless data transceivers
from Digi in the USA. Although in the past we have experimented with the inexpensive
315MHz transmit/receive pair modules (chapter 11), they have been somewhat low in
range and slow with data transmission. The XBee system changes this for the better.
First of all, what is an Xbee module? It is a very small piece of hardware that can connect
wirelessly with another using the Zigbee communication protocols. There are many
different models, including aerial types and power outputs. At this stage I will
demonstrate with the 1mW output chip-aerial model.
From Wikipedia, Zigbee is:
ZigBee is a specification for a suite of high level communication protocols using small,
low-power digital radios based on the IEEE 802.15.4-2003 standard for wireless home
area networks (WHANs), such as wireless light switches with lamps, electrical meters
with in-home-displays, consumer electronics equipment via short-range radio. The
technology defined by the ZigBee specification is intended to be simpler and less
expensive than other WPANs, such as Bluetooth. ZigBee is targeted at radio-frequency
(RF) applications that require a low data rate, long battery life, and secure networking.
Phew. For this chapter I will try and keep things as simple as possible to start off with.
Here is an image of a typical Xbee unit:

Note that the pin spacing is small than 2.54mm, so you cannot just drop these into a
breadboard. However for the purposes of our experimenting more equipment is needed.
Therefore I am making use of this retail package from Sparkfun retailers:

A great starting point


This bundle includes two Xbee modules, an Xbee shield to connect one of the modules to
an Arduino Duemilanove/Uno-style board. When it comes time to solder the sockets into
your shield, the best way is to insert them into another shield that is upside down, then
drop the new shield on top and solder. For example:

Finally, the bundle also includes a USB Explorer board, which allows us to connect one
Xbee to a personal computer. This allows us to display serial data received by the Xbee
using terminal software on the PC. One can also adjust certain Xbee hardware parameters
by using the explorer board such software.
Lets do that now. You will need some terminal software loaded on your computer. For
example, Hyperterminal or Realterm. Plug an Xbee into the explorer board, and that into
your PC via a USB cable. Determine which port (for example COM2:) it is using with
your operating system, then create a new terminal connection. Set he connection to 9600
speed, 8 bits, no parity, 1 stop bit and hardware flow control. For example, in
Hyperterminal this would look like:

Once you have established the connection, press +++ (that is, plus three times, dont
press enter) and wait. The terminal screen should display OK. This means you are in
the XBee configuration mode, where we can check the settings and change some
parameters of the module. Enter ATID and press enter. The terminal window should
display a four-digit number, which is the network ID of the module. It should be set by
default to 3332. Unless you plan on creating a huge mesh network anytime soon, leave it
be. To be sure your modules will talk to each other, repeat this process with your other
XBee and make sure it also returns 3332. However as this is the default value, they
should be fine.
Now for our first example of data transmission, insert one Xbee into the explorer module,
and the other into the Xbee shield. With regards to the Xbee shield whenever it is
connected to an Arduino board and you about to upload a sketch, look for a tiny switch

and change it to DLINE from UART. Dont forget to change it back after uploading the
sketch. See:

We are going to use the two Xbee modules as a straight, one-way serial line. That is, send
some data out of the TX pin on the transmit board, and receive it into the terminal on the
PC. Now upload this sketch into your Arduino board. This is a simple sketch, it just sends
numbers out via the serial output. Then set the switch on the shield back to UART, and
reset the board. If you can, run this board on external power and put it away from the
desk, to give you the feeling that this is working
Note: More often that not one can purchase AC plug packs that have USB sockets in
them, for charging fruity music players, and so on.

Or you might have received one as a mobile phone charger. These are great for powering
Arduino boards without using a PC.

Now ensure your explorer module is plugged in, and use the terminal software to connect
to the port the explorer is plugged into. After connecting, you should be presented with a
scrolling list of numbers from 0 to 99, as per example 14.1 sketch:

How did you go? Sometimes I used to get the COM: ports mixed up on the PC, so that is
something to keep track of. If you are powering both Xbees from your PC using USB
cables, double-check the terminal software is looking at the explorer board, as an Arduino
transmitting serial data through an Xbee shield will still send the same data back to the
PC via USB.
Now that we have sent data in one direction, we can start to harness the true power of
Xbees they are transceivers, i.e. send and receive data.
Example 14.2
We will create an on-demand temperature and light-level sensor. Our arduino board will
have a temperature sensor and a light-dependent resistor, and using the terminal on the
computer, we can request a temperature or light-level reading from the remote board.
More about temperature sensors in chapter two. First of all, the remote board hardware
setup:

and the schematic:

And as I live in a block of solid concrete/brick flats, it never hurts to elevate your other
Xbee:

For the PC side of things, use the explorer board and USB cable. Here is the sketch. It is
quite simple. The remote board listens to its serial in line. If it receives a 1, it reads
the temperature, converts it to Celsius and Fahrenheit, and writes the result to its serial
out line, which is sent over our Xbee data bridge and received by the host computer. A
2 will result in the analogue value of the photocell to be sent back as a light level.
Once again we use the terminal software to control the system. Here is a quick video of
the terminal in action:
The speed is quite good, almost instantaneous. By now hopefully you can see how easy it
is to end some data backwards and forwards over the ether. The range is only limited by
the obstacles between the Xbee transceivers and the particular power output of each
model. With example 14.2, there were two double-brick walls between them.
Furthermore, we can build fully computer-independent systems that can talk to each
other, such as more portable remote controls, or other data-gathering systems. In the next
few chapters, sooner rather than later.

Moving Forward with Arduino Chapter 15


RFID Introduction
Please note that the tutorials may not be compatible with Arduino IDE v1.0. Please
continue to use v22 or v23 until further notice.
This is part of a series originally titled Getting Started with Arduino! by John Boxall
A tutorial on the Arduino universe. The first chapter is here, the complete series is
detailed here.
Welcome back fellow arduidans!
In this instalment we will start to examine RFID systems
Please note that we will not be discussing the use of 13.56 MHz RFID systems such as
NXP Mifare Classic. Im not going to teach you how to clone stored-value public
transport fare cards.
First of all, RFID radio frequency identification. Some of us have already used these
things, and they have become part of everyday life. For example, with electronic vehicle
tolling, door access control, public transport fare systems and so on. Personally I thought
the electronics behind RFID systems was quite complex, and had even procrastinated
with examining them myself however finally I ordered some parts in and had them
working almost no time. (Theres a good lesson in that for all of us).
To explain RFID for the layperson, we can use a key and lock analogy. Instead of the key
having a unique pattern, RFID keys hold a series of unique numbers which are read by
the lock. It is up to our software (sketch) to determine what happens when the number is
read by the lock. The key is the tag, card or other small device we carry around or have
in our vehicles. We will be using a passive key, which is an integrated circuit and a small
aerial. This uses power from a magnetic field associated with the lock. Here are some key
or tag examples:

Our lock is a small circuit board and a loop aerial. This has the capability to read the data
on the IC of our key, and some locks can even write data to keys. Here is our reader
(lock) example:

As you can see from the 5mm graph paper, the circuitry is quite small, and the loop is
somewhat fragile. For installation and use, it would be wise to mount the loop aerial
inside something strong and protective. But more about that later. The RFID system we
will examine works on the 125 kHz frequency, but that is not so relevant at this stage.
Our use for the RFID equipment is to have our sketch make a decision based on the
unique tag number. For example, it could be used as a switch to turn on and off
something, perhaps an alarm system or a computer. It could control an electric door strike
(lock), or activate a series of lights to ones personal preference. The possibilities are only
limited by your imagination. I hope that with your existing knowledge you can
implement this RFID equipment into your next prototype or product.
Example 15.1

First of all, lets do a basic test what happens when we read a tag? To do this we need
to connect our reader to the Arduino or compatible board, and see what comes out when
we read a card. The connections are quite simple:

You may need to remove the wire from the RFID reader to Arduino D0 before uploading
the sketch, then replacing it after the upload. From the reader data sheet.pdf (our version
is the TTL model), the reader sends out serial data from the TX pin at 9600 bps. We will
read that data using the serial input (digital pin zero on the board) and display it on the
serial monitor box to see what it looks like. The LED activates (rather dimly) when
reading is taking place. Here is the sketch to use.
Once the sketch has been uploaded, open your serial monitor box, and wave a tag over
the antenna. You should have a reading similar to the video below, however your tag
number will be different.
Excellent simple numbers that we can work with. For example, one of my tags returns:
2,51,69,48,48,49,65,51,53,70,50,69,51,3 and another returns
2,51,67,48,48,67,69,49,48,68,53,51,55,3. Note that both start with 2 and end with 3, so
the unique tag details are the 12 integers between the 2 and 3. One could read the data as
characters or hexadecimal numbers by altering the data type in the sketch from int to
byte, but for simplicity I am working in integers.

Now all we need to do is fashion sketches to recognise the tag number(s) we want to use,
and perform an action based on which tag number is used (or do something when a tag is
read, but not the tag you want).
Example 15.2
In the following example, (download) the sketch reads the 14 integers returned from the
card reader when a tag is swiped. These integers are placed into a fourteen element array,
which is then compared against arrays holding the numbers my allowed tags. If an
allowed tag is read, the green LED comes on, if a disallowed tag is read, the red LED
comes on. Of course you could have the digital outputs controlling other things using a
switching transistor or a relay. Below is the schematic:

The hardware laid out:

And a short video in action:


Excellent now we are getting close to something useful. The example above could
make a simple door control, or an over-engineered cookie jar.
Speaking of cookies, time for a cup of tea

Now for some more practical uses of RFID and Arduino. In the past we have worked
with real time in many chapters, and also have stored data using a microSD card shield.
So:
Example 15.3
We will build on our previous example by adding time and date logging for all accesses
to the system, successful or not. This could be used again for door access, payroll
calculations as a modern-day punch-clock, or even a simple logging device to see what
time the children arrive home when you arent around to check. So we will need a
microSD shield, and some sort of DS1307 breakout board or shield.
When using more than one shield together, be mindful of the pins you will need to use.
For example, my DS1307 shield uses analogue 4 and 5 (for I2C interface), and the
microSD shield uses digital 10 to 13.
The sketch for this example is quite simple the good thing about programming for
Arduino is that just like the hardware shields, sketch procedures and functions can be
very modular and reused quite easily. If you are unsure about the microSD shield, please
read my instructional review. Most of the code can be copied from that microSD shield
articles demonstration sketch, which I have done for this example. The sketch writes the
time, date, tag number, and read status (accepted/rejected).
However there is one caveat when using the microSD shield the file needs to be closed
before the card can be removed for examination. In practical use, our RFID system would
be usually on most of the time, so a method will needed to activate the card write
function. This has been implemented with a function bossMode() that is called when a
certain tag is read one may call this the supervisors card. Once this particular tag is
read, the file is annotated as closed, reading stops, and the LEDs blink alternately when it
is safe to remove the card. A simple reset after the card is reinserted will start the reading
again. Here is the sketch, and a hardware layout.

The schematic is the same as example 15.2, with a few simple additions the use of the
microSD card shield, and the DS1307 real time clock shield. If you are using a DS1307
breakout board wired in separately, please use the following schematic as a guide:

Now here is a short video clip, with the addition of the boss mode shutdown sequence:
And finally, here is a copy of the text file that was produced from a recent test run:

As you can see, it is easy to reproduce expensive time-keeping systems with our own
equipment and some time. In the near future we will return to RFID and build some selfcontained units with an LCD display (I need to get some more LCD units!)
Thus concludes our introduction to RFID systems. However, stay tuned for more about
this and other interesting things!

Moving Forward with Arduino Chapter 16 Ethernet


Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.

This is part of a series originally titled Getting Started with Arduino! by John Boxall
A tutorial on the Arduino universe. The first chapter is here, the complete series is
detailed here.
Welcome back fellow arduidans!
In this instalment we will introduce and examine the use of Ethernet networking with
Arduino systems. This tutorial covers receiving data from an Arduino over the Internet. If
you are interested in controlling an Arduino over the Internet, see here.
It will be assumed that you have a basic understanding of computer networking, such as
the knowledge of how to connect computers to a hub/router with RJ45 cables, what an IP
and MAC address is, and so on. Furthermore, here is a good quick rundown
about Ethernet.
First of all, you will need an ethernet shield. There are a few on the market, such as the
original version by the Arduino team, and others from the usual retailer. Readers of my
articles will know my preference is for the Australian-designed Freetronics line of
hardware, so I will be using their shield. Plus it also has some interesting power-overethernet features which we will also consider later on.
Now, lets get started!
This is an ethernet shield on top of a TwentyTen board:

Notice that the digital pins ten to thirteen (the SPI) are highlighted on the shield they
are used exclusively by the ethernet shield, so you cannot (for now) use them for other i/o
operations. Plus all of that lovely space for circuitry
First of all, lets do something quick and easy to check that all is functional. If you are
using Arduino software version 19 (released this month) you need to also have the line:
#include <SPI.h>

Thanks to Scouris for that tip.


Open the Arduino software and select File > Examples > Ethernet > Webserver. This loads a
simple sketch which will display data gathered from the analogue inputs on a web browser.
However dont upload it yet, it needs a slight modification.

You need to specify the IP address of the ethernet shield which is done inside the
sketch. This is simple, go to the line:
byte ip[] = { 10, 0, 0, 177 };

The 10.0.0.177 is the IP address, so you can alter it to match your own setup. For
example, in my home the routers IP address is 192.168.0.1, the printer is 192.168.0.50
and all PCs are below 50. So I will set my shield IP to 192.168.0.77 by altering the
byteip[] array to:
byte ip[] = { 192, 168, 0, 77};

You also have the opportunity to change your MAC address. Each piece of networking
equipment has a unique serial number to identify itself over a network, and this is normall
hard-programmed into the equipments firmware. However with Arduino we can define
the MAC address ourselves. If you are running more than one ethernet shield on your
network, ensure they have different MAC addresses by altering the hexadecimal values in
the line:

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

However if you only have one shield just leave it be. There may be the very, very,
statistically rare chance of having a MAC address the same as your existing hardware, so
that would be another time to change it. Once you have made your alterations, upload the
sketch to your Arduino or compatible board. If you havent already, disconnect the power
and add your ethernet shield.
Update: Have received some feedback from those people with different network
configurations than the normal hub/router setup. If you are going to plug your Ethernet
shield directly into the network socket on a computer which is using wi-fi to connect to
the router make sure you are using a crossover cable between the shield and the PC.
Some Apple computers dont need one, but check first yourself. Furthermore, make sure
you have either turned off MAC address filtering on your router, or added your Ethernet
shields MAC to the accepted list.
Now, connect the shield to your router or hub with an RJ45 cable, and the Arduino board
to the power via USB or external power supply. Then return to your computer, and using
your web browser, enter your ethernet shields IP address into the URL bar. The web
browser will query the ethernet shield, which will return the values from the analogue
ports on the Arduino board, as such:

As there isnt anything plugged into the analog inputs, their value will change constantly.
Press F5 or refresh to see the new values. Neat your Arduino is now serving data over
a network. It is quite motivating to see it actually work. But now that we can see the
ethernet shield is working we can move on to something more useful. Lets dissect the
previous example in a simple way, and see how we can distribute and display more
interesting data over the network. For reference, all of the ethernet-related functions are
handled by the ethernet Arduino library. If you examine the previous sketch we just used,
the section that will be of interest is:

// output the value of each analog input pin


for (int i = 0; i < 6; i++) {
client.print(analog input );
client.print(i);
client.print( is );
client.print(analogRead(i));
client.println(<br />);
}
Hopefully this section of the sketch should be familiar remember how we have used
serial.print(); in the past when sending data to the serial monitor box? Well now we can
do the same thing, but sending data from our ethernet shield back to a web browser on
other words, a very basic type of web page. However there is something you may or may
not want to learn in order to format the output in a readable format HTML code. I am
not a website developer (which explains why tronixstuff is hosted by wordpress.com) so
will not delve into HTML too much. However if you wish to serve up nicely
formatted web pages with your Arduino and so on, here would be a good start. However
in the interests of simplicity, the following two lines will be the most useful:
client.print(" is ");

Client.print (); allows us to send text or data back to the web page. It works in the same
way as serial.print(), so nothing new there. You can also specify the data type in the same
way as with serial.print(). Naturally you can also use it to send data back as well. The
other useful line is:
client.println("<br />");

this sends the HTML code back to the web browser telling it to start a new line. The part
that actually causes the carriage return/new line is the <br /> which is an HTML code (or
tag) for a new line. So if you are creating more elaborate web page displays, you can
just insert other HTML tags in the client.print(); statement.
Note that the sketch will only send the data when it has been requested, i.e. received a
request from the web browser.
Example 16.1
So lets put our new knowledge into action with some simple sensor hardware
measuring temperature and pseudo-light levels. In chapter fourteen we did this and sent
the results over the air using XBee wireless modules. Now we shall make that data
available to a web browser instead.

We will need:

Arduino Uno or compatible board


Ethernet shield
Analog Devices TMP36 temperature sensor
10 k ohm resistor
light-dependent resistor/photocell

Here is the schematic for the circuit: (click to enlarge)

and in real life. If you were to construct a permanent application, the Freetronics shield is
great as you have all that prototyping space and our sketch.

Finally, the sketch in action, on the desktop PC:

and on a phone via my internal wireless access point (the screen is a little fuzzy due to the
adhesive screen protector):

Now you can see how easy it is to send data from your Arduino via an ethernet network
to a web browser. But that is only to a local web browser. What if I wanted to read that
data using my phone whilst trundling along on the Westlander, or from an internet cafe in
downtown Vientiane? It can be done, but is a little bit tricky for the uninitiated so lets
get initiated!
You will need a static IP address that is, the IP address your internet service provider
assigns to your connection needs to stay the same. If you dont have a static IP, as long as
you leave your modem/router permanently swiched on your IP shouldnt change.
However, if your internet service provider cannot offer you a static IP at all, you can still
move forward with the project by using an organisation that offers a Dynamic DNS.
These organisations offer you your own static IP hostname (e.g. mojo.monkeynuts.com)
instead of a number, keep track of your changing IP address and linking it to the new

hostname. From what I can gather, your modem needs to support (have an in-built client
for) these DDNS services. As an example, two companies are No-IP and DynDNS.com.
Please note that I havent used those two***, they are just offered as examples.
Now, to find your IP address, usually this can be found by logging into your routers
administration page.
If you happen to be in Australia and have an iinet BoB, we have the same hardware!
Anyhow, for example, if I enter 192.168.0.1 in a web browser, and after entering my
modem administration password, the following screen is presented:

What you are looking for is your WAN IP address, as artistically circled above. To keep
the pranksters away, I have blacked out some of my address. The next thing to do is turn
on port-forwarding. This tells the router where to redirect incoming requests from the
outside world. When the modem receives such a request, we want to send that request to
the port number of our ethernet shield. Using the Server server(80); function in our
sketch has set the port number to 80. Each modems configuration screen will look
different, but as an example here is one:

So you can see from the line number one, the inbound port numbers have been set to 80,
and the IP address of the ethernet shield has been set to 192.168.0.77 the same as in the
sketch. After saving the settings, were all set. The external address of my ethernet shield
will be the WAN:80, e.g. 213.123.456.128:80 into the browser of a web device will
contact the lonely Ethernet hardware back home. Furthermore, you may need to alter
your modems firewall settings, to allow the port 80 to be open to incoming requests.
Please check your modem documentation for more information on how to do this.
Now from basically any internet-connected device in the free world, I can enter my WAN
and port number into the URL field and receive the results. For example, from a phone
when it is connected to the Internet via 3.5G mobile data:

How neat is that? The web page, not the phone. Well, the phone is pretty awesome too.
OK, its just the temperature but with your other Arduino knowledge from our tutorials
and elsewhere you can wire up all sorts of sensors, poll them from your Arduino and
use the ethernet shield and an internet connection to access that data from anywhere.
Here are some applications that spring to mind, all can be made possible with details
from our previous tutorials:

Sensitive temperature monitoring (e.g. a smoke house, tropical fish tank, chemical
storage room, and so on);
Have the children come home from school? children must swipe their RFID
tag when they arrive home. Arduino stores time and tag number, which can be
converted into display data for web output;
For single room-mates perhaps a remote, high-tech version of a necktie on a
doorknob when the busy flatmate arrives home, they turn a switch which is
read by the Arduino, and is then polled by the sketch the other flatmates can poll
from their phone before coming home;
Using reed switch/magnet pairs, you could monitor whether important doors or
windows (etc.) were open or closed.
A small RFID could be placed on the collar of your pet two RFID readers on
each side of a cat/dog flap door. Using simple logic the Arduino could calculate if
the pet was inside or outside, and the last time the pet went through the door.

The possibilities are only limited by your imagination or requirements.


Now speaking of requirements, one of those is power to your Arduino or compatible
board. Naturally the Ethernet shield receives its power from the host board, but you still
need to power the host board. This can be a royal pain, as you need to run two cables, one
for power and the other for Ethernet. And as fate would usually have it, there isnt a
power point near your hardware to make using a plug pack/wall wart easy. In the past,
you may have spliced open your network cable, and soldered up your power supply to the
required pairs, then use some heat shrink to hold the whole mess back together again.
However, our friends at Freetronics have come up with a simple yet practical solution to
this their four channel power-over-Ethernet midspan injector:

Using it is very easy. First you will need to set the jumpers on your PoE-compatible
Ethernet shield so it feeds the power from the Ethernet line to the host board:

Then, run an Ethernet cable from your router/hub/switch port to the injector, and
another Ethernet lead out to your Ethernet shield that supports power-over-Ethernet.
Then, plug in your power supply (plug pack) to the injectors black power socket:

You can have an AC or DC supply, as the injector has a built-in bridge rectifier and
smoothing circuitry. For Arduino use, your power supply must output between seven
and twelve volts! Any more and your Arduino host board will get very cranky, as you will
be outside the limits of the on-board voltage regulator. Please note that the injector does
not reduce voltage, so if you insert a 20 volt AC power supply, the injector will happily
send 20V DC down the Ethernet cable.
Note that if you use a midspan injector, you dont run every network device through it
only the devices that require power. So you wouldnt run standard Ethernet devices such
as your printers or PCs through it. E.g.:

However, if you do need to send a voltage over 12 volts DC and below 24 volts DC, there
is a tiny regulator board available to solder onto your PoE Ethernet shield, as such:

It converts the input 14 to 24 volts DC that comes in from the midspan power injector to
a nice, smoothed 12 volts DC which your host board will be very happy with. The
regulator is a 7812, so you can draw up to one amp through it. This should be enough for
your host board, Ethernet shield, and even another shield or two depending on your
requirements.
For a detailed tutorial about power over Ethernet, review this tutorial.

Moving Forward with Arduino Chapter 17 GPS


Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is part of a series originally titled Getting Started with Arduino! by John Boxall
A tutorial on the Arduino universe. The first chapter is here, the complete series is
detailed here.
Welcome back fellow arduidans!
In this instalment we will introduce and examine the use of the Global Positioning
System receivers with Arduino systems. This will be part one.
What is the GPS? In very simple terms, a fleet of satellites orbit the earth, transmitting
signals from space. Your GPS receiver uses signals from these satellites to triangulate
position, altitude, compass headings, etc.; and also receives a time and date signal from
these satellites. The most popular GPS belongs to the USA, and was originally for
military use, however it is now available for users in the free world. Interestingly, the US
can switch off or reduce accuracy of their GPS in various regions if necessary, however
many people tell me this is not an issue unless youre in a combat zone against the US
forces. For more information, have a look at Wikipedia or the USAF Space Command
GPS Ops Centre site. As expected, other countries have their own GPS as well such
as Russia, China, and thankfully the EU is working on one as well.
So how can us mere mortals take advantage of a multi-billion dollar space navigation
system just with our simple Arduino? Easy with an inexpensive GPS receiver and
shield. When searching for some hardware to use, I took the easy way out and ordered the
Sparkfun GPS pack which includes the required Arduino shield and header sockets, short
connecting cable and an EM-406A 20-channel GPS receiver with in-built antenna:

For reference now and in the future, here is the data book for the GPS receiver: EM-406
manual.pdf.

If you have a different receiver and need some help or questions answered, please ask in
the Google Group and well do our best to help you.
All you will need is an Arduino Uno/Duemilanove or 100% compatible board, and the
usual odds and ends. At the present moment Im working on using this with a Mega. If
you are using a Mega and have questions, let me know. When it comes time to solder up
your shield, if possible try and sit it into another shield or board this keeps the pins in
line and saves a lot of trouble later on:

And were done:

Please notice in the photo above the cable is a lot longer between the shield and the GPS
receiver. This was an extra cable, which makes things a lot more convenient, and it never
hurts to have a spare. Finally, on the shield please take note of the following two
switches the shield/GPS power switch:

and the UART/DLINE switch:

For now, leave this set to UART while a sketch is running. When uploading a sketch to
the board, this needs to be on DLINE. Always turn off your GPS shield board before
changing this switch to avoid damage.

Example 17.1 Is anyone out there?


Now, lets get some of that juicy GPS data from outer space.
You will need:

Arduino Uno or compatible board


a suitable GPS setup for example the GPS shield bundle

Once you have your hardware assembled, upload the following sketch. Now for desk
jockeys such as myself, there is a catch, as a GPS receives signals from satellites the
receiver will need to be in line of sight with the open sky. If you have your desk next to a
window, or a portable computer youre in luck. Look at the LED on your GPS receiver
if it is blinking, it has a lock (this is what you want); on - it is searching for satellites; off it is off (!). Frankly I though it would blink for searching, and be on for satellite lock.
Moving along
The first time you power up your receiver, it may take a minute or so to lock onto the
available satellites, this period of time is the cold start time. This will be in ideal
conditions i.e. with a clear line of sight from the unit to the sky (clouds excepted!).
Once this has been done, the next time you power it up, the searching time is reduced
somewhat as our receiver stores some energy in a supercap (very high-value capacitor) to
remember the satellite data, which it will use the next time to reduce the search time (as it
already has a fair idea where the satellites are).
Now open the serial monitor box, sit back and wait a moment or two, and you should be
presented with something very similar to this:

What a mess. What on earth does all that mean? For one thing the hardware is working
correctly. Excellent! Now how do we decode these space-signals
They are called NMEA codes. Lets break down one and see what it means. For example,
the line:
$GPRMC,165307.000,A,2728.9620,S,15259.5159,E,0.20,48.84,140910,,*27
Each field represents:

$GPRMC tells us the following data is essential point-velocity-time data;


165307.000 is the universal time constant (Greenwich Mean Time) 16:53:07
(hours, minutes, seconds). So you now have a clock as well.
A is status A for active and data is valid, V for void and data is not valid.
2728.9620 is degrees latitude position data = 27 degrees, 28.962
S for south (south is negative, north is positive)
15259.5159 is degrees longitude position data = 152 degrees, 59.5159
E for east (east is positive, west is negative)
0.20 is my speed in knots over ground. This shows the inaccuracy that can be
caused by not having a clear view of the sky
48.84 course over ground (0 is north, 180 is south, 270 is west, 90 is east)
140910 is the date 14th September, 2010
the next is magnetic variation for which we dont have a value
checksum number

Thankfully the data is separated by commas. This will be useful if you are logging the
data to a text file using a microSD shield, you will then be able to use the data in a
spreadsheet very easily. Later on we will work with data from other codes, but if you
cant wait, here is the NMEA Reference Manual that explains them all.
In the meanwhile, how can we convert the location data (longitude and latitude) received
into a position on a map?

Visit this website


In the box that says paste your data here, enter (for example, using my data
above)

name,desc,latitude,longitude home,home,-2728.9660,15259.5143

For example:

Then click Draw the Map, and you will be presented with a Google map in a new
window that you can zoom around in, change views and so on. Interestingly enough the
coordinates returned in the test above were accurate down to around three meters. Later
on that website will be of great use, as you can import text files of coordinates, and it will
plot them out for you. If you use this mapping site a lot, please consider making a
donation to help them out. If youre going to stalk me, say hello. We can drink tea and
listen to Joan Baez records.
Now as always, there is an easier way. The purpose of the previous demonstrations were
to see the raw data that comes from a receiver, and understand how to work with it.

Moving on now we can receive GPS signals and in the past we have used LCD
modules so we can make our own variations of portable (!) GPS modules and other
devices. At this point you will need to install two libraries into the Arduino software
NewSoftSerial and TinyGPS. Extract the folders into the libraries folder within your
arduino-001x folder.
Example 17.2 My First GPS
Using various pieces of hardware from the past, we will build a simple, portable unit to
display our data.
You will need:

Arduino Uno or compatible board; Arduino Mega users your sketch is here
a suitable GPS setup for example the GPS shield bundle;
An LCD with HD44780 interface that has the ability to connect to your Arduino
system. The size is up to you, were using a 20 x 4 character unit. If you have
dropped in or are a bit rusty on LCDs, please read chapter two; and the LCD
shield projects one and two;
An external power supply for your setup (if you want to walk up and down the
street at midnight like I did) for example, a 9V battery snap soldered to a DC
plug is a quick and dirty solution!

Luckily I have made an LCD shield in the past which works nicely, and doesnt use
digital pins D0 and D1 these are used by the GPS shield to get the data back to the
Arduino. Therefore the whole lot just plugged in together as shields do. Here is the
Duemilanove/Uno sketch for your consideration; Mega users here is your sketch. Before
uploading the sketch, turn off the GPS shield, set the DLINE/UART switch on the GPS
shield to DLINE, upload the sketch, then set it back again, then back on with the GPS
shield.
So here it is all thrown together in my LBE shipping container/lunchbox:

And a close-up view of the LCD. There was not room for the course data, but you can
modify the sketch accordingly. The data will be a little off due to the photo being taken
indoors:

Now for some outdoor fun. In the video clip below, we take a ride on the bus and see our
GPS in action

For the record, Brisbane has a huge fleet of nice new buses, however in off-peak they
dust off the reserve fleet. I had to take an old bus that wasnt full of security cameras, so
the ride is bumpy:
As we have a lot of electronics in this setup, it would be interesting to know the current
draw, to help plan for an appropriate power supply. The trusty meter gives us:

Wow a maximum of 122 milliamps even with that LCD backlight blazing away. So
when we make some GPS logging devices without such a monstrous LCD, we should be
able to get the current draw down a lot more.
The purpose of this example was to show how you can manipulate the data from the GPS
receiver. So from now on it is just working with numbers, and displaying numbers.
Hopefully by now your imagination is starting to wind up with various ideas! And we
made something, instead of zoning out in front of the television.

Moving Forward with Arduino Chapter 18 RGB


LED Matrix
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is part of a series originally titled Getting Started with Arduino! by John Boxall
A tutorial on the Arduino universe. The first chapter is here, the complete series is
detailed here.
Welcome back fellow arduidans!
In this instalment we will take a turn away from the serious things for a while, (plus I
wanted a bit of a break) and instead enjoy some introductory fun with RGB LED
matrices. (Matrices is the plural form of matrix). I am sure some of you have seen these
do all sorts of things, so now it is time for me to learn about them and share this with you.
First of all, lets have a look at one:

Quite large 60 by 60 mm. Thankfully this unit has the diffused/opaque LED surfaces
some cheaper ones have clear surfaces which don t look that good it is like looking
directly at an incandescent light globe, you can see the element more than the colour it
emits. When you turn the matrix over, there are less pins than a newcomer may expect:

Two rows of sixteen pins. Considering there is so much real-estate on the bottom, one
would think the manufacturer could print some markings on there but they dont. So
you need the (example) data sheet.pdf. The three most important things we need to know
are:

the forward voltages: red 2 V, green and blue 3.3;


the current at the recommended forward voltage 20 milliamps;
and the pinouts (click to enlarge):

It looks like a mess but isnt that hard to work out. Do you remember how we used the
88 red LED matrix back in chapter nine? We will work on the same style of design in
this chapter as well. I do realise there are chips from TI, Maxim and so on that are quite
tricky but I am trying to keep the cost down, of which I am sure you would appreciate.
So instead we will use four 74HC595 shift registers (one to control the anodes of each
colour, and one to control the cathodes via a bank of switching transistors.

To get this started, first lets get the hardware out of the way. To fire this baby up we will
need:

an Arduino Uno or 100% compatible board;


a common-cathode RGB LED matrix;
24 x 560 ohm resistors (this value may seem like a bit much but the display was
still very bright)
8 x 1 kilo ohm resistors (for transistors)
8 x BC548 transistors
4 x 74HC595 shift registers (IC1~4)
1 x 1uF 16V (or higher) electrolytic capacitor
1 x 0.1 uF 16V (or higher) ceramic capacitor
a nice large breadboard
plenty of connecting wire

Initially I was concerned about the amount of current this circuit would draw, however it
was not to be an issue. With all the LEDs on, using the 560 ohm current-limiting
resistors, the drain was much less than expected. To check, I powered the lot from a 9V
PP3 battery and measured the current flow. 135 milliamps, not bad at all.

It just occurred to me that if you had an Arduino Mega it could directly take care of
everything instead of using three of the shift registers. Hmmm.
So here is our schematic:

In the schematic above, there are eight transistor-resistor combinations between the
cathodes of the matrix (pins 25, 24, 23, 10, 9, 8, 7 and IC4. And there are 560 ohm
resistors on all output pins of ICs 1~3. Furthermore, note that your LED matrixs
pinouts may vary so please check your data sheet before wiring it all up having to
retrace all those wires once theyre in is a real problem. As you can see from the resulting
breadboard photo:

Now how does all this work?


Quite easily really, the hardest part is putting the hardware together. First of all, please
review how we used shift registers in chapter four. And, you may recall how we used two
74HC595 shift registers to control an 88 red LED matrix back in chapter nine. This is
just the same type of set up, but with two more shift registers now we have one for the
cathodes (as we did before), and one shift register each for the red, green and blue LEDs.
Instead of sending out two bytes of data using shiftOut();, we need to send out four bytes.
For example, to turn on every LED at once (thereby mixing red, green and blue
producing white) we would create a function such as:

void allOn()
// turns on all LEDs.
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, 255); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, 255); // green
shiftOut(datapin, clockpin, MSBFIRST, 255); // blue
shiftOut(datapin, clockpin, MSBFIRST, 255); // red
digitalWrite(latchpin, HIGH);
}
So as you can see, the first byte out the door is the data for the cathodes, in this case 255
which is 11111111 in binary, or in 74HC595-speak hey, turn on all outputs. And the
same again in turn for each bank of colours, the other three registers are told to open all
gates and let current flow through the LEDs to the common-cathode lines controlled by
IC4. So naturally, using some binary to base-10 conversion you can set which LEDs to
come on and where. And of course, by mixing the primary colours you can create new
ones. For example, the additive colour chart gives us:

So now you can create yellow with red and green; red and blue makes purple; green and
blue makes aqua or teal, etc. However I am colour blind, so you tell me.
Example 18.1
This time we will view the demonstration video first:
Download the matching sketch.

Now to examine how each of the effects were created, so you can understand, use and
modify them yourself.
The basic operations are contained in these four lines:
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, c); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, g); // green
shiftOut(datapin, clockpin, MSBFIRST, b); // blue
shiftOut(datapin, clockpin, MSBFIRST, r); // red
digitalWrite(latchpin, HIGH);
So all you need to do is replace r, b, g and c with the base-10 values you want. For
example, to light up the red LED in position 1, 1 use 1, 0, 0, 1. Or if you want the
whole first line to be green, use: 255, 0, 0, 1. After a few moments you should become
proficient at converting binary to base-10. This chart from chapter four should help you:

Remember that you can also create patterns and so on. For example, if you only wanted
LEDs 1 and 8 for your x-axis, you would add 1 and 128 together, and use the sum (129)
for your x-value. To save some time, I have created a few functions for you to use. For
example:
void displayLEDs(int rr, int gg, int bb, int cc, int dd)
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, cc); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, gg); // green
shiftOut(datapin, clockpin, MSBFIRST, bb); // blue
shiftOut(datapin, clockpin, MSBFIRST, rr); // red
digitalWrite(latchpin, HIGH);
delay(dd);
}

So instead of having to manually repeat a lot of code, you can just insert the values into
displayLEDs();. Another handy thing to know about is looping. When looking at the
matrix it is easy to accidentally think Oh, I can just loop from 1 to 8 No. Remember
your binary to base-10 conversions. So if you wanted to scroll a horizontal line of red

LEDs your cathode or y-axis value must increment as such: 1, 2, 4, 8, 16, 32, 64, 128.
Every time the loop cycles, it needs to double the value. To do this, consider:
for (int q=1; q<129; q*=2)
{
displayLEDs(255,0,0,55,100);
}

Notice the q*=2? This will multiply the value of q by 2 every loop. Very useful. Another
method would be to create an array, as such:
int va[]={1,2,4,8,16,32,64,128,255};

and refer to the elements as required. This is done within the function lostinspace();
within example 18.1.
The next thing to take into account is the screen refresh. Every time you send four bytes
of data through the shift registers, those new bytes will shift the old bytes out of the
way. So if you want to alter the display even by just one LED, you need to redraw the
entire display over again with four new bytes of data. Also note that to hold an image on
the display, you only need to send the data once the shift registers will stay put until the
next four bytes of data come along.
And sometimes, you might just want to turn off the display. Just send four zeros down to
the registers, as the function clearMatrix(); does in the example sketch.
For now, please review the various functions found in example 18.1 alter them, mess
about and have some fun. Thus concludes our introduction to RGB LED matrices.
However, stay tuned for more about this and other interesting things! If you have any
requests, dont hesitate to ask.

Moving Forward with Arduino Chapter


19 GPS part II
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is part of a series originally titled Getting Started with Arduino! by John Boxall
A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here.
Welcome back fellow arduidans
In this instalment we will continue to examine the use of our GPS system and Arduino
through creating two more applications. Some of them may seem simple, but we will
build on them later on to make more complex things. To review previous information, the
first GPS instalment was chapter seventeen.
Example 19.1 Household official time
At home we often have various discussions about what the actual time is. At first it
sounds silly, but when you have clocks on the microwave, kitchen wall, VCR (yes),
wristwatch, mobile phone, clock-radio, and so on things can get a little out of hand.
And my mother has all her clocks ten minutes fast. Insanity may prevail!
So lets make a nice big LED-display reference clock something that wouldnt look out
of place in a radio or television studio:

Then when people start arguing over the time, you can point at your new clock and
smile. From a hardware perspective, we will combine three or four things: our Arduino
board, our GPS system, and the MAX7219 display driver. We will need the following
items:

Arduino Uno or compatible board


the GPS shield bundle
Maxim MAX7219 display driver IC

two four-digit, seven-segment LED displays (common cathode), such as Farnell


5014920 or Digikey 67-1442-ND. You could also rig up four separate digits with
some patience;
one 1 kilo ohm resistor
one 10 kilo ohm resistor
one single pole, double-throw switch
a nice breadboard and some connecting wire
a separate 5V power supply all those LED segments are thirsty, the completed
clock uses under 350 milliamps with a brightness setting of 8:

Here is the schematic:

Although the sketch (download) may seem quite complex, it is just made up of things we
have already examined in the past. The only unfamiliar part could be the MAX7219
display driver IC, which in itself is quite easy to use. There is a full part review and
explanation here. It is most likely that everyone will have different LED display units, as

the 4-digit modules can be hard to track for some people or too expensive so some
more explanation is in order.
You will need common-cathode display modules. If you line the digits up from left to
right, they will be numbered zero to nine with respect to the MAX7219 so connect
MAX7219 pin 2 to the cathode of your first display, and so on. With regards to the
anodes (a~g and dp [decimal point]) link each anode type together.
For example, if you have eight separate 7-segment display modules, connect each a pin
together, then to MAX pin 14. And so on. Here is the board layout a real mess:

And our action video:


An interesting twist you might find of interest is the function:
lc.setIntensity(0,8);

Which allows you to alter the brightness of the LED display(s). The range is 0 to 18 in
my examples it has been set to 8. You could then make your clock dim the display
brightness between (for example) 11pm and 5am so when you wake up in the middle of
the night the display wont act like a frickin laser-beam burning into your eyeballs.
Furthermore, dropping the brightness reduces the power consumption.
Anyhow, I hope you found the sketch and operation easy to understand, however if you
have any questions please ask in our Google Group.

Now it is time for what most of you have been waiting for making a GPS tracking
device. Now before you get too excited, it would be proper to make sure you have the
permission of someone before you track them.
Example 19.2 You went where?
From a hardware perspective this example is a lot easier that you think it is just the
Arduino board, GPS shield, an LED on digital pin 2 and one push-button connected to
digital 8 (dont forget the 10k ohm pull-down resistor). You will need to install
NewSoftSerial library, TinyGPS library and the SdFat library if not already installed.
Then, we will need the following items:

Arduino Uno or compatible board


the GPS shield bundle
one LED and 560 ohm resistor connected to digital 2.
microSD shield and a matching memory card
single push-button and 10k ohm resistor (connect these to digital pin 8)
portable power, for example an alkaline 9V PP3 battery and adaptor cable

Download the Example 19.2 sketch from here.


Although the hardware wasnt that interesting to plug together, what can be done with it
and the data it captures is quite fascinating. Dont forget to press the button to end
logging before removing the power and the microSD card from the shield.
To generate some sample data, I have taken the hardware for a walk to the post office. We
will now open the file produced by our hardware and examine it further. If you would
like to follow along, you can download the file from here.
The file is a typical, comma-delimited text file. You can examine it further using common
spreadsheet software such as Openoffice.org Calc. For example, if you open the file of
GPS data from here, you will be presented with the following window:

You can see that the data delimits quite easily. Just click OK and the file will be
presented to you.

So as you can see, there is time, date (remember GMT), latitude and longitude, my
speed (with a couple of anomalies) and random sensor data results (see the sketch). We
can have this data converted into a much more useful form by using the GPS Visualiser
website. Save the data as a .csv file. Then visit http://www.gpsvisualizer.com/, and use
the Get Started Now box in the middle of the web page. Select Google Maps as the output
format, then upload the file. This will result in the following:

Just like normal Google Maps there are many display options you can choose from, and
the GPS Visualiser web site has many tutorials about making the most of their service. If
you look in detail you will see some jittering along parts of the track that are not
representative of my movements (though I had just taken my morning coffee). This could
be the result of the receiver module moving about in all three axes during my walk, one
would imagine it would be a lot smoother inside a motor vehicle. So have fun with that.

Tutorial: Arduino and the I2C bus Part One


The first chapter is here, the complete series is detailed here. Please note from November
1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
Today we are going to start investigating the I2C data bus, and how we can control
devices using it with our Arduino systems. The I2C bus can be a complex interface to
master, so I will do my best to simplify it for you. In this article we will learn the
necessary theory, and then apply it by controlling a variety of devices. Furthermore it
would be in your interest to have an understanding of the binary, binary-coded decimal
and hexadecimal number systems.
But first of all, what is it?
I2C is an acronym for Inter-Integrated Circuit. In the late 1970s, Philips
semiconductor division (now NXP) saw the need for simplifying and standardising
the data lines that travel between various integrated circuits in their products. Their
solution was the I2C bus. This reduced the number of wires to two (SDA data, and SCL
clock). Here is a nice introductory video from NXP:
Why would we want to use I2C devices?
As there are literally thousands of components that use the I2C interface! For example,
click these supplier links to have a look at the range: NXP, Farnell, Digikey, Mouser,
and RS.
And our Arduino boards can control them all. There are many applications, such a realtime clocks, digital potentiometers, temperature sensors, digital compasses, memory
chips, FM radio circuits, I/O expanders, LCD controllers, amplifiers, and so on. And you
can have more than one on the bus at any time, in fact the maximum number of I2C
devices used at any one time is 112.
From a hardware perspective, the wiring is very easy. Those of you with an Arduino
Duemilanove, Uno or 100% compatible board, you will be using pins A4 for SDA (data)
and A5 for SCL (clock).

If you are using an Arduino Mega, SDA is pin 20 and SCL is 21, so note that shields with
I2C need to be specifically for the Mega. If you have another type of board, check your
data sheet or try the Arduino teams hardware website. And finally, if you are using a
bare DIP ATmega328-PU microcontroller, you will use pins 27 for SDA and 28 for SCL.
The bus wiring is simple:

If you are only using one I2C device, the pull-up resistors are (normally) not required, as
the ATmega328 microcontroller in our Arduino has them built-in. However if you are
running a string of devices, use two 10 kilo ohm resistors. Like anything, some testing on
a breadboard or prototype circuit will determine their necessity. Sometimes you may see
in a particular devices data sheet the use of different value pull-up resistors for
example 4.7k ohm. If so, heed that advice. The maximum length of an I2C bus is around
one metre, and is a function of the capacitance of the bus. This distance can be extended
with the use of a special IC, which we will examine during the next I2C chapter.
Each device can be connected to the bus in any order, and devices can be masters or
slaves. In our Arduino situation, the board is the master and the devices on the I2C bus
are the slaves. We can write data to a device, or read data from a device. By now you
should be thinking how do we differentiate each device on the bus? Each device has
a unique address. We use that address in the functions described later on to direct our read
or write requests to the correct device. It is possible to use two devices with identical
addresses on an I2C bus, but that will be discussed in a later article.

As like most devices, we make use of an Arduino library, in this case <wire.h>. Then use
the function Wire.begin(); inside of void setup() and were ready to go.
Sending data from our Arduino to the I2C devices requires two things: the unique device
address (we need this in hexadecimal) and at least one byte of data to send. For example,
the address of the part in example 20.1 (below) is 00101111 (binary) which is 0X2F in
hexadecimal. Then we want to set the wiper value, which is a value between 0 and 127,
or 000 and 0x7F in hexadecimal. So to set the wiper to zero, we would use the
following three functions:
Wire.beginTransmission(0x2F);

// part address is 0x2F or 0101111b

This sends the device address down the SDA (data) line of the bus. It travels along the
bus, and notifies the matching device that it has some data coming
Wire.send(69); // if you are using Arduino v23 or older
Wire.write(69); // if you are using Arduino v1.0 or later

Note the difference depending on the Arduino IDE version you are using. You will
need to change all the Wire.send commands in our examples to Wire.write if youre
using Arduino v1.0 or later.
This sends the byte of data to the device into the device register (or memory of sorts),
which is waiting for it with open arms. Any other devices on the bus will ignore this.
Note that you can only perform one I2C operation at a time! Then when we have finished
sending data to the device, we end transmission. This tells the device that were
finished, and frees up the I2C bus for the next operation:
Wire.endTransmission();

Some devices may have more than one register, and require more bytes of data in each
transmission. For example, the DS1307 real-time clock IC has eight registers to store
timing data, each requiring eight bits of data (one byte):

However with the DS1307 - the entire lot need to be rewritten every time. So in this case
we would use eight wire.send(); functions every time. Each device will interpret the byte
of data sent to it, so you need the data sheet for your device to understand how to use it.

Receiving data from an I2C device into our Arduino requires two things: the unique
device address (we need this in hexadecimal) and the number of bytes of data to accept
from the device. Receiving data at this point is a two stage process. If you review the
table above from the DS1307 data sheet, note that there is eight registers, or bytes of data
in there. The first thing we need to do is have the I2C device start reading from the first
register, which is done by sending a zero to the device:
Wire.beginTransmission(device_address);
Wire.send(0);
Wire.endTransmission();

Now the I2C device will send data from the first register when requested. We now need
to ask the device for the data, and how many bytes we want. For example, if a device
held three bytes of data, we would ask for three, and store each byte in its own variable
(for example, we have three variables of type byte: a, b, and c. The first function to
execute is:
Wire.requestFrom(device_address, 3);

Which tells the device to send three bytes of data back to the Arduino. We then
immediately follow this with:
*a = Wire.receive();
*b = Wire.receive();
*c = Wire.receive();

If you are using Arduino v1.0 or newer use Wire.read() instead of Wire.receive().
We do not need to use Wire.endTransmission() when reading data. Now that the requested
data is in their respective variables, you can treat them like any ordinary byte variable.
For a more detailed explanation of the I2C bus, read this explanatory document by
NXP. Now lets use our I2C knowledge by controlling a range of devices
Example 20.1
A new part for today, the Microchip MCP4018T digital linear potentiometer. The value of
this model is 10 kilo ohms. Inside this tiny, tiny SMD part is a resistor array consisting of
127 elements and a wiper that we control by sending a value of between 0 and 127 (in
hexadecimal) down the I2C bus. This is a volatile digital potentiometer, it forgets the
wiper position when the power is removed. However naturally there is a compromise
with using such a small part, it is only rated for 2.5 milliamps but used in conjunction
with op amps and so on. For more information, please consult the data sheet.
As this is an SMD part, for breadboard prototyping purposes it needed to be mounted on
a breakout board. Here it is in raw form:

Above the IC is a breakout board. Consider that the graph paper is 5mm square! It is the
incorrect size, but all I have. However soldering was bearable. Put a drop of solder on
one pad of the breakout board, then hold the IC with tweezers in one hand, and reheat the
solder with the other hand then push the IC into place. A few more tiny blobs of solder
over the remaining pins, and remove the excess with solder wick. Well it worked for
me:

Our example schematic is as follows:

As you can see, the part is simple to use, your signal enters pin 6 and the result of the
voltage division is found on pin 5. Please note that this is not a replacement for a typical
mechanical potentiometer, we cant just hook this up as a volume or motor-speed control!
Again, please read the data sheet.
Control is very simple, we only need to send one byte of data down, the hexadecimal
reference point for the wiper, e.g.:
Wire.beginTransmission(0x2F);
Wire.send(0x3F); //
Wire.endTransmission();

// part address is 0x2F or 0101111b

Here is a quick demonstration that moves the wiper across all points: (download)
/*
Example 20.1 Microchip MCP4018 digital potentiometer demonstration
sketch
http://tronixstuff.com/tutorials > chapter 20 CC by-sa v3.0
*/
int dt = 2000; // used for delay duration
byte rval = 0x00; // used for value sent to potentiometer
#include "Wire.h"
#define pot_address 0x2F // each I2C object has a unique bus address,
the MCP4018 is 0x2F or 0101111 in binary
void setup()
{
Wire.begin();
Serial.begin(9600);
}
void potLoop()
// sends values of 0x00 to 0x7F to pot in order to change the resistance
// equates to 0~127
{
for (rval=0; rval<128; rval++)
{
Wire.beginTransmission(pot_address);
Wire.send(rval);
Wire.endTransmission();
Serial.print(" sent - ");

Serial.println(rval, HEX);
delay(dt);
}
}
void loop()
{
potLoop();
}

and a video demonstration:


Example 20.2
Now we will read some data from an I2C device. Our test subject is the ST
Microelectronics CN75 temperature sensor. Again, we have another SMD component,
but the CN75 is the next stage larger than the part from example 20.1. Thankfully this
makes the soldering process much easier, however still requiring some delicate
handiwork:

First, a small blob of solder, then slide the IC into it. Once that has cooled, you can
complete the rest and solder the header pins into the breakout board:

Our example schematic is as follows:

Pins 5, 6 and 7 determine the final three bits of the device address in this case they are
all set to GND, which sets the address to 1001000. This allows you to use multiple
sensors on the same bus. Pin 3 is not used for basic temperature use, however it is an
output for the thermostat functions, which we will examine in the next chapter.
As a thermometer it can return temperatures down to the nearest half of a degree Celsius.
Although that may not be accurate enough, it was designed for automotive and thermostat
use. For more details please read the data sheet. The CN75 stores the temperature data in
two bytes, lets call them A and B. So we use
Wire.requestFrom(cn75address, 2)

with the second paramater as 2, as we want two bytes of data. Which we then store using
the following functions:
*a = Wire.receive(); // first received byte stored here
*b = Wire.receive(); // second received byte stored here

where *a and *b are variables of the type byte.


And as always, there is a twist to decoding the temperature from these bytes. Here are
two example pieces of sample data:
Example bytes one: 00011001 10000000
Example bytes two: 11100111 00000000

The bits in each byte note particular values the most significant bit (leftmost) of byte A
determines whether it is below or above zero degrees 1 for below zero. The remaining
seven bits are the binary representation of the integer part of the temperature; if it is

below zero, we subtract 128 from the value of the whole byte and multiply by -1. The
most significant bit of byte B determines the fraction, either zero or half a degree. So as
you will see in the following example sketch (download), there is some decision making
done in showCN75data():
/* Example 20.2
ST Microelectronics CN75 Digital Temperature sensor demonstration sketch
CC by-sa v3.0
*/
#include "Wire.h"
#define cn75address 0x48 // with pins 5~7 set to GND, the device address
is 0x48
void setup()
{
Wire.begin(); // wake up I2C bus Serial.begin(9600);
}
void getCN75data(byte *a, byte *b)
{
// move the register pointer back to the first register
Wire.beginTransmission(cn75address); // "Hey, CN75 @ 0x48! Message for
you"
Wire.send(0);
// "move your register pointer back to 00h"
Wire.endTransmission(); // "Thanks, goodbye..."
// now get the data from the CN75
Wire.requestFrom(cn75address, 2); // "Hey, CN75 @ 0x48 - please send me
the contents of your first two registers"
*a = Wire.receive(); // first received byte stored here
*b = Wire.receive(); // second received byte stored here
}
void showCN75data()
{
byte aa,bb;
float temperature=0;
getCN75data(&aa,&bb);
if (aa>127) // check for below zero degrees
{
temperature=((aa-128)*-1);
if (bb==128)
// check for 0.5 fraction
{
temperature-=0.5;
}
}
else // it must be above zero degrees
{
temperature=aa;
if (bb==128)
// check for 0.5 fraction
{
temperature+=0.5;
}
}
Serial.print("Temperature = ");
Serial.print(temperature,1);
Serial.println(" degrees C");
delay(1000);
}
void loop()

showCN75data();

And here is the result from the serial monitor:

Example 20.3
Now that we know how to read and write data to devices on the I2C bus here is an
example of doing both, with a very popular device the Maxim DS1307 real-time clock
IC. Maxim have written an good data sheet. For those of you new to the world of
tronixstuff, we use this part quite often, for example with our Arduino RTC shield and
modifications, or blinky the one-eyed clock. It is an 8-pin DIP IC that allows timing
with accuracy down to a few seconds a day:

Furthermore, it also has a programmable square-wave generator. Connection and use is


quite simple:

However some external components are required: a 32.768 kHz crystal, a 3V battery for
time retention when the power is off, and a 10k ohm pullup resistor is required if using as
a square-wave generator. You can use the SQW and timing simultaneously. If we have a
more detailed look at the register map for the DS1307:

We see that the first seven registers are for timing data, the eighth is the square-wave
control, and then another eight RAM registers. In this chapter we will look at the first
eight only. Hopefully you have noticed that various time parameters are represented by
less than eight bits of data the DS1307 uses binary-coded decimal. But dont panic, we
have some functions to do the conversions for us.
However, in general - remember that each bit in each register can only be zero or one
so how do we represent a registers contents in hexadecimal? First, we need to find
the binary representation, then convert that to hexadecimal. So, using the third register of

the DS1307 as an example, and a time of 12:34 pm we will read from left to right. Bit 7
is unused, so it is 0. Bit 6 determines whether the time kept is 12- or 24-hour time. So
well choose 1 for 12-hour time. Bit 5 (when bit 6 is 0) is the AM/PM indicator choose
1 for PM. Bit 4 represents the left-most digit of the time, that is the 1 in 12:34 pm. So
well choose 1. Bits 3 to 0 represent the BCD version of 2 which is 0010.
So to store 12pm as hours we need to write 00110010 as hexadecimal into the hours
register which is 032.
Reading data from the DS1307 should be easy for you now, reset the register pointed,
then request seven bytes of data and receive them into seven variables. The device
address is 068. For example:
Wire.beginTransmission(0x68);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
*second
= bcdToDec(Wire.receive();
*minute
= bcdToDec(Wire.receive();
*hour
= bcdToDec(Wire.receive();
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month
= bcdToDec(Wire.receive());
*year
= bcdToDec(Wire.receive());

At which point the time data will need to be converted to decimal numbers, which we
will take care of in the example sketch later. Setting the time, or controlling the squarewave output is another long operation you need to write seven variables to set the time
or eight to change the square-wave output. For example, the time:
Wire.beginTransmission(0x68);
Wire.send(0);
Wire.send(decToBcd(second));
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour));
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();

The decToBcd is a function defined in our example to convert the decimal numbers to
BCD suitable for the DS1307.
You can also address each register individually. We will demonstrate doing this with an
explanation of how to control the DS1037s in built square-wave generator (download
sketch):

/*

DS1307 Square-wave machine


Used to demonstrate the four different square-wave outputs from Maxim
DS1307
See page nine of data sheet for more information
John Boxall - tronixstuff.wordpress.com
*/
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus
address, the DS1307 is 0x68
void setup()
{
Wire.begin();
}
void sqw1() // set to 1Hz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x10); // sends 0x10 (hex) 00010000 (binary)
Wire.endTransmission();
}
void sqw2() // set to 4.096 kHz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x11); // sends 0x11 (hex) 00010001 (binary)
Wire.endTransmission();
}
void sqw3() // set to 8.192 kHz
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x12); // sends 0x12 (hex) 00010010 (binary)
Wire.endTransmission();
}
void sqw4() // set to 32.768 kHz (the crystal frequency)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x13); // sends 0x13 (hex) 00010011 (binary)
Wire.endTransmission();
}
void sqwOff()
// turns the SQW off
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x07); // move pointer to SQW address
Wire.send(0x00); // turns the SQW pin off
Wire.endTransmission();
}
void loop()
{
sqw1();
delay(5000);
sqw2();
delay(5000);
sqw3();
delay(5000);

sqw4();
delay(5000);
sqwOff();
delay(5000);
}

Here is the SQW output in action we measure the frequency using my very old Tek
CFC-250:
For further DS1307 examples, I will not repeat myself and instead direct you to the list of
many tronixstuff articles that make use of the DS1307.
So there you have it hopefully an easy to understand introduction to the world of the
I2C bus and how to control the devices within. Part two of my I2C tutorial has now been
published, as well as an article about the NXP SAA1064 LED display driver IC and the
Microchip MC23017 16-bit port expander IC.

Tutorial: Arduino and the I2C bus Part Two


The first chapter is here, the complete series is detailed here. Please note from November
1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
Today we are going to continue learning about the I2C bus and how it can work for us. If
you have not already, perhaps read the first I2C article before continuing.
Remember if you are using Arduino v1.0 or greater you will need to change all
the Wire.send commands in our examples to Wire.write, and use Wire.read() instead
of Wire.receive().
First of all, there are some limitations of I2C to take into account when designing your
projects. One of these is the physical length of the SDA and SCL lines. If all your devices
are on the same PCB, then there is nothing to worry about, however if your I2C bus is
longer than around one metre, it is recommended that you use an I2C bus extender IC.
These ICs reduce electrical noise over the extended-length bus runs and buffer the I2C
signals to reduce signal degradation and chance of errors in the data. An example of such
an IC is the NXP P82B715 (data sheet). Using a pair of these ICs, you can have cable
runs of 20 to 30 metres, using shielded twisted-pair cable. Below is a good example of
this, from the aforementioned NXP data sheet:

Several applications come to mind with an extended I2C bus, for example remote
temperature monitoring using the the ST Microelectronics CN75 temperature sensor from
part one; or controlling several I/O ports using an I2C expander without the expense or
worry of using a wireless system. Speaking of which, lets do that now
Example 21.1

A very useful and inexpensive part is the PCF8574 I/O expander (data sheet.pdf). This
gives us another eight outputs, in a very similar method to the 74HC595; or can be used
as eight extra inputs. In fact, if you were to use more than one 74HC595 this IC might be
preferable, as you can individually address each chip instead of having to readdress every
IC in line as you would with shift registers. So how do we do this? First, lets consult the
pinout:

There should not be any surprises for you there. A2~A0 are used to select the last three
bits of the device address, P0~P7 are the I/O pins, and INT is an interrupt output which
we will not use. To address the PCF8574 we need two things, the device address, and a
byte of data which represents the required output pin state. Huh? Consider:

So if we set pins A0 to A2 to GND, our device address in binary will be 0100000, or


020 in hexadecimal. And the same again to set the output pins, for example to turn them
all on we send binary 0 in hexadecimal which is 0; or to have the first four on and the
second four off, use 00001111 which is Ox0F. Hopefully you noticed that those last two
values seemed backwards why would we send a zero to turn all the pins on?
The reason is that the PCF8574 is a current sink. This means that current runs from +5v,
through into the I/O pins. For example, an LED would have the anode on the +5V, and
the cathode connected to an I/O pin. Normally (for example with a 74HC595) current
would run from the IC, through the resistor, LED and then to earth. That is a current
source. Consider the following quick diagram:

In the example above, please note that the PCF8574N can take care of current limitation
with LEDs, whereas the 74HC595 needs a current-limiting resistor to protect the LED.
Luckily this IC can handle higher volumes of current, so a resistor will not be required. It
sounds a bit odd, but like anything is easy once you spend a few moments looking into
it. So now lets use three PCF8574s to control 24 LEDs. To recreate this masterpiece of
blinkiness you will need:

Arduino Uno/Duemilanove or Freetronics TwentyTen board


A large solderless breadboard
Three TI PCF8574 I/O extenders
Eight each of red, green and yellow (or your choice) LEDs, each with a current
draw of no more than 20mA
Two 4.7 kilo ohm resistors
Hook-up wires
Three 0.1 uF ceramic capacitors

Here is the schematic:

and the example board layout:

and the example sketch. Note that the device addresses in the sketch match the schematic
above. If for some reason you are wiring your PCF8574s differently, you will need
to recalculate your device addresses: (download sketch)
/* Example 21.1
Texas Instruments PCF8574N demonstration sketch
element-14 part number 7527718; RS part number 517-0687
http://tronixstuff.com/tutorials > chapter 21
CC by-sa v3.0 */
#include "Wire.h"
#define redchip 0x20 // device addresses for PCF8547Ns on each LED
colour bank
#define yellowchip 0x22 // addresses in this example match the
published schematic in the tutorial
#define greenchip 0x21
// you will need to change addresses if you vary from the schematic
int dd=20; // used for delay timing
void setup()
{
Wire.begin();
allOff(); // the PCF8574N defaults to high, so this functions turns all
outputs off}
// remember that the IC "sinks" current, that is current runs fro +5v
through the LED and then to I/O pin
// this means that 'high' = off, 'low' = on.
}
void testfunc()
{
Wire.beginTransmission(redchip);
Wire.send(0);
Wire.endTransmission();
delay(dd+50);
Wire.beginTransmission(redchip);
Wire.send(255);
Wire.endTransmission();
delay(dd+50);
Wire.beginTransmission(yellowchip);
Wire.send(0);
Wire.endTransmission();
delay(dd+50);

Wire.beginTransmission(yellowchip);
Wire.send(255);
Wire.endTransmission();
delay(dd+50);
Wire.beginTransmission(greenchip);
Wire.send(0);
Wire.endTransmission();
delay(dd+50);
Wire.beginTransmission(greenchip);
Wire.send(255);
Wire.endTransmission();
delay(dd+50);
}
void testfunc2()
{
for (int y=1; y<256; y*=2)
{
Wire.beginTransmission(redchip);
Wire.send(255-y); // we need the inverse, that is high = off
Wire.endTransmission();
delay(dd);
Wire.beginTransmission(redchip);
Wire.send(255);
Wire.endTransmission();
delay(dd);
}
for (int y=1; y<256; y*=2)
{
Wire.beginTransmission(yellowchip);
Wire.send(255-y);
Wire.endTransmission();
delay(dd);
Wire.beginTransmission(yellowchip);
Wire.send(255);
Wire.endTransmission();
delay(dd);
}
for (int y=1; y<256; y*=2)
{
Wire.beginTransmission(greenchip);
Wire.send(255-y);
Wire.endTransmission();
delay(dd);
Wire.beginTransmission(greenchip);
Wire.send(255);
Wire.endTransmission();
delay(dd);
}
}
void testfunc3()
{
Wire.beginTransmission(redchip);
Wire.send(0);
Wire.endTransmission();
Wire.beginTransmission(yellowchip);
Wire.send(0);
Wire.endTransmission();

Wire.beginTransmission(greenchip);
Wire.send(0);
Wire.endTransmission();
delay(dd+50);
allOff();
delay(dd+50);
}
void allOff()
{
Wire.beginTransmission(redchip);
Wire.send(255);
Wire.endTransmission();
Wire.beginTransmission(yellowchip);
Wire.send(255);
Wire.endTransmission();
Wire.beginTransmission(greenchip);
Wire.send(255);
Wire.endTransmission();
}
void loop()
{
for (int z=0; z<10; z++)
{
testfunc();
}
for (int z=0; z<10; z++)
{
testfunc2();
}
for (int z=0; z<10; z++)
{
testfunc3();
}
}

And finally our demonstration video:

That was a good example of controlling many outputs with our humble I2C bus. You
could literally control hundreds of outputs if necessary a quite inexpensive way of
doing so. Dont forget to take into account the total current draw of any extended circuits
if you are powering from your Arduino boards.
The next devices to examine on our I2C bus ride are EEPROMs
- Electrically Erasable Programmable Read-Only Memory. These are memory chips that
can store data without requiring power to retain memory. Why would we want to use
these? Sometimes you might need to store a lot of reference data for use in calculations
during a sketch, such as a mathematical table; or perhaps numerical representations of
maps or location data; or create your own interpreter within a sketch that takes instruction
from data stored in an array.

In other words, an EEPROM can be used to store data of a more permanent use, ideal for
when your main microcontroller doesnt haven enough memory for you to store the data
in the program code. However, EEPROMs are not really designed for random-access or
constant read/write operations they have a finite lifespan. But their use is quite simple,
so we can take advantage of them.
EEPROMS, like anything else come in many shapes and sizes. The model we will
examine today is the Microchip 24LC256 (data sheet.pdf). It can hold 256 kilobits of data
(thats 32 kilobytes) and is quite inexpensive. If you are using an Arduino LilyPad or Pro
Mini 3.3V, etc., this EEPROM can also run on 3.3V. This model also has selectable
device addresses using three pins, so we can use up to eight at once on the same bus. An
example:

The pinouts are very simple:

Pin 7 is write protect set this low for read/write or high for read only. You could also
control this in software if necessary. Once again we need to create a slave I2C device
address using pins 1, 2 and 3 these correlate to A2, A1 and A0 in the following table:

So if you were just using one 24LC256, the easiest solution would be to set A0~A2 to
GND which makes your slave address 1010000 or 050 in hexadecimal. There are
several things to understand when it comes to reading and writing our bytes of data. As
this IC has 32 kilobytes of storage, we need to be able to reference each byte in order to
read or write to it. There is a slight catch in that you need more than one byte to reference
32767 (as in binary 32767 is 11111111 0100100 [16 bits]).
So when it comes time to send read and write requests, we need to send two bytes down
the bus one representing the higher end of the address (the first 8 bits from left to right),
and the next one representing the lower end of the address (the final 8 bits from left to
right) see figure 6.1 on page 9 of the data sheet.
An example we need to reference byte number 25000. In binary, 25000 is
0110000110101000. So we split that up into 01100001 and 10101000, then covert the
binary values to numerical bytes with which to send using the Wire.send(). Thankfully
there are two operators to help us with this. This first is >>, known as bitshift right. This
will take the higher end of the byte and drop off the lower end, leaving us with the first 8
bits. To isolate the lower end of the address, we use another operator &, known as bitwise
and. This unassuming character, when used with 0XFF can separate the lower bits for us.
This may seem odd, but will work in the examples below.
Writing data to the 24LC256
Writing data is quite easy. But first remember that a byte of data is 11111111 in binary, or
255 in decimal. First we wake up the I2C bus with
Wire.beginTransmission(0x50); // if pins A0~A2 are set to GND

then send down some data. The first data are the two bytes representing the address
(25000) of the byte (12) we want to write to the memory.
Wire.send(25000 >> 8); // send the left-hand side of the address down
Wire.send(25000 & 0xFF); // send the right-hand side of the address down

And finally, we send the byte of data to store at address 25000, then finish the
connection:
Wire.send(12);
Wire.endTransmission();

There we have it. Now for getting it back

Reading data from the 24LC256


Reading is quite similar. First we need to start things up and move the pointer to the data
we want to read:
Wire.beginTransmission(0x50); // if pins A0~A2 are set to GND
Wire.send(25000 >> 8); // send the left-hand side of the address down
Wire.send(25000 & 0xFF); // send the right-hand side of the address down
Wire.endTransmission();

Then, ask for the byte(s) of data starting at the current address:
Wire.beginTransmission(0x50); // if pins A0~A2 are set to GND
Wire.requestFrom(0x50,1);
Wire.receive(incomingbyte);
In this example, incomingbyte is a byte variable used to store the data we retrieved from the IC.

Example 21.2
Now we have the theory, lets put it into practice with the test circuit below, which
contains two 24LC256 EEPROMs. To recreate this you will need:

Arduino Uno/Duemilanove or Freetronics TwentyTen board


A large solderless breadboard
Two Microchip 24LC256 EEPROMs
Two 4.7 kilo ohm resistors
Hook-up wires
Two 0.1 uF ceramic capacitors

Here is the schematic:

the board layout:

and the example sketch. Note that the device addresses in the sketch match the schematic
above. If for some reason you are wiring your 24LC256s differently, you will need
to recalculate your device addresses. To save time with future coding, we have our own
functions for reading and writing bytes to the EEPROM readData() and writeData().
Consider the sketch for our example: (download sketch)
/*
Example 21.2 Reading and writing data to Microchip 24LC256 EEPROMS over
I2C
tronixstuff.com/tutorials > Chapter 21 CC by-sa v3.0
*/
#include "Wire.h"
// for I2C
#define chip1 0x50
// device address for left-hand chip on our
breadboard
#define chip2 0x51
// and the right
// always have your values in variables
byte d=0; // example variable to handle data going in and out of
EERPROMS
void setup()
{
Serial.begin(9600); // for screen output
Wire.begin();
// wake up, I2C!
}
void writeData(int device, unsigned int add, byte data)
// writes a byte of data 'data' to the chip at I2C address 'device', in
memory location 'add'
{
Wire.beginTransmission(device);
Wire.send((int)(add >> 8));
// left-part of pointer address
Wire.send((int)(add & 0xFF)); // and the right
Wire.send(data);
Wire.endTransmission();
delay(10);
}
byte readData(int device, unsigned int add) // reads a byte of data from
memory location 'add' in chip at I2C address 'device'
{
byte result; // returned value
Wire.beginTransmission(device); // these three lines set the pointer
position in the EEPROM
Wire.send((int)(add >> 8));
// left-part of pointer address
Wire.send((int)(add & 0xFF)); // and the right
Wire.endTransmission();
Wire.requestFrom(device,1); // now get the byte of data...

result = Wire.receive(); return result; // and return it as a result of


the function readData
}
void loop()
{
Serial.println("Writing data...");
for (int a=0; a<20; a++)
{
writeData(chip1,a,a);
writeData(chip2,a,a); // looks like a tiny EEPROM RAID solution!
}
Serial.println("Reading data...");
for (int a=0; a<20; a++)
{
Serial.print("chip1 pointer ");
Serial.print(a);
Serial.print(" holds ");
d=readData(chip1,a);
Serial.println(d, DEC);
}
for (int a=0; a<20; a++)
{
Serial.print("chip2 pointer ");
Serial.print(a);
Serial.print(" holds ");
d=readData(chip2,a);
Serial.println(d, DEC);
}
}
And the output from the example sketch:

Although the sketch in itself was simple, you now have the functions to read and write
byte data to EEPROMS. Now it is up to your imagination to take use of the extra
memory.

Tutorial: Arduino and the AREF pin


Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
The first chapter is here, the complete series is detailed here. Please note from November
1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
Today we are going to spend some time with the AREF pin what it is, how it works and
why you may want to use it.
First of all, here it is on our boards:

Uno/TwentyTen AREF

Mega AREF
[Please read the entire article before working with your hardware]
In chapter one of this series we used the analogRead() function to measure a voltage that
fell between zero and five volts DC. In doing so, we used one of the six analog input
pins. Each of these are connected to ADC (analog to digital conversion) pins in the
Arduinos microcontroller. And the analogRead() function returned a value that fell
between 0 and 1023, relative to the input voltage.
But why is the result a value between 0~1023? This is due to the resolution of the ADC.
The resolution (for this article) is the degree to which something can be represented
numerically. The higher the resolution, the greater accuracy with which something can be
represented. We call the 5V our reference voltage.
We measure resolution in the terms of the number of bits of resolution. For example, a 1bit resolution would only allow two (two to the power of one) values zero and one. A 2bit resolution would allow four (two to the power of two) values zero, one, two and
three. If we tried to measure a five volt range with a two-bit resolution, and the measured
voltage was four volts, our ADC would return a value of 3 as four volts falls between
3.75 and 5V.
It is easier to imagine this with the following image:

So with our example ADC with 2-bit resolution, it can only represent the voltage with
four possible resulting values. If the input voltage falls between 0 and 1.25, the ADC
returns 0; if the voltage falls between 1.25 and 2.5, the ADC returns a value of 1. And so
on.
With our Arduinos ADC range of 0~1023 we have 1024 possible values or 2 to the
power of 10. So our Arduinos have an ADC with a 10-bit resolution. Not too shabby at

all. If you divide 5 (volts) by 1024, the quotient is 0.00488 so each step of the ADC
represents 4.88 millivolts.
However not all Arduino boards are created equally. Your default reference voltage of
5V is for Arduino Duemilanoves, Unos, Megas, Freetronics Elevens and others that have
an MCU that is designed to run from 5V. If your Arduino board is designed for 3.3V, such
as an Arduino Pro Mini-3.3 your default reference voltage is 3.3V. So as always, check
your boards data sheet.
What if we want to measure voltages between 0 and 2, or 0 and 4.6? How would the
ADC know what is 100% of our voltage range?
And therein lies the reason for the AREF pin! AREF means Analogue REFerence. It
allows us to feed the Arduino a reference voltage from an external power supply. For
example, if we want to measure voltages with a maximum range of 3.3V, we would feed
a nice smooth 3.3V into the AREF pin perhaps from a voltage regulator IC. Then the
each step of the ADC would represent 3.22 millivolts.
Interestingly enough, our Arduino boards already have some internal reference voltages
to make use of. Boards with an ATmega328 microcontroller also have a 1.1V internal
reference voltage. If you have a Mega (!), you also have available reference voltages of
1.1 and 2.56V. At the time of writing the lowest workable reference voltage would be
1.1V.
So how do we tell our Arduinos to use AREF? Simple. Use the function
analogReference(type); in the following ways:
For Duemilanove and compatibles with ATmega328 microcontrollers:

analogReference(INTERNAL); selects the internal 1.1V reference voltage


analogReference(EXTERNAL); selects the voltage on the AREF pin (that must
be between zero and five volts DC)
And to return to the internal 5V reference voltage use
analogReference(DEFAULT);

If you have a Mega:

analogReference(INTERNAL1V1); selects the internal 1.1V reference voltage


analogReference(INTERNAL2V56); selects the internal 2.56V reference
voltage
analogReference(EXTERNAL); selects the voltage on the AREF pin (that must
be between zero and five volts DC)
And to return to the internal 5V reference voltage
use analogReference(DEFAULT)

Note you must call analogReference() before using analogRead(); otherwise you will
short the internal reference voltage to the AREF pin possibly damaging your board. If
unsure about your particular board, ask the supplier or perhaps in our Google Group.
Now that we understand the Arduino functions, lets look at some ways to make a
reference voltage. The most inexpensive method would be using resistors as a voltage
divider. For example, to halve a voltage, use two identical resistors as such:

For a thorough explanation on dividing voltage with resistors, please read this article. Try
and use resistors with a low tolerance, such as 1%, otherwise your reference voltage may
not be accurate enough. However this method is very cheap.
A more accurate method of generating a reference voltage is with a zener diode. Zener
diodes are available in various breakdown voltages, and can be used very easily. Here is
an example of using a 3.6V zener diode to generate a 3.6V reference voltage:

For more information about zener (and other diodes) please read this article. Finally, you
could also use a linear voltage regulator as mentioned earlier. Physically this would be
the easiest and most accurate solution, however regulators are not available in such a
wide range nor work with such low voltages (i.e. below 5V).
Finally, when developing your sketch with your new AREF voltage for analogRead();,
dont forget to take into account the mathematics of the operation. For example, if you
have a reference voltage of 5V, divide it by 1024 to arrive at a value of 4.88 millivolts per
analogRead() unit. Or as in the following example, if you have a reference voltage of
1.8V, dividing it by 1024 gives you 1.75 millivolts per analogRead() unit: (download
sketch)
/*
Example 22.1 Measuring range of analogRead() using a 1.8V AREF
voltage
tronixstuff.com/tutorials CC by-sa-nc
*/
int analoginput = 0; // our analog pin
int analogamount = 0; // stores incoming value
float percentage = 0; // used to store our percentage value
float voltage =0; // used to store voltage value
void setup()
{
Serial.begin(9600);
analogReference(EXTERNAL); // use AREF for reference voltage
}
void loop()
{
delay(200);
analogamount=analogRead(analoginput);
percentage=(analogamount/1024)*100;
voltage=analogamount*1.75; // in millivolts
Serial.print("Percentage of AREF: ");
Serial.println(percentage,2);
Serial.print("voltage on analog input (mV): ");
Serial.println(voltage,2);
}

So if necessary, you can now reduce your voltage range for analog inputs and measure
them effectively.

Tutorial: Arduino and the DS touch screen


This is chapter twenty-three of a series originally titled Getting Started/Moving
Forward with Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here.
Welcome back!
Today we are going to spend some time with a touch screen very similar to the ones
found in a Nintendo DS gaming unit. In doing so, we can take advantage of a more
interesting and somewhat futuristic way of gathering user input. Please note that in order
to use the screen without going completely insane, you will need the matching breakout
board, as shown in the following image:
SHAPE \* MERGEFORMAT

The flimsy flexible PCB runner is inserted into the plastic socket on the breakout board
be careful not to crease the PCB nor damage it as it can be rather easy to do so. (The
screen can be easy to break as well) However dont let that put you off. You will most
likely want to solder in some header pins for breadboard use, or sockets to insert wires.
For this article it is being used with pins for a breadboard.
Before we start to use the screen, lets have a quick investigation into how they actually
work. Instead of me trying to paraphrase something else, there is a very good explanation
in the manufacturers data sheet. So please read the data sheet then return. Theoretically

we can consider the X and Y axes to be two potentiometers (variable resistors) that can be
read with the analogRead() function. So all we need to do is use two analog inputs, one
to read the X-axis value and one for the Y-axis value.
However, as always, life isnt that simple. Although there are only four wires to the
screen, the wires purpose alters depending on whether we are measuring the X- or Yaxis. Which sounds complex but is not. Using the following example, we can see how it
all works.
Example 23.1
In this example, we will read the X- and Y-axis values returned from the touch screen and
display them on an LCD module. (Or you could easily send the values to the serial
monitor window instead). From a hardware perspective, you will need:

Arduino Uno/Duemilanove or 100% compatible board


DS touch screen and breakout board ready for use
Solderless breadboard and some jumper wires
Arduino-ready LCD setup. If you are unsure about using LCDs, please revisit
chapter two of my tutorials.

Connection of the touch screen to the Arduino board is simple, Arduino analog (yes,
analog - more on this later) pins A0 to Y1, A1 to X2, A2 to Y2 and A3 to X1 as below:

Mounting the rest for demonstration purposes is also a simple job. Hopefully by now you
have a test LCD module for easy mounting

I have mounted the touch screen onto the breadboard with some spare header pins, they
hold it in nicely for testing purposes. Also notice that the touch screen has been flipped
over, the sensitive side is now facing up. Furthermore, dont forget to remove the
protective plastic coating from the screen before use.
From a software (sketch) perspective we have to do three things read the X-axis value,
the Y-axis value, then display them on the LCD. As we (should) know from the data
sheet, to read the X-axis value, we need to set X1 as 5V, X2 as 0V (that is, GND) and
read the value from Y2. As described above, we use the analog pins to do this. (You can
use analog pins as input/output lines in a similar method to digital pins more
information here. Pin numbering continues from 13, so analog 0 is considered to be pin
14, and so on). In our sketch (below) we have created a function to do this and then return
the X-axis value.
The Y-axis reading is generated in the same method, and is quite self-explanatory. The
delay in each function is necessary to allow time for the analog I/O pins to adjust to their
new roles as inputs or outputs or analog to digital converters. Here is our sketch:
(download)
/* Example 23.1 - Arduino and touch screen
http://tronixstuff.com/tutorials > Chapter 23
CC by-sa-nc */

#include <LiquidCrystal.h> // we need this library for the LCD commands


LiquidCrystal lcd(12, 11, 5, 4, 2, 3); // your pins may vary
int x,y = 0;
void setup()
{
lcd.begin(20,4); // need to specify how many columns and rows are in the
LCD unit
lcd.clear();
}
int readX() // returns the value of the touch screen's X-axis
{
int xr=0;
pinMode(14, INPUT);
// A0
pinMode(15, OUTPUT);
// A1
pinMode(16, INPUT);
// A2
pinMode(17, OUTPUT);
// A3
digitalWrite(15, LOW); // set A1 to GND
digitalWrite(17, HIGH); // set A3 as 5V
delay(5); // short delay is required to give the analog pins time to
adjust to their new roles
xr=analogRead(0); // return xr;
}
int readY() // returns the value of the touch screen's Y-axis
{
int yr=0;
pinMode(14, OUTPUT);
// A0
pinMode(15, INPUT);
// A1
pinMode(16, OUTPUT);
// A2
pinMode(17, INPUT);
// A3
digitalWrite(14, LOW); // set A0 to GND
digitalWrite(16, HIGH); // set A2 as 5V
delay(5); // short delay is required to give the analog pins time to
adjust to their new roles
yr=analogRead(1); //
return yr;
}
void loop()
{
lcd.setCursor(0,0);
lcd.print(" x = ");
x=readX();
lcd.print(x, DEC);
y=readY();
lcd.setCursor(0,1);
lcd.print(" y = ");
lcd.print(y, DEC);
delay (200);
}

Next, lets have a look at this example in action. The numbers on the LCD may be not
what you expected
The accuracy of the screen is not all that great however first take into account the price
of the hardware before being too critical. Note that there are values returned even when
the screen is not being pressed, we could perhaps call these idle values. Later on you

will learn tell your sketch to ignore these values if waiting for user input, as they will note
that nothing has been pressed. Furthermore, the extremities of the screen will return odd
values, so remember to take this into account when designing bezels or mounting
hardware for your screen.
Each touch screen will have different values for each X and Y position, and that is why
most consumer hardware with touch screens has calibration functions to improve
accuracy. We can now use the X and Y values in sketches to determine which part of the
screen is being touched, and act on that touch.
In order to program our sketches to understand which part of the screen is being touched,
it will help to create a map of the possible values available. You can determine the
values using the sketch from example 23.1, then use the returned values as a reference for
designing the layout of your touch interface. For example, the following is a map of my
touch screen:

Example 23.2
For the next example, I would like to have four zones on my touch screen, to use as
virtual buttons for various things. The first thing to do is draw a numerical map of my
touch screen, in order to know the minimum and maximum values for both axes for each
zone on the screen:

At this point in the article I must admit to breaking the screen. Upon receiving the new
one I remeasured the X and Y points for this example and followed the process for
defining the numerical boundaries for each zone is completed by finding average midpoints along the axes and allowing some tolerance for zone boundaries.
Now that the values are known, it is a simple matter of using mathematical comparison
and Boolean operators (such as >, <, &&, etc) in a sketch to determine which zone a
touch falls into, and to act accordingly. So for this example, we will monitor the screen
and display on the LCD screen which area has been pressed. The hardware is identical to
example 23.1, and our touch screen map will be the one above. So now we just have to
create the sketch.
After reading the values of the touch screen and storing them into variables x and y, a
long ifthenelse if loop occurs to determine the location of the touch. Upon
determining the zone, the sketch calls a function to display the zone type on the LCD. Or
if the screen is returning the idle values, the display is cleared. So have a look for
yourself with the example sketch: (download)
/*
Example 23.2 - Arduino and touch screen - four zone demonstration
http://tronixstuff.com/tutorials > Chapter 23 CC by-sa-nc
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
LiquidCrystal lcd(12, 11, 5, 4, 2, 3); // your pins may vary
int x,y = 0;
int d = 500; // used for display delay
void setup()
{

lcd.begin(20,4); // need to specify how many columns and rows are in the
LCD unit
lcd.clear();
}
int readX() // returns the value of the touch screen's X-axis
{
int xr=0;
pinMode(14, INPUT);
// A0
pinMode(15, OUTPUT);
// A1
pinMode(16, INPUT);
// A2
pinMode(17, OUTPUT);
// A3
digitalWrite(15, LOW); // set A1 to GND
digitalWrite(17, HIGH); // set A3 as 5V
delay(5); // short delay is required to give the analog pins time to
adjust to their new roles
xr=analogRead(0); // return xr;
}
int readY() // returns the value of the touch screen's Y-axis
{
int yr=0;
pinMode(14, OUTPUT);
// A0
pinMode(15, INPUT);
// A1
pinMode(16, OUTPUT);
// A2
pinMode(17, INPUT);
// A3
digitalWrite(14, LOW); // set A0 to GND
digitalWrite(16, HIGH); // set A2 as 5V
delay(5); // short delay is required to give the analog pins time to
adjust to their new roles
yr=analogRead(1); // return yr;
}
// the next four functions just display a zone label on the LCD
void displayA()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("AAAAAAAAAA");
lcd.setCursor(0,1);
lcd.print("AAAAAAAAAA");
delay(d);
}
void displayB()
{
lcd.clear();
lcd.setCursor(10,0);
lcd.print("BBBBBBBBBB");
lcd.setCursor(10,1);
lcd.print("BBBBBBBBBB");
delay(d);
}
void displayC()
{
lcd.clear();
lcd.setCursor(0,2);
lcd.print("CCCCCCCCCC");
lcd.setCursor(0,3);
lcd.print("CCCCCCCCCC");
delay(d);

}
void displayD()
{
lcd.clear();
lcd.setCursor(10,2);
lcd.print("DDDDDDDDDD");
lcd.setCursor(10,3);
lcd.print("DDDDDDDDDD");
delay(d);
}
void loop()
{
// get values from touch screen
x=readX();
y=readY();
// now determine where the touch was located on the screen
if (y>510 && x>520 && x<1000 && y <1000)
{
displayA();
} else
if (y>510 && x<510)
{
displayB();
} else
if (y<500 && x>520)
{
displayC();
} else
if (y<500 && x<510)
{
displayD();
} else
if (x>1000 && y>1000)
{
lcd.clear();
}
}

And see it in operation:


So there you have it, I hope you enjoyed reading this as much as I did writing it. Now
you should have the ability to use a touch screen in many situations you just need to
decide how to work with the resulting values from the screen and go from there.

Tutorial: Arduino and monochrome LCDs


Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is chapter twenty-four of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here. Please note from November
1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
The purpose of this article is to summarise a range of affordable monochrome liquidcrystal display units that are available to work with our Arduino; and to replace the
section about LCDs in chapter two of this series. We will first examine some fixedcharacter and then graphical LCD units in this article. So lets go!
Fixed-character LCD modules
When shopping around for LCD modules, these will usually be the the most common
found in retail outlets. Their size is normally measured by the number of columns and
rows of characters in the display. For example, the three LCDs below are 82, 162 and
204 characters in size:

Currently, most LCDs should have a backlight of some sort, however you may come
across some heavily-discounted models on (for example) eBay that are not. Character,
background and backlight colours can vary, for example:

Interfacing these screens with our Arduino boards is very easy, and there are several ways
to do so. These interface types can include four- and eight-bit parallel, three-wire, serial,
I2C and SPI interfaces; and the LCD price is usually inversely proportional to the ease of
interface (that is, parallel are usually the cheapest).
Four-bit parallel interface
This is the cheapest method of interface, and our first example for this article. Your LCD
will need a certain type of controller IC called a Hitachi HD44780 or compatible such as
the KS0066. From a hardware perspective, there are sixteen pins on the LCD. These are
usually in one row:

or two rows of eight:

The pin labels for our example are the following:


1. GND
2. 5V (careful! Some LCDs use 3.3 volts adjust according to LCD data sheet from
supplier)
3. Contrast
4. RS
5. RW
6. Enable
7. DB0 (pins DB0~DB7 are the data lines)
8. DB1
9. DB2
10. DB3
11. DB4
12. DB5
13. DB6
14. DB7
15. backlight + (unused on non-backlit LCDs) again, check your LCD data sheet as
backlight voltages can vary.
16. backlight GND (unused on non-backlit LCDs)
As always, check your LCDs data sheet before wiring it up.
Some LCDs may also have the pinout details on their PCB if you are lucky, however it
can be hard to decipher:

Now lets connect our example 162 screen to our Arduino using the following diagram.

Our LCD runs from 5V and also has a 5V backlight yours may differ, so check the
datasheet:

(Circuit layout created using Fritzing)


Notice how we have used six digital output pins on the Arduino, plus ground and 5V. The
10k ohm potentiometer connected between LCD pins 2, 3 and 5 is used to adjust the
display contrast. You can use any digital out pins on your Arduino, just remember to take
note of which ones are connected to the LCD as you will need to alter a function in your
sketch. If your backlight is 3.3V, you can use the 3.3V pin on the Arduino.
From a software perspective, we need to use the LiquidCrystal() library. This library
should be pre-installed with the Arduino IDE. So in the start of your sketch, add the
following line:
#include <LiquidCrystal.h>

Next, you need to create a variable for our LCD module, and tell the sketch which pins
are connected to which digital output pins. This is done with the following function:

LiquidCrystal lcd(4,5,6,7,8,9);

The parameters in the brackets define which digital output pins connect to (in order) LCD
pins: RS, enable, D4, D5, D6, and D7.
Finally, in your void setup(), add the line:
lcd.begin(16,2);

This tells the sketch the dimensions in characters (columns, rows) of our LCD module
defined as the variable lcd.
Example 24.1
In this example we will get started with out LCD by using the basic setup and functions.
To save space the explanation of each function will be in the sketch itself. Please note
that you do not have to use an Arduino Mega it is used in this article as my usual
TwentyTens and other boards are occupied elsewhere.
/*
Example 24.1 - LCD demonstration
http://tronixstuff.com/tutorials > Chapter 24
CC by-sa-nc liquidCrystal library originally added 18 Apr 2008 by David
A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net,
http://www.adafruit.com)
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4,5,6,7,8,9); // define our LCD and which pins to user
int a = 63;
int d = 3000; // used for display delayfloat
float b = 3.1415926;
void setup()
{
lcd.begin(16, 2); // need to specify how many columns and rows are in
the LCD unit
lcd.clear();
// this clears the LCD. You can use this at any time
}
void loop()
{
lcd.clear();
lcd.setCursor(0,0);
// positions starting point on LCD, column 0, row 0 (that is, the top
left of our LCD)
lcd.print("Hello!");
// prints "Hello" at the LCD's cursor position defined above
lcd.setCursor(0,1);
// positions starting point on LCD, column 0, row 1 (that is, the bottom
left of our LCD)
lcd.println("This is fun
");
// note the rest of the line is padded out with spaces
delay(d);

lcd.clear();
lcd.setCursor(0,0);
lcd.print("a = ");
lcd.print(a); // this will immediately follow "a = "
lcd.setCursor(0,1);
lcd.print("pi = ");
lcd.print(b,7);
// the 7 means 7 decimal places. You can also replace this with DEC,
HEX, BIN as with
// other *.print functions, as such:
delay(d);
lcd.clear();
lcd.home(); // sets cursor back to position 0,0 - same as
lcd.setCursor(0,0);
lcd.print("a (HEX) = ");
lcd.print(a, HEX); // this will immediately follow "a = "
lcd.setCursor(0,1);
lcd.print("a (BIN) = ");
lcd.print(a,BIN);
delay(d);
lcd.noDisplay(); // turns off the display, leaving currently-displayed
data as is
delay(d);
// however this does not control the backlight
lcd.display();
// resumes display
delay(d);
}

And here is a quick video of the example 24.1 sketch in action:


There are also a some special effects that we can take advantage of with out display units
in that we can actually define our own characters (up to eight per sketch). That is,
control the individual dots (or pixels) that make up each character. With the our character
displays, each character is made up of five columns of eight rows of pixels, as illustrated
in the close-up below:

In order to create our characters, we need to define which pixels are on and which are off.
This is easily done with the use of an array (array? see chapter four). For example, to
create a solid block character as shown in the image above, our array would look like:

byte a[8] = {

B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111}

Notice how we have eight elements, each representing a row (from top to bottom), and
each element has five bits representing the pixel column for each row. The next step is
to reference the custom characters array to a reference number (0~7) using the following
function within void setup():
lcd.createChar(0,a);

Now when you want to display the custom character, use the following function:
lcd.write(0);

where 0 is the memory position of the character to display.


To help make things easier, there is a small website that does the array element creation
for you.
Example 24.2
Now lets display a couple of custom characters to get a feel for how they work. In the
following sketch there are three defined characters:
/* Example 24.2 - LCD custom character demonstration
http://tronixstuff.com/tutorials > Chapter 24 CC by-sa-nc
liquidCrystal library originally added 18 Apr 2008 by David A. Mellis
library modified 5 Jul 2009 by Limor Fried (http://www.ladyada.net,
http://www.adafruit.com)
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4,5,6,7,8,9); // define our LCD and which pins to use
int d = 3000; // used for display delay
byte a[8] = { B00000, B00000, B00000, B00100, B00100,
B00000, B00000, B00000};
byte b[8] =
{ B00000, B00000, B10001, B10001, B10001, B10001, B00000, B00000
};
byte c[8] =
{ B11111, B10001, B10001, B10001, B10001, B10001, B10001, B11111
};
void setup()
{
lcd.createChar(0,a); // define our characters into the sketch as
variables

lcd.createChar(1,b);
lcd.createChar(2,c);
lcd.begin(16, 2); // need to specify how many columns and rows are in
the LCD unit
lcd.clear();
// this clears the LCD. You can use this at any time
}
void loop()
{
for (int z=0; z<16; z++)
{
lcd.setCursor(z,0);
lcd.write(0); // write the first character
delay(250);
lcd.setCursor(z,0);
lcd.write(1); // write the second character
delay(250);
lcd.setCursor(z,0);
lcd.write(2); // write the third character
delay(250);
lcd.setCursor(z,0);
lcd.write(1); // write the second character
delay(250);
lcd.setCursor(z,0);
lcd.write(0); // write the first character
delay(250);
}
delay(1000);
lcd.clear();
}

And here is a quick video of the example 24.2 sketch in action:


So there you have it a summary of the standard parallel method of connecting an
LCD to your Arduino. Now lets look at the next type:
Three-wire LCD interface
If you cannot spare many digital output pins on your Arduino, only need basic text
display and dont want to pay for a serial or I2C LCD, this could be an option for you. A
4094 shift register IC allows use of the example HD44780 LCD with only three digital
output pins from your Arduino. The hardware is connected as such:

And in real life:

From a software perspective, we need to use the LCD3Wire library, which you can
download from here. To install the library, copy the folder within the .zip file to your
systems \Arduino-2x\hardware\libraries folder and restart the Arduino IDE. Then, in the
start of your sketch, add the following line:
#include <LCD3Wire.h>

Next, you need to create a variable for our LCD module, and tell the sketch which of the
4094s pins are connected to which digital output pins as well as define how many
physical lines are in the LCD module. This is done with the following function:
LCD3Wire lcd = LCD3Wire(2, 11, 12, 10); The parameters in the brackets are the
number of lines in the LCD and the digital output pins connected to 4094 pin numbers 2, 1 and 3.

Finally, in your void setup(), add the line:


lcd.init();

The number of available LCD functions in the LCD3wire library are few that is the
current trade-off with using this method of LCD connection you lose LCD functions
but gain Arduino output pins. In the following example, we will demonstrate all of the
available functions within the LCD3Wire library.
Example 24.3
/*
Example 24.3 - 3-wire LCD demonstration
http://tronixstuff.com/tutorials > chapter 24
Contains copyleft code from
http://www.arduino.cc/playground/Code/LCD3wires
and LCD3Wire library */
#include // we need this library for the LCD commands
LCD3Wire lcd = LCD3Wire(2, 11, 12, 10); //create object to control an
LCD.
void setup() {
lcd.init();
}
void loop()
{
lcd.printIn("LCD3Wire library"); // displays text on the LCD
lcd.cursorTo(2,0); // rows are 1... and columns are 0...
lcd.printIn("-tronixstuff.com");
delay(1000);
lcd.leftScroll(16,500);
// scrolls the entire display 16 chars to left, 100ms per charactershift
delay(1000);
lcd.clear(); // clears the display
}

And as always, lets see it in action. The LCD update speed is somewhat slower than
using the parallel interface, this is due to the extra handling of the data by the 4094 IC:
Now for some real fun with:
Graphic LCD modules
(Un)fortunately there are many graphic LCD modules on the market. To keep things
relatively simple, we will examine two one with a parallel data interface and one with a
serial data interface.
Parallel interface
Our example in this case is a 128 by 64 pixel unit with a KS0108B parallel interface:

For the more technically-minded here is the data sheet. From a hardware perspective
there are twenty interface pins, and were going to use all of them. For breadboard use,
solder in a row of header pins to save your sanity!
This particular unit runs from 5V and also has a 5V backlight. Yours may vary, so
check and reduce backlight voltage if different.
You will again need a 10k ohm potentiometer to adjust the display contrast. Looking at
the image above, the pin numbering runs from left to right. For our examples, please
connect the LCD pins to the following Arduino Uno/Duemilanove sockets:

1. 5V
2. GND
3. centre pin of 10k ohm potentiometer
4. D8
5. D9
6. D10
7. D11
8. D4
9. D5
10. D6
11. D7
12. A0
13. A1
14. RST
15. A2
16. A3
17. A4
18. outer leg of potentiometer; connect other leg to GND
19. 5V
20. GND
A quick measurement of current shows my TwentyTen board and LCD uses 20mA with
the backlight off and 160mA with it on. The display is certainly readable with the
backlight off, but it looks a lot better with it on.
From a software perspective we have another library to install. By now you should be
able to install a library, so download this KS0108 library and install it as usual. Once
again, there are several functions that need to be called in order to activate our LCD. The
first of these being:
GLCD.Init(NON_INVERTED);

which is placed within void setup(); The parameter sets the default pixel status. That is,
with NON_INVERTED, the default display is as you would expect, pixels off unless
activated; whereas INVERTED causes all pixels to be on by default, and turned off when
activated. Unlike the character LCDs we dont have to create an instance of the LCD in
software, nor tell the sketch which pins to use this is already done automatically. Also
please remember that whenever coordinates are involved with the display, the X-axis is
0~127 and the Y-axis is 0~63.
There are many functions available to use with the KS0108 library, so lets try a few of
them out in this first example. Once again, we will leave the explanation in the sketch, or
refer to the librarys page in the Arduino website. My creative levels are not that high, so
the goal is to show you how to use the functions, then you can be creative on your own
time

Example 24.4
This example demonstrate a simpler variety of graphic display functions.
/* Example 24.4 - KS0108 Graphic LCD demonstration
http://tronixstuff.com/tutorials > chapter 24 CC by-sa-nc
*/
#include <ks0108.h> // library header
int xc, yc = 0;
int d=1000; // for delay use
void setup()
{
GLCD.Init(NON_INVERTED);
// initialise the library with pixel default
as off
GLCD.ClearScreen();
// clear the LCD
randomSeed(analogRead(5));
}
void loop()
{
GLCD.DrawRect(0, 0, 127, 63, BLACK);
// draw an open rectangle that spans the extremties of the LCD
GLCD.DrawRect(10, 10, 117, 53, BLACK);
GLCD.DrawRect(20, 20, 107, 43, BLACK);
GLCD.DrawRect(30, 30, 97, 33, BLACK);
delay(d);
GLCD.ClearScreen(); // clear the LCD
for (int a=1; a<20; a++)
{
GLCD.DrawCircle(63,31,a,BLACK);
// draws a circle with centre at 61,31; radius of a, with black pixels
delay(d-800);
GLCD.DrawCircle(63,31,a,WHITE); // draws the same circle with the pixels
off
}
delay(d);
GLCD.ClearScreen(); // clear the LCD
for (int a=0; a<128; a++)
{
GLCD.DrawVertLine(a, 0, 63, BLACK);
// draws a vertical line from xy position a, 0 of length 63
delay(d-950);
}
delay(d-800);
for (int a=0; a<128; a++)
{
GLCD.DrawVertLine(a, 0, 63, WHITE);
delay(d-950);
}
GLCD.ClearScreen(); // clear the LCD
for (int a=0; a<64; a++)
{
GLCD.DrawHoriLine(0, a, 127, BLACK);
// draws a horizontal line from xy position 0, a of length 127
delay(d-950);
}
for (int a=0; a<64; a++)

{
GLCD.DrawHoriLine(0, a, 127, WHITE);
delay(d-950);
}
GLCD.ClearScreen(); // clear the LCD
GLCD.DrawRoundRect(30, 30, 20,20, 5,BLACK);
// draw a rectangle with rounded edges: x, y, width, height, radius of
rounded edge, colour
GLCD.DrawRoundRect(60, 30, 20,20, 5,BLACK);
delay(d);
GLCD.ClearScreen(); // clear the LCD
delay(d);
GLCD.FillRect(30, 30, 30, 10, BLACK);
// draws a filled rectangle: x, y, width, height, colour
delay(d);
GLCD.ClearScreen(); // clear the LCD
for (int a=0; a<1000; a++)
{
xc=random(0,127);
yc=random(0, 63);
GLCD.SetDot(xc, yc, BLACK);
// turn on a pixel at xc, yc);
delay(2);
}
GLCD.ClearScreen();
// clear the LCD
}

Now lets see all of that in action:


You can also send normal characters to your KS0108 LCD. Doing so allows you to
display much more information in a smaller physical size than using a character LCD.
Furthermore you can mix graphical functions with character text functions with some
careful display planning you can create quite professional installations. With a standard
57 pixel font, you can have eight rows of twenty-one characters each. Doing so is quite
easy, we need to use another two #include statements which are detailed in the following
example. You dont need to install any more library files to use this example. Once again,
function descriptions are in the sketch.
Example 24.5
/* Example 24.5 - KS0108 Graphic LCD demonstration #2
http://tronixstuff.com/tutorials > chapter 24 CC by-sa-nc
*/
#include <ks0108.h> // library for LCD
#include "SystemFont5x7.h"
// we need this for character display, included with ks0108.h download
void setup()
{
GLCD.Init(NON_INVERTED);
// load the GLCD library
GLCD.ClearScreen();
GLCD.SelectFont(System5x7);
// choose font to use (note this needs to match the #include above
}

int j = 24;
void loop()
{
GLCD.ClearScreen();
GLCD.DrawRect(0, 0, 127, 63,BLACK);
GLCD.CursorTo(1, 1);
// set cursor to top left of LCD (uses character coordinates
// not pixel coordinates
GLCD.Puts("Hello, world."); // sends strings to LCD. Does not wrap to
next line!
GLCD.CursorTo(1, 2);
GLCD.Puts("I hope you are ");
GLCD.CursorTo(1, 3);
GLCD.Puts("enjoying this");
GLCD.CursorTo(1, 4);
GLCD.Puts("series of lessons. ");
GLCD.CursorTo(1, 5);
GLCD.Puts("This is from ");
GLCD.CursorTo(1, 6);
GLCD.Puts("chapter ");
GLCD.PrintNumber(j); // sends an integer to the LCD. Does not wrap to
next line either
GLCD.Puts(".");
delay(3000);
GLCD.ClearScreen();
for (int xx=0; xx<21; xx++)
{
for (int yy=0; yy<8; yy++)
{
GLCD.CursorTo(xx, yy); // position the text cursor
GLCD.Puts("#");
delay(50);
}
}
delay(1000);
GLCD.ClearScreen();
}

Again, lets see all of that in action:


If youre looking for a very simple way of using character LCD modules, check this out.

Tutorial: Using analog input for multiple buttons


Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
This is chapter twenty-five of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here. Please note from November
1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
The purpose of this article is demonstrate how you can read many push buttons (used for
user-input) using only one analog input pin. This will allow you to save digital I/O pins
for other uses such as LCD modules and so on. Hopefully you recall how we used
analogRead() in chapter one, and how we used a potentiometer to control menu options
in exercise 10.1. For this article, we will be looking at reading individual presses, not
simultaneous (i.e. detecting multiple button presses).
To recap, an analog input pin is connected to an analog to digital (ADC) converter in our
Arduinos microcontroller. It has a ten bit resolution, and can return a numerical value
between 0 and 1023 which relates to an analog voltage being read of between 0 and 5
volts DC.
Example 25.1
With this sketch:
/* Example 25.1 - Demonstrating analogRead()
http://tronixstuff.com/tutorials > chapter 25
CC by-sa-nc*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 2, 3);
int a=0;
void setup()
{
lcd.begin(20, 4);
pinMode(A5, INPUT);
}
void loop()
{
a = analogRead(5);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" analogRead() ");
lcd.setCursor(0,1);
lcd.print(" value is :");
lcd.print(a);
delay(250);

and in the following short video, we have demonstrated the possible values returned by
measuring the voltage from the centre pin of a 10k ohm potentiometer, which is
connected between 5V and GND:
As the potentiometers resistance decreases, the value returned by analogRead()
increases. Therefore at certain resistance values, analogRead() will return certain
numerical values. So, if we created a circuit with (for example) five buttons that allowed
various voltages to be read by an analog pin, each voltage read would cause
analogRead() to return a particular value. And thus we can read the status of a number of
buttons using one analog pin.
Example 25.2
The following circuit is an example of using five buttons on one analog input, using the
sketch from example 25.1:

And here it is in action:


Where is the current coming from? Using pinMode(A5, INPUT); turns on the internal
pull-up resistor in the microcontroller, which gives us ~4.8V to use. Some of you may
have notice that when the right-most button is pressed, there is a direct short between
A5 and GND. When that button is depressed, the current flow is less than one
milliamp due to the pull-up resistor protecting us from a short circuit. Also note that you
dont have to use A5, any analog pin is fine.

As shown in the previous video clip, the values returned by analogRead() were:

1023 for nothing pressed (default state)


454 for button one
382 for button two
291 for button three
168 for button four
0 for button five

So for our sketches to react to the various button presses, they need to make decisions
based on the value returned by analogRead(). Keeping all the resistors at the same value
gives us a pretty fair spread between values, however the values can change slightly due
to the tolerance of resistors and parasitic resistance in the circuit.
So after making a prototype circuit, you should determine the values for each button, and
then have your sketch look at a range of values when reading the analog pin. Doing so
becomes more important if you are producing more than one of your project, as resistors
of the same value from the same batch can still vary slightly.
Example 25.3
Using the circuit from example 25.2, we will use a function to read the buttons and return
the button number for the sketch to act upon.
/* Example 25.3 - Digital buttons with analog input
http://tronixstuff.com/tutorials > chapter 25 CC by-sa-nc */
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 2, 3);
int a=0;
void setup()
{
lcd.begin(20, 4);
pinMode(A5, INPUT); // sets analog pin for input
}
int readButtons(int pin)
// returns the button number
// int pin is the analog pin
{
int b,c = 0;
c=analogRead(pin); // get the
{
b=0; // buttons have not been
}
else
if (c>440 && c<470)
{
b=1; // button 1 pressed
}
else
if (c<400 && c>370)
{

pressed, or zero for none pressed


number to read
analog value
pressed

if (c>1000)

b=2; // button 2 pressed


}
else
if (c>280 && c<310)
{
b=3; // button 3 pressed
}
else
if (c>150 && c<180)
{
b=4; // button 4 pressed
}
else
if (c<20)
{
b=5; // button 5 pressed
}
return b;
}
void loop()
{
a=readButtons(5);
lcd.clear();
if (a==0) // no buttons pressed
{
lcd.setCursor(0,1);
lcd.print("Press a button");
}
else
if (a>0) // someone pressed a button!
{
lcd.setCursor(0,2);
lcd.print("Pressed button ");
lcd.print(a);
}
delay(1000); // give the human time to read LCD
}

And now our video demonstration:


So now you have a useful method for receiving input via buttons without wasting many
digital input pins. I hope you found this article useful or at least interesting.

Tutorial: Arduino and GSM Cellular Part One


This is the revised, 2012 edition of chapter twenty-six of a series originally titled
Getting Started/Moving Forward with Arduino! by John Boxall A tutorial on
the Arduino universe. The first chapter is here, the complete series is detailed here.
Introduction
We are going to start using our Arduino to communicate over a GSM mobile telephone
network using the SM5100B GSM Cellular Shield:

This is the first of several articles related to the SM5100B GSM shield. My goal is to
illustrate various methods of interaction between an Arduino and the GSM cellular
network using the shield, with which you can then use your existing knowledge to build
upon those methods. For example, in this chapter we will accomplish the following:

Have your Arduino ring your phone upon an event


Being able to turn something on or off by calling your Arduino from any
telephone
Have your Arduino send you an SMS text message upon an event

Things you need to know!

It is assumed that you have an understanding of how to program your Arduino. If


not, start from chapter zero
The GSM shield-related Arduino tutorials use version 23 of the Arduino IDE
not v1.0 or greater.
Sending SMS messages and making phone calls cost real money, so it would be
very wise to use a prepaid cellular account or one that allows infinite calls/SMS
The GSM shield only works with 2G GSM mobile networks operating on the
850, 900 and PCS1800 MHz frequencies. If in doubt, ask your carrier first
Australians you can use any carriers SIM card except for Three
I cannot offer design advice for your project nor detailed technical support for this
article.
If you are working on a college/university project and need specific help talk to
your tutors or academic staff. They get paid to help you.
Please dont make an auto-dialler

Things you need to do!


The GSM shield can often require up to 2A of current in short bursts especially
when turned on, reset, or initiating a call. However your Arduino board can only
supply up to just under 1A. It is highly recommended that you use an external
5V power supply capable of delivering 2A of current from an AC adaptor, large
battery with power regulator, etc. Otherwise there is a very strong probability of
damaging your shield and Arduino. Ignore this at your own risk. When
connecting this supply DO NOT use the DC socket on the Arduino. Instead,
connect the 5V (positive) from the supply to the 5V pin on the GSM shield, and
the negative to the GND pin. For example:

Use a phone to turn off the power-on PIN requirement for your SIM card
Use an antenna! Seriously people, the wire hanging from the shield is not an
antenna. YOU NEED THE ANTENNA! There are two choices. Either use the
smaller one for areas where mobile reception is great, such as this one:

If you are in an area of weaker reception, use an external antenna such as that
used on a motor vehicle. If you are using the larger vehicle-style aerial, you might

find that the plug will not fit to the shields connector. For example, consider the
following:

On the left is the end of the lead from the carphone aerial, the right is the lead from the
GSM shield. Problem! The solution is in the centre: an FME male to SMA male adaptor.
This one came from element-14, part number 1826209 (it is a Multicomp R23-014-00002611000).

Furthermore, care needs to be taken with your GSM shield with regards to the
aerial lead-module connection, it is very fragile:

From a software perspective we will need the NewSoftSerial Arduino library, so


please download and install that before moving on.
And finally, download this document (.pdf). It contains all the AT and ERROR
codes that will turn up when you least expect it. Please review it if you are
presented with a code you are unsure about.

Are you using an Arduino Mega board?


Mega users things will be slightly different for you. Please make sure the TX and RX
pins of your GSM shield DO NOT plug into your Mega. You may wish to bend them out
or trim them if only using with a Mega. Furthermore, run a jumper wire from GSM shield
pin D2 to Mega pin 19, and a jumper from GSM shield pin D3 to Mega pin 18, as shown
below:

You also need to observe the same instructions with regards to the separate power supply
so use an external 5V 2A supply as described in this article. GND on the Arduino also
needs to connect to GND on the shield and your power supply (-). Finally, the example
sketches will be different. Mega will not use the NewSoftSerial library, instead we use the
Serial1 port. Please use the following Mega-equivalent sketches for this article: Example
26.1, 26.2, 26.3 and 26.4.
Now, on with the show
When shipped as new, our shield does not include the 6-pin and 8-pin headers (though it
should for the price cheapskates). So you will need to source your own and solder them
in by inserting them onto the pins of another shield and drop the shield on top, then solder
the shield in nicely.
Initial check does it work?
This may sound like a silly question, but considering the cost of the shield and the
variables involved, it is a good idea to check if your setup is functioning correctly before
moving on. From a hardware perspective for this article, you will need your Arduino
board, the GSM shield with activated SIM card and an aerial, and a range of previously
used components. Make sure your SIM card is set to not require a PIN when the phone is
turned on. You can check and turn this requirement off with your cellphone. For our
initial test, upload the following sketch :
Example 26.1
/* SparkFun Cellular Shield - Pass-Through Sample Sketch
SparkFun Electronics Written by Ryan Owens CC by v3.0 3/8/10
Thanks to Ryan Owens and Sparkfun for sketch */
#include <NewSoftSerial.h> //Include the NewSoftSerial library to send
serial commands to the cellular module.

#include <string.h>
//Used for string manipulations
char incoming_char=0;
//Will hold the incoming character from the
Serial Port.
NewSoftSerial cell(2,3); //Create a 'fake' serial port. Pin 2 is the Rx
pin, pin 3 is the Tx pin.
void setup()
{
//Initialize serial ports for communication.
Serial.begin(9600);
cell.begin(9600);
Serial.println("Starting SM5100B Communication...");
}
void loop()
{
//If a character comes in from the cellular module...
if(cell.available() >0)
{
incoming_char=cell.read();
//Get the character from the cellular
serial port.
Serial.print(incoming_char); //Print the incoming character to the
terminal.
}
//If a character is coming from the terminal to the Arduino...
if(Serial.available() >0)
{
incoming_char=Serial.read(); //Get the character coming from the
terminal
cell.print(incoming_char);
//Send the character to the cellular
module.
}
}

Then connect the GSM shield, aerial, insert the SIM card and apply power. Open the
serial monitor box in the Arduino IDE and you should be presented with the following:

It will take around fifteen to thirty seconds for the text above to appear in full. What you
are being presented with is a log of the GSM modules actions. But what do they all
mean?

+SIND: 1 means the SIM card has been inserted;


the +SIND: 10 line shows the status of the in-module phone book. Nothing to
worry about there for us at the moment;
+SIND: 11 means the module has registered with the cellular network
+SIND: 3 means the module is partially ready to communicate
and +SIND: 4 means the module is registered on the network, and ready to
communicate

If your terminal returned a +SIND 8 instead of 4, that is OK, well sort that out in a
moment.
From this point on, we will need to use a different terminal program, as the Arduino
IDEs serial monitor box isnt made for full two-way communications. You will need a
terminal program that can offer full two-way com port/serial communication. For those
running MS Windows, an excellent option is available here. Its free, however consider
donating for the use of it. For other operating systems, people say this works well.
So now lets try it out with the terminal software. Close your Arduino IDE serial monitor
box if still open, then run your terminal, set it to look at the same serial port as the
Arduino IDE was. Ensure the settings are 9600, 8, N, 1. Then reset your Arduino and the
following should appear:

The next step is to tell the GSM module which network frequency(ies) to use. Please
download this document (.pdf), and view page 127. There is a range of frequency choices
that our module can use. If you dont know which one to use, contact the telephone
company that your SIM card came from. Australia use option 4. Choose your option,
then enter
AT+SBAND=x

(where X is the value matching your required frequency) into the terminal software and
click SEND. Then press reset on the Arduino and watch the terminal display. You should
hopefully be presented with the same text as above, ending with +SIND: 4. If your
module returns +SIND: 4, were ready to move forward.
Our next test is to call our shield. So, pick up a phone and call it. Your shield will return
data to the terminal window, for example:

As you can see, the module returns what is happening. I let the originating phone ring
twice, and the module received the caller ID data (sorry, blacked it out). Some telephone
subscribers accounts dont send caller ID data, so if you dont see your number, no
problem. NO CARRIER occurred when I ended the call. +SIND: 6,1 means the call
ended and the SIM is ready.

The document (.pdf) we downloaded earlier contains a list of AT commands consider


this a guide to the language with which we instruct the GSM module to do things. Lets
try out some more commands before completing our initial test. The first one is:
ATDxxxxxx

which dials a telephone number xxxxxx. For example, to call (212)-8675309 use
ATD2128675309

The next one is


ATH

which hangs up or ends the call. So, lets reach out and touch someone. In the terminal
software, enter your ATDxxxxxxxx command, then hit send. Let your phone ring. Then
enter ATH to end the call. If you are experimenting and want to hang up in a hurry, you
can also hit reset on the Arduino and it will end the call as well as resetting the system. So
by now you should realise the GSM module is controlled by these AT commands.
To use an AT command in a sketch, we use the function
cell.println()

for example, to dial a phone number, we would use


cell.println("ATD2128675309");

To demonstrate this in a sketch, consider:


Example 26.2
A simple sketch to dial a telephone number, wait, then hang up. Replace xxxxxxxx with
the number you wish to call.
/* Example 26.2 GSM shield making and ending a telephone call
http://tronixstuff.com/tutorials > chapter 26 */
#include <NewSoftSerial.h>
//Include the NewSoftSerial library to send serial commands to the
cellular module.
NewSoftSerial cell(2,3); //Create a 'fake' serial port. Pin 2 is the Rx
pin, pin 3 is the Tx pin.
void setup()
{ //Initialize serial ports for communication.
cell.begin(9600);
delay(25000); // give the GSM module time to initialise, locate network
etc.
// this delay time varies. Use example 26.1 sketch to measure the amount
// of time from board reset to SIND: 4, then add five seconds just in
case

}
void loop()
{
cell.println("ATDxxxxxxxxx"); // dial the phone number xxxxxxxxx
// change xxxxxxx to your desired phone number (with area code)
delay(20000); // wait 20 seconds.
cell.println("ATH"); // end call
do // remove this loop at your peril
{
delay(1); }
while (1>0);
}

The sketch in example 26.2 assumes that all is well with regards to the GSM module, that
is the SIM card is ok, there is reception, etc. The delay function in void setup() is used to
allow time for the module to wake up and get connected to the network. Later on we will
read the messages from the GSM module to allow our sketches to deal with errors and so
on. However, you can see how we can simply dial a telephone. You could now have a
home alarm system that can call you upon an event happening, etc.
Another popular function is the SMS or short message service, or text messaging.
Sending text messages from our Arduino
The AT commands for sending text messages are a little more involved, but nothing to
worry about. First, we need to tell the module our SMS will be ASCII text, this is done
with:
AT+CMGF=1

Then we need to give the mobile phone number to send the message to:
AT+CMGS="xxxxxxxxx"

At this stage, there needs to be a small delay, around half a second. Then the module will
expect the contents of the message (maximum 160 characters) followed by the ASCII
equivalent of Ctrl-Z. After sending the message, the module needs around fifteen seconds
to finalise the procedure, so if sending multiple messages, allow for this with a delay()
function.
Do not use cell.println() on the function that sends the message text. Doing so will lock
up your SMS module.
Example 26.3
So lets send a text message. I have tried to simplify the process as much as possible, so
the following sketch is my simple Send an SMS example:
/* Example 26.3 GSM shield sending a SMS text message
http://tronixstuff.com/tutorials > chapter 26 */

#include <NewSoftSerial.h>
NewSoftSerial cell(2,3); // We need to create a serial port on D2/D3 to
talk to the GSM module
char mobilenumber[] = "xxxxxxxxx"; // Replace xxxxxxxx with the
recipient's mobile number
void setup()
{ //Initialize serial ports for communication.
cell.begin(9600);
delay(35000); // give the GSM module time to initialise, locate network
etc.
// this delay time varies. Use example 26.1 sketch to measure the amount
// of time from board reset to SIND: 4, then add five seconds just in
case
}
void loop()
{
cell.println("AT+CMGF=1"); // set SMS mode to text
cell.print("AT+CMGS="); // now send message...
cell.print(34,BYTE); // ASCII equivalent of "
cell.print(mobilenumber);
cell.println(34,BYTE); // ASCII equivalent of "
delay(500); // give the module some thinking time
cell.print("They call me the count... because I like to count! Ah ha ha
ha");
// our message to send
cell.println(26,BYTE); // ASCII equivalent of Ctrl-Z
delay(15000); // the SMS module needs time to return to OK status
do // You don't want to send out multiple SMSs.... or do you?
{
delay(1);
}
while (1>0);
}

Now we can consider sending data and a fixed text message. To do so, we need to split
the procedure of sending a text message into three parts: the sending data, the message
and any data, and ending the procedure. This is done in the following example. The
sketch generates a random number between 0 and 99. Then it counts from 0 to 99, and
when the count reaches the random number, it sends the text message containing an
initial note and the random number.
Example 26.4
/* Example 26.4 Send a text message upon an event occurring
http://tronixstuff.com/tutorials > chapter 26 */
#include <NewSoftSerial.h>
NewSoftSerial cell(2,3); // We need to create a serial port on D2/D3 to
talk to the GSM module
char mobilenumber[]="xxxxxxxx"; // Replace xxxxxxxx with the
recipient's mobile number
char textmessage[160]; // used to hold contents of message to send
int b=0;
void setup()
{ //Initialize serial ports for communication.
cell.begin(9600);

delay(35000); // give the GSM module time to initialise, locate network


etc.
// this delay time varies. Use example 26.1 sketch to measure the amount
// of time from board reset to SIND: 4, then add five seconds just in
case
pinMode(13, OUTPUT); // use the LED for status
randomSeed(analogRead(0));
}
void startSMS()
// function to send a text message
{
digitalWrite(13, HIGH);
cell.println("AT+CMGF=1"); // set SMS mode to text
cell.print("AT+CMGS=");
cell.print(34,BYTE); // ASCII equivalent of "
cell.print(mobilenumber);
cell.println(34,BYTE); // ASCII equivalent of "
delay(500); // give the module some thinking time
}
void endSMS()
{
cell.println(26,BYTE); // ASCII equivalent of Ctrl-Z
delay(15000); // the SMS module needs time to return to OK status
digitalWrite(13, LOW);
}
void loop()
{
b=random(0, 99);
for (int a=0; a<100; a++)
{
if (a==b)
{
startSMS();
cell.print("The random number is: ");
cell.print(b);
endSMS();
}
}
do
{
delay(1);
} while (1>0);
}

The result is shown in this quick video:


So now you can see the basic procedure for sending mixed data in a text message. For the
purpose of the video, and to save my sanity the GSM shields telephone number is
stored as a phone book entry, that is why the sender is shown as Arduino GSM.

Well that is all we have time for in this installment. I hope you enjoyed reading it as
much as I did writing it for you. Now you can move onto GSM and Arduino part two!

Tutorial: Arduino and GSM Cellular Part Two


This is the revised, 2012 edition of chapter twenty-seven of a series originally titled
Getting Started/Moving Forward with Arduino! by John Boxall A tutorial on
the Arduino universe. The first chapter is here, the complete series is detailed here.

Welcome back fellow arduidans!


Assumed understanding for this article is found in part one. If you have not already done
so, please read and understand it.
Today we are going to harness the awesome power of the telephone network to control an
Arduino board via a SM5100B Cellular Shield:

Are you using an Arduino Mega board?


Mega users things will be slightly different for you. Please make sure the TX and RX
pins of your GSM shield DO NOT plug into your Mega. Furthermore, run a jumper wire
from GSM shield pin D2 to Mega pin 19, and a jumper from GSM shield pin D3 to Mega
pin 18, as shown below:

Finally, the example sketches will be different. Mega will not use the NewSoftSerial
library, instead we use the Serial1 port. Please use the following Mega-equivalent
sketches for this article: Example 27.1 and 27.2.
Reach out and control something

First we will discuss how to make something happen by a simple telephone call. And the
best thing is that we dont need the the GSM module to answer the telephone call
(thereby saving money) just let the module ring a few times. How is this possible? Very
easily. Recall example 26.1 we monitored the activity of the GSM module by using our
terminal software. In this case what we need to do is have our Arduino examine the text
coming in from the serial output of the GSM module, and look for a particular string of
characters.
When we telephone the GSM module from another number, the module returns the text
as shown in the image below (click to enlarge):

We want to look for the text RING, as (obviously) this means that the GSM shield has
recognised the ring signal from the exchange. Therefore need our Arduino to count the
number of rings for the particular telephone call being made to the module. (Memories
Many years ago we would use public telephones to send messages to each other. For
example, after arriving at a foreign destination we would call home and let the phone ring
five times then hang up which meant we had arrived safely). Finally, once the GSM
shield has received a set number of rings, we want the Arduino to do something.
From a software perspective, we need to examine each character as it is returned from the
GSM shield. Once an R is received, we examine the next character. If it is an I, we
examine the next character. If it is an N, we examine the next character. If it is a G,
we know an inbound call is being attempted, and one ring has occurred. We can set the
number of rings to wait until out desired function is called. In the following example,
when the shield is called, it will call the function doSomething() after three rings.
The function doSomething() controls two LEDs, one red, one green. Every time the GSM
module is called for 3 rings, the Arduino alternately turns on or off the LEDs. Using this

sketch as an example, you now have the ability to turn basically anything on or off, or
call your own particular function. Another example would be to return some type of data,
for example you could dial in and have the Arduino send you a text message containing
temperature data.
Example 27.1 (Mega version)
/* Example 27.1 Turn something on or off by telephoning the GSM shield
for a set number of rings
tronixstuff.com/tutorials > chapter 27 CC by-sa-nc
NOT for Arduino Mega */
#include <NewSoftSerial.h> //Include the NewSoftSerial library to send
serial commands to the cellular module
char inchar;
// Will hold the incoming character from the Serial
Port
NewSoftSerial cell(2,3);
//Create a 'fake' serial port. Pin 2 is the
Rx pin, pin 3 is the Tx pin
int numring=0; // used to count the number of 'rings' received by the
GSM module
int comring=3; // this is the number of rings to wait for until calling
the function doSomething();
int onoff=0; // used to track LED status - 0 = off, 1 = on
void setup()
{
pinMode(12, OUTPUT);
pinMode(13, OUTPUT); // LEDs - off = red, on = green
digitalWrite(12, HIGH);
digitalWrite(13, LOW); //Initialize serial port for communication.
cell.begin(9600);
}
void doSomething()
{
if (onoff==0)
{
onoff=1;
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
}
else
if (onoff==1)
{
onoff=0;
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
}
}
void loop()
{ //If a character comes in from the cellular module...
if(cell.available() >0)
{
inchar=cell.read();
if (inchar=='R')
{
delay(10);

inchar=cell.read();
if (inchar=='I')
{
delay(10);
inchar=cell.read();
if (inchar=='N')
{
delay(10);
inchar=cell.read();
if (inchar=='G')
{
delay(10);
// So the phone (our GSM shield) has 'rung' once, i.e. if it were a real
phone
// it would have sounded 'ring-ring'
numring++;
if (numring==comring)
{
numring=0; // reset ring counter
doSomething();
}
}
}
}
}
}
}

And now for a quick video demonstration. The first call is made, and the LEDs go from
red (off) to green (on). A second call is made, and the LEDs go from green (on) to red
(off). Although this may seem like an over-simplified example, with your existing
Ardiuno knowledge you now have the ability to run any function by calling your GSM
shield.
Now although turning one thing on or off is convenient, how can we send more control
information to our GSM module? For example, control four or more digital outputs at
once? These sorts of commands can be achieved by the reception and analysis of text
messages.
Doing so is similar to the method we used in example 27.1. Once again, we will analyse
the characters being sent from the GSM module via its serial out. However, there are two
AT commands we need to send to the GSM module before we can receive SMSs, and one
afterwards. The first one you already know:
AT+CMGF=1

Which sets the SMS mode to text. The second command is:
AT+CNMI=3,3,0,0

This command tells the GSM module to immediately send any new SMS data to the
serial out. An example of this is shown in the terminal capture below (click to enlarge):

Two text messages have been received since the module was turned on. You can see how
the data is laid out. The blacked out number is the sender of the SMS. The number
+61418706700 is the number for my carriers SMSC (short message service centre).
Then we have the date and time. The next line is the contents of the text message what
we need to examine in our sketch.
The second text message in the example above is how we will structure our control SMS.
Our sketch will wait for a # to come from the serial line, then consider the values after a,
b, c and d 0 for off, 1 for on. Finally, we need to send one more command to the GSM
module after we have interpreted our SMS:
AT+CMGD=1,4

This deletes all the text messages from the SIM card. As there is a finite amount of
storage space on the SIM, it is prudent to delete the incoming message after we have
followed the instructions within. But now for our example. We will control four digital
outputs, D9~12. For the sake of the exercise we are controlling an LED on each digital
output, however you could do anything you like. Although the sketch may seem long and
complex, it is not just follow it through and you will see what is happening.
Example 27.2 (Mega version)

/*
Example 27.2
Control four digital outputs via SMS
tronixstuff.com/tutorials > chapter 27
CC by-sa-nc
NOT for Arduino Mega
*/
#include <NewSoftSerial.h> //Include the NewSoftSerial library to send
serial commands to the cellular module.
char inchar;
//Will hold the incoming character from the
Serial Port.
NewSoftSerial cell(2,3);
//Create a 'fake' serial port. Pin 2 is the
Rx pin, pin 3 is the Tx pin.
int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;
void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
//Initialize GSM module serial port for
communication.
cell.begin(9600);
delay(30000); // give time for GSM module to register on network etc.
cell.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to
serial out upon receipt
delay(200);
}
void loop()
{
//If a character comes in from the cellular module...
if(cell.available() >0)
{
inchar=cell.read();
if (inchar=='#') // OK - the start of our command
{
delay(10);
inchar=cell.read();
if (inchar=='a')
{
delay(10);
inchar=cell.read();
if (inchar=='0')
{
digitalWrite(led1, LOW);
}
else if (inchar=='1')
{
digitalWrite(led1, HIGH);
}
delay(10);
inchar=cell.read();
if (inchar=='b')
{

inchar=cell.read();
if (inchar=='0')
{
digitalWrite(led2, LOW);
}
else if (inchar=='1')
{
digitalWrite(led2, HIGH);
}
delay(10);
inchar=cell.read();
if (inchar=='c')
{
inchar=cell.read();
if (inchar=='0')
{
digitalWrite(led3, LOW);
}
else if (inchar=='1')
{
digitalWrite(led3, HIGH);
}
delay(10);
inchar=cell.read();
if (inchar=='d')
{
delay(10);
inchar=cell.read();
if (inchar=='0')
{
digitalWrite(led4, LOW);
}
else if (inchar=='1')
{
digitalWrite(led4, HIGH);
}
delay(10);
}
}
cell.println("AT+CMGD=1,4"); // delete all SMS
}
}
}
}
}

And now for a video demonstration:


So there you have it controlling your Arduino digital outputs via a normal telephone or
SMS. Now it is up to you and your imagination to find something to control, sensor data
to return, or get up to other shenanigans.
If you enjoyed this article, you may find this of interest controlling AC power outlets
via SMS.

Tutorial: Arduino and Colour LCD


This is chapter twenty-eight of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here. Please note that the
tutorials are not currently compatible with Arduino IDE v1.0. Please continue to
use v22 or v23 until further notice.

Welcome back fellow arduidans!


Today we are going to start using a colour LCD with our Arduino for data display and
other fun and games. (The monochrome LCD article is here). Although there are many
colour LCDs on the market, the first one we examine is relatively inexpensive and easy to
mount and use the Sparkfun Color LCD Shield:

From a hardware perspective there isnt much to do only solder in some header pins
(which, again, are not included) to enable use with out Arduino boards. The quickest way
to solder them in is to insert the pins into another Arduino board or shield, place the LCD
shield on top, check the alignment, and solder away. The shield pins used are D3~D5 for
the three buttons, and D8, 9, 11 and 13 for the LCD interface. The shield takes 5V and
doesnt require any external power for the backlight. The LCD unit is 128 x 128 pixels,
with nine defined colours (red, green, blue, cyan, magenta, yellow, brown, orange, pink)
as well as black and white.
Hint there is a huge database of shields and their details at http://shieldlist.org
From a software perspective, the first thing to do is download and install the library for
the LCD shield. There are two versions of the library floating around. First of all, please
try the original library from here if your shield was purchased before (around) July 2011.
If the example sketches do not work, please try the new library from here. (Why? There
are two versions of the shield using different controller chipsets. This was made known to
me only recently [August 2011] The example sketches are written for the original library
and shield. They may not work with the new library and shield. I dont have a new
shield and cannot help you with it). Extract and copy the resulting folder into your
..\arduino-2x\libraries folder. Considering there are more parameters to consider as
against using a monochrome LCD, there is nothing to worry about. This shield is easy to
use and we will prove this in the following examples.
At the start of every sketch, you will need the following lines:
#include "LCD_driver.h"

#include
#include
#include
#include
#include
#include
#include
#include
#include

<string.h>
<stdlib.h>
<stdio.h>
<ctype.h>
<avr/io.h>
<avr/interrupt.h>
<avr/pgmspace.h>
"WProgram.h"
"HardwareSerial.h"

as well as the following in void setup():


ioinit();
LCDInit(); or LCDInit(EPSON) or LCDInit(PHILLIPS) // depends on the
chipset on your LCD - see below.
LCDContrast(45); // sets LCD contrast (value between 0~63)

With regards to LCDInit(), try it first without a parameter. If the screen doesnt work, try
PHILLIPS or EPSON instead. There are two versions of the LCD shield floating about
each with a different controller chipset. If you have the PHILLIPS chipset, my example
sketches may not work. This is out of my control, Sparkfun changed the chipset and some
functions have not been defined in the new library. The contrast parameter is subjective,
however 45 looks good and will be used in the forthcoming demonstrations. We will
examine each function with a small example, then use the LCD shield in more complex
applications.
Example 28.1 Text display
The LCD can display 9 rows of 16 characters of text. The function to display text is:
LCDPutStr("text", y,x, foreground colour, background colour);

where x and y are the coordinates of the top left pixel of the first character in the string.
Another necessary function is:
LCDClear(colour);

Which clears the screen and sets the background colour to the parameter colour.
(Please note when referring to the X- and Y-axis in this article, they are relative to
the LCD in the position shown below)
For example, to recreate the following display:

use the following sketch:


/* Example 28.1 - Colour LCD shield
tronixstuff.com/tutorials > chapter 28 CC by-sa */
// we need all these for the LCD
#include "LCD_driver.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "WProgram.h"
#include "HardwareSerial.h"
void setup()
{
// following two required for LCD
ioinit();
LCDInit();
LCDContrast(45); // sets LCD contrast (value between 0~63)
}
void loop()
{
LCDClear(BLACK);
LCDPutStr("0123456789012345", 0,2, WHITE, BLACK);
LCDPutStr("0123456789012345", 13,2, WHITE, BLACK);
LCDPutStr("0123456789012345", 26,2, WHITE, BLACK);
LCDPutStr("0123456789012345", 39,2, WHITE, BLACK);
LCDPutStr("0123456789012345", 52,2, WHITE, BLACK);
LCDPutStr("0123456789012345", 65,2, WHITE, BLACK);

LCDPutStr("0123456789012345", 78,2, WHITE, BLACK);


LCDPutStr("0123456789012345", 91,2, WHITE, BLACK);
LCDPutStr("0123456789012345", 104,2, WHITE, BLACK);
delay(30000);
}

In example 28.1 we used the function LCDClear();, which unsurprisingly cleared the
screen and set the background a certain colour. Lets have a look at the various
background colours in the following example. The LCDClear() function is helpful as it
can set the entire screen area to a particular colour. As mentioned earlier, there are the
predefined colours red, green, blue, cyan, magenta, yellow, brown, orange, pink, as well
as black and white. Here they are in the following example:
Example 28.2
/* Example 28.2 - Colour LCD shield
tronixstuff.com/tutorials > chapter 28 CC by-sa */
#include "LCD_driver.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>\
#include "WProgram.h"
#include "HardwareSerial.h"
int del = 1000;
void setup()
{
ioinit();
LCDInit();
LCDContrast(45);
}
void loop()
{
LCDClear(WHITE);
LCDPutStr("White", 39,40, WHITE, BLACK);
delay(del);
LCDClear(BLACK);
LCDPutStr("Black", 39,40, WHITE, BLACK);
delay(del);
LCDClear(YELLOW);
LCDPutStr("Yellow", 39,40, WHITE, BLACK); delay(del);
LCDClear(PINK);
LCDPutStr("Pink", 39,40, WHITE, BLACK);
delay(del);
LCDClear(MAGENTA);
LCDPutStr("Magenta", 39,40, WHITE, BLACK);
delay(del);
LCDClear(CYAN);
LCDPutStr("Cyan", 39,40, WHITE, BLACK);

delay(del);
LCDClear(BROWN);
LCDPutStr("Brown", 39,40, WHITE, BLACK);
delay(del);
LCDClear(ORANGE);
LCDPutStr("Orange", 39,40, WHITE, BLACK);
delay(del);
LCDClear(BLUE);
LCDPutStr("Blue", 39,40, WHITE, BLACK);
delay(del);
LCDClear(RED);
LCDPutStr("Red", 39,40, WHITE, BLACK);
delay(del);
LCDClear(GREEN);
LCDPutStr("Green", 39,40, WHITE, BLACK);
delay(del);
}

And now to see it in action. The colours are more livid in real life, unfortunately the
camera does not capture them so well.
Now that we have had some experience with the LCD librarys functions, we can move
on to drawing some graphical objects. Recall that the screen has a resolution of 128 by
128 pixels. We have four functions to make use of this LCD real estate, so lets see how
they work. The first is:
LCDSetPixel(COLOUR, Y, X);

This functions places a pixel (one LCD dot) at location x, y of colour COLOUR. Next is:
LCDSetLine(x0, y0, x1, y1, COLOUR);

Which draws a line of colour COLOUR, from position x0, y0 to x1, y1. Our next
function is:
LCDSetRect(x0, y0, x1, y1, fill, COLOUR);
This function draws an oblong or square of colour COLOUR with the top-left point at x0, y0 and
the bottom right at x1, y1. Fill is set to 0 for an outline, and 1 for a filled oblong. It would be
convenient for drawing bar graphs for data representation. And finally, we can also create circles,
using:
LCDDrawCircle(x, y, radius, COLOUR, type);
X and Y is the location for the centre of the circle, radius and COLOUR are self-explanatory.
However type presents some more options FULLCIRCLE, OPENSOUTH, OPENNORTH, OPENEAST,
OPENWEST, OPENNORTHEAST, OPENNORTHWEST, OPENSOUTHEAST, OPENSOUTHWEST.
These parameters determine how much of the circles circumference is drawn. FULLCIRCLE natuarlly
generates a whole circle, OPENSOUTH generates the top-half of a circle, OPENNORTH generates the
bottom half of a circle, and so on.

We will now use these graphical functions in the following demonstration sketch. For photographic
reasons, I will stick with white on black for the colours. The sketch is quite long, so it can be downloaded
from the following link Example 28.3. And here is a short clip of the sketch in action:

That is all we have time for in this instalment. Now you have an explanation of the
functions to drive the screen, only your imagination is holding you back. In a future
instalment we will examine some another type of colour display the TFT.

Tutorial: Arduino and TFT LCD


This is chapter twenty-nine of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe.

The first chapter is here, the complete series is detailed here. Please note that the
tutorials are not currently compatible with Arduino IDE v1.0. Please continue to
use v22 or v23 until further notice.
Welcome back fellow arduidans!
Today we continue with experimenting with colour LCD units. In this article we will get
started with a very clear and sharp unit the 4D Systems 1.44 TFT serial interface LCD:

The LCD is an LED-backlit thin-film transistor type, resolution is 128 x 128 pixels, with
an RGB colour range of 65536.
As an aside, this is a very powerful piece of hardware. The module not only contains a
1.44 square TFT LCD, there is also a dedicated graphics processor and a microSD card
interface. One can program the display processor in the same manner as another
microcontroller platform for incredibly interesting results. For more information, please
visit here.
However in the spirit of keeping things simple, this article will focus on driving the LCD
directly using our Arduino or compatible boards. There are two firmware versions of this
module the GFX and the SGC. We need to have the SGC firmware, as this allows
control via the serial TX/RX pins from our Arduno board. If you have purchased the SGC
module, youre ready to go. Scroll down until you see And were back. However if
you have the GFX version, please read the following instructions on how to change your
LCDs firmware from GFX to SGC
Changing the firmware from GFX to SGC

At the moment this process only seems available to users of Microsoft Windows.
All complaints to 4D Systems.
Unfortunately this process may not work with an Arduino Mega board.
First of all, remove the ATmega328 from your Arduino board. Please be careful,
use a chip puller if possible. We are going to use the board as a simple serial-USB
converter;
Insert your LCD module into a solderless breadboard;

Connect Arduino pin 0 (RX) to display pin 7 (RX); connect Arduino pin 1 (TX) to
display pin 8 (TX). [Yes - TX>TX, RX>RX];
Connect Arduino 5V to display pin 9; connect Arduino GND to display pin 6;
your LCD should display the following:

Visit here, download and open the PmmC Loader application; visit here and
download the .pmmc file to your local drive;
Connect your Arduino board via USB to the computer; then run the PmmC loader
application;
Select the appropriate COM: port, load in the .pmmc file, then click Load. The
firmware update should take less than sixty seconds;
When finished, you will be presented with the following on the computer:

and the following on your LCD:

At this point unplug the USB lead from your Arduino board and all leads into the
Arduino board;
Re-insert the ATmega328 back into your Arduino board;
Reconnect the wires from the LCD module to the Arduino, but this time connect
Arduino TX to LCD RX; and LCD TX to Arduino RX.
Now you have the serial-interface SGC firmware model LCD.

And were back


To control this LCD, it requires commands to be sent via Serial.write(), and such
commands are in the form of hexadecimal numbers. (You see something new every day).
You can download the reference book with all the commands: SGC Commands.pdf and
bypass the library by directly writing the hexadecimal numbers directly to the module.
However, to get up to speed as fast as possible we can use a library with more of the
popular functions included. Kudos and thanks to Oscar Gonzalez for writing a very useful
library. Download the library from here and install into your ../Arduino-002x/libraries
folder, then re-start the Arduino IDE if you had it running. You may be wondering why
the library is named displayshield4d - the LCD manufacturer sells this LCD on an
Arduino shield. Although that would be great for experimenting, one would need to
purchase another standalone LCD if their project moved forward myself included. So
thats why were using the bare LCD board.

To connect the LCD to our Arduino is very simple:

LCD pin 5 to Arduino RST;


LCD pin 6 to Arduino GND;
LCD pin 7 to Arduino D1;
LCD pin 8 to Arduino D0;
LCD pin 9 to Arduino 5V.

In the following examples we will demonstrate the various functions available in the
library. As this is chapter 29, (when will this stop?) I will no longer explain the more
basic functions or ideas that you should know by now, instead relying on comments
within the sketch if it feels necessary. It can take a short moment for the LCD controller
to process, so always put a short delay between functions.
When uploading a sketch to your Arduino you may need to disconnect the LCD from
Arduino D0/D1 as it can interfere with the serial process.
Firstly we will demonstrate text display. Initialising the display requires a few functions:
#include <displayshield4d.h> // include the LCD library
DisplayShield4d lcd;

The second line creates an instance of lcd to be used with the relevant functions. Next,
within void setup():
Serial.begin(115200); // LCD speed is very high
lcd.Init(); // wake up LCD
lcd.Clear(); // clear the LCD, set background to black

To write text to the LCD, the following function is required:


lcd.setfontmode(OLED_FONT_TRANSPARENT);

// set font background type

This line sets the font transparency. If we use the parameter


OLED_FONT_TRANSPARENT the unused pixels in the character area will be transparent
and continue to show what they were set to before the text was over-written with. You
can also use OLED_FONT_OPAQUE, which blocks the item displayed behind the text.
Whenever a function requires a colour parameter, we use:
lcd.RGB(x,y,z);

where x, y and z are numerical values (between 0 and 255) for the red, green and blue
components of the required colour. If you need an RGB numerical reference, download
this handy chart. Finally, to display some text we use the following:
lcd.drawstringblock(a, b, c, lcd.RGB(255, 255, 255), d, e, "Hello,
world");

The parameters required are:

a the x-position of the first character. E.g. if this was a zero, the top-left pixel of
the first character would be on the left-most pixel column of the LCD;
b the y-position of the first character. e.g. if both a and b were zero, the text
would start from the top-left of the LCD;
c numerical code for the font to use: 1 is for 57 pixel characters, 2 for 88 and
3 for 812;
the three values within the lcd.RGB() function determine the colour of the text;
d x-axis resolution multiplier. E.g. if you double this and use the 57 font, the
characters will be double-width;
e y-axis resolution multiplier.

Now lets see this in action with the following sketch:


Example 29.1
/* Example 29.1 - uLCD-144 text demonstration
http://tronixstuff.com/tutorials > chapter 29 CC by-sa-nc */
#include <displayshield4d.h> // necessary library
DisplayShield4d lcd; // create an instance of the LCD
void setup()
{
Serial.begin(115200); // LCD speed is very high
lcd.Init(); // wake up LCD
delay(20);
}
void loop()
{
lcd.Clear(); // clear LCD
delay(20);
lcd.setfontmode(OLED_FONT_TRANSPARENT); // set font background type
delay(20);
for (int a=0; a<128; a+=8)
{
lcd.drawstringblock(0, a, 2 , lcd.RGB(255, 0, 0), 1, 1, "visit me");
delay(20);
}
delay(2000);
lcd.Clear();
for (int a=0; a<128; a+=16)
{
lcd.drawstringblock(0, a, 0, lcd.RGB(0, 255, 0), 2, 2, "0123456789");
delay(20);
}
delay(2000);
lcd.Clear();
delay(20);
for (int a=0; a<128; a+=32)
{
lcd.drawstringblock(0, a, 0, lcd.RGB(0, 0, 255), 4, 4, "Great");
delay(20);
}

delay(2000);
}

And a short video clip of the example in action:


As you can see the display update speed is much better than the LCD from the previous
chapter. Although this example was short, dont be afraid to try out your own parameters
in the example sketch.
Next we will demonstrate the various graphics functions in the library. Creating graphics
isnt rocket science, it just takes some imagination (something I admit to lacking) and
following the parameters for each function. Our first is
lcd.putpixel(x,y,lcd.RGB(r,g,b));

which places a pixel on the screen at location x,y of colour described using lcd.RGB().
Next we have
lcd.line(x1,y1,x2,y2,lcd.RGB(r,g,b));

which draws a line from x1, y1 to x2, y2 of colour rgb. One can also create rectangles and
so on using
lcd.rectangle(x,y,l,h,z,lcd.RGB(r,g,b));

This will create a rectangle with the top-left point at x,y; width is l pixels, height is h
pixels, and a new parameter z. If z is 0, the function will draw a solid shape, if z is 1, it
will display only a wire-frame rectangle with a pixel width of one. Circles are created
using
lcd.circle(x,y,r,z,lcd.RGB(r,g,b);

where x and y are the coordinates for the centre of the circle, r is the radius, and z is the
solid/wireframe parameter. And finally triangles:
lcd.triangle(x1,y1,x2,y2,x3,y3,z,lcd.RGB(r,g,b));

This will draw a triangle with the corners at the coordinate parameters; z again is the
solid/wireframe parameter. However you need to order the corners in an anti-clockwise
order. This will become evident in the example sketch below.
Example 29.2
In this example we run through the graphical functions described above. By following
through the sketch you should gain an idea of how the graphical functions are used, in
order to create your own displays.
/*

Example 29.2 - uLCD-144 graphic library demonstration

http://tronixstuff.com/tutorials > chapter 29 CC by-sa-nc


int a,b,c,d,e=0;
#include <displayshield4d.h> // necessary library
DisplayShield4d lcd; // create an instance of the LCDvoid
setup()
{
randomSeed(analogRead(0));
Serial.begin(115200); // LCD speed is very high
lcd.Init(); // wake up LCD
delay(50);
}
void loop()
{
lcd.Clear();
delay(50);
for (int z=0; z<2500; z++)
{
a=random(127);
b=random(127);
c=random(255);
d=random(255);
e=random(255);
lcd.putpixel(a,b,lcd.RGB(c,d,e));
delay(50);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=0; z<64; z++)
{
lcd.line(0,0,127,z*2,lcd.RGB(0,255,0));
delay(50);
}
for (int z=0; z<64; z++)
{
lcd.line(0,0,z*2,127,lcd.RGB(0,0,255));
delay(50);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=0; z<15; z++)
{
lcd.rectangle(z*10, z*10, 20, 20, 1, lcd.RGB(255,0,0));
delay(250);
lcd.rectangle(z*10, z*10, 20, 20, 0, lcd.RGB(0,0,255));
delay(250);
lcd.rectangle(z*10, z*10, 20, 20, 0, lcd.RGB(0,0,0));
delay(250);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=0; z<14; z++)
{
lcd.circle(63,63,z*3, 1, lcd.RGB(0,0,255));
delay(250);

*/

lcd.circle(63,63,z*3, 0, lcd.RGB(0,255,0));
delay(250);
lcd.circle(63,63,z*3, 0, lcd.RGB(0,0,0));
delay(250);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=10; z>-0; --z)
{
lcd.triangle(127,127,64,z*10,0,127,1,lcd.RGB(0,255,0));
delay(250);
lcd.triangle(127,127,64,z*10,0,127,0,lcd.RGB(0,0,255));
delay(250);
lcd.triangle(127,127,64,z*10,0,127,0,lcd.RGB(0,0,0));
delay(250);
}
}
And here is the video of example 29.2 in action brought to you by Mr Blurrycam:

So there you have it, another useful part and a very nice colour LCD to make use of.

Moving Forward with Arduino Chapter 30 twitter


This is chapter thirty of a series originally titled Getting Started/Moving Forward with
Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here. Please note that the
tutorials are not currently compatible with Arduino IDE v1.0. Please continue to
use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this article we will learn how to send messages from our Arduino to twitter. For the
uninitiated who may be thinking what is all this twitter nonsense about?, twitter is a
form of microblogging. You can create a message with a maximum length of 140
characters, and broadcast this on the twitter service. For people to receive your messages
(or tweets) they also need to be a member of twitter and choose to subscribe to your
tweets.
Generally people will use the twitter service using one of three methods: using a web
browser on a personal computer or internet device, on a mobile phone, or using a specific
application such as TweetDeck on one of the aforementioned devices. For example, here
is a typical web browser view:

And here is an example of the twitter application running on an Android OS smartphone:

So as you can see, it is easy enough to read peoples tweets. Therein lies the reason for
this article we can harness twitter as an output device for our Arduino systems. We can
broadcast various messages, so systems can be created to monitor specific parameters and
report on their status at regular intervals, upon an event occurring, and so on.
In some areas, you can set twitter to send tweets from a certain user to your mobile phone
via SMS however if doing so be careful to confirm possible charges to your mobile
phone account. Finally, if you are worried about privacy with regards to your tweets, you
can set your account to private and only allow certain people to follow your tweets.
So lets get started. First of all you will need a twitter account. If you do not have one,
you can sign up for one here. If you already have a twitter account, you can always open
more for other uses such as an Arduino. For example, my twitter account
is @tronixstuff, but my demonstration machine twitter account is @tronixstuff2. Then I
have set my primary account to follow my machines twitter account. Once you have
logged into twitter with your machine account, visit this page and get yourself a token by
following the Step One link. Save your token somewhere safe.
Next, you will need some hardware. Apart from your usual Arduino board, you will need
an Ethernet shield. Once again we will use the awesome Freetronics Ethernet shield as
used in chapter sixteen:

If you are unfamiliar with using Arduino and ethernet, please review chapter sixteen
before continuing forward with this article.
From a software perspective, we will need some libraries for our Arduino IDE. Download
and install the twitter library from here, and the EthernetDNS library from here. At this
point, please run the Webserver example described in chapter sixteen and ensure it is
working before moving forward from this point.
Time for a break

Now it is time to send our first tweet. The following sketch is a modification of the
demonstration version, in which we have isolated the tweet-sending into a separate
function called (strangely enough) tweet();. It is not complex at all:
Example 30.1
/* Example 30.1 - simple twitter interface
Use the ethernet shield and your Arduino board to send tweets
Big thanks to @neocat and Georg Kaindl
tronixstuff.com/tutorials > chapter thirty */
// necessary libraries
#if defined(ARDUINO) && ARDUINO > 18
// If using Arduino 0019 or
later, include SPI.h
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDNS.h>
#include <Twitter.h>
// Ethernet Shield Settings
// Alter ip, gateway and subnet to suit your own network!
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // create MAC
address for ethernet shield
byte ip[] = { 10,0,0,69}; // choose your own IP for ethernet shield
byte gateway[] = { 10,0,0,138 }; // your network gateway
byte subnet[] = { 255, 255, 255, 0 }; // your network subnet
Twitter twitter("aaaaaaa"); // replace aaaaaaa with your token
void setup()
{
delay(5000);
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
}
void tweet(char msg[])
{
Serial.println("connecting ...");
if (twitter.post(msg))
{
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200)
{
Serial.println("OK.");
} else
{
Serial.print("failed : code ");
Serial.println(status);
}
} else
{
Serial.println("connection failed.");
}
}

void loop()
{
delay(1000);
tweet("Hello world");
do{} while(1>0); // endless loop
}

So after uploading the above sketch, running a network cable from your access point to
the ethernet shield, and powering up the Arduino board, your tweet should appear as
such:

Excellent it works. And I hope yours did as well. If it did not, open the serial monitor
box to get some feedback from the sketch. From experimentation the most amount of
errors are caused by incorrect IP and subnet addresses. If you get excited and try to run
the sketch again by hitting reset, twitter will reply back with an error it does not allow
duplicate tweets to be sent (over a short period of time). Twitter will reply to your tweet
with a code which describes the result of your tweet. This code is stored in an integer
variable using the function
int status = twitter.wait(&Serial);

For example, 200 means the tweet was sent successfully, and 403 means you have
attempted a duplicate tweet. However you can omit the code-checking if you are not
fussed about your tweets status.
Although it was fun tweeting Hello world, lets create an example that reacts to various
events and tweets about them. To simulate some events I have connected four buttons to
digital inputs (using the button board from chapter twelve). Pressing a button sends of the
matching message. However you can use any form of digital output or decision-making
in your sketch. For now, here is the example sketch:
Example 30.2
/* Example 30.2 - tweeting digital event status
Use the ethernet shield and your Arduino board to send tweets
Big thanks to @neocat and Georg Kaindl
tronixstuff.com/tutorials >
chapter thirty */
// necessary libraries#if defined(ARDUINO) && ARDUINO > 18
// If using Arduino 0019 or later, include SPI.h
#include
#endif
#include

#include
#include
// our event messages
char b1[]="one";
char b2[]="two";
char b3[]="three";
char b4[]="four";
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // create MAC
address for ethernet shield
byte ip[] = { 10,0,0,69}; // choose your own IP for ethernet shield
byte gateway[] = { 10,0,0,138 }; // your network gateway
byte subnet[] = { 255, 255, 255, 0 }; // your network subnet
// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("aaaaaaa");
// replace aaaaaaa with your token
void setup()
{
delay(5000);
Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
}
void tweet(char msg[])
{
Serial.println("connecting ...");
if (twitter.post(msg))
{
int status = twitter.wait(&Serial);
if (status == 200)
{
Serial.println("OK.");
} else
{
Serial.print("failed : code ");
Serial.println(status);
}
} else
{
Serial.println("connection failed.");
}
}
void loop()
{
if (digitalRead(2)==HIGH)
{
tweet(b1);
delay(2000); }
if (digitalRead(3)==HIGH)
{
tweet(b2);
delay(2000); }
if (digitalRead(4)==HIGH)
{
tweet(b3);
delay(2000); }
if (digitalRead(5)==HIGH)
{
tweet(b4);
delay(2000); }
}

And here is a screen shot of the results after pressing buttons one, four, two then three:

So there you have it, another useful way to send information from your Arduino to the
outside world. Stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS
feed (top-right), twitter or joining our Google Group. Big thanks to @neocat and Georg
Kaindl for their work with the twitter and EthernetDNS Arduino libraries.

Tutorial: Your Arduinos inbuilt EEPROM


This is chapter thirty-one of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here. Please note that this
tutorial is currently compatible with Arduino IDE v1.0.
Welcome back fellow arduidans!
Today we are going to examine the internal EEPROM in our Arduino boards. What is an
EEPROM some of you may be saying? An EEPROM is an Electrically Erasable
Programmable Read-Only Memory. It is a form of non-volatile memory that can
remember things with the power being turned off, or after resetting the Arduino. The
beauty of this kind of memory is that we can store data generated within a sketch on a
more permanent basis.
Why would you use the internal EEPROM? For situations where data that is unique to a
situation needs a more permanent home. For example, storing the unique serial number
and manufacturing date of a commercial Arduino-based project a function of the sketch
could display the serial number on an LCD, or the data could be read by uploading a
service sketch. Or you may need to count certain events and not allow the user to reset
them such as an odometer or operation cycle-counter.
What sort of data can be stored? Anything that can be represented as bytes of data. One
byte of data is made up of eight bits of data. A bit can be either on (value 1) or off (value
0), and are perfect for representing numbers in binary form. In other words, a binary
number can only uses zeros and ones to represent a value. Thus binary is also known as
base-2, as it can only use two digits.
How can a binary number with only the use of two digits represent a larger number? It
uses a lot of ones and zeros. Lets examine a binary number, say 10101010. As this is a
base-2 number, each digit represents 2 to the power of x, from x=0 onwards:

See how each digit of the binary number can represent a base-10 number. So the binary
number above represents 85 in base-10 the value 85 is the sum of the base-10
values. Another example 11111111 in binary equals 255 in base 10.

Now each digit in that binary number uses one bit of memory, and eight bits make a
byte. Due to internal limitations of the microcontrollers in our Arduino boards, we can
only store 8-bit numbers (one byte) in the EEPROM. This limits the decimal value of the
number to fall between zero and 255. It is then up to you to decide how your data can be
represented with that number range. Dont let that put you off numbers arranged in the
correct way can represent almost anything!
There is one limitation to take heed of the number of times we can read or write to the
EEPROM. According to the manufacturer Atmel, the EEPROM is good for 100,000
read/write cycles (see the data sheet). One would suspect this to be a conservative
estimate, however you should plan accordingly. *Update* After some experimentation,
the life proved to be a lot longer
Now we know our bits and and bytes, how many bytes can be store in our Arduinos
microcontroller? The answer varies depending on the model of microcontroller. For
example:

Boards with an Atmel ATmega328, such as Arduino Duemilanove, Uno, Uno


SMD, Lilypad or the Freetronics KitTen/Eleven - 1024 bytes (1 kilobyte)
Boards with an Atmel ATmega1280 or 2560, such as the Arduino Mega series
4096 bytes (4 kilobytes)
Boards with an Atmel ATmega168, such as the original Arduino Lilypad, old
Nano, Diecimila etc 512 bytes.

If y0u are unsure have a look at the Arduino hardware index or ask your board supplier.
If you need more EEPROM storage than what is available with your microcontroller,
consider using an external I2C EEPROM as described in the Arduino and I2C tutorial
part two.
At this point we now understand what sort of data and how much can be stored in our
Arduinos EEPROM. Now it is time to put this into action. As discussed earlier, there is a
finite amount of space for our data. In the following examples, we will use a typical
Arduino board with the ATmega328 with 1024 bytes of EEPROM storage.
To use the EEPROM, a library is required, so use the following library in your sketches:
#include <EEPROM.h>

The rest is very simple. To store a piece of data, we use the following function:
EEPROM.write(a,b);

The parameter a is the position in the EEPROM to store the integer (0~255) of data b. In
this example, we have 1024 bytes of memory storage, so the value of a is between 0 and
1023. To retrieve a piece of data is equally as simple, use:
z = EEPROM.read(a);

Where z is an integer to store the data from the EEPROM position a. Now to see an
example:
Example 31.1
This sketch (download) will create random numbers between 0 and 255, store them in the
EEPROM, then retrieve and display them on the serial monitor. The variable EEsize is
the upper limit of your EEPROM size, so (for example) this would be 1024 for an
Arduino Uno, or 4096 for a Mega.
/* Example 31.1 - Arduino internal EEPROM demonstration
http://tronixstuff.com/tutorials > chapter 31 | CC by-sa-nc */
#include <EEPROM.h>
int zz;
int EEsize = 1024; // size in bytes of your board's EEPROM
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));
}
void loop()
{
Serial.println("Writing random numbers...");
for (int i = 0; i < EEsize; i++)
{
zz=random(255);
EEPROM.write(i, zz);
}
Serial.println();
for (int a=0; a<EEsize; a++)
{
zz = EEPROM.read(a);
Serial.print("EEPROM position: ");
Serial.print(a);
Serial.print(" contains ");
Serial.println(zz);
delay(25);
}
}

The output from the serial monitor will appear as such:

So there you have it, another useful way to store data with our Arduino systems.
Although not the most exciting tutorial, it is certainly a useful.

Tutorial: Arduino and Infra-red control


This is chapter thirty-two of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe.
The first chapter is here, the complete series is detailed here.
Welcome back!
In this article we will look at something different to the usual, and hopefully very
interesting and useful interfacing our Arduino systems with infra-red receivers. Why
would we want to do this? To have another method to control our Ardiuno-based systems,
using simple infra-red remote controls.
A goal of this article is to make things as easy as possible, so we will not look into the
base detail of how things work - instead we will examine how to get things done. If you
would like a full explanation of infra-red, perhaps see the page on Wikipedia. The remote
controls you use for televisions and so on transmit infra-red beam which is turned on and
off at a very high speed usually 38 kHz, to create bits of serial data which are then
interpreted by the receiving unit. As the wavelength of infra-red light is too high for
human eyes, we cannot see it. However using a digital camera we can. Here is a
demonstration video of IR codes being sent via a particularly fun kit the adafruit TV-BGone:
Now to get started. You will need a remote control, and a matching IR receiver device.
The hardware and library used in this tutorial only supports NEC, Sony SIRC, Philips
RC5, Philips RC6, and raw IR protocols. Or you can purchase a matching set for a good
price, such as this example:

Or you may already have a spare remote laying around somewhere. I kept this example
from my old Sony Trinitron CRT TV after it passed away:

It will more than suffice for a test remote. Now for a receiver if you have purchased the
remote/receiver set, you have a nice unit that is ready to be wired into your Arduino, and
also a great remote that is compact and easy to carry about. To connect your receiver
module as per the PCB labels, connect Vcc to Arduino 5V, GND to Arduino GND, and
D (the data line) to Arduino digital pin 11.
Our examples use pin 11, however you can alter that later on. If you are using your own
remote control, you will just need a receiver module. These are very cheap, and an ideal
unit is the Vishay TSOP4138 (data sheet .pdf). These are available from element-14 and
the other usual retail suspects. They are also dead-simple to use. Looking at the following
example:

From left to right the pins are data, GND and Vcc (to Arduino +5V). So it can be easily
wired into a small breadboard for testing purposes. Once you have your remote and
receiver module connected, you need to take care of the software side of things. There is
a new library to download and install, download it from here. Extract the IRremote folder
and place into the ..\arduino-002x\libraries folder. Then restart your Arduino IDE if it
was already open.
Using Arduino v1.0? Open the file IRRemoteInt.h in the library folder, and change the
line
#include <WProgram.h>
to
#include <Arduino.h>
Then save and close the file, restart the Arduino IDE and youre set.
Example 32.1
With our first example, we will receive the commands from our remote control and
display them on the serial monitor. Download and run the following sketch:
// example 32.1 - IR receiver code repeater
// http://tronixstuff.com/tutorials > chapter 32
// based on code by Ken Shirriff - http://arcfn.com
#include <IRremote.h> // use the library
int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
void setup()
{
Serial.begin(9600); // for serial monitor output
irrecv.enableIRIn(); // Start the receiver
}
void loop()
{
if (irrecv.decode(&results)) // have we received an IR signal?
{
Serial.println(results.value, HEX); // display it on serial monitor
in hexadecimal
irrecv.resume(); // receive the next value
} // Your loop can do other things while waiting for an IR command
}

Open the serial monitor box, point your remote control to the receiver and start pressing
away. You should see something like this:

What have we here? Lots of hexadecimal numbers. Did you notice that each button on
your remote control resulted in an individual hexadecimal number? I hope so. The
number FFFFFFFF means that the button was held down. The remote used was from a
yum-cha discount TV. Now I will try again with the Sony remote:

This time, each button press resulted in the same code three times. This is peculiar to
Sony IR systems. However nothing to worry about. Looking back at the sketch for
example 32.1, the
if (irrecv.decode(&results))

section is critical if a code has been received, the code within the if statement is
executed. The hexadecimal code is stored in the variable
results.value

with which we can treat as any normal hexadecimal number. At this point, press a few
buttons on your remote control, and take a note of the matching hexadecimal codes that
relate to each button. We will need these codes for the next example
Example 32.2
Now we know how to convert the infra-red magic into numbers, we can create sketches
to have our Arduino act on particular commands. As the IR library returns hexadecimal
numbers, we can use simple decision functions to take action. In the following example,
we use switchcase to examine each inbound code, then execute a function. In this case
we have an LCD module connected via I2C, and the sketch is programmed to understand
fifteen Sony IR codes. If you dont have an LCD you could always send the output to the
serial monitor. If you are using the DFRobot I2C LCD display, you need to use Arduino
v23.
Furthermore you can substitute your own values if not using Sony remote controls.
Finally, this sketch has a short loop after the translateIR(); function call which ignores
the following two codes we do this as Sony remotes send the same code three times.
Again. you can remove this if necessary. Note that when using hexadecimal numbers in
our sketch we preced them with 0x.
Download the sketch below from here:
// example 32.2 - IR receiver code translator
// for Sony IR codes (ignores 2nd and 3rd signal repeat)
// http://tronixstuff.com/tutorials > chapter 32
// based on code by Ken Shirriff - http://arcfn.com
#include "Wire.h" // for I2C bus
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module
http://bit.ly/eNf7jM
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a
16 chars and 2 line display
#include <IRremote.h> // use the library for IR
int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
void setup()
{
lcd.init();
// initialize the lcd

lcd.backlight(); // turn on LCD backlight


irrecv.enableIRIn(); // Start the receiver
}
void translateIR() // takes action based on IR code received
// describing Sony IR codes on LCD module
{
switch(results.value)
{
case 0x37EE: lcd.println(" Favourite
"); break;
case 0xA90: lcd.println(" Power button
"); break;
case 0x290: lcd.println(" mute
"); break;
case 0x10: lcd.println(" one
"); break;
case 0x810: lcd.println(" two
"); break;
case 0x410: lcd.println(" three
"); break;
case 0xC10: lcd.println(" four
"); break;
case 0x210: lcd.println(" five
"); break;
case 0xA10: lcd.println(" six
"); break;
case 0x610: lcd.println(" seven
"); break;
case 0xE10: lcd.println(" eight
"); break;
case 0x110: lcd.println(" nine
"); break;
case 0x910: lcd.println(" zero
"); break;
case 0x490: lcd.println(" volume up
"); break;
case 0xC90: lcd.println(" volume down
"); break;
case 0x90:
lcd.println(" channel up
"); break;
case 0x890: lcd.println(" channel down
"); break;
default: lcd.println(" other button
");
}
delay(500);
lcd.clear();
}
void loop()
{
if (irrecv.decode(&results)) // have we received an IR signal?
{
translateIR();
for (int z=0; z<2; z++) // ignore 2nd and 3rd signal repeat
{
irrecv.resume(); // receive the next value
}
}
}

And here it is in action:

You might be thinking why would I want to make things appear on the LCD like that?.
The purpose of the example is to show how to react to various IR commands. You can
replace the LCD display functions with other functions of your choosing.
At the start working with infra-red may have seemed to be complex, but with the
previous two examples it should be quite simple by now. So there you have it, another
useful way to control our Arduino systems. Hopefully you have some ideas on how to
make use of this technology. In future articles we will examine creating and sending IR

codes from our Arduino. So stay tuned for upcoming Arduino tutorials by subscribing to
the blog, RSS feed (top-right), twitter or joining our Google Group. Furthermore, a big
thanks to Ken Shirriff for his Arduino library.

Tutorial: Control AC outlets via SMS


This is the revised, 2012 edition of chapter thirty-three of a series originally titled
Getting Started/Moving Forward with Arduino! by John Boxall A tutorial on
the Arduino universe. The first chapter is here, the complete series is detailed here.
Welcome back fellow arduidans!
Assumed understanding for this article is found in part one. If you have not already done
so, please read and understand it.
In this chapter we will continue with the use of the SM5100 cellular shield to turn digital
outputs on and off via SMS. However please read chapters twenty-six and twenty-seven
first if you are unfamiliar with using the GSM shield with Arduino. As an extension of
chapter twenty-seven, we will use our Arduino to turn on or off AC outlets via a common
remote-control AC outlet pack. Please note this is more of a commentary of my own
experience, and not an exact tutorial. In other words, by reading this I hope you will gain
some ideas into doing the necessary modifications yourself and in your own way.
Firstly, we need some remote-control AC outlets. Most electrical stores or giant retail
warehouses may have something like this:

Nothing too original, just a wireless remote control that can switch on or off receiver
outlets on a choice of four radio frequencies. Before moving forward I would like to
acknowledge that this article was inspired by the wonderful book Practical Arduino
Cool Projects for Open Source Hardware by Jon Oxer and Hugh Blemings. In chapter
two an appliance remote-control system is devised using a similar system.

At first glance the theory behind this project is quite simple using the hardware in
example 27.2, instead of controlling LEDs, activate the buttons on the wireless remote
control for the AC outlets leaving us with AC outlets controlled via SMS. However
there are a few things to keep in mind and as discovered during the process, various
pitfalls as well.
Before voiding the warranty on your remote control, it would be wise to test the range of
the remote control to ensure it will actually work in your situation. I found this was made
a lot easier by connecting a radio to the remote outlet then you can hear when the outlet
is on or off. If this is successful, make a note of the amount of time required to press the
on and off buttons as we need to control the delay in our Arduino sketch.
The next step is to crack open the remote control:

and see what we have to work with:

Straight away there are two very annoying things the first being the required power
supply 12 volts; and the second being the type of button contacts on the PCB. As you
can see above we only have some minute PCB tracks to solder our wires to. It would
be infinitely preferable to have a remote control that uses actual buttons soldered into a
PCB, as you can easily desolder and replace them with wires to our Arduino system.
However unless you can casually tear open the remote control packaging in the store
before purchase, it can be difficult to determine the type of buttons in the remote.
As you can see in the photo above, there is an off and on pad/button each for four
channels of receiver. In my example we will only use two of them to save time and space.
The next question to solve is how to interface the Arduino digital outputs with the remote
control. In Practical Arduino, the authors have used relays, but I dont have any of those
in stock. However I do have a quantity of common 4N25 optocouplers, so will use those
instead. An optocoupler can be thought of as an electronic switch that is isolated from
what is it controlling see my article on optocouplers for more information.
Four optocouplers will be required, two for each radio channel. To mount them and the
associated circuitry, we will use a blank protoshield and build the Arduino-remote control
interface onto the shield. The circuitry for the optocoupler for each switch is very simple,
we just need four of the following:

As the LED inside the optocoupler has a forward voltage of 1.2 volts at 10mA, the 390
ohm resistor is required as our Arduino digital out is 5 volts. Dout is connected to the
particular digital out pin from the Arduino board. Pins 4 and 5 on the optocoupler are
connected to each side of the button contact on our remote control.
The next consideration is the power supply. The remote control theoretically needs 12
volts, however the included battery only measured just over nine. However for the
optimum range, the full 12 should be supplied. To save worrying about the battery, our
example will provide 12V to the remote control. Furthermore, we also need to supply 5
volts at a higher current rating that can be supplied by our Arduino. In the previous GSM
chapters, I have emphasised that the GSM shield can possibly draw up to two amps in
current. So once again, please ensure your power supply can deliver the required amount
of current. From experience in my location, I know that the GSM shield draws around
400~600 milliamps of current which makes things smaller and less complex.
The project will be supplied 12 volts via a small TO-92 style 78L12 regulator, and 5 volts
via a standard TO-220 style 7805 regulator. You could always use a 7812, the 78L12 was

used as the current demand is lower and the casing is smaller. The power for the whole
project will come from a 15V DC 1.5A power supply. So our projects power supply
schematic will be as follows:

Now to mount the optocouplers and the power circuitry on the blank protoshield. Like
most things in life it helps to make a plan before moving forward. I like to use graph
paper, each square representing a hole on the protoshield, to plan the component layout.
For example:

It isnt much, but it can really help. After checking the plan over, it is a simple task to get
the shield together. Here is my prototype example:

It isnt neat, but it works. The header pins are used to make connecting the wires a little
easier, and the pins on the right hand side are used to import the 15V and export 12V for
the remote.
While the soldering iron is hot, the wires need to be soldered to the remote control. Due
to the unfortunate size of the PCB tracks, there wasnt much space to work with:

But with time and patience, the wiring was attached:

Again, as this is a prototype the aesthetics of the modification are not that relevant. Be
careful when handling the remote, as any force on the wiring can force the soldered wire
up and break the PCB track. After soldering each pair of wires to the button pads, use the
continuity function of a multimeter to check for shorts and adjust your work if necessary.
At this stage the AC remote control shield prototype is complete. It can be tested with a
simple sketch to turn on and off the related digital outputs. For example, the following
sketch will turn on and off each outlet in sequence:
Example 33.1
/*
Example 33.1 - test our AC remote prototype
http://tronixstuff.com/tutorials > chapter 33 | CC by-sa-nc
*/
void setup()
{
pinMode(9,
pinMode(8,
pinMode(5,
pinMode(4,
}

OUTPUT);
OUTPUT);
OUTPUT);
OUTPUT);

//
//
//
//

1
1
2
2

off
on
off
on

void loop()
{
// outlets on channel 1 on
digitalWrite(8, HIGH);
delay(1000);
digitalWrite(8, LOW);
delay(5000);
// outlets on channel 1 off
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(9, LOW);
delay(5000);
// outlets on channel 2 on
digitalWrite(4, HIGH);
delay(1000);
digitalWrite(4, LOW);

delay(5000);
// outlets on channel 2 off
digitalWrite(5, HIGH);
delay(1000);
digitalWrite(5, LOW);
delay(5000);
}

Now to get connected with our GSM shield. It is a simple task to insert the remote shield
over the GSM shield, and to connect the appropriate power supply and (for example)
GSM aerial. The control sketch is a slight modification of example 27.2, and is shown
below:
Example 33.2 (Mega version)
/*
Example 33.2 Control two AC remote outlets via SMS
tronixstuff.com/tutorials > chapter 33 | CC by-sa-nc
NOT for Arduino Mega
*/
#include
//Include the NewSoftSerial library to send serial commands
to the cellular module.
char inchar;
//Will hold the incoming character from the
Serial Port.
NewSoftSerial cell(2,3);
//Create a 'fake' serial port. Pin 2 is the
Rx pin, pin 3 is the Tx pin.
int
int
int
int
int

aon = 8;
aoff = 9;
bon = 4;
boff = 5;
pressdelay = 1000; // duration to activate a button on remote

void setup()
{
// prepare the digital output pins
pinMode(aon, OUTPUT);
pinMode(aoff, OUTPUT);
pinMode(bon, OUTPUT);
pinMode(boff, OUTPUT);
//Initialize GSM module serial port for communication.
cell.begin(9600);
delay(30000); // give time for GSM module to register on network etc.
cell.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to
serial out upon receipt
delay(200);
}
void loop()
{
//If a character comes in from the cellular module...
if(cell.available() >0)

inchar=cell.read();
if (inchar=='#')
{
delay(10);
inchar=cell.read();
if (inchar=='a')
{
delay(10);
inchar=cell.read();
if (inchar=='0')
{
digitalWrite(aoff, HIGH);
delay(pressdelay);
digitalWrite(aoff, LOW);
}
else if (inchar=='1')
{
digitalWrite(aon, HIGH);
delay(pressdelay);
digitalWrite(aon, LOW);
}
delay(10);
inchar=cell.read();
if (inchar=='b')
{
inchar=cell.read();
if (inchar=='0')
{
digitalWrite(boff, HIGH);
delay(pressdelay);
digitalWrite(boff, LOW);
}
else if (inchar=='1')
{
digitalWrite(bon, HIGH);
delay(pressdelay);
digitalWrite(bon, LOW);

}
}
}

}
delay(10);
inchar=cell.read();
cell.println("AT+CMGD=1,4"); // delete all SMS

The variable pressdelay stores the amount of time in milliseconds to press a remote
control button. To control our outlets, we send a text message using the following syntax:
#axbx

Where a/b are remote channels one and two, and x is replaced with 0 for off and 1 for on.
So there you have it controlling almost any AC powered device via text message from a
cellular phone. Imagine trying to do that ten, or even five years ago. As always, now it is
up to you and your imagination to find something to control or get up to other
shenanigans.

Tutorial: Arduino and the SPI bus


This is chapter thirty-four of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A seemingly endless tutorial on
the Arduino universe. The first chapter is here, the complete series is
detailed here. Please note that the tutorials are not currently compatible with Arduino
IDE v1.0. Please continue to usev22 or v23 until further notice.
Welcome back fellow arduidans!
This is the first of two chapters in which we are going to start investigating the SPI data
bus, and how we can control devices using it with our Arduino systems. The SPI bus may
seem to be a complex interface to master, however with some brief study of this
explanation and practical examples you will soon become a bus master! To do this we
will learn the necessary theory, and then apply it by controlling a variety of devices. In
this tutorial things will be kept as simple as possible.
But first of all, what is it? And some theory
SPI is an acronym for Serial Peripheral Interface. It is a synchronous serial data bus
data can travel in both directions at the same time, as opposed to (for example) the I2C
bus that cannot do so. To allow synchronous data transmission, the SPI bus uses four
wires. They are called:

MOSI Master-out, Slave-in. This line carries data from our Arduino to the SPIcontrolled device(s);
MISO Master-in, Slave out. This line carries data from the SPI-controlled
device(s) back to the Arduino;
SS Slave-select. This line tells the device on the bus we wish to communicate
with it. Each SPI device needs a unique SS line back to the Arduino;
SCK Serial clock.

Within these tutorials we consider the Arduino board to be the master and the SPI devices
to be slaves. On our Arduino Duemilanove/Uno and compatible boards the pins used are:

SS digital 10. You can use other digital pins, but 10 is generally the default as it
is next to the other SPI pins;
MOSI digital 11;
MISO digital 12;
SCK digital 13;

Arduino Mega users MISO is 50, MOSI is 51, SCK is 52 and SS is usually 53. If you
are using an Arduino Leonardo, the SPI pins are on the ICSP header pins. See here for
more information. You can control one or more devices with the SPI bus. For example,
for one device the wiring would be:

Data travels back and forth along the MOSI and MISO lines between our Arduino and the
SPI device. This can only happen when the SS line is set to LOW. In other words, to
communicate with a particular SPI device on the bus, we set the SS line to that device to
LOW, then communicate with it, then set the line back to HIGH. If we have two or more
SPI devices on the bus, the wiring would resemble the following:

Notice how there are two SS lines we need one for each SPI device on the bus. You can
use any free digital output pin on your Arduino as an SS line. Just remember to have all
SS lines high except for the line connected to the SPI device you wish to use at the time.
Data is sent to the SPI device in byte form. You should know by now that eight bits make
one byte, therefore representing a binary number with a value of between zero and 255.
When communicating with our SPI devices, we need to know which way the device deals
with the data MSB or LSB first. MSB (most significant bit) is the left-hand side of the

binary number, and LSB (least significant bit) is the right-hand side of the number. That
is:

Apart from sending numerical values along the SPI bus, binary numbers can also
represent commands. You can represent eight on/off settings using one byte of data, so a
devices parameters can be set by sending a byte of data. These parameters will vary with
each device and should be illustrated in the particular devices data sheet. For example, a
digital potentiometer IC with six pots:

This device requires two bytes of data. The ADDR byte tells the device which of six
potentiometers to control (numbered 0 to 5), and the DATA byte is the value for the
potentiometer (0~255). We can use integers to represent these two values. For example,
to set potentiometer number two to 125, we would send 2 then 125 to the device.
How do we send data to SPI devices in our sketches?
First of all, we need to use the SPI library. It is included with the default Arduino IDE
installation, so put the following at the start of your sketch:
#include "SPI.h"

Next, in void.setup() declare which pin(s) will be used for SS and set them as OUTPUT.
For example,
pinMode(ss, OUTPUT);

where ss has previously been declared as an integer of value ten. Now, to activate the SPI
bus:
SPI.begin();

and finally we need to tell the sketch which way to send data, MSB or LSB first by using

SPI.setBitOrder(MSBFIRST);

or
SPI.setBitOrder(LSBFIRST);

When it is time to send data down the SPI bus to our device, three things need to happen.
First, set the digital pin with SS to low:
digitalWrite(SS, LOW);

Then send the data in bytes, one byte at a time using:


SPI.transfer(value);

Value can be an integer/byte between zero and 255. Finally, when finished sending data
to your device, end the transmission by setting SS high:
digitalWrite(ss, HIGH);

Sending data is quite simple. Generally the most difficult part for people is interpreting
the device data sheet to understand how commands and data need to be structured for
transmission. But with some practice, these small hurdles can be overcome.
Now for some practical examples!
Time to get on the SPI bus and control some devices. By following the examples below,
you should gain a practical understanding of how the SPI bus and devices can be used
with our Arduino boards.
Example 34.1
Our first example will use a simple yet interesting part a digital potentiometer (we also
used one in the I2C tutorial). This time we have a Microchip MCP4162-series 10k
rheostat:

Here is the data sheet.pdf for your perusal. To control it we need to send two bytes of data
the first byte is the control byte, and thankfully for this example it is always zero (as the
address for the wiper value is 00h [see table 4-1 of the data sheet]). The second byte is
the the value to set the wiper, which controls the resistance. So to set the wiper we need
to do three things in our sketch
First, set the SS (slave select) line to low:
digitalWrite(10, LOW);

Then send the two byes of data:


SPI.transfer(0); // command byte
SPI.transfer(value); // wiper value

Finally set the SS line back to high:


digitalWrite(10, HIGH);

Easily done. Connection to our Arduino board is very simple consider the MCP4162
pinout:

Vdd connects to 5V, Vss to GND, to digital 10, SCK to digital 13, SDI to digital 11 and
SDO to digital 12. Now lets run through the available values of the MCP4162 in the
following sketch (download):
/*
Example 34.1 - SPI bus demo using a Microchip MCP4162 digital
potentiometer [http://bit.ly/iwDmnd]
http://tronixstuff.com/tutorials > chapter 34 | CC by-sa-nc | John
Boxall
*/
#include "SPI.h" // necessary library
int ss=10; // using digital pin 10 for SPI slave select
int del=200; // used for various delays
void setup()
{
pinMode(ss, OUTPUT); // we use this for SS pin
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
// our MCP4162 requires data to be sent MSB (most significant byte)
first
}
void setValue(int value)
{
digitalWrite(ss, LOW);
SPI.transfer(0); // send command byte
SPI.transfer(value); // send value (0~255)
digitalWrite(ss, HIGH);
}
void loop()
{
for (int a=0; a<256; a++)
{
setValue(a);
delay(del);
}
for (int a=255; a>=0; --a)
{
setValue(a);
delay(del);
}

Now to see the results of the sketch. In the following video clip, a we run up through the
resistance range and measure the rheostat value with a multimeter:

Before moving forward, if digital potentiometers are new for you, consider reading this
short guide written by Microchip about the differences between mechanical and digital
potentiometers.
Example 34.2
In this example, we will use the Analog Devices AD5204 four-channel digital
potentiometer (data sheet.pdf). It contains four 10k ohm linear potentiometers, and each
potentiometer is adjustable to one of 256 positions. The settings are volatile, which
means they are not remembered when the power is turned off. Therefore when power is
applied the potentiometers are all pre set to the middle of the scale. Our example is the
SOIC-24 surface mount example, however it is also manufactured in DIP format as well.

To make life easier it can be soldered onto a SOIC breakout board which converts it to a
through-hole package:

In this example, we will control the brightness of four LEDs. Wiring is very simple.
Pinouts are in the data sheet.pdf.

And the sketch (download):


/*

Example 34.2 - SPI bus demo using Analog Devices AD5204 digital
potentiometer [http://bit.ly/joB51b]
http://tronixstuff.com/tutorials > chapter 34 | CC by-sa-nc | John
Boxall
*/
#include "SPI.h" // necessary library
int ss=10; // using digital pin 10 for SPI slave select
int del=5; // used for fading delay
void setup()
{
pinMode(ss, OUTPUT); // we use this for SS pin
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
// our AD5204 requires data to be sent MSB (most significant byte)
first. See data sheet page 5
allOff(); // we do this as pot memories are volatile
}
void allOff()
// sets all potentiometers to minimum value
{
for (int z=0; z<4; z++)
{
setPot(z,0);
}

}
void allOn()
// sets all potentiometers to maximum value
{
for (int z=0; z<4; z++)
{
setPot(z,255);
}
}
void setPot(int pot, int level)
// sets potentiometer 'pot' to level 'level'
{
digitalWrite(ss, LOW);
SPI.transfer(pot);
SPI.transfer(level);
digitalWrite(ss, HIGH);
}
void blinkAll(int count)
{
for (int z=0; z=0; --l)
{
setPot(a,l);
delay(del);
}
}
}
void allFade(int count)
{
for (int a=0; a=0; --l)
{
setPot(0,l);
setPot(1,l);
setPot(2,l);
setPot(3,l);
delay(del);
}
}
}
void loop()
{
blinkAll(3);
delay(1000);
indFade();
allFade(3);
}

The function allOff() and allOn() are used to set the potentiometers to minimum and
maximum respectively. We use allOff() at the start of the sketch to turn the LEDs off.
This is necessary as on power-up the wipers are generally set half-way. Furthermore we
use them in the blinkAll() function to blink the LEDs. The function setPot() accepts a

wiper number (0~3) and value to set that wiper (0~255). Finally the function
indFade() does a nice job of fading each LED on and off in order causing an effect very
similar to pulse-width modulation.
Finally, here it is in action:
Question Would you use a rheostat or a potentiometer to divide voltage?
Example 34.3
In this example, we will use use a four-digit, seven-segment LED display that has an SPI
interface. Using such a display considerably reduces the amount of pins required on
the micro controller and also negates the use of shift register ICs which helps reduce
power consumption and component count. The front of our example:

and the rear:

Thankfully the pins are labelled quite clearly. Please note that the board does not include
header pins they were soldered in after receiving the board. Although this board is
documented by Sparkfun there seems to be issues in the operation, so instead we will use
a sketch designed by members of the Arduino forum. Not wanting to ignore this nice
piece of hardware we will see how it works and use it with the new sketch from the
forum.
Again, wiring is quite simple:

Board GND to Arduino GND


Board VCC to Arduino 5V
Board SCK to Arduino D12
Board SI to Arduino D11
Board CSN to Arduino D10

The sketch is easy to use, you need to replicate all the functions as well as the library
calls and variable definitions. To display numbers (or the letters A~F) on the display, call
the function
write_led(a,b,c);

where a is the number to display, b is the base system used (2 for binary, 8 for octal, 10
for usual, and 16 for hexadecimal), and c is for padded zeros (0 =off, 1=on). If you look
at the void loop() part of the example sketch, we use all four number systems in the
demonstration. If your number is too large for the display, it will show OF for
overflow. To control the decimal points, colon and the LED at the top-right the third digit,
we can use the following:
write_led_decimals(1); // left-most decimal point
write_led_decimals(2);
write_led_decimals(4);
write_led_decimals(8); // right-most decimal point
write_led_decimals(16); // colon LEDs
write_led_decimals(32); // apostrophe LED
write_led_decimals(0); // off

After all that, here is the demonstration sketch for your perusal (download):
/*
Example 34.3 - SPI bus demo using SFE 4-digit LED display
[http://bit.ly/ixQdbT]
http://tronixstuff.com/tutorials > chapter 34
Based on code by Quazar & Busaboi on Arduio forum http://bit.ly/iecYBQ
*/
#define
#define
#define
#define

DATAOUT 11 //MOSI
DATAIN 12 //MISO - not used, but part of builtin SPI
SPICLOCK 13 //sck
SLAVESELECT 10 //ss

char spi_transfer(volatile char data)


{
SPDR = data;
// Start the transmission
while (!(SPSR & (1<16) || (num>(base*base*base*base-1)) ) {
write_led_numbers(' ', 0x00, 0x0f, ' '); // indicate overflow
}
else {
while ( (num || pad) && (place<4) ) {
if ( (num>0) || pad )
digit[place++] = num % base;
num /= base;
}
write_led_numbers(digit[3], digit[2], digit[1], digit[0]);
}
}
void pointDemo()
{
write_led_decimals(1);
delay(1000);
write_led_decimals(2);
delay(1000);
write_led_decimals(4);
delay(1000);
write_led_decimals(8);
delay(1000);
write_led_decimals(16);
delay(1000);
write_led_decimals(32);
delay(1000);
write_led_decimals(0); // non-digits all off
}
void loop()
{
pointDemo();
delay(500);
for (int i = 0; i < 100; i++) {
write_led (i,10,1);
delay(25);
}
delay(500);
for (int i = 100; i >=0; --i) {
write_led (i,10,0);
delay(25);
}
delay(500); // now binary
for (int i = 0; i < 16; i++) {
write_led (i,2,0);
delay(100);
}
delay(500);
for (int i = 15; i >=0; --i) {
write_led (i,2,0);
delay(100);
}

delay(500); // now octal


for (int i = 0; i < 500; i++) {
write_led (i,8,0);
delay(50);
}
delay(500);
// now hexadecimal
for (int i = 20000; i < 22000; i++) {
write_led (i,16,0);
delay(50);
}
delay(500);
}

And a short video of the demonstration:


So there you have it hopefully an easy to understand introduction to the world of the
SPI bus and how to control the devices within. As always, now it is up to you and your
imagination to find something to control or get up to other shenanigans. In the next SPI
article we will look at reading and writing data via the SPI bus. If you have any
suggestions with regards to parts for the next article, leave a comment below and well
look into it. Thank you for your patience in awaiting this series of articles. Although
getting it together was a little tricky, it was a lot of fun. I hope you enjoyed reading it as
much as I did writing it for you.
If you have any questions about the processes or details in this article, please ask in
our Google Group dedicated to the projects and related items on this website. Sign up
its free, there is the odd competition or give-away and we can all learn something. Or
follow tronixstuff on twitter and facebook. High resolution images available on flickr.
Otherwise, have fun, stay safe, be good to each other and make something!

Tutorial: Video output from your Arduino


This is chapter thirty-five of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A seemingly endless series of tutorials about
the Arduino universe. The first chapter is here, the complete series is detailed here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this chapter we will examine something different the ability of our Arduino and
compatible boards to create composite video output. In other words, displaying stuff from
the Arduino on a TV. A lot of people were unaware of the ability to do this, however the
process is very simple and not difficult to implement from a hardware perspective. Within
this chapter we will learn to construct the minumum hardware required and demonstrate
basic functions to get started.
To whet your appetite, here is a quick video demonstration of what is possible:
You cant expect too much from a 16 Mhz microcontroller without a video card but the
price is right, and with some imagination and the right functions you can do quite well.
To make this happen we need to knock out some hardware of our own (or you could buy
a kit instead). Connection is very easy. First we need to locate three pins on our Arduino
board. They will be used to output Sync, Video and also GND. For those with Arduno
Uno/Duemilanove/Freetronics Eleven etc Sync is digital 9, video is digital 7 and GND is
GND. If you have a Mega/Mega2560 Sync is digital 11 and video is D29. There is
also the ability to generate audio with the methods in this article, and if you want to do
this the Uno (etc.) pin is digital 11 or 10 on the Mega.
The monitor or television used needs to have a composite video-in socket (jack). For
those with older televisions that have a VCR connected, you could use the video-in
socket on the VCR.
The schematic for video out is very simple, you only need two normal 0.25W resistors
and a video lead:

(tronixCAD v1.0)
If youre not up for soldering into an RCA plug, a simple way is to chop up a standard
video lead as such:

Then just wire the termination of the two resistors to the centre core (pin) and GND to
the shield. For the purpose of this article I have made a quick TV-out shield that also
includes a thumb joystick (as reviewed here).

A real triumph of engineering however it solves the problem. The vertical trimmer is
connected to A0; the horizontal to A1; the button to digital 8 via a 10k0 pull-up resistor.
Next, you will need to download and install the arduino-tvout library. It can be found
here. We will use the TVoutBeta1.zip version. Copy the downloaded folder into the
../arduino-002x/libraries folder and restart the Arduino IDE. Those of you who may have
a nootropic design Hackvision please note your library is different.
Now to see how to integrate TV-out into our sketch. We will run through the basic
functions which integrated with your imagination should see some interesting results
So lets go!
For every project, place these two lines at the top of your sketch:
#include <TVout.h>
TVout TV;

The first brings in the library, and the second line creates an instance of TV to use with
the library functions. Next, we need to activate TVout and select the appropriate
broadcast standard (PAL or NTSC). In void setup() use either
TV.start_render(_NTSC) // for NTSC (or)
TV.start_render(_PAL); // for PAL system

Now for the main functions. The first one of interest will be:
TV.clear_screen();

which clears the screen. Or if you would like to fill the screen with white, use

TV.fill_screen(1);

Moving on to write some text. First we need to select a font. There are three basic fonts
to choose from:

font4x6 (each character being 4 pixels by 6 pixels, etc.)


font6x8
font8x8

Well there is four, but it wouldnt display for me. Working on it! To choose a font use:
TV.select_font(font4x6); // using font4x6

Then to write the text, choose the screen location with:


TV.set_cursor(x,y);

then display the text with:


TV.print("Hello, world..."); // etc

You can also use TV.println(); to add a carriage return as expected. Display single
characters with a position in the one function using:
TV.print_char(x,y,c); // c is the character to display

So lets have a look at the various fonts in action with the following sketch (download):
Example 35.1
/*

Example 35.1 - arduino-tvout text demonstration


http://tronixstuff.wordpress.com/tutorials > chapter 35 | CC by-sa-nc
*/

#include
#include
TVout TV;
int d=10; // for delay purposes
char c='X';
void setup()
{
TV.begin(_PAL); // for PAL system
TV.clear_screen();
}
void loop()
{
TV.select_font(font4x6);

for (int a=0; a<6; a++)


{
for (int b=0; b<128; b++)
{
TV.print_char(b,a*6,c);
delay(d);
TV.clear_screen();
}
}
delay(1000);
TV.clear_screen();
TV.select_font(font6x8);
for (int a=0; a<6; a++)
{
for (int b=0; b<128; b++)
{
TV.print_char(b,a*8,c);
delay(d);
TV.clear_screen();
}
}
delay(1000);
TV.clear_screen();

TV.select_font(font8x8);
for (int a=0; a<6; a++)
{
for (int b=0; b<128; b++)
{
TV.print_char(b,a*8,c);
delay(d);
TV.clear_screen();
}
}
delay(1000);
TV.clear_screen();

Now to move into the 1970s with some basic graphical functions. We have a
screen resolution of 128 by 96 pixels to work with. When planning your display, you
need to ensure that the sketch never attempts to display a pixel outside of the 128 x 96
screen area. Doing so generally causes the Arduino to reboot.
First lets start with basic pixels. To draw a pixel, use:
TV.set_pixel(x,y,z);

where x and y are the coordinates of the pixel, and z is the colour (1 = white, 0 = black, 2
= inverse of current pixels colour). You want more than a pixel? How about a line:
TV.draw_line(x1,y1,x2,y2,colour);

Draws a line from x1, y1 to x2, y2 of colour colour. (1 = white, 0 = black, 2 = inverse of
current pixels colour).
Rectangles? Easy:
TV.draw_rectangle(x,y,w,h,colour,fill);

Draws a rectangle with the top-left corner at x,y; width w, height h, colour and optional
fill colour.
Circles are just as simple:
TV.draw_circle(x,y,r,colour,fill);

Draws a circle with centre at x,y; radius r pixels, edge colour, optional fill colour.
Now to see these functions in action with the following sketch (download):
Example 35.2
/*

Example 35.2 - arduino-tvout font demonstration II


http://tronixstuff.wordpress.com/tutorials > chapter 35 | CC by-sa-nc
*/

#include
TVout TV;
int d=100; // for delay purposes
int x1,x2,y1,y2,r=0;
void setup()
{
TV.begin(_PAL); // for PAL system
TV.clear_screen();
randomSeed(analogRead(0)); // seed the random number generator
}
void pixels()
{
TV.clear_screen();
for (int a=0; a<200; a++)
{
x1=random(128);
y1=random(96);
TV.set_pixel(x1,y1,2);
delay(d);
}
delay(1000);
TV.clear_screen();
}
void lines()

TV.clear_screen();
for (int a=0; a<96; a++)
{
TV.draw_line(0,a,127,a,1);
delay(d);
}
delay(500);
for (int a=0; a<96; a++)
{
TV.draw_line(0,a,127,a,0);
delay(d);
}
TV.clear_screen();
delay(500);

void circles()
{
TV.clear_screen();
for (int i=0; i<30; i++)
{
TV.draw_circle(64,48,i,1,0);
delay(200);
TV.draw_circle(64,48,i,1,1);
delay(200);
TV.draw_circle(64,48,i,0,0);
delay(200);
}
delay(1000);
TV.clear_screen();
}
void loop()
{
pixels();
lines();
circles();
}

And for the video demonstration:


So there you have it, a start with Arduino and TV-out. Furthermore, a big thanks to
http://code.google.com/u/mdmetzle/ for the arduino-tvout library.

Tutorial: Arduino and the SPI bus part II


This is chapter thirty-six of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A seemingly endless series of articles on
the Arduino universe. The first chapter is here, the complete series is
detailed here. Please note that the tutorials are not currently compatible with Arduino
IDE v1.0. Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
This is the second of several chapters in which we are investigating the SPI data bus, and
how we can control devices using it with our Arduino systems. If you have not done so
already, please read part one of the SPI articles. Again we will learn the necessary theory,
and then apply it by controlling a variety of devices. As always things will be kept as
simple as possible.
First on our list today is the use of multiple SPI devices on the single bus. We briefly
touched on this in part one, by showing how multiple devices are wired, for example:

Notice how the slave devices share the clock, MOSI and MISO lines however they both
have their own chip select line back to the master device. At this point a limitation of the

SPI bus becomes prevalent for each slave device we need another digital pin to control
chip select for that device. If you were looking to control many devices, it would be
better to consider finding I2C solutions to the problem. To implement multiple devices is
very easy. Consider the example 34.1 from part one we controlled a digital rheostat.
Now we will repeat the example, but instead control four instead of one. For reference,
here is the pinout diagram:

Doing so may sound complex, but it is not. We connect the SCK, MOSI and MISO pins
together, then to Arduino pins D13, D11, D12 respectively. Each CS pin is wired to a
separate Arduino digital pin. In our example rheostats 1 to 4 connect to D10 through to
D7 respectively. To show the resistance is changing on each rheostat, there is an LED
between pin 5 and GND and a 470 ohm resistor between 5V and pin 6. Next, here is the
sketch (download):
Example 36.1
/*
Example 36.1 - Multiple SPI bus device demo using four Microchip
MCP4162s [http://bit.ly/iwDmnd]
http://tronixstuff.com/tutorials > chapter 36 | CC by-sa-nc | John
Boxall
*/
#include "SPI.h" // necessary library
int del=3; // used for various delays
int
int
int
int

led1=10; // CS lines for each SPI device


led2=9;
led3=8;
led4=7;

void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);

SPI.begin(); // wake up the SPI bus.


SPI.setBitOrder(MSBFIRST);
// our MCP4162s requires data to be sent MSB (most significant byte)
first
}
void setValue(int l, int value)
// sends value 'value' to SPI device on CS digital out pin 'l'
{
digitalWrite(l, LOW);
SPI.transfer(0); // send command byte
SPI.transfer(value); // send value (0~255)
digitalWrite(l, HIGH);
}
void allOff()
// sets all pots to max resistance
{
setValue(led1,255);
setValue(led2,255);
setValue(led3,255);
setValue(led4,255);
}
void pulse(int l)
{
allOff();
for (int a=255; a>=0; --a)
{
setValue(l,a);
delay(del);
}
for (int a=0; a<256; a++)
{
setValue(l,a);
delay(del);
}
}
void pulseAll()
{
allOff();
for (int a=255; a>=0; --a)
{
setValue(led1,a);
setValue(led2,a);
setValue(led3,a);
setValue(led4,a);
delay(del);
}
for (int a=0; a<256; a++)
{
setValue(led1,a);
setValue(led2,a);
setValue(led3,a);
setValue(led4,a);
delay(del);

void loop()
{
pulse(led1);
pulse(led2);
pulse(led3);
pulse(led4);
pulseAll();
}

Although the example sketch may be longer than necessary, it is quite simple. We have
four SPI devices each controlling one LED, so to keep things easy to track we have
defined led1~led4 to match the chip select digital out pins used for each SPI device. Then
see the first four lines in void setup(); these pins are set to output in order to function as
required. Next this is very important we set the pins state to HIGH. You must do this
to every chip select line! Otherwise more than one CS pins may be initially low in some
instances and cause the first data sent from MOSI to travel along to two or more SPI
devices. With LEDs this may not be an issue, but for motor controllers well it could
be.
The other point of interest is the function
void setValue(int l, int value)

We pass the value for the SPI device we want to control, and the value to send to the
device. The value for l is the chip select value for the SPI device to control, and ranges
from 10~7 or as defined earlier, led1~4. The rest of the sketch is involved in controlling
the LEDs brightness by varying the resistance of the rheostats. Now to see example 36.1
in action via the following video clip:

(If you are wondering what I have done to the Freetronics board in that video, it was
to add a DS1307 real-time clock IC in the prototyping section).
Next on the agenda is a digital-to-analogue converter, to be referred to using the acronym
DAC. What is a DAC? In simple terms, it accepts a numerical value between zero and a
maximum value (digital) and outputs a voltage between the range of zero and a maximum
relative to the input value (analogue). One could consider this to be the opposite of the
what we use the function analogRead(); for. For our example we will use a Microchip
MCP4921 (data sheet.pdf):

(Please note that this is a beginners tutorial and is somewhat simplified). This DAC has a
12-bit resolution. This means that it can accept a decimal number between 0 and 4095
in binary this is 0 to 1111 1111 1111 (see why it is called 12-bit) and the outpout voltage
is divided into 4096 steps. The output voltage for this particular DAC can fall between 0
and just under the supply voltage (5V). So for each increase of 1 in the decimal input
value, the DAC will output around 1.221 millivolts.
It is also possible to reduce the size of the voltage output steps by using a lower reference
voltage. Then the DAC will consider the reference voltage to be the maximum output
with a value of 4095. So (for example) if the reference voltage was 2.5V, each increase of
1 in the decimal input value, the DAC will output around 0.6105 millivolts. The
minimum reference voltage possible is 0.8V, which offers a step of 200 microvolts (uV).
The output of a DAC can be used for many things, such as a function generator or the
playback of audio recorded in a digital form. (For an excellent example of this, check out
the adafruit waveshield). For now we will examine how to use the hardware, and
monitoring output on an oscilloscope. First we need the pinouts:

By now these sorts of diagrams shouldnt present any problems. In this example, we keep
pin 5 permanently set to GND; pin 6 is where you feed in the reference voltage we will
set this to +5V; AVss is GND; and Vouta is the output signal pin where the magic comes
from The next thing to investigate is the MCP4921s write command register:

Bits 0 to 11 are the 12 bits of the output value; bit 15 is an output selector (unused on the
MPC4921); bit 14 controls the input buffer; bit 13 controls an inbuilt output amplifier;
and bit 12 can shutdown the DAC. Unlike previous devices, the input data is spread
across two bytes (or a word of data). Therefore a small amount of work needs to be done
to format the data ready for the DAC. Lets explain this through looking at the sketch for
example 36.2 that follows. The purpose of the sketch is to go through all possible DAC
values, from 0 to 4095, then back to 0 and so on.
First. note the variable outputvalue - it is a word, a 16-bit unsigned variable. This is
perfect as we will be sending a word of data to the DAC. We put the
increasing/decreasing value for a into outputValue. However as we can only send bytes of
data at a time down the SPI bus, we will use the function highbyte() to separate the high
side of the word (bits 15~8) into a byte variable called data.
We then use the bitwise AND and OR operators to set the parameter bits 15~12. Then this
byte is sent to the SPI bus. Finally, the function lowbyte() is used to send the low side of
the word (bits 7~0) into data and thence down the SPI bus as well.
Now for our demonstration sketch (download):
Example 36.2
/*
Example 36.2 - SPI bus device demo using a Microchip MCP4921 DAC
[http://bit.ly/j3TSak]
http://tronixstuff.com/tutorials > chapter 36 | CC by-sa-nc | John
Boxall
*/
#include "SPI.h" // necessary library
int del=0; // used for various delays
word outputValue = 0; // a word is a 16-bit number
byte data = 0; // and a byte is an 8-bit number
void setup()
{
//set pin(s) to input and output
pinMode(10, OUTPUT);
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
}

void loop()
{
for (int a=0; a<=4095; a++)
{
outputValue = a;
digitalWrite(10, LOW);
data = highByte(outputValue);
data = 0b00001111 & data;
data = 0b00110000 | data;
SPI.transfer(data);
data = lowByte(outputValue);
SPI.transfer(data);
digitalWrite(10, HIGH);
delay(del);
}
delay(del+25);
for (int a=4095; a>=0; --a)
{
outputValue = a;
digitalWrite(10, LOW);
data = highByte(outputValue);
data = 0b00001111 & data;
data = 0b00110000 | data;
SPI.transfer(data);
data = lowByte(outputValue);
SPI.transfer(data);
digitalWrite(10, HIGH);
delay(del);
}
delay(del+25);
}

And a quick look at the DAC in action via an oscilloscope:


By now we have covered in detail how to send data to a device on the SPI bus. But how
do we receive data from a device?
Doing so is quite simple, but some information is required about the particular
device. For the rest of this chapter, we will use the Maxim DS3234 extremely accurate
real-time clock. Please download the data sheet (.pdf) now, as it will be referred to many
times.
The DS3234 is not available in through-hole packaging, so we will be using one that
comes pre-soldered onto a very convenient breakout board:

It only takes a few moments to solder in some header pins for breadboard use. The
battery type is CR1220 (12 x 2.0mm, 3V); if you dont have a battery you will need to
short out the battery holder with some wire otherwise the IC will not work. Readers have
reported that the IC doesnt keep time if the USB and external power are both applied to
the Arduino at the same time.
A device will have one or more registers where information is read from and written to.
Look at page twelve of the DS3234 data sheet, there are twenty-three registers, each
containing eight bits (one byte) of data. Please take note that each register has a read and
write address. An example to retrieve the contents of the register at location 08h (alarm
minutes) and place it into the byte data we need to do the following:
digitalWrite(10, LOW); // select the DS3234 that has its CS line on
digital 10
SPI.transfer(0x08); // tell the DS3234 device we're requesting data
from the register at 08h
data=SPI.transfer(0); // the DS3234 sends the data back and stores it
in the byte data
digitalWrite(10, HIGH); // deselect the DS3234 if finished with it

Dont forget to take note of the function SPI.setBitOrder(MSBFIRST); in your sketch, as


this also determines the bit order of the data coming from the device.
To write data to a specific address is also quite simple, for example:
digitalWrite(10, LOW);
SPI.transfer(0x80); // tells the device which address to write to
SPI.transfer(b00001010);
// you can send any representation of a byte
digitalWrite(10, HIGH);

Up to this point, we have not concerned ourselves with what is called the SPI data mode.
The mode determines how the SPI device interprets the pulses of data going in and out
of the device. For a well-defined explanation, please read this article. With some devices
(and in our forthcoming example) the data mode needs to be defined. So we use:
SPI.setDataMode(SPI_MODE1);

to set the data mode, within void(setup);. To determine a devices data mode, as always
consult the data sheet. With our DS3234 example, the mode is mentioned on page 1
under Features List.
Finally, lets delve a little deeper into SPI via the DS3234. The interesting people at
Sparkfun have already written a good demonstration sketch for the DS3234, so lets have
a look at that and deconstruct it a little to see what is going on. You can download the
sketch below from here, then change the file extension from .c to .pde.
#include
const int

cs=8; //chip select

void setup() {
Serial.begin(9600);
RTC_init();
//day(1-31), month(1-12), year(0-99), hour(0-23), minute(0-59),
second(0-59)
SetTimeDate(11,12,13,14,15,16);
}
void loop() {
Serial.println(ReadTimeDate());
delay(1000);
}
//=====================================
int RTC_init(){
pinMode(cs,OUTPUT); // chip select
// start the SPI library:
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE1); // both mode 1 & 3 should work
//set control register
digitalWrite(cs, LOW);
SPI.transfer(0x8E);
SPI.transfer(0x60); //60= disable Osciallator and Battery SQ
wave @1hz, temp compensation, Alarms disabled
digitalWrite(cs, HIGH);
delay(10);
}
//=====================================
int SetTimeDate(int d, int mo, int y, int h, int mi, int s){
int TimeDate [7]={s,mi,h,0,d,mo,y};
for(int i=0; i<=6;i++){
if(i==3)
i++;
int b= TimeDate[i]/10;

int a= TimeDate[i]-b*10;
if(i==2){
if (b==2)
b=B00000010;
else if (b==1)
b=B00000001;
}
TimeDate[i]= a+(b<<4);
digitalWrite(cs, LOW);
SPI.transfer(i+0x80);
SPI.transfer(TimeDate[i]);
digitalWrite(cs, HIGH);

}
}
//=====================================
String ReadTimeDate(){
String temp;
int TimeDate [7]; //second,minute,hour,null,day,month,year
for(int i=0; i<=6;i++){
if(i==3)
i++;
digitalWrite(cs, LOW);
SPI.transfer(i+0x00);
unsigned int n = SPI.transfer(0x00);
digitalWrite(cs, HIGH);
int a=n & B00001111;
if(i==2){
int b=(n & B00110000)>>4; //24 hour mode
if(b==B00000010)
b=20;
else if(b==B00000001)
b=10;
TimeDate[i]=a+b;
}
else if(i==4){
int b=(n & B00110000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==5){
int b=(n & B00010000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==6){
int b=(n & B11110000)>>4;
TimeDate[i]=a+b*10;
}
else{
int b=(n & B01110000)>>4;
TimeDate[i]=a+b*10;
}
}
temp.concat(TimeDate[4]);
temp.concat("/") ;
temp.concat(TimeDate[5]);
temp.concat("/") ;
temp.concat(TimeDate[6]);

temp.concat("
") ;
temp.concat(TimeDate[2]);
temp.concat(":") ;
temp.concat(TimeDate[1]);
temp.concat(":") ;
temp.concat(TimeDate[0]);
return(temp);

Dont let the use of custom functions and loops put you off, they are there to save time.
Looking in the function SetTimeDate();, you can see that the data is written to the
registers 80h through to 86h (skipping 83h day of week) in the way as described earlier
(set CS low, send out address to write to, send out data, set CS high). You will also notice
some bitwise arithmetic going on as well. This is done to convert data between binarycoded decimal and decimal numbers.
Why? Go back to page twelve of the DS3234 data sheet and look at (e.g.) register
00h/80h seconds. The bits 7~4 are used to represent the tens column of the value, and
bits 3~0 represent the ones column of the value. So some bit shifting is necessary to
isolate the digit for each column in order to convert the data to decimal. For other ways to
convert between BCD and decimal, see the examples using the Maxim DS1307 in
chapter seven.
So there you have it more about the world of the SPI bus and how to control the devices
within. As always, now it is up to you and your imagination to find something to control
or get up to other shenanigans.

Tutorial: Arduino timing methods with millis()


This is chapter thirty-seven of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall in what feels like an endless series of articles on
the Arduino universe. The first chapter is here, the complete series is detailed here. Any
files from tutorials will be found here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this article we introduce the millis(); function and put it to use to create various timing
examples. Please ensure you are running version 13 or upwards of the Arduino IDE.
Millis? Nothing to do with lip-syncers hopefully you recognised milli as being the
numerical prefix for one-thousandths; that is multiplying a unit of measure by 0.001 (or
ten to the power of negative 3). Interestingly our Arduino systems will count the number
of milliseconds (thousands of a second) from the start of a sketch running until the count
reaches the maximum number capable of being stored in the variable type unsigned long
(a 32-bit [four byte] integer that ranges from zero to (2^32)-1.
(2^32)-1, or 4294967295 milliseconds converts to 49.71027-odd days. The counter resets
when the Arduino is reset, it reaches the maximum value or a new sketch is uploaded. To
get the value of the counter at a particular juncture, just call the function for example:

start=millis();

Where start is an unsigned long variable. Here is a very simple example (download
sketch) to show you millis() in action:
Example 37.1
/*
Example 37.1 - millis() demonstration
http://tronixstuff.wordpress.com/tutorials > chapter 37
John Boxall | CC by-sa-nc

*/

unsigned long start, finished, elapsed;


void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println("Start...");
start=millis();
delay(1000);
finished=millis();
Serial.println("Finished");
elapsed=finished-start;
Serial.print(elapsed);
Serial.println(" milliseconds elapsed");
Serial.println();
delay(500);
}

The sketch stores the current millis count in start, then waits one second, then stores the
value of millis again in finished. Finally it calculates the elapsed time of the delay. In the
following screen dump of the serial monitor, you can see that the duration was not always
exactly 1000 milliseconds:

To put it simply, the millis function makes use of an internal counter within the ATmega
microcontroller at the heart of your Arduino. This counter increments every clock cycle
which happens (in standard Arduino and compatibles) at a clock speed of 16 Mhz. This
speed is controlled by the crystal on the Arduino board (the silver thing with T16.000
stamped on it):

Crystal accuracy can vary depending on external temperature, and the tolerance of the
crystal itself. This in turn will affect the accuracy of your millis result. Anecdotal
experience has reported the drift in timing accuracy can be around three or four seconds
per twenty-four hour period. If you are using a board or your own version that is using a
ceramic resonator instead of a crystal, note that they are not as accurate and will
introduce the possibility of higher drift levels. If you need a much higher level of timing
accuracy, consider specific timer ICs such as the Maxim DS3231.
Now we can make use of the millis for various timing functions. As demonstrated in the
previous example sketch, we can calculate elapsed time. To take this idea forward, lets
make a simple stopwatch. Doing so can be as simple or as complex as necessary, but for
this case we will veer towards simple. On the hardware perspective, we will have two
buttons Start and Stop - with the 10k ohm pull-down resistors connected to digital pins
2 and 3 respectively.
When the user presses start the sketch will note the value for millis then after stop is
pressed, the sketch will again note the value for millis, calculate and display the elapsed
time. The user can then press start to repeat the process, or stop for updated data. Here is
the sketch (download):
Example 37.2
/*
Example 37.2 Super-basic stopwatch using millis();
http://tronixstuff.wordpress.com/tutorials > chapter 37
John Boxall | CC by-sa-nc

*/

unsigned long start, finished, elapsed;


void setup()
{
Serial.begin(9600);

pinMode(2, INPUT); // start button


pinMode(3, INPUT); // stop button
Serial.println("Press 1 for Start/reset, 2 for elapsed time");

void displayResult()
{
float h,m,s,ms;
unsigned long over;
elapsed=finished-start;
h=int(elapsed/3600000);
over=elapsed%3600000;
m=int(over/60000);
over=over%60000;
s=int(over/1000);
ms=over%1000;
Serial.print("Raw elapsed time: ");
Serial.println(elapsed);
Serial.print("Elapsed time: ");
Serial.print(h,0);
Serial.print("h ");
Serial.print(m,0);
Serial.print("m ");
Serial.print(s,0);
Serial.print("s ");
Serial.print(ms,0);
Serial.println("ms");
Serial.println();
}
void loop()
{
if (digitalRead(2)==HIGH)
{
start=millis();
delay(200); // for debounce
Serial.println("Started...");
}
if (digitalRead(3)==HIGH)
{
finished=millis();
delay(200); // for debounce
displayResult();
}
}

The calls to delay() are used to debounce the switches these are optional and their use
will depend on your hardware. Below is an example of the sketchs serial monitor output
the stopwatch has started, and then button two pressed six times across periods of time:

If you had a sensor at the start and end of a fixed distance, speed could be calculated:
speed = distance time.
You can also make a speedometer for a wheeled form of motion, for example a bicycle.
At the present time I do not have a bicycle to mess about with, however we can describe
the process to do so it is quite simple. (Disclaimer do so at your own risk etc.) First
of all, lets review the necessary maths. You will need to know the circumference of the
wheel. Hardware you will need a sensor. For example a reed switch and magnet.
Consider the reed switch to be a normally-open button, and connect as usual with a 10k
ohm pull-down resistor. Others may use a hall-effect sensor each to their own).
Remember from maths class:

(image licence)
To calculate the circumference use the formula:
circumference = 2r
where r is the radius of the circle. Now that you have the wheel circumference, this value
can be considered as our fixed distance, and therefore the speed can be calculated by
measuring the elapsed time between of a full rotation.
Your sensor once fitted should act in the same method as a normally-open button that
is pushed every rotation. Our sketch will measure the time elapsed between every pulse
from the sensor. To do this, our example will have the sensor output connected to digital
pin 2 as it will trigger an interrupt to calculate the speed. (Interrupts? See chapter three).
The sketch will otherwise be displaying the speed on a normal I2C-interface LCD
module. The I2C interface is suggested as this requires only 4 wires from the Arduino
board to the LCD the less wires the better.
Here is the sketch for your perusal (download):
Example 37.3
/*

Example 37.3 Basic speedometer using millis();


http://tronixstuff.wordpress.com/tutorials > chapter 37
John Boxall | CC by-sa-nc

*/

#include "Wire.h" // for I2C bus LCD


#include "LiquidCrystal_I2C.h" // for I2C bus LCD module http://bit.ly/m7K5wt
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a
16 chars and 2 line display
float start, finished;
float elapsed, time;
float circMetric=1.2; // wheel circumference relative to sensor position
(in meters)
float circImperial; // using 1 kilometer = 0.621371192 miles
float speedk, speedm;
// holds calculated speed vales in metric and
imperial
void setup()
{
attachInterrupt(0, speedCalc, RISING); // interrupt called when
sensors sends digital 2 high (every wheel rotation)
start=millis();
// setup LCD
lcd.init();
// initialize the lcd
lcd.backlight(); // turn on LCD backlight
lcd.clear();
lcd.println(" Wear a helmet! ");
delay(3000);
lcd.clear();
Serial.begin(115200);
circImperial=circMetric*.62137; // convert metric to imperial for MPH
calculations
}
void speedCalc()
{
elapsed=millis()-start;
start=millis();
speedk=(3600*circMetric)/elapsed; // km/h
speedm=(3600*circImperial)/elapsed; // Miles per hour
}
void loop()
{
lcd.setCursor(0,0);
lcd.print(int(speedk));
lcd.print(" km/h ");
lcd.print(int(speedm));
lcd.print(" MPH
");
lcd.setCursor(0,1);
lcd.print(int(elapsed));
lcd.print(" ms/rev
");
delay(1000); // adjust for personal preference to minimise flicker
}

There isnt that much going on every time the wheel completes one revolution the
signal from the sensor will go from low to high triggering an interrupt which calls the
function speedCalc(). This takes a reading of millis() and then calculates the difference

between the current reading and the previous reading this value becomes the time to
cover the distance (which is the circumference of the wheel relative to the sensor stored
in
float circMetric=1.2;

and is measured in metres). It finally calculates the speed in km/h and MPH. Between
interrupts the sketch displays the updated speed data on the LCD as well as the raw time
value for each revolution for curiositys sake. In real life I dont think anyone would
mount an LCD on a bicycle, perhaps an LED display would be more relevant. If you
didnt feel like making something from scratch, you could use a Digit Shield or
something similar. In the meanwhile, you can see how this example works in the
following short video clip. Instead of a bike wheel and reed switch/magnet combination, I
have connected the square-wave output from a function generator to the interrupt pin to
simulate the pulses from the sensor, so you can get an idea of how it works:
That just about sums up the use of millis() for the time being. There is also the micros();
function which counts microseconds.
So there you have it another practical function that can allow more problems to be
solved via the world of Arduino. As always, now it is up to you and your imagination to
find something to control or get up to other shenanigans.

Tutorial: Arduino and a Thermal Printer


This is chapter thirty-eight of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here. Any files from tutorials will be
found here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this article we introduce the inexpensive thermal printer that has recently become
widely available from Sparkfun and their resellers. The goal of the article is to be as
simple as possible so you can get started without any problems or confusion. In the past
getting data from our Arduino to a paper form would either have meant logging it to an
SD card then using a PC to finish the job, or perhaps viewing said data on an LCD then
writing it down. Not any more with the use of this cheap and simple serial printer.
Before we get started, here is a short demonstration video of it in action:

Not bad at all considering the price. Lets have a look in more detail. Here is the printer
and two matching rolls of thermal paper:

and the inside of the unit:

Loading paper is quite simple, just drop the roll in with the end of the paper facing away
from you, pull it out further than the top of the front lip, then close the lid. The paper rolls
required need to be 57mm wide and have a diameter of no more than 39mm. For
example. There is a piece of white cardboard stuck to the front this is an economical
cover that hides some of the internals. Nothing of interest for us in there. The button next
to the LED on the left is for paper advance, and the LED can blink out the printer status.
From a hardware perspective wiring is also very simple. Looking at the base of the
printer:

there are two connections. On the left is DC power, and data on the right. For this
example I have fitted my own rubber feet to stop the printer rocking about. Thankfully
the leads are included with the printer and have the plugs already fitted a great time
saver.
Please note you need an external power supply with a voltage of between 5 and 9
volts DC that can deliver up to 1.5 amps of current. When idling the printer draws less
than 10 milliamps, but when printing it peaks at around 1.47 A. So dont try and run it
from your Arduino board. Furthermore you need to ensure the GND from your printer
runs to the power supply GND and the Arduino GND. However the data lines are easy, as
the printer has a serial interface we only need to connect printer RX (white) to Arduino
digital 3, and printer TX (green) to Arduino digital 2. We will use a virtual serial port on
pins 2 and 3 as 0 and 1 will be taken for use with the serial monitor window for
debugging and possible control purposes.
If you want to quickly test your printer connect it to the power, drop in some paper,
hold down the feed button and turn on the power. It will quickly produce a test print.
Next we need to understand how to control the printer in our sketches. Consider this very
simple sketch (download):
/*
Example 38.1 - Sparkfun Thermal Printer Test (COM-10438)
http://tronixstuff.wordpress.com/tutorials > chapter 38
Based on code by Nathan Seidle of Spark Fun Electronics 2011
http://littlebirdelectronics.com/products/thermal-printer
*/
#include
NewSoftSerial Thermal(2, 3); // printer green to digital 2, printer
white to digital 3
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15;
char printBreakTime = 15;
void setup()
{
Serial.begin(57600); // used for debugging via serial monitor
Thermal.begin(19200); // used for writing to the printer
initPrinter();
}
void initPrinter()
{
//Modify the print speed and heat
Thermal.print(27, BYTE);
Thermal.print(55, BYTE);
Thermal.print(7, BYTE); //Default 64 dots = 8*('7'+1)

Thermal.print(heatTime, BYTE); //Default 80 or 800us


Thermal.print(heatInterval, BYTE); //Default 2 or 20us
//Modify the print density and timeout
Thermal.print(18, BYTE);
Thermal.print(35, BYTE);
int printSetting = (printDensity<<4) | printBreakTime;
Thermal.print(printSetting, BYTE); //Combination of printDensity and
printBreakTime
Serial.println();
Serial.println("Printer ready");
}
void loop()
{
Thermal.println(" Visit http://tronixstuff.com ");
Thermal.print(10, BYTE); // Sends the LF to the printer, advances the
paper
Thermal.print("
Millis = ");
Thermal.println(millis());
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
do { } while (1>0);
}

After ensuring your printer is connected as described earlier, and has the appropriate
power supply and paper uploading the sketch will result in the following:

Now that the initial burst of printing excitement has passed, lets look at the sketch and
see how it all works. The first part:
#include <NewSoftSerial.h>
NewSoftSerial Thermal(2, 3); // printer RX to digital 2, printer TX to
digital 3

configures the virtual serial port and creates an instance for us to refer to when writing to
the printer. Next, four variables are defined. These hold parameters used for configuring
the printer. As the printer works with these settings there is no need to alter them,
however if you are feeling experimental nothing is stopping you. Next we have the
function initPrinter(). This sets a lot of parameters for the printer to ready itself for work.
We call initPrinter() only once in void setup(); For now we can be satisfied that it just
works.
Now time for action void loop(). Writing text to the printer is as simple as:
Thermal.print("text");

You can also use .println to advance along to the next line. Generally this is the same as
writing to the serial monitor with Serial.println() etc. So nothing new there. Each line of
text can be up to thirty-two characters in length.
The next thing to concern ourselves with is sending commands to the printer. You may
have noticed the line
Thermal.print(10, BYTE);

This sends the command to advance to the next line (in the old days we would say
carriage return and line feed). There are many commands available to do various things.
When sending commands, dont use .println() - as this sends the carriage return as
well. At this point you will need to refer to the somewhat amusing user manual.pdf. Open
it up and have a look at section 5.2.1 on page ten. Notice how each command has an
ASCII, decimal and hexadecimal equivalent? We will use the decimal command values.
So to send them, just use:
Thermal.print(value, BYTE);

Easy. If the command has two or more values (for example, to turn the printer offline
[page 11] ) just send each value in a separate statement. For example:
Thermal.print(27, BYTE);
Thermal.print(61, BYTE);
Thermal.print(0, BYTE);

will put the printer into offline mode.


For out next example, lets try out a few more commands:

Underlined text (the printer seemed to have issues with thick underlining,
however your experience may vary)
Bold text
Double height and width

Here is the sketch (download):


/*
Example 38.2 - Sparkfun Thermal Printer Test II (COM-10438)
http://tronixstuff.wordpress.com/tutorials > chapter 38
Based on code by Nathan Seidle of Spark Fun Electronics 2011
http://littlebirdelectronics.com/products/thermal-printer
*/
#include
NewSoftSerial Thermal(2, 3); // printer RX to digital 2, printer TX to
digital 3
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15;
char printBreakTime = 15;
void setup()
{
Serial.begin(57600); // for debug info to serial monitor
Thermal.begin(19200); // to write to our new printer
initPrinter();
}
void initPrinter()
{
//Modify the print speed and heat
Thermal.print(27, BYTE);
Thermal.print(55, BYTE);
Thermal.print(7, BYTE); //Default 64 dots = 8*('7'+1)
Thermal.print(heatTime, BYTE); //Default 80 or 800us
Thermal.print(heatInterval, BYTE); //Default 2 or 20us
//Modify the print density and timeout
Thermal.print(18, BYTE);
Thermal.print(35, BYTE);
int printSetting = (printDensity<<4) | printBreakTime;
Thermal.print(printSetting, BYTE); //Combination of printDensity and
printBreakTime
Serial.println();
Serial.println("Printer ready");
}
void loop()
{
// underline - one pixel
Thermal.print(27,BYTE);
Thermal.print(45,BYTE);
Thermal.print(1,BYTE);
Thermal.println("Underline - thin");
Thermal.println("01234567890123456789012345678901");
Thermal.print(10,BYTE);
// underline - two pixels
Thermal.print(27,BYTE);

Thermal.print(45,BYTE);
Thermal.print(2,BYTE);
Thermal.println("Underline - thick");
Thermal.println("01234567890123456789012345678901");
Thermal.print(10,BYTE);
// turn off underline
Thermal.print(27,BYTE);
Thermal.print(45,BYTE);
Thermal.print(0,BYTE);
delay(3000);
Thermal.print(10,BYTE);
// bold text on
Thermal.print(27,BYTE);
Thermal.print(32,BYTE);
Thermal.print(1,BYTE);
Thermal.println(" #### Bold text #### ");
Thermal.println("01234567890123456789012345678901");
delay(3000);
// bold text off
Thermal.print(27,BYTE);
Thermal.print(32,BYTE);
Thermal.print(0,BYTE);
Thermal.print(10, BYTE); //Sends the LF to the printer, advances the
paper
delay(3000);
// height/width enlarge
Thermal.print(29,BYTE);
Thermal.print(33,BYTE);
Thermal.print(255,BYTE);
Thermal.println("ABCDEF");
Thermal.println("012345");
delay(3000);
// back to normal
Thermal.print(29,BYTE);
Thermal.print(33,BYTE);
Thermal.print(0,BYTE);
delay(3000);
Thermal.print(10, BYTE);
Thermal.println("Back to normal...");
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
do { } while (1>0); // do nothing
}

And the results:

Frankly bold doesnt look that bold, so I wouldnt worry about it too much. However the
oversized characters could be very useful, and still print relatively quickly.
Next on our list are barcodes. A normal UPC barcode has 12 digits, and our little printer
can generate a variety of barcode types see page twenty-two of the user manual. For our
example we will generate UPC-A type codes and an alphanumeric version. Alphanumeric
barcodes need capital letters, the dollar sign, percent sign, or full stop. The data is kept in
an array of characters named barCode[] and barCode[]2. Consider the
functions printBarcode(), printBarcodeThick() and printBarcodeAlpha() in the following
example sketch (download):
/*
Example 38.3 - Sparkfun Thermal Printer Test III (COM-10438)
http://tronixstuff.wordpress.com/tutorials > chapter 38
Based on code by Nathan Seidle of Spark Fun Electronics 2011
http://littlebirdelectronics.com/products/thermal-printer
*/
#include
NewSoftSerial Thermal(2, 3); // printer RX to digital 2, printer TX to
digital 3
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15;
char printBreakTime = 15;
char barCode[]={ '9','2','3','0','5','6','4','8','9','8','4','4'};

char
barCode2[]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P' };
void setup()
{
Serial.begin(57600); // for debug info to serial monitor
Thermal.begin(19200); // to write to our new printer
initPrinter();
}
void initPrinter()
{
//Modify the print speed and heat
Thermal.print(27, BYTE);
Thermal.print(55, BYTE);
Thermal.print(7, BYTE); //Default 64 dots = 8*('7'+1)
Thermal.print(heatTime, BYTE); //Default 80 or 800us
Thermal.print(heatInterval, BYTE); //Default 2 or 20us
//Modify the print density and timeout
Thermal.print(18, BYTE);
Thermal.print(35, BYTE);
int printSetting = (printDensity<<4) | printBreakTime;
Thermal.print(printSetting, BYTE); //Combination of printDensity and
printBreakTime
Serial.println();
Serial.println("Printer ready");
}
void printBarcode(char zz[])
{
Thermal.print(29, BYTE); //GS
Thermal.print(107, BYTE); //k
Thermal.print(0, BYTE); //m = 0
for (int z=0; z<12; z++)
{
Thermal.print(zz[z]);
}
Thermal.print(0, BYTE); // bar code terminator
delay(3000);
// necessary delay
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
}
void printBarcodeThick(char zz[])
{
Thermal.print(29, BYTE); // specified height of barcode
Thermal.print(104, BYTE);
Thermal.print(200, BYTE); // 200 pixels high (default is 50)
Thermal.print(29, BYTE); //GS
Thermal.print(107, BYTE); //k
Thermal.print(0, BYTE); //m = 0
for (int z=0; z<12; z++)
{
Thermal.print(zz[z]);

}
Thermal.print(0, BYTE); //
delay(3000);
//
Thermal.print(29, BYTE); //
Thermal.print(104, BYTE);
Thermal.print(50, BYTE); //
delay(3000);
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);

bar code terminator


necessary delay
specified height of barcode
need to set back to 50 pixel height

}
void printBarcodeAlpha(char zz[])
{
Thermal.print(29, BYTE); //GS
Thermal.print(107, BYTE); //k
Thermal.print(4, BYTE); //m = 0
for (int z=0; z<16; z++)
{
Thermal.print(zz[z]);
}
Thermal.print(0, BYTE); // bar code terminator
delay(3000);
// necessary delay
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
Thermal.print(10, BYTE);
}
void loop()
{
printBarcode(barCode);
printBarcodeThick(barCode);
printBarcodeAlpha(barCode2);
do {} while (1>0);
}

Notice in printBarcodeThick() we make use of the ability to change the vertical size of
the barcode the height in pixels is the third parameter in the group. And here is the
result:

So there you have it another practical piece of hardware previously considered to be out
of our reach is now under our control. Now you should have an understanding of the
basics and can approach the other functions in the user guide with confidence. Please
keep in mind that the price of this printer really should play a large part in determining
suitability for a particular task. It does have issues printing large blocks of pixels, such as
the double-width underlining and inverse text. This printer is great but certainly not for
commercial nor high-volume use. That is what professional POS printers from Brother,
Star, Epson, etc., are for. However for low-volume, personal or hobby use this printer is
certainly a deal. As always, now it is up to you and your imagination to put this to use or
get up to other shenanigans.
This article would not have been possible without the example sketches provided by
Nathan Seidle, the founder and CEO of Sparkfun. If you meet him, shout him a beer.
Please dont knock off bus tickets or so on. Im sure there are heavy penalties for doing
so if caught.
Update! adafruit are also selling these printers, and have written their own completely
awesome library as well as a matching tutorial.

Tutorial: Arduino and the NXP SAA1064 4-digit LED


display driver
This is chapter thirty-nine of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here. Any files from tutorials will be
found here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this article we investigate controlling the NXP (formerly Philips) SAA1064 4-digit
LED display driver IC with Arduino and the I2C bus interface. If you are not familiar
with using the I2C bus, please read my tutorials (parts one and two) before moving on.
Although the SAA1064 is not the newest on the market, it is still popular, quite
inexpensive and easy to source. Furthermore as it is controlled over the I2C bus you
dont waste any digital I/O pins on your Arduino, and you can also operate up to four
SAA1064s at once (allowing 16 digits!). Finally, it has a constant-current output
keeping all the segments of your LED display at a constant brightness (which is also
adjustable). So lets get started
Here is an example of the SAA1064 in SOIC surface mount packaging:

It measures around 15mm in length. For use in a solderless breadboard, I have soldered
the IC onto a through-hole adaptor:

The SAA1064 is also available in a regular through-hole DIP package. At this point,
please download the data sheet (.pdf) as you will need to refer to it during the article.
Next, our LED display examples. We need common-anode displays, and for this article
we use two Agilent HDSP521G two-digit modules (data sheet [.pdf]) as shown below:

For the uninitiated a common anode display has all the segments anodes connected
together, with the cathodes terminated separately. For example, our LED displays are
wired as such:

Notice the anodes for the left digit are pin 14, and the right digit pin 13. A device that is
connected to all the cathodes (e.g. our SAA1064) will control the current flow through
each element thereby turning each segment on (and controlling the brightness) or off.
Our SAA1064 is known as a current-sink as the current flows through the LED, and then
sinks into the IC.
Now, lets get it connected. There is an excellent demonstration circuit on page twelve of
the data sheet that we will follow for our demonstrations:

It looks pretty straight-forward, and it is. The two transistors are standard NPN-type, such
as PN2222. The two transistors are used to each turn on or off a pair of digits as the IC
can only drive digits 1+3 or 2+4 together. (When presented in real life the digits are
numbered 4-3-2-1). So the pairs are alternatively turned on and off at a rapid rate, which
is controlled by the capacitor between pin 2 and GND. The recommended value is 2.7 nF.
At the time of writing, I didnt have that value in stock, so chose a 3.3 nF instead.
However due to the tolerance of the ceramic capacitor it was actually measured to be 2.93
nF:

So close enough to 2.7 nF will be OK. The other capacitor shown between pins 12 and 13
is a standard 0.1 uF smoothing capacitor. Pin 1 on the SAA1064 is used to determine the
I2C bus address for our example we have connected it straight to GND (no resistors at
all) resulting in an address of 070. See the bottom page five of the data sheet for other
address options. Power for the circuit can be taken from your Arduinos 5V pin and
dont forget to connect the circuit GND to Arduino GND. You will also use 4.7k ohm
pull-up resistors on the SDA and SCL lines of the I2C bus.
The last piece of the schematic puzzle is how to connect the cathodes of the LED displays
to the SAA1064. Display pins 14 and 13 are the common anodes of the digits.
The cathodes for the left-hand display module:

LED display pins 4, 16, 15, 3, 2, 1, 18 and 17 connect to SAA1064 pins 22, 21,
20, 19, 18, 17, 16 and 15 respectively (that is, LED pin 4 to IC pin 22, etc.);
LED display pins 9, 11, 10, 8, 6, 5, 12 and 7 also connect to SAA1064 pins 22,
21, 20, 19, 18, 17, 16 and 15 respectively.

The cathodes for the right-hand display module:


LED display pins 4, 16, 15, 3, 2, 1, 18 and 17 connect to SAA1064 pins 3, 4, 5, 6,
7, 8, 9 and 10 respectively;
LED display pins 9, 11, 10, 8, 6, 5, 12 and 7 also connect to SAA1064 pins 3, 4,
5, 6, 7, 8, 9 and 10 respectively.

Once your connections have been made, you could end up with spaghetti junction like
this

Note the use of the Arduino Nano they are very convenient when doing
small prototyping on solderless breadboards.
-=Now it is time to consider the Arduino sketch to control out SAA1064. Each write request
to the SAA1064 requires several bytes. We either send a control command (to alter some
of the SAA1064 parameters such as display brightness) or a display command (actually
display numbers). For our example sketches the I2C bus address 070 >> 1 is stored in
the byte variable saa1064. First of all, lets look at sending commands, as this is always
done first in a sketch to initiate the SAA1064 before sending it data.
As always, we send the address down the I2C bus to awaken the SAA1064 using
Wire.beginTransmission(saa1064);

Then the next byte is the instruction byte. If we send zero:


Wire.send(B00000000);

the IC expects the next byte down the bus to be the command byte. And finally our
command byte:
Wire.send(B01000111);

The control bits are described on page six of the data sheet. However for four-digit
operation bits 0, 1 and 2 should be 1; bit 3 should be 0; and bits 4~6 determine the
amount of current allowed to flow through the LED segments. Note that they are
cumulative, so if you set bits 5 and 6 to 1 18 mA of current will flow. We will
demonstrate this in detail later on.
Next, to send actual numbers to be displayed is slightly different. Note that the digits are
numbered (from left to right) 4 3 2 1. Again, we first send the address down the I2C bus
to awaken the SAA1064 using
Wire.beginTransmission(saa1064);

Then the next byte is the instruction byte. If we send 1, the next byte of data will
represent digit 1. If that follows with another byte, it will represent digit 2. And so on. So
to send data to digit 1, send
Wire.send(B00000001);

Although sending binary helps with the explanation, you can send decimal equivalents.
Next, we send a byte for each digit (from right to left). Each bit in the byte represents a
single LED element of the digit as well as the decimal point. Note how the elements are
labelled (using A~G and DP) in the following image:

The digit bytes describe which digit elements to turn on or off. The bytes are described as
such: Bpgfedcba. (p is the decimal point). So if you wanted to display the number 7, you
would send B00000111 as this would turn on elements a, b and c. To add the decimal
point with 7 you would send B10000111. You can also send the byte as a decimal
number. So to send the digit 7 as a decimal, you would send 7 as 00000111 in base-10
is 7. To include the decimal point, send 135 as 100000111 in base-10 is 135. Easy! You
can also create other characters such as A~F for hexadecimal. In fact lets do that now in
the following example sketch (download):
/*

Example 39.1 - NXP SAA1064 I2C LED Driver IC Demo I


Demonstrating display of digits
http://tronixstuff.wordpress.com/tutorials > chapter 39
John Boxall July 2011 | CC by-sa-nc
*/

#include "Wire.h"

// enable I2C bus

byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064
(pin 1 to GND)
int digits[16]={63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57,
94, 121, 113};
// these are the byte representations of pins required to display each
digit 0~9 then A~F

void setup()
{
Wire.begin(); // start up I2C bus
delay(500);
initDisplay();
}
void initDisplay()
// turns on dynamic mode and adjusts segment current to 12mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B01000111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 12mA segment current
Wire.endTransmission();
}
void displayDigits()
// show all digits 0~9, A~F on all digits of display
{
for (int z=0; z<16; z++)
{
Wire.beginTransmission(saa1064);
Wire.send(1); // instruction byte - first digit to control is 1
(right hand side)
Wire.send(digits[z]); // digit 1 (RHS)
Wire.send(digits[z]); // digit 2
Wire.send(digits[z]); // digit 3
Wire.send(digits[z]); // digit 4 (LHS)
Wire.endTransmission();
delay(500);
}
// now repeat but with decimal point
for (int z=0; z<16; z++)
{
Wire.beginTransmission(saa1064);
Wire.send(1); // instruction byte - first digit to control is 1
(right hand side)
Wire.send(digits[z]+128); // digit 1 (RHS)
Wire.send(digits[z]+128); // digit 2
Wire.send(digits[z]+128); // digit 3
Wire.send(digits[z]+128); // digit 4 (LHS)
Wire.endTransmission();
delay(500);
}
}
void clearDisplay()
// clears all digits
{
Wire.beginTransmission(saa1064);
Wire.send(1); // instruction byte - first digit to control is 1 (right
hand side)
Wire.send(0); // digit 1 (RHS)
Wire.send(0); // digit 2
Wire.send(0); // digit 3

Wire.send(0); // digit 4 (LHS)


Wire.endTransmission();
}
void loop()
{
displayDigits();
clearDisplay();
delay(1000);
}

In the function initDisplay() you can see an example of using the instruction then the
control byte. In the function clearDisplay() you can see the simplest form of sending
digits to the display we send 0 for each digit to turn off all elements in each digit. The
bytes that define the digits 0~9 and A~F are stored in the array digits[]. For example, the
digit zero is 63 in decimal, which is B00111111 in binary which turns on elements
a,b,c,d,e and f. Finally, notice the second loop in displayDigits() 128 is added to each
digit value to turn on the decimal point. Before moving on, lets see it in action:
Our next example revisits the instruction and control byte we change the brightness of
the digits by setting bits 4~6 in the control byte. Each level of brightness is separated into
a separate function, and should be self-explanatory. Here is the sketch (download):
/*

Example 39.2 - NXP SAA1064 I2C LED Driver IC Demo II


Demonstrating brightness levels via adjusting segment current
http://tronixstuff.wordpress.com/tutorials > chapter 39
John Boxall July 2011 | CC by-sa-nc

*/

#include "Wire.h"

// enable I2C bus

byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064
(pin 1 to GND)
int digits[16]={63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57,
94, 121, 113};
// these are the byte representations of pins required to display each
digit 0~9 then A~F
void setup()
{
Wire.begin(); // start up I2C bus
delay(500);
init12ma();
}
void init3ma()
// turns on dynamic mode and adjusts segment current to 3mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte

Wire.send(B00010111); // control byte (dynamic mode on, digits 1+3 on,


digits 2+4 on, 3mA segment current
Wire.endTransmission();
}
void init6ma()
// turns on dynamic mode and adjusts segment current to 6mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B00100111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 6mA segment current
Wire.endTransmission();
}
void init9ma()
// turns on dynamic mode and adjusts segment current to 9mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B00110111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 9mA segment current
Wire.endTransmission();
}
void init12ma()
// turns on dynamic mode and adjusts segment current to 12mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B01000111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 12mA segment current
Wire.endTransmission();
}
void init18ma()
// turns on dynamic mode and adjusts segment current to 12mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B01100111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 18mA segment current
Wire.endTransmission();
}
void init21ma()
// turns on dynamic mode and adjusts segment current to 12mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B01110111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 21mA segment current

Wire.endTransmission();

void loop()
{
int d=250; // for delay
// first, light up all segments
Wire.beginTransmission(saa1064);
Wire.send(0); // instruction byte - Zero means the next byte is the
control byte
Wire.send(B01001111); // set current and bit 3 to 1 for all segments
on
Wire.endTransmission();
// now loop through the brightness levels
do
{
init3ma();
delay(d);
init6ma();
delay(d);
init9ma();
delay(d);
init12ma();
delay(d);
init18ma();
delay(d);
init21ma();
delay(d);
}
while (1>0);

And again, see it in action:


For our final example, there is a function displayInteger(a,b) which can be used to easily
display numbers from 0~9999 on the 4-digit display. The parameter a is the number to
display, and b is the leading-zero control zero off, one on. The function does some
maths on the integet to display and separates the digits for each column, then sends them
to the SAA1064 in reverse order. By now you should be able to understand the following
sketch (download):
/*

Example 39.3 - NXP SAA1064 I2C LED Driver IC Demo III


Displaying numbers on command
http://tronixstuff.wordpress.com/tutorials > chapter 39
John Boxall July 2011 | CC by-sa-nc
*/

#include "Wire.h" // enable I2C bus


byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064
(pin 1 to GND)

int digits[17]={
63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57, 94, 121, 113,
0};
// these are the byte representations of pins required to display each
digit 0~9 then A~F, and blank digit
void setup()
{
Wire.begin(); // start up I2C bus
delay(500);
initDisplay();
}
void initDisplay()
// turns on dynamic mode and adjusts segment current to 12mA
{
Wire.beginTransmission(saa1064);
Wire.send(B00000000); // this is the instruction byte. Zero means the
next byte is the control byte
Wire.send(B01000111); // control byte (dynamic mode on, digits 1+3 on,
digits 2+4 on, 12mA segment current
Wire.endTransmission();
}
void clearDisplay()
{
Wire.beginTransmission(saa1064);
Wire.send(1); // start with digit 1 (right-hand side)
Wire.send(0); // blank digit 1
Wire.send(0); // blank digit 2
Wire.send(0); // blank digit 3
Wire.send(0); // blank digit 4
Wire.endTransmission();
}
void displayInteger(int num, int zero)
// displays the number 'num'
// zero = 0 - no leading zero
// zero = 1 - leading zero
{
int thousand, hundred, ten, one;
// breakdown number into columns
thousand = num/1000;
hundred = (num-(thousand*1000))/100;
ten = (num-((thousand*1000)+(hundred*100)))/10;
one = num-((thousand*1000)+(hundred*100)+(ten*10));
if (zero==1) // yes to leading zero
{
Wire.beginTransmission(saa1064);
Wire.send(1);
Wire.send(digits[one]);
Wire.send(digits[ten]);
Wire.send(digits[hundred]);
Wire.send(digits[thousand]);
Wire.endTransmission();
delay(10);
}

else
if (zero==0) // no to leading zero
{
if (thousand==0) { thousand=16; }
if (hundred==0 && num<100) { hundred=16; }
if (ten==0 && num<10) { ten=16; }
Wire.beginTransmission(saa1064);
Wire.send(1);
Wire.send(digits[one]);
Wire.send(digits[ten]);
Wire.send(digits[hundred]);
Wire.send(digits[thousand]);
Wire.endTransmission();
delay(10);
}

void loop()
{
for (int a=0; a<251; a++)
// display 0~250 without leading zero
{
displayInteger(a,0);
delay(20);
}
delay(1000);
clearDisplay();
delay(1000);

for (int a=0; a<1000; a++)


// display 0~999 with leading zero
{
displayInteger(a,1);
delay(5);
}

And the final example in action:


So there you have it another useful IC that can be used in conjunction with our Arduino
systems to make life easier and reduce the required digital output pins.

Tutorial: Arduino and Push-wheel switches


This is chapter forty of a series originally titled Getting Started/Moving Forward with
Arduino! by John Boxall a series of articles on the Arduino universe. The first chapter
is here, the complete series is detailed here. Any files from tutorials will be found here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Update! See the addendum for using four switches at once to read four-digit
numbers here.
Welcome back fellow arduidans!
In this article we go back to the past via the use of push-wheel/thumb-wheel switches
with out Arduino systems. Here are some examples sourced from somewhere on eBay:

For the uninitiated, each switch is one vertical segment and they can be connected
together to form various sizes. You can use the buttons to select from digits zero through
to nine. There are alternatives available that have a wheel you can move with your thumb
instead of the increase/decrease buttons. Before the days of fancy user interfaces these
switches were quite popular methods for setting numerical data entry. However they are
still available today, so lets see how they work and how we can use them.
The switchs value is made available via binary-coded decimal. Consider the rear of the
switch:

We have common on the left, then contacts for 1, 2, 4 and 8. If you apply a small voltage
(say 5V) to common, the value of the switch can be measured by adding the values of the
contacts that are in the HIGH state. For example, if you select 3 contacts 1 and 2 will be
at the voltage at common. The values between zero and nine can be represented as such:

By now you should realise that it would be easy to read the value of a switch and
youre right, it is. We can connect 5V to the common, the outputs to digital input pins of
our Arduino boards, then use digitalRead() to determine the value of each output. In the
sketch we use some basic mathematics to convert the BCD value to a decimal number. So
lets do that now.
From a hardware perspective, we need to take into account one more thing the pushwheel switch behaves electrically like four normally-open push buttons. This means we
need to use pull-down resistors in order to have a clear difference between high and low
states. So the schematic for one switch would be (click image to enlarge):

Now it is a simple matter to connect the outputs labelled 1, 2, 4, and 8 to (for example)
digital pins 8, 9, 10 and 11. Connect 5V to the switch C point, and GND to GND.
Next, we need to have a sketch that can read the inputs and convert the BCD output to
decimal. Consider the following sketch (download):
Example 40.1
/*

Example 40.1 - display single thumbwheel switch data


http://tronixstuff.wordpress.com/tutorials > chapter 40 | cc v3.0 bysa-nc
Uses Gravitech SAA1064 numerical display shield
http://www.gravitech.us/7segmentshield.html
Uses serial monitor if you don't have the SAA1064 shield
*/
#include
#define
#define
#define
#define

q1
q2
q4
q8

8
9
10
11

void setup()
{
Serial.begin(9600);
Wire.begin();
delay(500);
pinMode(q1, INPUT);
pinMode(q2, INPUT);
pinMode(q4, INPUT);
pinMode(q8, INPUT);
}

// join i2c bus (address optional for master)


//
//
//
//

thumbwheel
thumbwheel
thumbwheel
thumbwheel

'1'
'2'
'4'
'8'

void dispSAA1064(int Count)


// sends integer 'Count' to Gravitech SAA1064 shield
{
const int lookup[10] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
int Thousands, Hundreds, Tens, Base;
Wire.beginTransmission(0x38);

};

Wire.send(0);
Wire.send(B01000111);
Wire.endTransmission();
Wire.beginTransmission(0x38);
Wire.send(1);
Thousands = Count/1000;
Hundreds = (Count-(Thousands*1000))/100;
Tens = (Count-((Thousands*1000)+(Hundreds*100)))/10;
Base = Count-((Thousands*1000)+(Hundreds*100)+(Tens*10));
Wire.send(lookup[Base]);
Wire.send(lookup[Tens]);
Wire.send(lookup[Hundreds]);
Wire.send(lookup[Thousands]);
Wire.endTransmission();
delay(10);

int readSwitch()
{
int total=0;
if (digitalRead(q1)==HIGH)
if (digitalRead(q2)==HIGH)
if (digitalRead(q4)==HIGH)
if (digitalRead(q8)==HIGH)
return total;
}

{
{
{
{

total+=1;
total+=2;
total+=4;
total+=8;

}
}
}
}

void loop()
{
dispSAA1064(readSwitch()); // sends switch value to display shield
Serial.println(readSwitch()); // sends switch value to serial monitor
box
}

The function readSwitch() is the key. It calculates the value of the switch by adding the
numerical representation of each switch output and returns the total as its result. For this
example we used a numerical display shield that is controlled by the NXP SAA1064. If
you dont have one, thats ok the results are also sent to the serial monitor. Now, lets
see it in action:
Ok it doesnt look like much, but if you need numerical entry it saves a lot of physical
space and offers a precise method of entry.
So there you have it. Would you actually use these in a project? For one digit yes. For
four? Probably not perhaps it would be easier to use a 12-digit keypad. Theres an
idea But for now I hope you enjoyed reading this as much as I did writing it for you.
Update! See the addendum for using four switches at once to read four-digit numbers
here.

Tutorial: Arduino and multiple push-wheel switches


This is an addendum to chapter forty of a series originally titled Getting Started/Moving
Forward with Arduino! by John Boxall a series of articles on
the Arduino universe. The first chapter is here, the complete series is detailed here. Any
files from tutorials will be found here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
This article continues with the push-wheel switches introduced the other week. In the
previous article, we learned how to read the value of a single digit using the digital pins
of our Arduino. With this instalment we will examine how to read four digits and not
waste all those digital pins in the process. Instead, we will use the Microchip MCP23017
16-bit port expander IC that communicates via the I2C bus. It has sixteen digital
input/output pins that we can use to read the status of each switch.
Before moving forward, please note that some assumed knowledge is required for this
article the I2C bus (parts one and two) and the MCP23017.
We first will describe the hardware connections, and then the Arduino sketch. Recall the
schematic used for the single switch example:

When the switch was directly connected to the Arduino, we read the status of each pin to
determine the value of the switch. We will do this again, on a larger scale using
the MCP23017. Consider the pinout diagram:

We have 16 pins, which allows four switches to be connected. The commons for each
switch still connect to 5V, and each switch contact still has a 10k pull-down resistor to
GND. Then we connect the 1,2,4,8 pins of digit one to GPBA0~3; digit twos 1,2,4,8 to
GPA4~7; digit threes 1,2,4,8 to GPB0~3 and digit fours 1,2,4,8 to GPB4~7. For
demonstration purposes we are using the Gravitech 7-segment shield as reviewed in the
past.
Now how do we read the switches? All those wires may cause you to think it is difficult,
but the sketch is quite simple. When we read the value of GPBA and B, one byte is
returned for each bank, with the most-significant bit first. Each four bits will match the
setting of the switch connected to the matching I/O pins.
For example, if we request the data for both IO banks and the switches are set to 1 2 3 4
bank A will return 0010 0001 and bank B will return 0100 0011. We use some bitshift
operations to separate each four bits into a separate variable which leaves us with the
value of each digit. For example, to separate the value of switch four, we shift the bits
from bank B >> 4. This pushes the value of switch three out, and the blank bits on the left
become zero. To separate the value for switch three, we use a compound bitwise &
which leaves the value of switch three.
Below is a breakdown of the binary switch values it shows the raw GPIOA and B byte
values, then each digits binary value, and decimal value:

So lets see the demonstration sketch (download):


Example 40a
/*

Example 40a - Read four pushwheel BCD switches via MCP23017, display
on SAA1064/4-digit 7-segment LED display
http://tronixstuff.wordpress.com | John Boxall CC by-sa-nc
*/
// MCP23017 pins 15~17 to GND, I2C bus address is 0x20
// SAA1064 I2C bus address 0x38
#include "Wire.h"
// for LED digit definitions
int digits[16]={
63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57, 94, 121, 113};
byte GPIOA, GPIOB, dig1, dig2, dig3, dig4;
void initMCP23017()
{
// setup MCP23017
Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.send(0x20); // use table 1.4 addressing
Wire.endTransmission();
}
void initSAA1064()
{
//setup 0x38
Wire.beginTransmission(0x38);
Wire.send(0);
Wire.send(B01000111); // 12mA output, no digit blanking
Wire.endTransmission();

}
void setup()
{
Serial.begin(9600);
Wire.begin(); // start up I2C bus
initMCP23017();
initSAA1064();
}
void loop()
{
// read the inputs of bank A
Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.endTransmission();
Wire.requestFrom(0x20, 1);
GPIOA=Wire.receive(); // this byte contains the switch data for digits
1 and 2
// read the inputs of bank B
Wire.beginTransmission(0x20);
Wire.send(0x13);
Wire.endTransmission();
Wire.requestFrom(0x20, 1);
GPIOB=Wire.receive(); // this byte contains the switch data for digits
3 and 4
// extract value for each switch
// dig1 LHS, dig4 RHS
dig4=GPIOB >> 4;
dig3=GPIOB & B00001111;
dig2=GPIOA >> 4;
dig1=GPIOA & B00001111;
// send all GPIO and individual switch data to serial monitor
// for debug and interest's sake
Serial.print("GPIOA = ");
Serial.println(GPIOA, BIN);
Serial.print("GPIOB = ");
Serial.println(GPIOB, BIN);
Serial.println();
Serial.print("digit 1 = ");
Serial.println(dig1, BIN);
Serial.print("digit 2 = ");
Serial.println(dig2, BIN);
Serial.print("digit 3 = ");
Serial.println(dig3, BIN);
Serial.print("digit 4 = ");
Serial.println(dig4, BIN);
Serial.println();
Serial.print("digit 1 = ");
Serial.println(dig1, DEC);
Serial.print("digit 2 = ");
Serial.println(dig2, DEC);
Serial.print("digit 3 = ");
Serial.println(dig3, DEC);

Serial.print("digit 4 = ");
Serial.println(dig4, DEC);
Serial.println();
// send switch value to LED display via SAA1064
Wire.beginTransmission(0x38);
Wire.send(1);
Wire.send(digits[dig4]);
Wire.send(digits[dig3]);
Wire.send(digits[dig2]);
Wire.send(digits[dig1]);
Wire.endTransmission();
delay(10);
delay(1000);
}

And for the non-believers a video demonstration:


So there you have it. Four digits instead of one, and over the I2C bus conserving Arduino
digital I/O pins. Using eight MCP23017s you could read 32 digits at once. Have fun with
doing that!

Tutorial: Maximising your Arduinos I/O ports


This is chapter forty-one of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here. Any files from tutorials will be
found here.
Welcome back fellow arduidans!
In this article we discuss how to use the Microchip MCP23017 16-bit serial expander
with I2C serial interface. This 28-pin IC offers sixteen inputs or outputs and up to eight
of the ICs can be used on one I2C bus offering a maximum of 128 extra I/O ports. A
few people may be thinking Why not just get an Arduino Mega2560? a good
question. However you may have a distance between the Arduino and the end-point of
the I/O pins so with these ICs you can run just four wires instead of a lot more; save
board space with custom designs, and preserve precious digital I/O pins for other uses.
Plus I think the I2C bus is underappreciated! So lets get started
Here is our subject of the article in DIP form:

At this point you should also download yourself a copy of data sheet it will be referred
to several times, and very useful for reference and further reading. Furthermore if you are
not familiar with Arduino and the I2C bus, please familiarise yourself with the I2C
tutorials parts one and two. The MCP23017 can be quite simple or complex to
understand, so the goal of this article is to try and make it as simple as possible. After
reading this you should have the knowledge and confidence to move forward with using a
MCP23017.
First, lets look at the hardware basics of this IC. Consider the pinouts:

The sixteen I/O ports are separated into two banks A (on the right) and B (on the left.
Pin 9 connects to 5V, 10 to GND, 11 isnt used, 12 is the I2C bus clock line (Arduino
Uno/Duemilanove analogue pin 5, Mega pin 21), and 13 is the I2C bus data line
(Arduino Uno/Duemailnove analogue pin 4, Mega pin 20). External pull-up resistors
should be used on the I2C bus in our examples we use 4.7k ohm values. Pin 14 is
unused, and we wont be looking at interrupts, so ignore pins 19 and 20. Pin 18 is the
reset pin, which is normally high therefore you ground it to reset the IC. So connect it
to 5V!
Finally we have the three hardware address pins 15~17. These are used to determine the
I2C bus address for the chip. If you connect them all to GND, the address is 020. If you
have other devices with that address or need to use multiple MCP23017s, see figure 1-2
on page eight of the data sheet. You can alter the address by connecting a combination of
pins 15~17 to 5V (1) or GND (0). For example, if you connect 15~17 all to 5V, the
control byte becomes 0100111 in binary, or 027 in hexadecimal.
Next, here is a basic schematic illustrating how to connect an MCP23017 to a typical
Arduino board. It contains the minimum to use the IC, without any sensors or
components on the I/O pins:

Now to examine how to use the IC in our sketches.


Remember if you are using Arduino v1.0 or greater you will need to change all the
Wire.send commands in our examples to Wire.write, and use Wire.read() instead of
Wire.receive().
As you should know by now most I2C devices have several registers that can be
addressed. Each address holds one byte of data that determines various options. With the
MCP23017 the registers can be ordered in one of two ways see tables 1.3 and 1.4 on
page nine of the data sheet. In our examples we will use the addresses listed on table 1.4.
So the first command to use in void setup() is:
Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.send(0x20); // use table 1.4 addressing
Wire.endTransmission();

The next is to set the I/O ports as inputs or outputs. First we will work with outputs.
When the MCP23017 is turned on or reset, it defaults to inputs so we need to change
them. So we use:
Wire.beginTransmission(0x20);
Wire.send(0x00); // IODIRA register
Wire.send(0x00); // set all of bank A to outputs
Wire.send(0x00); // set all of bank B to outputs
Wire.endTransmission();

Go back to the data sheet and see table 1.4. Notice how we started with the IODIRA
(I/O direction, bank A) register at 000 and sent two bytes? You can do this without
having to separate address the second register. This only works when the registers have
sequential addresses, as in this example we wanted a byte to go to 000 then 001. We
sent zero which in binary is 00000000 each bit refers to one output of the bank and
refers to I/O pins 7~0.
So now we are in void loop() or a function of your own creation and want to control
some output pins. To control bank A, we use:
Wire.beginTransmission(0x20);
Wire.send(0x12); // address bank A
Wire.send(??); // value to send
Wire.endTransmission();

replacing ?? with the binary or equivalent hexadecimal or decimal value to send to the
register. To calculate the required number, consider each I/O pin from 7 to 0 matches one
bit of a binary number 1 for on, 0 for off. So you can insert a binary number
representing the output levels. Or if binary does your head in, convert it to hexadecimal.
So for example, you want pins 7 and 1 on. In binary that would be 10000010, in
hexadecimal that is 082, or 130 decimal. (Using decimals is convenient if you want to
display values from an incrementing value or function result).
If you had some LEDs via resistors connected to the outputs, you would have this as a
result of sending 082:

Now if you want to address all the outputs at once, just send the byte for bank B after
bank A. For example, we want bank A to be 11001100 and bank B to be 10001000 so
we send the following:
Wire.beginTransmission(0x20);
Wire.send(0xCC); // address bank A
Wire.send(0x88); // address bank B
Wire.endTransmission();

with the results as such (bank B on the left, bank A on the right):

You can also just address bank B, if so bank A does not change. Now lets put all of this
output knowledge into a more detailed example. From a hardware perspective we are
using a circuit as described above, with the addition of a 560 ohm resistor followed by an
LED thence to ground from on each of the sixteen outputs. Here is the sketch
(download):
Example 41.1
/*
Example 41.1 - Microchip MCP23017 with Arduino
http://tronixstuff.wordpress.com/tutorials > chapter 41
John Boxall | CC by-sa-nc
*/
// pins 15~17 to GND, I2C bus address is 0x20
#include "Wire.h"
void setup()
{
Wire.begin(); // wake up I2C bus
// setup addressing style
Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.send(0x20); // use table 1.4 addressing
Wire.endTransmission();
// set I/O pins to outputs
Wire.beginTransmission(0x20);
Wire.send(0x00); // IODIRA register
Wire.send(0x00); // set all of bank A to outputs
Wire.send(0x00); // set all of bank B to outputs
Wire.endTransmission();
}
void binaryCount()
{
for (byte a=0; a<256; a++)
{
Wire.beginTransmission(0x20);
Wire.send(0x12); // GPIOA
Wire.send(a);
// bank A
Wire.send(a);
// bank B
Wire.endTransmission();
delay(100);
}
}
void loop()

{
}

binaryCount();
delay(500);

And here is the example blinking away:


Although that may have seemed like a simple demonstration, it was created show how
the outputs can be used. So now you know how to control the I/O pins set as outputs.
Note that you cant source more than 25 mA of current from each pin, so if switching
higher current loads use a transistor and an external power supply and so on.
Now lets turn the tables and work on using the I/O pins as digital inputs. The MCP23017
I/O pins default to input mode, so all we need to do is set the addressing method as such
in void setup()
// setup addressing style
Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.send(0x20); // use table 1.4 addressing
Wire.endTransmission();

Then in the void loop() or other function all we do is set the address of the register to read
and receive one byte of data. For our next example, we have our basic sketch as described
at the start of this article using four normally-open buttons (once again using the button
board) which are connected to bank B inputs 0~3. Consider the first five lines of void
loop() in the following example (download);
Example 41.2
/*
Example 41.2 - Microchip MCP23017 with Arduino
http://tronixstuff.wordpress.com/tutorials > chapter 41
John Boxall | CC by-sa-nc
*/
// pins 15~17 to GND, I2C bus address is 0x20
#include "Wire.h"
byte inputs=0;
void setup()
{
Serial.begin(9600);
Wire.begin(); // wake up I2C bus

// setup addressing style


Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.send(0x20); // use table 1.4 addressing
Wire.endTransmission();

void loop()
{
Wire.beginTransmission(0x20);
Wire.send(0x13); // set MCP23017 memory pointer to GPIOB address
Wire.endTransmission();
Wire.requestFrom(0x20, 1); // request one byte of data from MCP20317
inputs=Wire.receive(); // store the incoming byte into "inputs"
if (inputs>0) // if a button was pressed
{
Serial.println(inputs, BIN); // display the contents of the GPIOB
register in binary
delay(200); // for debounce
}
}

In this example void loop() sends the GPIOB address (013) to the IC. Then using
Wire.requestFrom() it asks for one byte of data from the IC the contents of the register
at 013. This byte is stored in the variable inputs. Finally if inputs is greater than zero
(i.e. a button has been pressed) the result is sent to the serial monitor window and
displayed in binary. We display it in binary as this represents the state of the inputs 0~7.
Here is an example of pressing the buttons 1, 2, 3 then 4 three times:

And as we are reading eight inputs at once you can detect multiple keypresses. The
following is an example of doing just that:

As you can see pressing all four buttons returned 1111, or the first and third returned 101.
Each combination of highs and lows on the inputs is a unique 8-bit number that can also
be interpreted in decimal or hexadecimal. And if you wanted to read all sixteen inputs at
once, just request and store two bytes of data instead of one.
For our last example a demonstration of using bank A as outputs and bank B as inputs.
Four LEDs with matching resistors are connected to bank A outputs 0~3, with the buttons
connected as per example 41.2. Here is the sketch (download):
Example 41.3
/*
Example 41.3 - Microchip MCP23017 with Arduino
http://tronixstuff.wordpress.com/tutorials > chapter 41
John Boxall | CC by-sa-nc
*/
// pins 15~17 to GND, I2C bus address is 0x20
#include "Wire.h"
byte inputs=0;
void setup()
{
Serial.begin(9600);
Wire.begin(); // wake up I2C bus
// setup addressing style
Wire.beginTransmission(0x20);
Wire.send(0x12);
Wire.send(0x20); // use table 1.4 addressing
Wire.endTransmission();
Wire.beginTransmission(0x20);

Wire.send(0x00); // IODIRA register


Wire.send(0x00); // set all of bank A to outputs
Wire.endTransmission();

void loop()
{
// read the inputs of bank B
Wire.beginTransmission(0x20);
Wire.send(0x13);
Wire.endTransmission();
Wire.requestFrom(0x20, 1);
inputs=Wire.receive();
// now send the input data to bank A
Wire.beginTransmission(0x20);
Wire.send(0x12); // GPIOA
Wire.send(inputs);
// bank A
Wire.endTransmission();
delay(200); // for debounce
}

By now there shouldnt be any surprises in the last example it receives a byte that
represents bank B, and sends that byte out to bank A to turn on the matching outputs and
LEDs. For the curious, here it is in action:
So there you have it another way to massively increase the quantity of digital I/O pins
on any Arduino system by using the I2C bus.

Tutorial: Arduino and Numeric Keypads


This is chapter forty-two of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here. Any files from tutorials will be
found here.
Welcome back fellow arduidans!
This is part one of two chapters that will examine another useful form of input the
numeric keypad; and some applications that hopefully may be of use. Here is the
example we will be working with:

It seems quite similar to the keypad from a 1980s-era Dick Smith Electronics cordless
phone. Turning the keypad over we find seven pins:

Personally I like this type of connection, as it makes prototyping very easy using a
breadboard you just push it in. Looking at the back the pins are numbered seven to one
(left to right). My example was from Futurlec of all places. You can also find types that
have solder pads, such as this one. At this point you need to download the data sheet.pdf,
as it shows the pinouts for the rows and columns. At first glance trying to establish a way
of reading the keypad with the Arduino does seem troublesome however the basic
process is to scan each row and then test if a button has been pressed.
If your keypad has more than seven pins or contacts and the data sheet was not
supplied, you will need to manually determine which contacts are for the rows and
columns. This can be done using the continuity function of a multimeter (the buzzer).
Start by placing one probe on pin 1, the other probe on pin 2, and press the keys one by
one. Make a note of when a button completes the circuit, then move onto the next pin.
Soon you will know which is which. For example, on the example keypad pins 1 and 5
are for button 1, 2 and 5 for 4, etc
In the interest of keeping things simple and relatively painless we will use the numeric
keypad Arduino library. Download the library from here, copy the Keypad folder into
your ../arduino-002x/libraries folder, then restart the Arduino IDE.
Now for our first example. From a hardware perspective you will need

An Arduino Uno or 100% compatible board


A numeric keypad
An LCD of some sort. We will be using an I2C-interface model. If you are unsure
about LCD usage, please see this tutorial
If you dont have an LCD thats ok. After installing the keypad library, select
File>Examples>Keypad>Examples>HelloKeypad in the IDE.

Connect the keypad to the Arduino in the following manner:


Keypad row 1 to Arduino digital 5
Keypad row 2 to Arduino digital 4
Keypad row 3 to Arduino digital 3
Keypad row 4 to Arduino digital 2
Keypad column 1 to Arduino digital 8
Keypad column 2 to Arduino digital 7
Keypad column 3 to Arduino digital 6

Now for the sketch. You can download it here


Example 42.1
/* Example 42.1 - Numeric keypad and I2C LCD
http://tronixstuff.wordpress.com/tutorials > chapter 42
Uses Keypad library for Arduino
http://www.arduino.cc/playground/Code/Keypad
by Mark Stanley, Alexander Brevig */
#include "Keypad.h"
#include "Wire.h" // for I2C LCD
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module
http://bit.ly/eNf7jM
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a
16 chars and 2 line display
// keypad type definition
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
byte rowPins[ROWS] = {
5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
8, 7, 6}; // connect to the column pinouts of the keypad
int count=0;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS,
COLS );
void setup()
{
lcd.init();
// initialize the lcd
lcd.backlight(); // turn on LCD backlight
}
void loop()
{
char key = keypad.getKey();
if (key != NO_KEY)
{
lcd.print(key);
count++;
if (count==17)
{
lcd.clear();
count=0;
}
}
}

For the non-believers, here it is in action:

As you can see the library really does all the work for us. In the section below the
comment keypad type definition we have defined how many rows and columns make
up the keypad. Furthermore which digital pins connect to the keypads row and column
pins. If you have a different keypad such as a 16-button version these will need to be
modified. Furthermore you can also map out what the buttons will represent in the array
keys. Then all of these variables are passed to the library in the function Keypad
keypad = Keypad() etc.
Reading the buttons pressed is accomplished in void loop() it reads the keypad by
placing the current value into the char variable key. The if statement tests if a button
has been pressed. You can reproduce this loop within your own sketch to read values and
then move forward to other functions. Lets do that now in our next example.
Keypad Switch
Using our existing example hardware we can turn something on or off by using the
keypad replicating what can be found in some alarm systems and so on. Our goal with
this example is simple the systems waits for a PIN to be entered. If the PIN is correct,
do something. If the PIN is incorrect, do something else. What the actions are can be up
to you, but for the example we will turn on or off a digital output. This example is to give
you a concept and framework to build you own ideas with.
The hardware is the same as the previous example but without the LCD. Instead, we have
a 560 ohm resistor followed by an LED to GND from digital pin ten. Now for the sketch.
You can download it from here.
Example 42.2
// Example 42.2 - Six-digit keypad switch
// http://tronixstuff.wordpress.com/tutorials > chapter 42
#include "Keypad.h"
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
byte rowPins[ROWS] = {
5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS,


COLS );
char PIN[6]={'1','2','3','4','5','6'}; // our secret (!) number
char attempt[6]={
0,0,0,0,0,0}; // used for comparison
int z=0;
void setup()
{
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
incorrectPIN();
}
void correctPIN() // do this if correct PIN entered
{
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
}
void incorrectPIN() // do this if incorrect PIN entered
{
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
}
void checkPIN()
{
int correct=0;
for (int q=0; q<6; q++)
{
if (attempt[q]==PIN[q])
{
correct++;
}
}
if (correct==6)
{
correctPIN();
} else
{
incorrectPIN();
}
for (int zz=0; zz<6; zz++) // wipe attempt
{
attempt[zz]=0;
}
}
void readKeypad()
{
char key = keypad.getKey();
if (key != NO_KEY)
{
switch(key)
{

case '*':
z=0;
break;
case '#':
delay(100); // for extra debounce
checkPIN();
break;
default:
attempt[z]=key;
z++;
}

}
void loop()
{
readKeypad();
}

And the ubiquitous demonstration video:


This sketch is somewhat more complex. It starts with the usual keypad setting up and so
on. We have two arrays, attempt and PIN. PIN holds the number which will successfully
activate the switch, and attempt is used to store the key presses entered by the user. Users
must press * then the PIN then # to activate the switch.
The comparison to check for accuracy is in the function checkPIN(). It compares the
contents of PIN against attempt. If they match, the function correctPIN() is called. If the
entered PIN is incorrect, the function incorrectPIN() is called. We also call the function
incorrectPIN() in void setup to keep things locked down in case of a power failure or a
system reset.
You can now see that such a complex device can be harnessed very easily, and could have
a variety of uses. In part two, we will look at the 16-digit

Tutorial: Arduino and Numeric Keypads Part Two

This is an addendum to chapter forty-two of a series originally titled Getting


Started/Moving Forward with Arduino! by John Boxall a series of articles on
the Arduino universe. The first chapter is here, the complete series is detailed here. Any
files from tutorials will be found here.
Welcome back fellow arduidans!
This is the second part of our numeric keypad tutorial in which we use the larger
keypads with four rows of four buttons. For example:

Again, the keypad looks like a refugee from the 1980s however it serves a purpose.
Notice that there are eight connections at the bottom instead of seven the extra
connection is for the extra column of buttons A~D. This example again came from
Futurlec. For this tutorial you will need the data sheet for the pinouts, so download it
from here (.pdf).
To use this keypad is very easy, if you havent already done so, download the numeric
keypad Arduino library from here, copy the Keypad folder into your ../arduino002x/libraries folder, then restart the Arduino IDE.
Now for our first example just to check all is well. From a hardware perspective you
will need:

An Arduino Uno or 100% compatible board


A 44 numeric keypad

An LCD of some sort. We will be using an I2C-interface model. If you are unsure
about LCD usage, please see this tutorial
If you dont have an LCD thats ok. Our demonstration sketch also sends
the key presses to the serial monitor. Just delete the lines referring to Wire, LCD
etc.

Connect the keypad to the Arduino in the following manner:


Keypad row 1 (pin eight) to Arduino digital 5
Keypad row 2 (pin 1) to Arduino digital 4
Keypad row 3 (pin 2) to Arduino digital 3
Keypad row 4 (pin 4) to Arduino digital 2
Keypad column 1 (pin 3) to Arduino digital 9
Keypad column 2 (pin 5) to Arduino digital 8
Keypad column 3 (pin 6) to Arduino digital 7
Keypad column 4 (pin 7) to Arduino digital 6
Now for the sketch take note how we have accommodated for the larger numeric
keypad:
the extra column in the array char keys[]
the extra pin in the array colPins[]
and the byte COLS = 4.
You can download the sketch from here.
Example 42.3
/* Example 42.3 - Numeric keypad and I2C LCD
http://tronixstuff.wordpress.com/tutorials > chapter 42a
Uses Keypad library for Arduino
http://www.arduino.cc/playground/Code/Keypad
by Mark Stanley, Alexander Brevig */
#include "Keypad.h"
#include "Wire.h" // for I2C LCD
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module
http://bit.ly/eNf7jM
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a
16 chars and 2 line display
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
byte rowPins[ROWS] = {
5, 4, 3, 2}; //connect to the row pinouts of the keypad

byte colPins[COLS] = {
9, 8, 7, 6}; //connect to the column pinouts of the keypad
int count=0;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS,
COLS );
void setup()
{
Serial.begin(9600);
lcd.init();
// initialize the lcd
lcd.backlight(); // turn on LCD backlight
}
void loop()
{
char key = keypad.getKey();
if (key != NO_KEY)
{
lcd.print(key);
Serial.print(key);
count++;
if (count==17)
{
lcd.clear();
count=0;
}
}
}

And our action video:

Now for another example we will repeat the keypad switch from chapter 42 but allow
the letters into the PIN, and use the LCD instead of LEDs for the status. In the following
example, the PIN is 12AD56. Please remember that the functions correctPIN() and
incorrectPIN() are example functions for resulting PIN entry you would replace these
with your own requirements, such as turning something on or off. You can download the
sketch from here.
Example 42.4
// Example 42.4 - Six-character keypad switch
// http://tronixstuff.wordpress.com/tutorials > chapter 42a
#include "Keypad.h"
#include "Wire.h" // for I2C LCD
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module
http://bit.ly/eNf7jM
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a
16 chars and 2 line display

const byte ROWS = 4; //four


const byte COLS = 4; //four
char keys[ROWS][COLS] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
byte rowPins[ROWS] = {
5, 4, 3, 2}; //connect to
byte colPins[COLS] = {
9, 8, 7, 6}; //connect to

rows
columns

the row pinouts of the keypad


the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS,


COLS );
char PIN[6]={'1','2','A','D','5','6'}; // our secret (!) number
char attempt[6]={
0,0,0,0,0,0}; // used for comparison
int z=0;
void setup()
{
lcd.init();
// initialize the lcd
lcd.backlight(); // turn on LCD backlight
lcd.print(" Enter PIN...");
}
void correctPIN() // do this if correct PIN entered
{
lcd.print("* Correct PIN *");
delay(1000);
lcd.clear();
lcd.print(" Enter PIN...");
}
void incorrectPIN() // do this if incorrect PIN entered
{
lcd.print(" * Try again *");
delay(1000);
lcd.clear();
lcd.print(" Enter PIN...");
}
void checkPIN()
{
int correct=0;
for (int q=0; q<6; q++)
{
if (attempt[q]==PIN[q])
{
correct++;
}
}
if (correct==6)
{
correctPIN();
} else

incorrectPIN();
}
for (int zz=0; zz<6; zz++) // wipe attempt
{
attempt[zz]=0;
}

void readKeypad()
{
char key = keypad.getKey();
if (key != NO_KEY)
{
switch(key)
{
case '*':
z=0;
break;
case '#':
delay(100); // for extra debounce
lcd.clear();
checkPIN();
break;
default:
attempt[z]=key;
z++;
}
}
}
void loop()
{
readKeypad();
}

Now lets see it in action:


So now you have the ability to use twelve and sixteen-button keypads with your Arduino
systems.

Tutorial: Arduino Port Manipulation

This is chapter forty-three of a series originally titled Getting Started/Moving Forward


with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here. Any files from tutorials will be
found here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this article we are going to revisit the I/O pins, and use what is called Port
Manipulation to control them in a much faster manner than using
digitalWrite()/digitalRead().
Why?
Speed! Using this method allows for much faster I/O control, and we can control or read
groups of I/O pins simultaneously, not one at a time;
Memory! Using this method reduces the amount of memory your sketch will use.
Once again I will try and keep things as simple as possible. This article is written for
Arduino boards that use the ATmega168 or ATmega328 microcontrollers (used in
Arduino Duemilanove/Uno, Freetronics TwentyTen/Eleven/EtherTen, etc). My Arduino
Mega is out at the moment, so I will update the tutorial for Mega users when it is
replaced.
First, well use the I/O as outputs. There are three port registers that we can alter to set
the status of the digital and analogue I/O pins. A port register can be thought of as a
special byte variable that we can change which is read by the microcontroller, therefore
controlling the state of various I/O ports. We have three port registers to work with:

D for digital pins seven to zero (bank D)


B for digital pins thirteen to eight (bank B)
C for analogue pins five to zero (bank C!)

Register C can control analogue pins seven to zero if using an Arduino with the TQFP
style of ATmega328, such as the Nano or Freetronics EtherTen). For example:

It is very simple to do so. In void setup(), we use


DDRy = Bxxxxxxxx

where y is the register type (B/C/D) and xxxxxxxx are eight bits that determine if a pin is
to be an input or output. Use 0 for input, and 1 for output. The LSB (least-significant bit
[the one on the right!]) is the lowest pin number for that register. Next, to control a bank
of pins, use
PORTy = Bxxxxxxxx

where y is the register type (B/C/D) and xxxxxxxx are eight status bits 1 for HIGH, 0
for LOW. This is demonstrated in the following example:
//
//
//
//

Example 43.1
tronixstuff.wordpress.com/tutorials > chapter 43
John Boxall - October 2011
Digital 0~7 set to outputs, then on/off using port manipulation

void setup()
{
DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}
void loop()
{
PORTD = B11110000; // digital 4~7 HIGH, digital 3~0 LOW
delay(1000);
PORTD = B00001111; // digital 4~7 LOW, digital 3~0 HIGH
delay(1000);
}

It sets digital pins 7~0 to output in void setup(). Then it alternates turning on and off
alternating halves of digital pins 0~7.
At the start I mentioned that using port manipulation was a lot faster than using regular
Arduino I/O functions. How fast? To test the speed of port manipulation vs. using
digitalWrite(), we will use the following circuit:

and analyse the output at digital pins zero and seven using a digital storage
oscilloscope. Our first test sketch turns on and off digital pins 0~7 without any delay
between PORTD commands in other words, as fast as possible. The sketch:
//
//
//
//

Example 43.1.1
tronixstuff.wordpress.com/tutorials > chapter 43
John Boxall - October 2011
Digital 0~7 set to outputs, then on/off using port manipulation

void setup()
{
DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}
void loop()
{
PORTD = B11111111;
PORTD = B00000000;
}

In the image below, digital zero is channel one, and digital seven is channel three:

Wow check the frequency measurements 1.1432 MHz! Interesting to note the longer
duration of time when the pins are low vs. high.
[Update] Well it turns out that the extra time in LOW includes the time for the Arduino
to go back to the top of void loop(). This can be demonstrated in the following sketch. We
turn the pins on and off five times instead of once:
// Example 43.1.2
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
void setup()
{
DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}
void loop()
{
PORTD = B11111111;
PORTD = B00000000;
PORTD = B11111111;
PORTD = B00000000;
PORTD = B11111111;
PORTD = B00000000;
PORTD = B11111111;
PORTD = B00000000;
PORTD = B11111111;
PORTD = B00000000;
}

And the results from the MSO. You can see the duty cycle is much closer to 50% until the
end of the sketch, at which point around 660 nanoseconds is the time used between the
end of the last LOW period and the start of the next HIGH:

Next we do it the normal way, using this sketch:


//
//
//
//

Example 43.2
tronixstuff.wordpress.com/tutorials > chapter 43
John Boxall - October 2011
Digital 0~7 set to outputs, then on/off using digitalWrite()

void setup()
{
for (int a=0; a<8; a++)
{
pinMode(a, OUTPUT);
}
}
void loop()
{
for (int a=0; a<8; a++)
{
digitalWrite(a, HIGH);
}
for (int a=0; a<8; a++)
{
digitalWrite(a, LOW);
}

And the results:

That was a lot slower were down to 14.085 kHz, with a much neater square-wave
output. Could some CPU time be saved by not using the for loop? We tested once more
with the following sketch:
// Example 43.3
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// Digital 0~7 set to outputs, then on/off using individual
digitalWrite()
void setup()
{
for (int a=0; a<8; a++)
{
pinMode(a, OUTPUT);
}
}
void loop()
{
digitalWrite(0,
digitalWrite(1,
digitalWrite(2,
digitalWrite(3,
digitalWrite(4,
digitalWrite(5,
digitalWrite(6,

HIGH);
HIGH);
HIGH);
HIGH);
HIGH);
HIGH);
HIGH);

digitalWrite(7,
digitalWrite(0,
digitalWrite(1,
digitalWrite(2,
digitalWrite(3,
digitalWrite(4,
digitalWrite(5,
digitalWrite(6,
digitalWrite(7,

HIGH);
LOW);
LOW);
LOW);
LOW);
LOW);
LOW);
LOW);
LOW);

and the results:

A small speed boost, the frequency has increased to 14.983 kHz. Hopefully you can now
understand the benefits of using port manipulation. However there are a few things to
take note of:

You cant control digital pins 0 and 1 (in bank D) and use the serial monitor/port.
For example if you set pin zero to output, it cant receive data!
Always document your sketch take pity on others who may need to review it
later on and become puzzled about wchich bits are controlling or reading what!

Now to waste some electron flows by blinking LEDs. Using the circuit described earlier,
the following sketch will create various effects for someones enjoyment (download):
//
//
//
//

Example 43.4
tronixstuff.wordpress.com/tutorials > chapter 43
John Boxall - October 2011
Fun with 8 LEDs on digital 7~0

void setup()
{
DDRD = B11111111; // set PORTD (digital 7~0)
// to output
}
byte
byte
byte
byte

a
b
c
e

=
=
=
=

B11111111;
B00000001;
B10000000;
B10101010;

void krider()
{
for (int k=0; k<5; k++)
{
for (int z=0; z<8; z++)
{
PORTD = b << z;
delay(100);
}

for (int z=0; z<8; z++)


{
PORTD = c >> z;
delay(100);
}

}
void onOff()
{
for (int k=0; k<10; k++)
{
PORTD = a;
delay(100);
PORTD = 0;
delay(100);
}
}
void invBlink()
{
for (int z=0; z<10; z++)
{
PORTD = e;
delay(100);
PORTD = ~e;
delay(100);
}
}
void binaryCount()
{
for (int z=0; z<256; z++)
{
PORTD = z;

delay(100);
}
PORTD=0;

void loop()
{
invBlink();
delay(500);
binaryCount();
delay(500);
krider();
delay(500);
onOff();
}

And here it is in real life:


Now to use the I/O pins as inputs. Again, it is very simple to do so. In void setup(), we
use
DDRy = Bxxxxxxxx

where y is the register type (B/C/D) and xxxxxxxx are eight bits that determine if a pin is
to be an input or output. Use 0 for input. The LSB (least-significant bit [the one on the
right!]) is the lowest pin number for that register. Next, to read the status of the pins we
simply read the byte:
PINy

where y is the register type (B/C/D).


So if you were using port B as inputs, and digital pins 8~10 were high, and 11~13 were
low, PINB would be equal to B00000111. Really, thats it!
Now for another demonstration using both inputs and outputs. We will use a push-wheel
switch from Chapter 40 on our inputs (digital pins 8~11), and a seven segment LED
display for output (on digtal pins 7~0 segments dp then a~f). The following sketch
reads the input from the switch, which returns 0~9 in binary-coded decimal. This value is
then used in the function void disp() to retrieve the matching byte from the array
segments, which contains the appropriate outputs to drive the seven segment LED
display unit. Here is the sketch (download):
//
//
//
//

Example 43.5
tronixstuff.wordpress.com/tutorials > chapter 43
John Boxall - October 2011
inputs and outputs

byte segments[] = {
B01111110, B00110000, B01101101, B01111001, B00110011, B01011011,
B01011111, B01110000, B01111111, B01111011};

// digital pins 7~0 connected to display pins dp,a~g


void setup()
{
DDRB = B00000000; // set PORTB (digital 13~8) to inputs
DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}
void disp(int z)
{
PORTD = segments[z];
}
void loop()
{
disp(PINB);
delay(100);
}

And the ubiquitous demonstration video:

By now I hope you have an understanding of using port manipulation for your benefit.
With a little effort your sketches can be more efficient in terms of speed and memory
space, and also allow nifty simultaneous reading of input pins.

Using an ATtiny as an Arduino


This is chapter forty-four of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back
In the last few weeks an article about how to use either an Atmel ATtiny45 or ATtiny85
microcontroller with Arduino software took my interest. The team at the High-Low Tech
Group at MIT had published the information and examples on how to do this, and it
looked like fun so the purpose of this article is to document my experience with the
ATtiny and Arduino. All credit goes to the interesting people at the MIT HLT Group for
their article and of course to Alessandro Saporetti for his work on making all this
possible.
Introduction
Before anyone gets too excited there are a few limitations to doing this
Limitation one the ATtiny has tiny in the name for a reason:

it's the one on the left!


Therefore we have less I/O pins to play with. Consider the pinout for the ATtiny from the
data sheet:

So as you can see we have thee analogue inputs (pins 7, 3 and 2) and two digital outputs
with PWM (pins 5 and 6). Pin 4 is GND, and pin 8 is 5V.
Limitation two memory. The ATtiny45 has 4096 bytes of flash memory available, the
-85 has 8192. So you may not be controlling your home-built R2D2 with it.
Limitation three available Arduino functions. As stated by the HLT article, the
following commands are supported:

pinMode()
digitalWrite()
digitalRead()
analogRead()
analogWrite()
shiftOut()
pulseIn()
millis()
micros()
delay()
delayMicroseconds()

So please keep the limitations in mind when planning your ATtiny project.
Getting Started
Hardware
The ATtiny needs to be wired up a certain way to allow the Arduino to act as a
programmer.
For those with an Arduino Duemilanove/Freetronics TwentyTen (click schematic to
enlarge):

For those with an Arduino Uno/Freetronics Eleven/EtherTen etc. (click schematic to


enlarge):

Note the Uno version of the schematic has a 10uF electrolytic capacitor between Arduino
RST and GND. Follow the schematics above each time you want to program the ATtiny.
For more frequent use they would be an excellent candidate for a protoshield.
Software
From a software perspective, to use the ATtinys you need to add some files to your
Arduino IDE. First, download this zip file. Create a folder called hardware in the the
folder where you save your sketches. If you are unsure of this location, in the Arduino
IDE select the File>Preferences option and you will see the following:

The top field Sketchbook location: will tell you where to put the files.
Next, extract the contents of the downloaded .zip file into the newly-created
hardware folder. Finally, plug in your Arduino board, load the IDE and upload the
ArduinoISP sketch which is in the File>Examples menu. Whenever you want to upload a
sketch to your ATtiny, you need to upload the ArduinoISP sketch to your Arduino first.
Consider this sketch the bridge between the IDE and the ATtiny.
Next, create your sketch. Note the following pin number allocations:

digital pin zero is physical pin five (also PWM)


digital pin one is physical pin six (also PWM)
analogue input two is physical pin seven
analogue input three is physical pin two
analogue input four is physical pin three

Before uploading your sketch you need to select the correct board type. Select
Tools>Board>ATtiny45 (or 85) (w/ Arduino as ISP). Then upload as normal. You will
see an error message in the status window of the IDE as such:

The message is normal in this situation, so nothing to worry about.


For a quick demonstration, load the Blink example sketch File>Examples>1.
Basics>Blink. Change the pin number for the digital output from 13 to 0. For example:
void setup()
{
pinMode(0, OUTPUT);
}
void loop() {
digitalWrite(0, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(0, LOW); // set the LED off
delay(1000); // wait for a second
}

Upload the sketch using the method as described earlier. The matching circuit is:

Although its only a blinking LED, by making it work you have mastered the process.
However, for the non-believers:
Final example

We test the digital outputs with digital and PWM outputs using two

LEDs instead of one:

And the sketch:


void setup()
{
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
}
void loop()
{
for (int a=0; a<6; a++)
{
digitalWrite(0, HIGH); // set the LED on
digitalWrite(1, LOW); // set the LED off
delay(1000); // wait for a second
digitalWrite(0, LOW); // set the LED off
digitalWrite(1, HIGH); // set the LED on
delay(1000); // wait for a second
}
for (int z=0; z<3; z++)
{
for (int a=0; a<256; a++)
{
analogWrite(0, a);
analogWrite(1, a);
delay(1);
}
for (int a=255; a>=0; --a)
{
analogWrite(0, a);
analogWrite(1, a);
delay(1);
}
}
}

And a quick demonstration video:So there you have it another interesting derivative of
the Arduino system. Once again, thanks and credit to Alesssandro Saporetti and the MIT
HLT Group for their published information.
Update 25/11/11 - this method has been updated for use with Arduino v1.0 beta.

Tutorial Parallax Ping))) Ultrasonic Sensor


This is chapter forty-five (!) of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall a series of articles on the Arduino universe. The first
chapter is here, the complete series is detailed here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0.
Please continue to use v22 or v23 until further notice.
Welcome back
Whilst being a passenger in a vehicle with a reversing sensors, I became somewhat
curious as to how the sensors operated and how we can make use of them. So for this
chapter we will investigate an ultrasonic sensor from Parallax called the Ping)))
Ultrasonic Distance Sensor. It can measure distances between ~2cm and ~3m in length.
Here is our example sensor:

(Memories of Number Five )


Parallax have done a lot of work, the board contains not just the bare sensor hardware but
controller circuitry as well:

Which is great as it leaves us with only three pins 5V, GND and signal. More on those
in a moment, but first

How does it work?


Good question. The unit sends out an ultrasonic (a sound that has a frequency which is
higher than can be heard by the human ear) burst of sound from one transducer (the
round silver things) and waits for it bounce off an object and return which is detected
by the other transducer. The board will then return to us the period of time taken for this
process to take, which we can interpret to determine the distance between the sensor and
the object from which the ultrasonic sound bounced from.
The Ping))) only measures a distance when requested to do this we send a very short
HIGH pulse of five microseconds to the signal pin. After a brief moment a pulse will
come from the board on the same signal pin. The period of this second pulse is the
amount of time the sound took to travel out and back from the sensor so we divide it by
two to calculate the distance. Finally, as the the speed of sound is 340 metres per second,
the Arduino sketch can calculate the distance to whatever units required.
It may sound complex, but it is not so lets run through the theory of operation with an
example. Using our digital storage oscillscope we have measured the waveforms on the
signal pin during a typical measurement. Consider the following example of measuring a
distance of 12cm (click image to enlarge):

You can see the 5uS pulse in the centre and the pulse returned from the sensor board on
the right. Now to zoom in on the returned pulse (click image to enlarge):

Without being too picky the pulse is roughly 720uS (microseconds) long the duration of
ultrasonic sounds return trip from the sensor board. So we divide this by two to find the
time to travel the distance 360uS. Recall the speed of sound is 340 metres per second
which converts to 29.412 uS per centimetre. So, 360uS divided by 29.412 uS gives
12.239902081 centimetres. Rounded that gives us 12 centimetres. Easy!
Finally, there are some limitations to using the Ping))) sensor. Download the data
sheet (pdf) and read pages three to five for information on how to effectively mount the
sensor and the sensitivity results from factory resting.
How do we use it with Arduino?
As described previously we first need to send a 5uS pulse, then listen for the return pulse.
The following sketch does just that, then converts the data to centimetres and displays the
result on the serial monitor. The code has been commented to explain each step.
Example 45.1
// Example 45.1 - tronixstuff.wordpress.com - CC by-sa-nc
// Connect Ping))) signal pin to Arduino digital 8
int signal=8;
int distance;
unsigned long pulseduration=0;
void setup()
{
pinMode(signal, OUTPUT);
Serial.begin(9600);
}
void measureDistance()
{
// set pin as output so we can send a pulse

pinMode(signal, OUTPUT);
// set output to LOW
digitalWrite(signal, LOW);
delayMicroseconds(5);
// now send the 5uS pulse out to activate Ping)))
digitalWrite(signal, HIGH);
delayMicroseconds(5);
digitalWrite(signal, LOW);
// now we need to change the digital pin
// to input to read the incoming pulse
pinMode(signal, INPUT);
// finally, measure the length of the incoming pulse
pulseduration=pulseIn(signal, HIGH);
}
void loop()
{
// get the raw measurement data from Ping)))
measureDistance();
// divide the pulse length by half
pulseduration=pulseduration/2;
// now convert to centimetres. We're metric here people...
distance = int(pulseduration/29);
// Display on serial monitor
Serial.print("Distance - ");
Serial.print(distance);
Serial.println(" cm");
delay(500);

And the results of some hand-waving in the serial monitor:

So there you have it you can now measure distance with a degree of accuracy. However
that image above isnt very exciting instead lets use a 7-segment display shield to get
things up in lights. The shield uses the NXP SAA1064 LED display driver IC (explained
quite well here). You can download the demonstration sketch from here. And now for the
video:
So there you have it now the use of the sensor is up to your imagination. Stay tuned
using the methods below to see what we get up to with this sensor in the future.

Tutorial: Analog input for multiple buttons Part Two


This is chapter forty-six of a series originally titled Getting Started/Moving Forward
with Arduino! by John Boxall A tutorial on the Arduino universe. The first chapter
is here, the complete series is detailed here.
Welcome back fellow arduidans!
A while back I described how to read multiple buttons using only one analog input pin.
However we could only read one button at a time. In this instalment we revisit this topic
and examine an improved method of doing so which allows for detecting more than one
button being pressed at the same time. This method is being demonstrated as it is
inexpensive and very easy to configure.
(For a more exact and expensive method please consider the use of the Microchip
MCP23017 which allows for sixteen inputs via the I2C bus).
As you know the analogue input pins of the Arduino can read a voltage of between zero
and five volts DC and return this measurement as an integer between zero and
1023. Using a small external circuit called a R-2R ladder, we can alter the voltage
being measured by the analogue pin by diverting the current through one or more
resistors by our multiple buttons. Each combination of buttons theoretically will cause a
unique voltage to be measured, which we can then interpret in our Arduino sketch and
make decisions based on the button(s) pressed.
First the circuit containing four buttons:

Can you see why this is called an R-2R circuit? When building your circuit use 1%
tolerance resistors and check them with a multimeter to be sure. As always, test and
experiment before committing to anything permanent.
Now to determine a method for detecting each button pressed, and also combinations.
When each button is closed, the voltage applied to analogue pin zero will be different.
And if two buttons are pressed at once, the voltage again will be different. Therefore the
value returned by the function analogRead() will vary for each button-press combination.
To determine these, I connected a numeric display to my Arduino-compatible board, then
simply sent the analogRead() value to the display. You can see some of the results of this
in the following video:
The analogRead() results of pressing every combination of button can be found in the
following table:

After this experiment we now have the values returned by analogRead() and can use
them in a switch case function or other decision-making functions in our sketches to
read button(s) and make decisions based on the user input. Unfortunately there was some
overlap with the returned values and therefore in some cases not every possible
combination of press will be available.
However, were still doing well and you can get at least eleven or twelve combinations
still with only one analog input pin. You can add delay() functions in your sketch if
necessary to take care of switch debouncing or do it with hardware if you feel it is
necessary.
So now you have a more useful method for receiving input via buttons without wasting
many digital input pins. I hope you found this article useful or at least interesting. This
series of tutorials has been going for almost two years now, and may soon start to wind
down its time to move forward to the next series of tutorials
So if you have any suggestions for further articles (and not thinly-veiled methods of
asking me to do your work for you) email them to john at tronixstuff dot com.

You might also like