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.
Part Review – Peter H. Anderson Serial LCD Controllers
Hello interested readers
Today we are going to examine a part that makes using LCD modules much easier to interface with microcontrollers – a serial LCD controller IC. Note that this is designed for LCD modules with the standard Hitachi HD44780 interface (almost all LCD modules…) Normally your LCD module would interface with a controller using a 4- or 8-bit parallel interface. In fact, we have done this in chapter of the arduino tutorial here. However in some cases, you may need the digital output pins on your controller for other uses, which can be frustrating. With a serial LCD interface, you only need one serial out port, your +5V power supply and some space on the board for another IC. Therefore it is very easy for even the smallest microcontroller, such as an 8-pin PICAXE -08M to control an LCD. Who would have thought a little micro could push an LCD?
Moving on, a gentleman in the US by the name of Peter H. Anderson has developed his own serial LCD module controller IC using a Microchip PIC16F648A and his own custom software. First of all, let’s say hello.
Peter also offers these in a surface mount SOIC-18 profile in bulk amounts. Great for those projects that hit a successful market.
If you had an Arduino Mega, with 4 serial out pins – you could run 4 LCD modules at once. That would be interesting…
Consider the following image, the only pin used on the arduino is TX (serial out). The other two are GND and 5V, as it is being powered from the breadboard PSU.
Unsurprisingly the software for these chips is not open source, however the purchase price is more than outweighed by the convenience that they offer the user. Peter has created some simple commands to control the LCD – which are just sent as serial output text, including:
?a - set cursor to home position. ?b - destructive backspace ?f - clear LCD and leave cursor at home position ?g - beep ?h - backspace ?i - forward cursor ?j - up cursor ?k - down cursor ?l - clear current line and leave cursor at the beginning of the line ?m - carriage return. Position the cursor at the beginning of the current line. ?n - new line. Advance to the beginning of the next line and clear this line. ?t - tab. Advance the cursor one tab. ?? - display the character '?'. More command examples can be found here. With the right circuitry (detailed in the website) you can also control the back light brightness. You can even create jumbo-sized numbers if you have a four line LCD module. The chip does remove a lot of hard work for the user on the software side, however does require some hardware for itself. Sending commands and data to the LCD is as easy as a serial write command, for example with arduino:
/*
Arduino demo sketch using Peter H. Anderson serial LCD chip - http://www.phanderson.com
by John Boxall - http://tronixstuff.wordpress.com - 19/04/2010
*/
float noisy = 0;
void setup()
{
Serial.begin(2400); // am using 2400bps serial LCD chip, therefore this line is required
randomSeed(analogRead(0)); // reseed the random number generator with some noise
delay (5000); // the serial LCD chip needs about five seconds to boot up
}
void loop()
{
// setup the chip parameters
Serial.print("?G216"); // define the LCD as 2 rows by 16 characters
delay (1000); // need a delay between each instruction to the serial LCD chip
Serial.print("?C0tronixstuff.com "); // next two define the boot-up message displayed. This can also be delayed on call using "?*"
delay (1000);
Serial.print("?C1* part review * "); // you need to fill the entire 16 characters
delay (1000);
Serial.print("?S2"); // chip will display boot message every time it is reset
delay (1000);
Serial.print("?*"); // display boot message as defined above
delay (5000);
// now some displaying...
for (int j = 1; j<9999; j++)
{
Serial.print("?f"); //clear the screen
delay (500);
Serial.print("all your base");
delay (500);
Serial.print("?n"); // move cursor to start of next line
delay(1000);
Serial.print("... belong to us");
delay (2000);
Serial.print("?f"); //clear the screen
delay (500);
Serial.print("?*"); // display boot message as defined above
delay (5000);
Serial.print("?f"); //clear the screen
delay (500);
// display some random numbers
Serial.print("Random Numbers!");
Serial.print("?n"); // move cursor to start of next line
for (int i = 1; i<5; i++)
{
noisy=random(1000);
Serial.print("Number: ");
Serial.print(noisy,0);
delay (1000);
Serial.print("?m"); // move cursor to start of the current line
}
Serial.print("?f"); //clear the screen
delay (500);
Serial.print("?*"); // display boot message as defined above
delay (5000);
Serial.print("?f"); // clear screen
Serial.print("Earth");
delay(500);
Serial.print(".");
delay(500);
Serial.print(".");
delay(500);
Serial.print(".");
delay(500);
Serial.print("?n"); // move cursor to start of next line
delay(500);
Serial.print("Mostly harmless");
delay(5000);
}
}
or with PICAXE:
main:' LCD test with phanderson.com seral controller chip - 23/03/2010
wait 5 ' it takes a moment for the chip to boot and the LCD to wake up
'serout 2, T2400, ("?S2") ' show my copyright message [as shown below] at boot
'wait 1
'serout 2, T2400, ("?f") ' clear screen
'wait 1
'serout 2, T2400, ("?c0") ' turns off blinking cursor
'wait 1
'serout 2, T2400, ("?C0copyright 2010 ") ' set top line of initial boot message
'wait 1
'serout 2, T2400, ("?C1tronixstuff.com ") ' set bottom line of initial boot message
'wait 3
serout 2,T2400,("Hello. I hope")
serout 2, T2400, ("?n")
serout 2, T2400,("that this works")
wait 3
serout 2, T2400, ("?f") ' clear screen
serout 2, T2400, ("?*") ' show boot message
wait 3
serout 2, T2400, ("?f") 'clear screen
serout 2, T2400, ("Close the fridge")' as this is 16 characters, you can keep sending characters and the LCD will auto scroll to the next line
serout 2, T2400, ("door now please!") '
wait 3
serout 2, T2400, ("?f") ' clear screen completely for next text display
goto main
end
Here is a video clip of the arduino example (no audio):
More code examples are available on Peter’s web site. So a short and sweet review, but a good product that will make a complex task quite easy.
Please subscribe (see the top right of this page) to receive notifications of new articles. If you have any questions at all please leave a comment (below).
[Note - these parts were purchased by myself personally and reviewed without notifying the manufacturer or retailer]














