t r o n i x s t u f f

fun and learning with electronics

Getting Started with Arduino! – Chapter Nine

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 index is here.

Welcome back fellow arduidans!

In this chapter we will start looking at LED matrix displays, designing user interfaces, implementing a user interface for  a clock, and finish up making an alarm clock.

Firstly, let’s have plenty of fun with 64 LEDs! Using an 8×8 LED display module:

Previously we have used 74HC595 shift registers to drive strips of LEDs, single and four-digit LED displays. An LED matrix seems complex at first, but after further investigation quite simple. With sixteen pins you can control 64 LEDs. It works by having 8 row pins, each pin connected to all the anodes on one row; and 8 pins each connected to the cathodes on one column:

It does look like a mess, but we can work it out. As we did with the 4-digit 7-segment display module, we just need one shift register for the anodes, and one for the cathodes. Moving along from exercise 6.2, it will be easy to drive the an LED matrix display – one shift register (the left hand side) will apply current to the rows (anodes) and the other shift register will apply current to NPN transistors to allow current to flow from the cathodes (columns) to ground. So we can make an example quite easily. You will need:

  • Your standard Arduino setup (computer, cable, Uno or compatible)
  • One 8×8 LED matrix. Try to find one that has LEDs with a forward voltage of 2 volts and a current of less than 20mA. If it is bicolour, that’s ok – just use one colour for now
  • Eight 560 ohm 1/4 watt resistors
  • Eight 1 kilo ohm 1/4 resistors
  • Eight BC548 NPN transistors
  • Two 74HC595 shift registers
  • Solderless breadboard and connecting wires

Here is a circuit diagram for our example (click on it to enlarge):

Please note that there are eight transistor/resistor combinations from the second shift register – I just have not drawn them in to save my sanity. They’re on the bottom right of my board:

Now how are we going to light up those LEDs? We need to send two bytes of data to the shift registers, one byte for the row, and one for the column. For this example we will work with individual pixels. For example, say you want to turn on the pixel at 8 across, 8 down – the bottom right. You need to send the following bytes of data to the shift registers: b00000001 and b00000001. In decimal those two numbers are 128 and 128. Or the top-left LED, at 1 across, 1 down – it would be b10000000, b10000000 or decimal 1,1. Once again we can use the functions:

digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, 1); // byte of data for the right-hand shift register (cathode controller)
shiftOut(datapin, clockpin, MSBFIRST, 1);  // for the left-hand shift register (anode controller)
digitalWrite(latchpin, HIGH);

… to send the data to the shift registers. This example sketch for the above circuit should be pretty well self-explanatory if you have been following my tutorials.

Here is is in action:

Once again, quite mesmerising. Did you notice that the horizontal solid rows were dimmer than the solid vertical columns? This is because when you light up one row, all eight LEDs are drawing current from one pin of the shift register – so there is less current for each LED; whereas in the column, each LED has its own source of current, so can therefore operate at full brightness. So a hint – when you are creating images or characters for your display, use scrolling columns to display the image.

Experiment with the example 9.1 sketch, if you display only vertical columns, and make the delay zero – you can give the illusion that the entire display is on, but it is not.

Which leads us into the first exercise for the week!

Exercise 9.1

We can display entire columns with our matrix display. We can position these columns on demand. And without a delay, fill up the entire matrix. Now you can create images, or characters and display them on the matrix, one column at a time. For example, the little yellow dude from that popular arcade game many years ago might look like this:

Using the circuit described for example 9.1, create a character, shape, or whatever tickles your fancy, and animate it to move across the screen.

Hint – To animate an image, you will need to map the matrix every time the image changes – just like a normal animation or cartoon. However, store all the values for the entire animation in one array, otherwise you will go bonkers. When you need to read the array, each matrix image can be read as they are multiples of eight (then add the reference to the value you want).

For inspiration, here is what I came up with:

and the corresponding sketch.

How did you go? If you have an interesting animation, and you can do so – please email a link to Youtube, Vimeo, etc showing your creation – you could win a prize.

Time to get a little more serious now. :(

Over time you have been making things, some useful, some more experimental than anything. Hopefully you will reach the stage of designing something that has a real-world use and could be used by people other than yourself or your immediate circle of friends. In the next few weeks we will look at methods of transitioning projects from prototypes to standalone products you can develop!

A major part of your design should be the user interface, or how your project responds to user input and displays data, results and so on. If something is difficult to use, or understand, it will not be a good product. So what can we do about this? This week we will examine the clock made in example 7.4 and change it to be independent of a computer, and easy for the user to operate. But now for some design inspiration…

The humble alarm clock (it has been staring at me every morning). Here is my late grandfather’s clock from the 1960s:

Simple, yet functional. It does what it is supposed to do with the minimum of fuss. (It’s German). And that is how our project user interfaces should be. As technical people it is very easy to get carried away and put buttons, lights, and all sorts of things together, but at the end of the day, less is more. How can we emulate this with Arduino – but in a simple method?

Looking at the face of the clock, it displays the time (hours, minutes, seconds) and the alarm time. We can use an LCD for that. On the top is the alarm off button. We can use a button for that. On the rear there are winders for the time and alarm spring – we have electricity for that. There are two knobs, one to adjust the time, and one to adjust the alarm – here we have several options. We could use up/down buttons… perhaps we could use a knob as well? And finally there is the gain control – we don’t need this as our DS1307 is infinitely more accurate.

A rough map of how you want things to work is always a good start, for example my mess below:

How can this be implemented? Let’s see. The clock will normally display the date, time, etc. If a button is pressed, it will switch to menu mode (on the right). A knob will be used to select one of the options listed on the right, when the required option is displayed, the user presses the button to select the option. Then the user can use the knob to adjust the variable for that option, and press the button to return to the menu. The last menu option is to return to the clock display. So we can control the whole lot with only one button and one knob.

The button is easy with Arduino, and to save money we can use a potentiometer as a knob. Remember we did this in in exercise 6.2. Normally it can return a value between 0 and 1023, but with our clock we need it to return a value that falls within a variety of ranges – from 0 to 6 for day of the week, to 0 to 59 for the minute adjustment.

Exercise 9.2

Create a function to use a potentiometer to return an integer between zero and a maximum range value. The function will accept the maximum range value, and return an integer which represents the position of the knob. For example:

int dialposition(int maxrange);

Here is a short video of my interpretation in action.

And the resulting sketch. The value rangemax that is fed into the function is the number of positions in the range you want to work with. For example, if I want the knob to return a value between zero and fifty-nine (sixty values in the range) I would set rangemax to 60. The value dialpin is the number of the analogue pin the potentiometer is connected to. You should use a linear potentiometer to ensure a nice smooth adjustment.

Great – now we have a way of reading our knob and customising the result for our range requirements. Our clock example’s menu will require eight options, each with their own function (e.g. set hours, set minutes, set year, return to clock, etc). We have one button, so you could use that to trigger an interrupt to start the menu display (interrupts were covered in chapter three). However if you have made an LCD shield use the interrupt pins, you will need to check the button status while displaying the time. We will make the display of the menu a separate function as well.

For now we will make our clock respond to the ‘menu’ button, and display the eight options when the knob is rotated. We will build on the sketch from example 7.4. Here is the result of doing this:

Now it is time (ha!) to make those menu options actually do something. First we need our displaymenu() function to call the selected option. This can be done with a switch…case function. For example, I will put this code after the while loop:

switch(readdial(8,1))   
{     
case 0: msethours; 
break;     
case 1: 
msetminutes; 
break;     
case 2: 
mset1224; 
break;     
case 3: msetday; 
break;     
case 4: msetmonth; 
break;     
case 5: msetyear; 
break;     
case 6: msetdow; 
break;   
}

There is no need for a seventh option (return to clock display) as this will default if the knob is in the ’7′ range. Notice I have already declared the name of the functions to call. All we have to do is create the individual functions. However there is one catch to work around, when it comes to setting time and date data, this is all done with the one function:

setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

So inside the function that (for example) sets the hour, immediately before setting the hour, read the rest of the values from the clock, and reset them back in with the setDateDS1307() function.

Once again the basic work has been done for you, please see this video:

… and the sketch. Although the contents of the LCD during the menus may be brief, the framework of the user interface has been created and can now be easily modified. For example, if you had a 20 x 4 character LCD, you could offer more help to the user.

But returning to the original task – emulating Grandfather’s alarm clock. We need an alarm!

Exercise 9.3

You guessed it – modify the clock in example 9.3 to have an alarm as well. User can set the alarm, and turn it on or off with the menu system. When the alarm sounds, the user should be able to turn off the alarm, Have fun!

How did you go? Here is a video demonstration of my work:

… and the sketch. That was really fun – I have a lot more clock ideas now.

I hope you enjoyed the change of pace this article and have a greater understanding on why we should create simpler human-machine interfaces wherever possible. Now to move on to Chapter Ten.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, 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.

June 6, 2010 - Posted by | arduino, education, microcontrollers, tutorial | , , , , , , , , , , , , , ,

37 Comments »

  1. Instead of using a ton of transistors and resistors to drive the LED matrix’s cathodes, could you instead use an analogue switch like the 4066 (http://search.digikey.com/scripts/DkSearch/dksus.dll?vendor=0&keywords=CD4066BE&stock=1)

    Comment by Beta | June 8, 2010 | Reply

    • Hello again
      What an excellent question, I hadn’t thought of that. I don’t think the 4066 can handle more than 10mA per pin; however looking at data sheets for NXP and ON Semi 74HC4066 they can handle up to 25mA per pin. If you like I will order some this week and try them out. Cheers, John

      Comment by John Boxall | June 8, 2010 | Reply

    • Oh. That could be a problem unless you controled the led’s by rows. You might could move the curent limiting resistors to the cathode side, which would give the array the brigh appearance.

      Comment by Beta | June 8, 2010 | Reply

  2. Why use the transistors at all? The 74HC595 has more than enough current to drive that matrix.

    Comment by Mike | July 26, 2010 | Reply

    • Correct me if I’m wrong but each pin of the 74HC595 can only handle 25~35mA a pin (NXP data sheet)… therefore if I light up a whole row that will be somewhat exceeded.
      cheers
      john

      Comment by John Boxall | July 26, 2010 | Reply

  3. Hi John!

    With your colaboration and example i made a scrolling termometer:

    http://www.miklos.blog.br/2010/07/termometro-rolante-com-matriz-5×7.html

    (in portuguese but the code and ilustration show the idea)

    Maybe my experiment can help other of your followers to be good and make things!

    Comment by Claudio Miklos | July 31, 2010 | Reply

    • Hello Miklos
      That is a great thermometer – nice work. Plus it looks good enough to convert into a saleable product.
      Congratulations
      john

      Comment by John Boxall | July 31, 2010 | Reply

  4. Thanks Jone very good tutorials, Sir can you don one favour to me as i am new to programming. How can i store array of Hours and minutes and compare the same every second and trigger some thing when time reaches

    int TimeONHour[5]
    int TimeONMinutes[5]
    Int TimeOffHour[5]
    int TimeOffMinutes[5]

    it will be a great help

    Thanks
    Tirlochan

    Comment by Tirlochan | August 28, 2010 | Reply

    • Hello
      you should read chapter four about arrays, and then use the if() function for your decision making process. A good example program for you to see is exercise 10.1.
      Furthermore you should get a copy of “Getting Started with Arduino” by Massimo Banzi
      cheers
      john

      Comment by John Boxall | August 30, 2010 | Reply

  5. I’m interested in designing a similar circuit with an LCD and potentiometer and push button as seen in exercise 9.2. Can you direct me to how they are connected to the Arduino. I see a module based switch, resistor and potentiometer and need more information on how to setup your exercise.

    Thank you.

    Comment by Tim Gilmore | February 1, 2011 | Reply

    • Hello Tim
      1) The potentiometer will have three connections. The centre one goes to an analogue input pin (A0~A5), then one on the left goes to GND and the one on the right goes to 5V.
      2) A good example of connecting buttons is in chapter 12, look for the ‘button board’. Although it has four buttons, you can see how each button is wired to 5V, GND and a digital input pin.
      3) LCD modules are covered in chapter 24
      cheers
      john

      Comment by John Boxall | February 2, 2011 | Reply

  6. On the NPN transistor, where should “E” be connected to?

    Comment by Chris | April 12, 2011 | Reply

    • Hello.
      Please connect the emitter to GND.
      thanks
      john

      Comment by John Boxall | April 12, 2011 | Reply

  7. Thank you for your reply John.
    I have one more question.
    After I followed your project (8×8 led matrix), I used the arduino code from this website http://www.bryanchung.net/?p=177 to this project, and as you see the video in the bryan’s website, my led matrix blinks like the led matrix in the video, but only half of my led’s lights blink…. do you know why? I checked wiring connections a lot of times, but still can’t figure it out.

    Comment by Chris | April 13, 2011 | Reply

    • Hello Chris
      It is hard for me to say without looking at your circuit in person.
      However if you are using /exactly/ the same sketch, the problem lies with wiring or a faulty MAX7219.
      cheers
      john

      Comment by John Boxall | April 14, 2011 | Reply

  8. Your grandfather’s clock is apparently angry about it being almost seven o’clock. That makes it 7am I presume.

    /D

    Comment by David | April 18, 2011 | Reply

    • Yes, used to write those tutorials starting after midnight.
      cheers
      john

      Comment by John Boxall | April 18, 2011 | Reply

  9. can any one help me in my project.. i just want to do the same but i will control my matrix using parallel port

    so i guess the circuit will be same except the arduino
    but i wonder how many wire i will use.. i mean for each shifted register.. there is only one input and 8out out
    is it ok to connect that register directly with parallel port? no need for resistors or any thing else?

    Comment by Tarneem | December 13, 2011 | Reply

  10. Hi John,

    We are about to use your tutorial for a project at school.
    It’s a very good tutorial !!
    But I have one question: What kind of capacitors are you using and where can I buy them?

    Thank you!

    Ruben

    Comment by Ruben | December 23, 2011 | Reply

    • In which country are you located?

      Comment by John Boxall | December 23, 2011 | Reply

      • In the Netherlands

        Comment by Ruben | December 23, 2011

      • For my projects unless otherwise specified use ceramic capacitors for values below 1uF, or electrolytics for values 1uF and higher.
        Try http://nl.farnell.com/
        john

        Comment by John Boxall | December 23, 2011

  11. Are resistor values are good? Especially the 560 ohms, current would be 5mA with 5V suplly.

    Comment by Tomas | January 15, 2012 | Reply

    • Sorry, I’m not entirely sure about what you are asking.

      Comment by John Boxall | January 15, 2012 | Reply

  12. I was asking about this picture http://tronixstuff.files.wordpress.com/2010/06/example9p1schematicsmall.jpg . I thought the current through LEDs will be too small.

    Comment by Tomas | January 20, 2012 | Reply

    • Although I do tend to be conservative, those resistor values are fine. However you are free to check your matrix’s LED specs and try other values.

      Comment by John Boxall | January 20, 2012 | Reply

  13. Hi
    I’ve seen the error
    button pin 8 clashes with my LCD shield 11.12.7,8,9,10
    because I can connect button pin 8 to the extended pins on my LCD shield I never spotted my mistake
    never mind
    you live and learn
    I guess I would have to change the pin 8 in you prog to something else or mod my LCD shield
    garry
    keep up the good work

    Comment by Garry | March 22, 2012 | Reply

  14. Hi,
    can I using this code using my arduino uno with atmega328.
    I have a problem after loading this program into my arduino.
    when I press the button which connected to digital pin 8, I can’t set both time and date.
    my potentiomer not function as well.
    do you connect the potentiometer to analog pin 1?

    Comment by shin kagawa | September 12, 2012 | Reply

    • You can select the analogue pin for the potetiometer swiper in the function, we used pin 1.

      Comment by John Boxall | September 14, 2012 | Reply

  15. ok,i just done what you have tell.but when i press the push button, it doesn’t show “pressed” at the LCD.the other problem is I can’t set the date and time for my ds1307. in the LCD screen it keeps show the selection menu,when i don’t turn the potentiometer. can youexplain to me, how this clock is working actually.Thanks

    Comment by shin kagawa | September 15, 2012 | Reply

    • Have you worked through the earlier chapters, especially 7? This explains how the DS1307 works. The clock is an exercise based from what you have learned from chapters 0 to 9.

      Comment by John Boxall | September 16, 2012 | Reply

  16. Thanks,do you ever try to build propeller clock using arduino? if, yes, which chapter you teach how to build it?

    Comment by shin kagawa | September 16, 2012 | Reply

  17. hello, do you ever build a clock without using rtc? just using millis function?

    Comment by shin kagawa | October 4, 2012 | Reply

    • People do, however I don’t like to.

      Comment by John Boxall | October 4, 2012 | Reply

      • Do you know how to do it?? do you have any recommended website that build digital clock using millis function?

        Comment by shin kagawa | October 4, 2012

      • We have a chapter on millis(), that and some maths should sort you out.

        Comment by John Boxall | October 5, 2012


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 3,835 other followers

%d bloggers like this: