Getting Started with Arduino! – Chapter Three
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 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.
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. Ohm’s 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);
}
}
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);
}
}
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, you may have a system that reads the temperature of a room, and automatically adjusts an air-conditioner’s thermostat to maintain a precise 23 degrees Celsius. You also have a sensor that monitors the mains voltage, and changes state when there is a blackout. This would be a trigger for an interrupt – so you would know on your display right away that the mains power is off – instead of finding out over a longer span of time due to the room temperature slowly rising. Then you could do something before the room temperature was too much.
Another example may be 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, I’m 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 wouldn’t 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 – it’s 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, and 48 (wow) on the arduino mega. Please note you cannot usedanalogWrite(); 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 doesn’t draw much current, so it’s 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 – that’s 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!
Have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.












Hi,
About to try out my first test code with interrupts…
Having a look at your Example 3.2 – interrupts, you mention the 4 Modes, (LOW,CHANGE,RISING,FALLING), but your code is uses ‘HIGH’ ? Also I can’t see a pinMode statement to set the interrupt pin for the switch (Input), does it matter?
Cheers
dargs
Hello dargs
With interrupts no need for pinMode, as they are hard-programmed to digital 2 and 3, e.g. from sketch:
attachInterrupt(0, panicone, HIGH); // so when interrupt zero (digital pin 2) changes state, it will trigger the interrupt and go to function ‘panicone’
attachInterrupt(1, panictwo, HIGH); // so when interrupt one (digital pin 3) changes state, it will trigger the interrupt and go to function ‘panicone’
Yes, I used HIGH (see above).
have fun
john
Cool Stuff! I’m eager to go through the upcoming tutorials. :^)
In the example sketch for Exercise 3.2, the last word on the last line of the setup() function should be ‘panictwo’ instead of ‘panicone’.
Happy New Year!
Hello
Thank you very much for pointing it out
cheers
john
Dir sir,
thanks you !
Cheers
john
Hi to all,
writing my first code with interrupts, i have this problem: the system trigger both interrupts normally, but when the pin state change again the program remain blocked and not go back to the loop routine. Someone know why ?
Tks a lot
Cheers
Renato
I’ve read that the hxt900 can pull up to 750mA. I take it you didn’t have a problem with this?
No, I didn’t have it under load. However I did write “… 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.”. However I will update the article. Thanks for your feedback
john
1) Hi, I need to run 30 volts. Would the circuit resistor value be any different?
2) I am using TIP120 instead of the transistor you indicate. I fried my first duino. I am considering adding diodes coming from the pins, before the signal resistor, to hopefully prevent any feedback to the arduino. Any opinion?
if you want to control a TIP120, you can directly connect the base to arduino digital output. have a diode with the cathode on the collector and anode to GND that exceeds the voltage and current requirement.
Why use a “hard” relay? Solid State relays are easy to find that will operate down to 3V, and around 40 mA or less, even for massive current loads on the output. The SSRs will switch faster, and won’t wear out.
Absolutely. Will keep that in mind for the rewrite.
i can not download any sketches in this web site.
could you please help about this problem?
There are links to each sketch as required in each article, and all of them can be found here:
https://sites.google.com/site/tronixstuff/home/arduino-tutorial-series-files
Thanks for this tutorial and your very good explanation !
It help me a lot.
it’s my second day now viewing your tutorials and i am impressed! can’t wait to order my very own kit. for now, i’ll just read on to learn more! as always, thanks!
Great to hear you are enjoying them.
thanks
John
Hello,
First a big thank you for those courses which are most helpfull!
Now my newbie question… I read the functions and tried to use to blink LEDs… here is the code I produced:
/*
example 1.2 – fun with PWM and RGB LED – Created 07/04/2010 — CC by-sa v3.0 Share the love!
By John Boxall — http://tronixstuff.wordpress.com
*/
int red = 11; // the PinNumbers for the LED
int green = 9;
int blue = 10;
int i = 0; // for loops
void setup()
{
pinMode(red, OUTPUT); // tell Arduino LED is an output
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
}
void loop()
{
blinkLED(9, 5);
blinkLED(11, 2);
blinkLED(10, 10);
}
void blinkLED(int PIN, int TIME)
{
for (int i=1; i=TIME; i++)
{
analogWrite(PIN,HIGH);c\
delay(1000);
analogWrite(PIN,LOW);
delay(1000);
}
}
of course it does not work and I am not able to find why… what is happening is the LED pin9 blinking and blinking and blinking forever……………….
Any clues on what I messed up in my code? I would appreciate some help…
Use digitalWrite not analogWrite in your blinkLED function.
THANK YOU!!!!!!!!!!!!!! working now.
Alexandre
Your for loop is wrong:
for (int i=1; i=TIME; i++) the condition i=TIME will never be true
Should be:
for (int i=1; i<=TIME; i++)
Or:
for (int i=0; i<TIME; i++)
Correction: i=TIME is an assignment statement ie set i to 1 rather than a condition i==TIME
Hello John – Great series. I have ordered an UNO and can’t wait to start experimenting. Great series. Thank you