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:

ledmatrixsmall

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:

matrixschematic

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):

example9p1schematicsmall

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:

example9p1boardsmall

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:

… 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 this chapter.

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:

frontclocksmall

rearclocksmall

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:

uidraftsmall

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:

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:

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:

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.

LEDborder

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.

The following two tabs change content below.

John Boxall

Founder, owner and managing editor of tronixstuff.com.

41 Responses to “Getting Started with Arduino! – Chapter Nine”

  1. Beta says:

    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)

    • John Boxall says:

      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

    • Beta says:

      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.

  2. Mike says:

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

    • John Boxall says:

      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

  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!

  4. Tirlochan says:

    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

    • John Boxall says:

      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

  5. Tim Gilmore says:

    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.

    • John Boxall says:

      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

  6. Chris says:

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

  7. Chris says:

    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.

    • John Boxall says:

      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

  8. David says:

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

    /D

  9. Tarneem says:

    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?

  10. Ruben says:

    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

  11. Tomas says:

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

  12. Tomas says:

    I was asking about this picture http://tronixstuff.com/wp-content/uploads/2010/06/example9p1schematicsmall.jpg . I thought the current through LEDs will be too small.

  13. Garry says:

    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

  14. shin kagawa says:

    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?

  15. shin kagawa says:

    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

  16. shin kagawa says:

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

  17. shin kagawa says:

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

  18. mark says:

    Instead of a Potentiometer. How much different would the code be if a rotary encoder was used. If you could show one example of setting say hours, I should be able to figure the other parameters.

    • John Boxall says:

      We cover rotary encoders in chapter eleven.

      • Chris says:

        Hi John, I’m in the middle of a HNC project and I plan to use an UNO to control a watering valve. I thought I could make it easy on myself and use an alarm clock code and use the signal intended for a buzzer to operate a relay/solenoid. What do you think?
        Chris

      • John Boxall says:

        Sure – you just replace the code that make the buzz with code to turn on/off a digital output etc.

Trackbacks/Pingbacks


Leave a Reply

Receive notifications of new posts by email.

The Arduino Book

Arduino Workshop

Für unsere deutschen Freunde

Dla naszych polskich przyjaciół ...

Australian Electronics!

Buy and support Silicon Chip - Australia's only Electronics Magazine.

Use of our content…

%d bloggers like this: