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!
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 – let’s 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 haven’t 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: Example 5.1
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 7-segment 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?
Let’s 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 let’s 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: example5p2.pdf. Note in the sketch that the decimal point is also used; it’s 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 isn’t 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, Duemilanove)
- 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 isn’t an integer. While you are thinking, here is the shot of my layout:
and the ubiquitous video:
And here is my sketch: exercise5.1.pdf
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 don’t 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 Ohm’s 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 didn’t 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:
/*
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. Let’s see what happens:
That’s a good start, things are moving when we want them to move. However the car’s 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. Let’s 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, Duemilanove)
- 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: exercise 5.2.pdf
At this point we are taking a week off from the tutorials, however chapter six will be published around 21st May. But stick around – we will have two new kit reviews, some great part reviews, and a new project published in the next 7 days, so subscribe and follow us – see the top right of this web page!
High resolution images available at flickr.
If you have any questions at all please leave a comment (below). If you would like to showcase your work from this article, email a picture or a link to john at tronixstuff dot com.
You might even win a prize. Don’t forget to check out the range of gear at Little Bird Electronics!
So have fun, stay safe and see you for our next instalment!