Tutorial: Video output from your Arduino
This is chapter thirty-five of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A seemingly endless series of tutorials about the Arduino universe. The first chapter is here, the complete series is detailed here.
Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice.
Welcome back fellow arduidans!
In this chapter we will examine something different – the ability of our Arduino and compatible boards to create composite video output. In other words, displaying stuff from the Arduino on a TV. A lot of people were unaware of the ability to do this, however the process is very simple and not difficult to implement from a hardware perspective. Within this chapter we will learn to construct the minumum hardware required and demonstrate basic functions to get started.
To whet your appetite, here is a quick video demonstration of what is possible:
You can’t expect too much from a 16 Mhz microcontroller without a video card… but the price is right, and with some imagination and the right functions you can do quite well. To make this happen we need to knock out some hardware of our own (or you could buy a kit instead). Connection is very easy. First we need to locate three pins on our Arduino board. They will be used to output Sync, Video and also GND. For those with Arduno Uno/Duemilanove/Freetronics Eleven etc Sync is digital 9, video is digital 7 and GND is … GND. If you have a Mega/Mega2560 Sync is digital 11 and video is D29. There is also the ability to generate audio with the methods in this article, and if you want to do this the Uno (etc.) pin is digital 11 or 10 on the Mega.
The monitor or television used needs to have a composite video-in socket (jack). For those with older televisions that have a VCR connected, you could use the video-in socket on the VCR.
The schematic for video out is very simple, you only need two normal 0.25W resistors and a video lead:
(tronixCAD v1.0…)
If you’re not up for soldering into an RCA plug, a simple way is to chop up a standard video lead as such:
Then just wire the termination of the two resistors to the centre core (“pin”) and GND to the shield. For the purpose of this article I have made a quick TV-out shield that also includes a thumb joystick (as reviewed here).
A real triumph of engineering… however it solves the problem. The vertical trimmer is connected to A0; the horizontal to A1; the button to digital 8 via a 10k0 pull-up resistor. Next, you will need to download and install the arduino-tvout library. It can be found here. We will use the TVoutBeta1.zip version. Copy the downloaded folder into the ../arduino-002x/libraries folder and restart the Arduino IDE. Those of you who may have a nootropic design Hackvision – please note your library is different.
Now to see how to integrate TV-out into our sketch. We will run through the basic functions which integrated with your imagination should see some interesting results… So let’s go!
For every project, place these two lines at the top of your sketch:
#include <TVout.h> TVout TV;
The first brings in the library, and the second line creates an instance of TV to use with the library functions. Next, we need to activate TVout and select the appropriate broadcast standard (PAL or NTSC). In void setup() use either
TV.start_render(_NTSC) // for NTSC (or)
TV.start_render(_PAL); // for PAL system
Now for the main functions. The first one of interest will be:
TV.clear_screen();
which … clears the screen. Or if you would like to fill the screen with white, use
TV.fill_screen(1);
Moving on – to write some text. First we need to select a font. There are three basic fonts to choose from:
- font4x6 (each character being 4 pixels by 6 pixels, etc.)
- font6x8
- font8x8
Well there is four, but it wouldn’t display for me. Working on it! To choose a font use:
TV.select_font(font4x6); // using font4x6
Then to write the text, choose the screen location with:
TV.set_cursor(x,y);
then display the text with:
TV.print("Hello, world..."); // etc
You can also use TV.println(); to add a carriage return as expected. Display single characters with a position in the one function using:
TV.print_char(x,y,c); // c is the character to display
So let’s have a look at the various fonts in action with the following sketch (download):
Example 35.1
/*
Example 35.1 - arduino-tvout text demonstration
http://tronixstuff.wordpress.com/tutorials > chapter 35 | CC by-sa-nc
*/
#include
#include
TVout TV;
int d=10; // for delay purposes
char c='X';
void setup()
{
TV.begin(_PAL); // for PAL system
TV.clear_screen();
}
void loop()
{
TV.select_font(font4x6);
for (int a=0; a<6; a++)
{
for (int b=0; b<128; b++)
{
TV.print_char(b,a*6,c);
delay(d);
TV.clear_screen();
}
}
delay(1000);
TV.clear_screen();
TV.select_font(font6x8);
for (int a=0; a<6; a++)
{
for (int b=0; b<128; b++)
{
TV.print_char(b,a*8,c);
delay(d);
TV.clear_screen();
}
}
delay(1000);
TV.clear_screen();
TV.select_font(font8x8);
for (int a=0; a<6; a++)
{
for (int b=0; b<128; b++)
{
TV.print_char(b,a*8,c);
delay(d);
TV.clear_screen();
}
}
delay(1000);
TV.clear_screen();
}
Now to move into the 1970s with some basic graphical functions. We have a screen resolution of 128 by 96 pixels to work with. When planning your display, you need to ensure that the sketch never attempts to display a pixel outside of the 128 x 96 screen area. Doing so generally causes the Arduino to reboot.
TV.set_pixel(x,y,z);
where x and y are the coordinates of the pixel, and z is the colour (1 = white, 0 = black, 2 = inverse of current pixel’s colour). You want more than a pixel? How about a line:
TV.draw_line(x1,y1,x2,y2,colour);
Draws a line from x1, y1 to x2, y2 of colour colour. (1 = white, 0 = black, 2 = inverse of current pixel’s colour).
Rectangles? Easy:
TV.draw_rectangle(x,y,w,h,colour,fill);
Draws a rectangle with the top-left corner at x,y; width w, height h, colour and optional fill colour.
Circles are just as simple:
TV.draw_circle(x,y,r,colour,fill);
Draws a circle with centre at x,y; radius r pixels, edge colour, optional fill colour.
Now to see these functions in action with the following sketch (download):
Example 35.2
/*
Example 35.2 - arduino-tvout font demonstration II
http://tronixstuff.wordpress.com/tutorials > chapter 35 | CC by-sa-nc
*/
#include
TVout TV;
int d=100; // for delay purposes
int x1,x2,y1,y2,r=0;
void setup()
{
TV.begin(_PAL); // for PAL system
TV.clear_screen();
randomSeed(analogRead(0)); // seed the random number generator
}
void pixels()
{
TV.clear_screen();
for (int a=0; a<200; a++)
{
x1=random(128);
y1=random(96);
TV.set_pixel(x1,y1,2);
delay(d);
}
delay(1000);
TV.clear_screen();
}
void lines()
{
TV.clear_screen();
for (int a=0; a<96; a++)
{
TV.draw_line(0,a,127,a,1);
delay(d);
}
delay(500);
for (int a=0; a<96; a++)
{
TV.draw_line(0,a,127,a,0);
delay(d);
}
TV.clear_screen();
delay(500);
}
void circles()
{
TV.clear_screen();
for (int i=0; i<30; i++)
{
TV.draw_circle(64,48,i,1,0);
delay(200);
TV.draw_circle(64,48,i,1,1);
delay(200);
TV.draw_circle(64,48,i,0,0);
delay(200);
}
delay(1000);
TV.clear_screen();
}
void loop()
{
pixels();
lines();
circles();
}
And for the video demonstration:
So there you have it, a start with Arduino and TV-out. Furthermore, a big thanks to http://code.google.com/u/mdmetzle/ for the arduino-tvout library.
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.
Kit review – nootropic design Digit Shield
Hello readers
Time once again to examine another kit. This week we have the nootropic design Digit Shield for Arduino Uno/Duemilanove and compatible boards. Although a finger can be called a digit this shield is not some sort of biotechnological experiment – instead it gives us four seven-segment LED displays to show various forms of numerical data from our Arduino sketches.
Although many people may be tempted to use a standard LCD unit, there are a few advantages to using an LED display – such as digit size, enhanced readability in daylight, and LED displays are generally much more robust than LCDs. Therefore there should be many uses for the Digit Shield. Furthermore, the people at nootropic design have been awesome as they support the Open Hardware Definition 1.0, and the Digit Shield design files have been made available under Creative Commons attribution-share alike.
First let’s run through construction, then operation with some demonstrations. The kit arrives in a nice reusable bag with a pointer to the online instructions:
Kit construction was relatively simple thanks to the excellent instructions by nootropic design. All the parts required for completion are included, except for IC sockets:
My demonstration kit included green LED displays, however it is also available in red-orange, depending on the retail outlet you choose. Once again the PCB is well laid out, with a good solder mask and a nicely labelled silk screen on top:
Now to start soldering. The process is nothing out of the ordinary, and should take around half an hour at the most. First in are the resistors:
Notice how the current-limiting resistors for the LED segments will be under the LED displays. So now we solder in the LED modules and create a resistor jail:
Now for the shift register and BCD to decimal ICs. I found inserting them a little tricky due to my large hands and the LED display already being in place, so it would be easier to fit the ICs before the LED modules:
This leaves us with the transistors, capacitors, header sockets and the reset button:
After soldering the reset button, you may need trim down the solder and legs (as shown below) otherwise there is a possibility they will rub the DC input socket on the Arduino board:
Finally the shield pins are fitted and the shield is ready:
The next task is to download and install the Digit Shield’s Arduino library. The latest version can be found here. Extract the folder into your
../arduino-002x/libraries
folder, then restart the Arduino IDE software. A quick test of the shield can be accomplished with the SimpleCounter sketch available from the inbuilt examples. To find this, select File>Examples>DigitShield>SimpleCounter in the Arduino IDE, and upload the sketch. Hold onto the desk as you watch some numbers increment:
Using the shield in your own sketch is quite simple. Instead of reinventing the wheel there is an excellent explanation of the various functions available on the lower section of this page. A very useful feature is when the shield cannot display a number – it shows all four decimal points instead. The only slight criticism that comes to mind is the inability to directly display hexadecimal digits A~F, as the LED units lend themselves nicely to doing so; or the option of controlling each LED segment individually with a simple function. So let’s see if that is possible…
One of the joys of open hardware is the fact we can get the schematic, see how it works and attempt to solve such dilemmas ourselves. For those without software that can read Cadsoft EAGLE files, here is the schematic in .pdf format. The section we need to see is how the LED segments are driven. Look for the 74HC595 and 74LS247 ICs. Serial data is shifted out from the Arduino digital pins to the 74HC595 shift register. (For more information about how 74HC595s work with Arduino please visit this tutorial).
Outputs A~D (Q0~Q3) represent binary-coded decimal output and the outputs E~H (Q4~Q7) control the transistors which select the current digit to use. The BCD output is fed to the 74LS247 BCD to seven-segment drive IC. Although this is a very useful IC, it can only display the decimal digits and a few odd characters (see page two of the data sheet.pdf). So this leaves us unable to modify our sketches or the shield library to solve our problem. Such is life!
Perhaps the people at nootropic design can consider a change in the hardware for the next version to incorporate such requirements. However there are several projects available in the Digit Shield’s website that may be of interest, including a way to daisy-chain more than one shield at a time.
Nevertheless the Digit Shield is a simple kit that makes displaying Arduino-generated numerical data simple and clear. Furthermore lovers of blinking LEDs will have a ball. For further questions about the Digit Shield contact nootropic design or perhaps post on their forum. The Digit Shield is available from Little Bird Electronics.
As always, thank you for reading and I look forward to your comments and so on. Furthermore, don’t be shy in pointing out errors or places that could use improvement. Please subscribe using one of the methods at the top-right of this web page to receive updates on new posts, follow me on twitter or facebook, or join our Google Group for further discussion.
High resolution images are available on flickr.
[Note - The kit was purchased by myself personally and reviewed without notifying the manufacturer or retailer]
Otherwise, have fun, be good to each other – and make something!
Kit review – nootropic design Hackvision
Hello readers
Time for another kit review – the nootropics design Hackvision, a nice change from test equipment. The purpose of the Hackvision is to allow the user to create retro-style arcade games and so on that can be played on a monitor or television set with analogue video input. Although the display resolution is only 128 by 96 pixels, this is enough to get some interesting action happening. Frankly I didn’t think the Arduino hardware environment alone was capable of this, so the Hackvision was a pleasant surprise.
Assembly is quick and relatively simple, the instructions are online and easy to follow. All the parts required are included:
The microcontroller is pre-loaded with two games so you can start playing once construction has finished. However you will need a 5V FTDI cable if you wish to upload new games as the board does not have a USB interface. The board is laid out very clearly, and with the excellent silk-screen and your eyes open construction will be painless. Note that you don’t need to install R4 unless necessary, and if your TV system is PAL add the link which is between the RCA sockets. Speaking of which, when soldering them in, bend down the legs to lock them in before soldering, as such:
Doing so will keep them nicely flush with the PCB whilst soldering. Once finished you should have something like this:
All there is to do now is click the button covers into place, plug in your video and audio RCA leads to a monitor, insert nine volts of DC power, and go:
Nice one. For the minimalist users out there, be careful if playing games as the solder on the rear of the PCB can be quite sharp. Included with the kit is some adhesive rubber matting to attach to the underside to smooth everything off nicely. However only fit this once you have totally finished with soldering and modifying the board, otherwise it could prove difficult to remove neatly later on. Time to play some games… in the following video you can see how poor my reflexes are when playing Pong and Space Invaders:
[ ... the Hackvision also generates sounds, however my cheap $10 video capture dongle from eBay didn't come through with the audio ... ]
Well that takes me back. There are some more contemporary games and demonstration code available on the Hackvision games web page. For the more involved Hackvision gamer, there are points on the PCB to attach your own hand-held controls such as paddles, nunchuks and so on. There is a simple tutorial on how to make your own paddles here.
Those who have been paying attention will have noticed that although the Hackvision PCB is not the standard Arduino Duemilanove-compatible layout, all the electronics are there. Apart from I/O pins used by the game buttons, you have a normal Arduino-style board with video and audio out. This opens up a whole world of possibilities with regards to the display of data in your own Arduino sketches (software). From a power supply perspective, note that the regulator is a 78L05 which is only good for 100mA of current, and the board itself uses around 25mA.
To control the video output, you will need to download and install the hackvision-version arduino-tvout library. Note that this library is slightly different to the generic arduino-tvout library with regards to function definitions and parameters. To make use of the included buttons easier, there is also the controllers library. Here is a simple, relatively self-explanatory sketch that demonstrates some uses of the tvout functions (download):
/* nootropics Hackvision display demo two http://tronixstuff.wordpress.com > kit reviews John Boxall 13 May 2011 | CC by-sa */
#include "avr/pgmspace.h" #include "TVout.h" #include "video_gen.h" #include "EEPROM.h" #include "Controllers.h"
int x,y=0;
int d=500; // used for various delays
// declare screen resolution
#define W 136
#define H 98
// create instance of TV
TVout tv;
void setup() {
// If pin 12 is pulled LOW, then the PAL jumper is shorted.
pinMode(12, INPUT);
digitalWrite(12, HIGH);
if (digitalRead(12) == LOW) {
tv.begin(_PAL, W, H);
// Since PAL processing is faster, we need to slow the game play down.
}
else {
tv.begin(_NTSC, W, H);
}
randomSeed(analogRead(0));
}
void randomPixels()
{
tv.clear_screen(); // clears the screen
for (int a=0; a<500; a++)
{
x=random(128);
y=random(96);
tv.set_pixel(x,y,1); // 1 for white, 0 for black, 2 for inverse of current colour at that location
delay(10);
}
}
void randomLines()
{
tv.clear_screen(); // clears the screen
for (int a=0; a<128; a++)
{
tv.draw_line(a,1,a,96,1); // x,y to x,y, colour 1 = white
delay(50);
}
}
void rectangles()
{
tv.clear_screen(); // clears the screen
for (int a=0; a<30; a++)
{
x=random(128);
y=random(96);
tv.draw_box(x,y,x+10,y+10,1,0,0,1); // top-left x,y, length, width, colour, fill (0 = no, 1 = yes)
delay(50);
tv.draw_box(x,y,x+10,y+10,1,1,0,1); // top-left x,y, length, width, colour, fill (0 = no, 1 = yes)
delay(50);
}
}
void circles()
{
tv.clear_screen(); // clears the screen
for (int a=0; a<30; a++)
{
x=random(128);
y=random(96);
tv.draw_circle(x,y,a,1,0,1); // x,y coordinates, radius, line colour, fill
delay(50);
tv.draw_circle(y,x,a,1,1,1);
delay(50);
}
}
void loop()
{
randomPixels();
delay(d);
randomLines();
delay(d);
rectangles();
delay(d);
circles();
delay(d);
}
And the resulting video demonstration:
I will be the first to admit that my imagination is lacking some days. However with the sketch above hopefully you can get a grip on how the functions work. But there are some very good game implementations out there, as listed on the Hackvision games page. After spending some time with this kit, I feel that there is a lack of documentation that is easy to get into. Sure, having some great games published is good but some beginners’ tutorials would be nice as well. However if you have the time and the inclination, there is much that could be done. In the meanwhile you can do your own sleuthing with regards to the functions by examining the TVout.cpp file in the Hackvision tvout library folder.
For further questions about the Hackvision contact nootropic design or perhaps post on their forum. However the Hackvision has a lot of potential and is an interesting extension of the Arduino-based hardware universe – another way to send data to video monitors and televisions, and play some fun games. The Hackvision is available from Little Bird Electronics. If you are looking for a shield-based video output device, perhaps consider the Batsocks Tellymate.
As always, thank you for reading and I look forward to your comments and so on. Furthermore, don’t be shy in pointing out errors or places that could use improvement. Please subscribe using one of the methods at the top-right of this web page to receive updates on new posts, follow me on twitter or facebook, or join our Google Group for further discussion.
High resolution images are available on flickr.
[Note - The kit was purchased by myself personally and reviewed without notifying the manufacturer or retailer]
Otherwise, have fun, be good to each other – and make something!
Tutorial: Arduino and the SPI bus
This is chapter thirty-four of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A seemingly endless tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here. Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to usev22 or v23 until further notice.
Welcome back fellow arduidans!
This is the first of two chapters in which we are going to start investigating the SPI data bus, and how we can control devices using it with our Arduino systems. The SPI bus may seem to be a complex interface to master, however with some brief study of this explanation and practical examples you will soon become a bus master! To do this we will learn the necessary theory, and then apply it by controlling a variety of devices. In this tutorial things will be kept as simple as possible.
But first of all, what is it? And some theory…
SPI is an acronym for “Serial Peripheral Interface”. It is a synchronous serial data bus – data can travel in both directions at the same time, as opposed to (for example) the I2C bus that cannot do so. To allow synchronous data transmission, the SPI bus uses four wires. They are called:
- MOSI – Master-out, Slave-in. This line carries data from our Arduino to the SPI-controlled device(s);
- MISO – Master-in, Slave out. This line carries data from the SPI-controlled device(s) back to the Arduino;
- SS – Slave-select. This line tells the device on the bus we wish to communicate with it. Each SPI device needs a unique SS line back to the Arduino;
- SCK – Serial clock.
Within these tutorials we consider the Arduino board to be the master and the SPI devices to be slaves. On our Arduino Duemilanove/Uno and compatible boards the pins used are:
- SS – digital 10. You can use other digital pins, but 10 is generally the default as it is next to the other SPI pins;
- MOSI – digital 11;
- MISO – digital 12;
- SCK – digital 13;
Arduino Mega users – MISO is 50, MOSI is 51, SCK is 52 and SS is usually 53. If you are using an Arduino Leonardo, the SPI pins are on the ICSP header pins. See here for more information. You can control one or more devices with the SPI bus. For example, for one device the wiring would be:
Data travels back and forth along the MOSI and MISO lines between our Arduino and the SPI device. This can only happen when the SS line is set to LOW. In other words, to communicate with a particular SPI device on the bus, we set the SS line to that device to LOW, then communicate with it, then set the line back to HIGH. If we have two or more SPI devices on the bus, the wiring would resemble the following:
Notice how there are two SS lines – we need one for each SPI device on the bus. You can use any free digital output pin on your Arduino as an SS line. Just remember to have all SS lines high except for the line connected to the SPI device you wish to use at the time.
Data is sent to the SPI device in byte form. You should know by now that eight bits make one byte, therefore representing a binary number with a value of between zero and 255. When communicating with our SPI devices, we need to know which way the device deals with the data – MSB or LSB first. MSB (most significant bit) is the left-hand side of the binary number, and LSB (least significant bit) is the right-hand side of the number. That is:
Apart from sending numerical values along the SPI bus, binary numbers can also represent commands. You can represent eight on/off settings using one byte of data, so a device’s parameters can be set by sending a byte of data. These parameters will vary with each device and should be illustrated in the particular device’s data sheet. For example, a digital potentiometer IC with six pots:
This device requires two bytes of data. The ADDR byte tells the device which of six potentiometers to control (numbered 0 to 5), and the DATA byte is the value for the potentiometer (0~255). We can use integers to represent these two values. For example, to set potentiometer number two to 125, we would send 2 then 125 to the device.
How do we send data to SPI devices in our sketches?
First of all, we need to use the SPI library. It is included with the default Arduino IDE installation, so put the following at the start of your sketch:
#include "SPI.h"
Next, in void.setup() declare which pin(s) will be used for SS and set them as OUTPUT. For example,
pinMode(ss, OUTPUT);
where ss has previously been declared as an integer of value ten. Now, to activate the SPI bus:
SPI.begin();
and finally we need to tell the sketch which way to send data, MSB or LSB first by using
SPI.setBitOrder(MSBFIRST);
or
SPI.setBitOrder(LSBFIRST);
When it is time to send data down the SPI bus to our device, three things need to happen. First, set the digital pin with SS to low:
digitalWrite(SS, LOW);
Then send the data in bytes, one byte at a time using:
SPI.transfer(value);
Value can be an integer/byte between zero and 255. Finally, when finished sending data to your device, end the transmission by setting SS high:
digitalWrite(ss, HIGH);
Sending data is quite simple. Generally the most difficult part for people is interpreting the device data sheet to understand how commands and data need to be structured for transmission. But with some practice, these small hurdles can be overcome.
Now for some practical examples!
Time to get on the SPI bus and control some devices. By following the examples below, you should gain a practical understanding of how the SPI bus and devices can be used with our Arduino boards.
Example 34.1
Our first example will use a simple yet interesting part – a digital potentiometer (we also used one in the I2C tutorial). This time we have a Microchip MCP4162-series 10k rheostat:
Here is the data sheet.pdf for your perusal. To control it we need to send two bytes of data – the first byte is the control byte, and thankfully for this example it is always zero (as the address for the wiper value is 00h [see table 4-1 of the data sheet]). The second byte is the the value to set the wiper, which controls the resistance. So to set the wiper we need to do three things in our sketch…
First, set the SS (slave select) line to low:
digitalWrite(10, LOW);
Then send the two byes of data:
SPI.transfer(0); // command byte
SPI.transfer(value); // wiper value
Finally set the SS line back to high:
digitalWrite(10, HIGH);
Easily done. Connection to our Arduino board is very simple – consider the MCP4162 pinout:
Vdd connects to 5V, Vss to GND, CS to digital 10, SCK to digital 13, SDI to digital 11 and SDO to digital 12. Now let’s run through the available values of the MCP4162 in the following sketch (download):
/*
Example 34.1 - SPI bus demo using a Microchip MCP4162 digital potentiometer [http://bit.ly/iwDmnd]
http://tronixstuff.com/tutorials > chapter 34 | CC by-sa-nc | John Boxall
*/
#include "SPI.h" // necessary library
int ss=10; // using digital pin 10 for SPI slave select
int del=200; // used for various delays
void setup()
{
pinMode(ss, OUTPUT); // we use this for SS pin
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
// our MCP4162 requires data to be sent MSB (most significant byte) first
}
void setValue(int value)
{
digitalWrite(ss, LOW);
SPI.transfer(0); // send command byte
SPI.transfer(value); // send value (0~255)
digitalWrite(ss, HIGH);
}
void loop()
{
for (int a=0; a<256; a++)
{
setValue(a);
delay(del);
}
for (int a=255; a>=0; --a)
{
setValue(a);
delay(del);
}
}
Now to see the results of the sketch. In the following video clip, a we run up through the resistance range and measure the rheostat value with a multimeter:
Before moving forward, if digital potentiometers are new for you, consider reading this short guide written by Microchip about the differences between mechanical and digital potentiometers.
Example 34.2
In this example, we will use the Analog Devices AD5204 four-channel digital potentiometer (data sheet.pdf). It contains four 10k ohm linear potentiometers, and each potentiometer is adjustable to one of 256 positions. The settings are volatile, which means they are not remembered when the power is turned off. Therefore when power is applied the potentiometers are all pre set to the middle of the scale. Our example is the SOIC-24 surface mount example, however it is also manufactured in DIP format as well.
To make life easier it can be soldered onto a SOIC breakout board which converts it to a through-hole package:
In this example, we will control the brightness of four LEDs. Wiring is very simple. Pinouts are in the data sheet.pdf.
And the sketch (download):
/*
Example 34.2 - SPI bus demo using Analog Devices AD5204 digital potentiometer [http://bit.ly/joB51b]
http://tronixstuff.com/tutorials > chapter 34 | CC by-sa-nc | John Boxall
*/
#include "SPI.h" // necessary library
int ss=10; // using digital pin 10 for SPI slave select
int del=5; // used for fading delay
void setup()
{
pinMode(ss, OUTPUT); // we use this for SS pin
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
// our AD5204 requires data to be sent MSB (most significant byte) first. See data sheet page 5
allOff(); // we do this as pot memories are volatile
}
void allOff()
// sets all potentiometers to minimum value
{
for (int z=0; z<4; z++)
{
setPot(z,0);
}
}
void allOn()
// sets all potentiometers to maximum value
{
for (int z=0; z<4; z++)
{
setPot(z,255);
}
}
void setPot(int pot, int level)
// sets potentiometer 'pot' to level 'level'
{
digitalWrite(ss, LOW);
SPI.transfer(pot);
SPI.transfer(level);
digitalWrite(ss, HIGH);
}
void blinkAll(int count)
{
for (int z=0; z=0; --l)
{
setPot(a,l);
delay(del);
}
}
}
void allFade(int count)
{
for (int a=0; a=0; --l)
{
setPot(0,l);
setPot(1,l);
setPot(2,l);
setPot(3,l);
delay(del);
}
}
}
void loop()
{
blinkAll(3);
delay(1000);
indFade();
allFade(3);
}
The function allOff() and allOn() are used to set the potentiometers to minimum and maximum respectively. We use allOff() at the start of the sketch to turn the LEDs off. This is necessary as on power-up the wipers are generally set half-way. Furthermore we use them in the blinkAll() function to … blink the LEDs. The function setPot() accepts a wiper number (0~3) and value to set that wiper (0~255). Finally the function indFade() does a nice job of fading each LED on and off in order – causing an effect very similar to pulse-width modulation.
Finally, here it is in action:
Question – Would you use a rheostat or a potentiometer to divide voltage?
Example 34.3
In this example, we will use use a four-digit, seven-segment LED display that has an SPI interface. Using such a display considerably reduces the amount of pins required on the micro controller and also negates the use of shift register ICs which helps reduce power consumption and component count. The front of our example:
and the rear:
Thankfully the pins are labelled quite clearly. Please note that the board does not include header pins – they were soldered in after receiving the board. Although this board is documented by Sparkfun there seems to be issues in the operation, so instead we will use a sketch designed by members of the Arduino forum. Not wanting to ignore this nice piece of hardware we will see how it works and use it with the new sketch from the forum.
Again, wiring is quite simple:
- Board GND to Arduino GND
- Board VCC to Arduino 5V
- Board SCK to Arduino D12
- Board SI to Arduino D11
- Board CSN to Arduino D10
The sketch is easy to use, you need to replicate all the functions as well as the library calls and variable definitions. To display numbers (or the letters A~F) on the display, call the function
write_led(a,b,c);
where a is the number to display, b is the base system used (2 for binary, 8 for octal, 10 for usual, and 16 for hexadecimal), and c is for padded zeros (0 =off, 1=on). If you look at the void loop() part of the example sketch, we use all four number systems in the demonstration. If your number is too large for the display, it will show OF for overflow. To control the decimal points, colon and the LED at the top-right the third digit, we can use the following:
write_led_decimals(1); // left-most decimal point write_led_decimals(2); write_led_decimals(4); write_led_decimals(8); // right-most decimal point write_led_decimals(16); // colon LEDs write_led_decimals(32); // apostrophe LED write_led_decimals(0); // off
After all that, here is the demonstration sketch for your perusal (download):
/*
Example 34.3 - SPI bus demo using SFE 4-digit LED display [http://bit.ly/ixQdbT]
http://tronixstuff.com/tutorials > chapter 34
Based on code by Quazar & Busaboi on Arduio forum - http://bit.ly/iecYBQ
*/
#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO - not used, but part of builtin SPI
#define SPICLOCK 13 //sck
#define SLAVESELECT 10 //ss
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<16) || (num>(base*base*base*base-1)) ) {
write_led_numbers(' ', 0x00, 0x0f, ' '); // indicate overflow
}
else {
while ( (num || pad) && (place<4) ) {
if ( (num>0) || pad )
digit[place++] = num % base;
num /= base;
}
write_led_numbers(digit[3], digit[2], digit[1], digit[0]);
}
}
void pointDemo()
{
write_led_decimals(1);
delay(1000);
write_led_decimals(2);
delay(1000);
write_led_decimals(4);
delay(1000);
write_led_decimals(8);
delay(1000);
write_led_decimals(16);
delay(1000);
write_led_decimals(32);
delay(1000);
write_led_decimals(0); // non-digits all off
}
void loop()
{
pointDemo();
delay(500);
for (int i = 0; i < 100; i++) {
write_led (i,10,1);
delay(25);
}
delay(500);
for (int i = 100; i >=0; --i) {
write_led (i,10,0);
delay(25);
}
delay(500); // now binary
for (int i = 0; i < 16; i++) {
write_led (i,2,0);
delay(100);
}
delay(500);
for (int i = 15; i >=0; --i) {
write_led (i,2,0);
delay(100);
}
delay(500); // now octal
for (int i = 0; i < 500; i++) {
write_led (i,8,0);
delay(50);
}
delay(500);
// now hexadecimal
for (int i = 20000; i < 22000; i++) {
write_led (i,16,0);
delay(50);
}
delay(500);
}
And a short video of the demonstration:
So there you have it – hopefully an easy to understand introduction to the world of the SPI bus and how to control the devices within. As always, now it is up to you and your imagination to find something to control or get up to other shenanigans. In the next SPI article we will look at reading and writing data via the SPI bus. If you have any suggestions with regards to parts for the next article, leave a comment below and we’ll look into it. Thank you for your patience in awaiting this series of articles. Although getting it together was a little tricky, it was a lot of fun. I hope you enjoyed reading it as much as I did writing it for you.
If you have any questions about the processes or details in this article, please ask in our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, there is the odd competition or give-away – and we can all learn something. Or follow tronixstuff on twitter and facebook. High resolution images available on flickr.
Otherwise, have fun, stay safe, be good to each other – and make something!
Discovering Arduino’s internal EEPROM lifespan
Hello readers
Some time ago I published a short tutorial concerning the use of the internal EEPROM belonging to the Atmel ATmega328 (etc.) microcontroller in our various Arduino boards. Although making use of the EEPROM is certainly useful, it has a theoretical finite lifespan – according to the Atmel data sheet (download .pdf) it is 100,000 write/erase cycles.
One of my twitter followers asked me “is that 100,000 uses per address, or the entire EEPROM?” – a very good question. So in the name of wanton destruction I have devised a simple way to answer the question of EEPROM lifespan. Inspired by the Dangerous Prototypes’ Flash Destroyer, we will write the number 170 (10101010 in binary) to each EEPROM address, then read each EEPROM address to check the stored number. The process is then repeated by writing the number 85 (01010101 in binary) to each address and then checking it again. The two binary numbers were chosen to ensure each bit in an address has an equal number of state changes.
After both of the processes listed above has completed, then the whole lot repeats. The process is halted when an incorrectly stored number is read from the EEPROM – the first failure. At this point the number of cycles, start and end time data are shown on the LCD.
In this example one cycle is 1024 sequential writes then reads. One would consider the entire EEPROM to be unusable after one false read, as it would be almost impossible to keep track of individual damaged EEPROM addresses. (Then again, a sketch could run a write/read check before attempting to allocate data to the EEPROM…)
If for some reason you would like to run this process yourself, please do not do so using an Arduino Mega, or another board that has a fixed microcontroller. (Unless for some reason you are the paranoid type and need to delete some data permanently). Once again, please note that the purpose of this sketch is to basically destroy your Arduino’s EEPROM. Here is the sketch (download):
/* Arduino EEPROM killer John Boxall - http://tronixstuff.com - March 2011 CC by-sa Note: This sketch will destroy your Arduino's EEPROM Do not use with Arduino boards that have fixed microcontrollers Sketch assumes DS1307 already contains current date and time */
#include "EEPROM.h" #include "LiquidCrystal.h"
LiquidCrystal lcd(4,5,6,7,8,9);
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
// all these bytes necessary for time and date data
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte sday, smonth, ssecond, sminute, shour;
byte fday, fmonth, fsecond, fminute, fhour;
// to store number of cycles. Should be enough
long cycles=0; // maximum size is 2,147,483,647
int zz=0;
void setup()
{
lcd.begin(16, 2); // fire up the LCD
Wire.begin(); // and the I2C bus
}
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
void killEEPROM()
{
boolean dead=false;
// record start time
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
sday=dayOfMonth;
smonth=month;
ssecond=second;
sminute=minute;
shour=hour;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Cycles so far...");
do // write and read EEPROM addresses until the first failure
{
for (int a=0; a<1024; a++)
{
EEPROM.write(a, 170); // write binary 10101010 to each EEPROM address
}
for (int a=0; a<1024; a++) // check each address
{
zz = EEPROM.read(a);
if (zz!=170)
{
dead=true; // uh-oh, an address has died
cycles-=2; // easy way out to calculate cycles once died
}
}
cycles++;
lcd.setCursor(0,1);
lcd.print(cycles);
for (int a=0; a<1024; a++)
{
EEPROM.write(a, 85); // write binary 01010101 to each EEPROM address
}
for (int a=0; a<1024; a++) // check each address
{
zz = EEPROM.read(a);
if (zz!=85)
{
dead=true; // uh-oh, an address has died
--cycles; // easy way out to calculate cycles once died
}
}
cycles++;
lcd.setCursor(0,1);
lcd.print(cycles); // update the LCD
}
while (dead!=true);
// so now one address write/read has failed, the game's up
// record end time
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
fday=dayOfMonth;
fmonth=month;
fsecond=second;
fminute=minute;
fhour=hour;
// display final statistics (endless loop)
do
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Start date/time: ");
lcd.setCursor(1,1);
lcd.print(sday, DEC);
lcd.print("/");
lcd.print(smonth, DEC);
lcd.print(" ");
lcd.print(shour, DEC);
lcd.print(":");
if (sminute<10)
{
lcd.print("0");
}
lcd.print(sminute, DEC);
lcd.print(":");
if (ssecond<10)
{
lcd.print("0");
}
lcd.print(ssecond, DEC);
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("End date/time: ");
lcd.setCursor(1,1);
lcd.print(fday, DEC);
lcd.print("/");
lcd.print(fmonth, DEC);
lcd.print(" ");
lcd.print(fhour, DEC);
lcd.print(":");
if (fminute<10)
{
lcd.print("0");
}
lcd.print(fminute, DEC);
lcd.print(":");
if (fsecond<10)
{
lcd.print("0");
}
lcd.print(fsecond, DEC);
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" # of cycles:");
lcd.setCursor(0,1);
lcd.print(cycles);
delay(2000);
}
while(1>0);
}
void loop()
{ // nice intro display with countdown
lcd.clear();
lcd.setCursor(0,0);
lcd.print("EEPROM Destroyer");
lcd.setCursor(0,1);
for (int a=99; a>0; --a)
// gives user 99 seconds to change mind before start
{
lcd.setCursor(0,1);
lcd.print("Starting in ");
lcd.print(a);
lcd.print("s ");
delay(995);
}
lcd.clear();
killEEPROM();
}
If you are unfamiliar with the time-keeping section, please see part one of my Arduino+I2C tutorial. The LCD used was my quickie LCD shield – more information about that here. A quicker, painless option would be a Freetronics 16×2 LCD shield as tested here. Or you could always just send the data to the serial monitor box – however you would need to leave the PC on for a loooooong time… So instead the example sat on top of an AC adaptor (wall wart) behind a couch (sofa) for a couple of months:
The only catch with running it from AC was the risk of possible power outages. We had one planned outage when our house PV system was installed, so I took a count reading before the mains was turned off, and corrected the sketch before starting it up again after the power cut. Nevertheless, here is a short video – showing the start and the final results of the test:
So there we have it, 1230163 cycles with each cycle writing and reading each individual EEPROM address. If repeating this odd experiment, your result will vary.
Well I hope someone out there found this interesting. Please refrain from sending emails or comments criticising the waste of a microcontroller – this was a one off. Otherwise, to keep up with new activities here at tronixtuff please subscribe to the blog, RSS feed (top-right), twitter or joining our Google Group.
If you have any questions about the processes or details in this article, please ask in our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, there is the odd competition or give-away – and we can all learn something.
Otherwise, have fun, stay safe, be good to each other – and make something!
May 2011 Competition
Hello Readers
The May competition has now closed and the results will be published shortly. Thank you to all those who entered in May!
Another month has commenced and that means time for another competition! To enter is very easy. There will be five(!) questions hidden within articles published in the month of May (but not this one!). Once you have answers to all five, email them to competition at tronixstuff dot com with “May 2011″ in the subject line. Then in the first week of June, I will compile a list of people with the correct answers, and randomly select two winners. Please note competition rules at end of article.
The first winner drawn will receive a brand new, hot off the pick and place – Freetronics EtherTen!
The EtherTen must be the ultimate Arduino-Uno compatible board on the market. From the Freetronics website:
Two tastes that taste great together: Arduino and Ethernet. But until now the only way to connect an Arduino to the Internet via a LAN was to add an Ethernet Shield. Wouldn’t it be great if there was an Arduino-compatible board with on-board Ethernet? Better still, what if that board was based on the Freetronics Eleven and the Freetronics Ethernet Shield (with Power-over-Ethernet support!) but merged together into a single, integrated board that was 100% Arduino compatible and network-enabled?
This, folks, is what you’ve been waiting for.
The EtherTen is a 100% Arduino compatible board that can talk to the world. Do Twitter updates automatically, serve web pages, connect to web services, display sensor data online, and control devices using a web browser. The Freetronics EtherTen uses the same ATmega328P as the Duemilanove and the same Wiznet W5100 chip used by the official Arduino Ethernet Shield, so it’s 100% compatible with the Ethernet library and sketches. Any project you would previously have built with an Arduino and an Ethernet shield stacked together, you can now do all in a single, integrated board.
We’ve even added a micro SD card slot so you can store web content on the card, or log data to it.
All the good things about the Eleven and the Ethernet Shield have been combined into this one device so please see those pages for all the specific details, but the highlights include:
- Gold-plated PCB.
- Top and bottom parts overlays.
- Top-spec ATmega328P MCU.
- Mini-USB connector: no more shorts against shields!
- D13 pin isolated with a MOSFET so you can use it as an input.
- Power-over-Ethernet support, both cheapie DIY or full 802.3af standards-compliant.
- Ethernet activity indicators on the PCB and the jack.
- 10/100base-T auto-selection.
- Fully compatible with standard Ethernet library.
- Reset management chip.
- Fixed SPI behavior on Ethernet chipset.
- Robust power filtering.
- Sexy rounded corners. Hmm.
As with any other competition, there needs to be some rules:
- Prizes will be delivered via Australia Post domestic or regular international air mail. Winners may elect for other methods upon payment of real cost;
- Winners outside of Australia will be responsible for any taxes, fees or levies imposed by your local Governments (such as import levies, excise, VAT, etc.) upon importation of purchased goods;
- Prizes may take up to 45 days to be received;
- If you have won a previous competition you cannot enter;
- The Judge’s decision is final with regards to any dispute;
- Entries will be accepted until 2359h GMT on 3rd June 2011.
So have fun and keep checking into tronixstuff.com. Why not follow things on twitter, 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.
Once again, thank you to our generous competition sponsor Freetronics
April 2011 Competition – Results
Hello readers
The month of April has ended and thus another monthly tronixstuff.com competition. There were six questions hidden within the posts, and once again all entrants were correct with their answers. Questions for April were:
- Name the two people who founded the predecessor to Agilent Technologies – Bill Hewlett and Dave Packard;
- Name the magazine that originally described this kit (Current clamp meter adaptor) – Silicon Chip;
- What does the acronym FTDI mean – Future Technology Devices International;
- What is the mains power frequency in Australia? 50 Hz;
- What is the name of the Evil Mad Science Arduino-compatible development board – Diavolino;
- Unit of measurement for elastance – the daraf.
The first winner drawn will receves a full PoGa system bundle courtesy of 4D Systems, an Australian-based company who are a worldwide leader in the development and manufacture of intelligent graphic display modules.
What is a PoGa you may ask? Here is an example:
As you can see, the PoGa is an amazing piece of work. The people at 4D Systems have really put together a fun and accessible way to develop your own games. However the PoGa is a lot more powerful than the retail price would suggest:
PoGa Features:
- Single chip, low cost educational game development platform, incorporating the tiny GOLDELOX-PoGa graphics processor chip.
- Comes in an easy to build kit form with very low parts count and cost: GOLDELOX-PoGa chip, 6 buttons, Colour LCD-TFT, Battery Holder and few discrete components.
- Display: 1.44″, 128xRGBx128 resolution, 65K colour TFT-LCD (directly interfaced to the GOLDELOX-PoGa chip).
- Colours: 65K simultaneous colours.
- microSD Card Interface: Supports the PoGa-Disk which can store and load up to 512 games and other applications as well as images and video clips. It can also be used as a storage medium for data logging applications during run time.
- Sound Support: Single channel sound engine with extended RTTTL format and allows complex generation of game sounds.
- Console: Layout fashion follows most standard game consoles with 6 buttons for game and non game related application control.
- Expandable: Power and UART lines are available via 8pin expansion port.
- Battery: Supports 3 x AAA batteries for mobility (hight capacity alkaline or lithium recommended).
- Supports the high level 4DGL language platform, syntax very similar to C.
- Software Tools: Free fully integrated 4D Workshop3 IDE software development tool suite.
- RoHS compliant.
PoGa Specifications:
- CPU: GOLDELOX-PoGa chip.
- Total RAM: 510 bytes (or 255 word sized variables).
- Program Memory: 11K bytes (more than adequate for all PoGa applications).
- Speed: 12Mips (internal).
- Screen: 1.44″ LCD-TFT, with greater than 160deg viewing angle.
- Resolution: 128 x RGB x 128 pixels.
- Colours: 65K colours. Pixels arranged in a 5:6:5 colour format (Red:5 bits, Green:6 bits, Blue: 5 bits).
- Graphics:Supports all primitives such as:
- Lines, Circles, Rectangles, Dots, Triangles
- Chars, Strings, Text Buttons
- Images and Video clips.
- Sprites: Up to 64 sprites can be defined, simultaneous display of sprites is unlimited.
- Sound: Single channel mono, supports extended RTTTL format and allows complex generation of game sounds.
- Console: 4 x Navigation keys, 2 x Selection keys.
- PoGa-Disk: microSD card interface that supports most uSD memory cards for video, images, game and application storage. 2Gb and larger size cards can support PoGa file system application storage.
- Expansion: External expansion port, (RX, TX, VBat, 3.3V and GND).
The first prize not only includes a fully-assembled PoGa unit, to enable extended application and experimentation with their PoGa the winner also receives a USB programming cable, external breakout board and the GPS receiver module as shown below:
The second prize winner receives exactly the same as the first! Except for being the review hardware used to play… test out the PoGa here at tronixstuff. Nevertheless both winners will have a ball playing the sample games, or spending time to develop their own games, quizzes, possible GPS applications including reverse geocaching, and so on. In the next week I will review the PoGa system in more detail and document my experience with it.
To get your hands on a PoGa, they can be ordered directly from 4DSystems, Little Bird Electronics, Sparkfun and their resellers, or Tigal for EU customers.
So have fun and keep checking into tronixstuff.com. Why not follow things on twitter, 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.
Once again, thank you to our generous competition sponsor 4D Systems!




































