Tutorial – Arduino and PCF8591 ADC DAC IC
Learn how to use the NXP PCF 8591 8-bit A/D and D/A IC with Arduino in chapter fifty-two of my Arduino Tutorials. The first chapter is here, the complete series is detailed here.
Updated 17/06/2013
Introduction
Have you ever wanted more analogue input pins on your Arduino project, but not wanted to fork out for a Mega? Or would you like to generate analogue signals? Then check out the subject of our tutorial – the NXP PCF8591 IC. It solves both these problems as it has a single DAC (digital to analogue) converter as well as four ADCs (analogue to digital converters) – all accessible via the I2C bus. If the I2C bus is new to you, please familiarise yourself with the readings here before moving forward.
The PCF8591 is available in DIP form, which makes it easy to experiment with:
You can get them from the usual retailers. Before moving on, download the data sheet. The PCF8591 can operate on both 5V and 3.3V so if you’re using an Arduino Due, Raspberry Pi or other 3.3 V development board you’re fine. Now we’ll first explain the DAC, then the ADCs.
Using the DAC (digital-to-analogue converter)
The DAC on the PCF8591 has a resolution of 8-bits – so it can generate a theoretical signal of between zero volts and the reference voltage (Vref) in 255 steps. For demonstration purposes we’ll use a Vref of 5V, and you can use a lower Vref such as 3.3V or whatever you wish the maximum value to be … however it must be less than the supply voltage. Note that when there is a load on the analogue output (a real-world situation), the maximum output voltage will drop – the data sheet (which you downloaded) shows a 10% drop for a 10kΩ load. Now for our demonstration circuit:
Note the use of 10kΩ pull-up resistors on the I2C bus, and the 10μF capacitor between 5V and GND. The I2C bus address is set by a combination of pins A0~A2, and with them all to GND the address is 0×90. The analogue output can be taken from pin 15 (and there’s a seperate analogue GND on pin 13. Also, connect pin 13 to GND, and circuit GND to Arduino GND.
To control the DAC we need to send two bytes of data. The first is the control byte, which simply activates the DAC and is 1000000 (or 0×40) and the next byte is the value between 0 and 255 (the output level). This is demonstrated in the following sketch (download):
// Example 52.1 PCF8591 DAC demo // http://tronixstuff.com/tutorials Chapter 52 // John Boxall June 2013
#include #define PCF8591 (0x90 >> 1) // I2C bus address
void setup()
{
Wire.begin();
}
void loop()
{
for (int i=0; i<256; i++)
{
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
Wire.write(i); // value to send to DAC
Wire.endTransmission(); // end tranmission
}
for (int i=255; i>=0; --i)
{
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
Wire.write(i); // value to send to DAC
Wire.endTransmission(); // end tranmission
}
}
Did you notice the bit shift of the bus address in the #define statement? Arduino sends 7-bit addresses but the PCF8591 wants an 8-bit, so we shift the byte over by one bit.
The results of the sketch are shown below, we’ve connected the Vref to 5V and the oscilloscope probe and GND to the analogue output and GND respectively (click image to enlarge):
If you like curves you can generate sine waves with the sketch below. It uses a lookup table in an array which contains the necessary pre-calculated data points (download):
// Example 52.2 PCF8591 DAC demo - sine wave // http://tronixstuff.com/tutorials Chapter 52 // John Boxall June 2013
#include #define PCF8591 (0x90 >> 1) // I2C bus address
uint8_t sine_wave[256] = {
0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};
void setup()
{
Wire.begin();
}
void loop()
{
for (int i=0; i<256; i++)
{
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
Wire.write(sine_wave[i]); // value to send to DAC
Wire.endTransmission(); // end tranmission
}
}
And the results (click image to enlarge):
For the following DSO image dump, we changed the Vref to 3.3V – note the change in the maxima on the sine wave:
Now you can experiment with the DAC to make sound effects, signals or control other analogue circuits.
Using the ADCs (analogue-to-digital converters)
If you’ve used the analogRead() function on your Arduino (way back in Chapter One) then you’re already familiar with an ADC. With out PCF8591 we can read a voltage between zero and the Vref and it will return a value of between zero and 255 which is directly proportional to zero and the Vref. For example, measuring 3.3V should return 168. The resolution (8-bit) of the ADC is lower than the onboard Arduino (10-bit) however the PCF8591 can do something the Arduino’s ADC cannot. But we’ll get to that in a moment.
First, to simply read the values of each ADC pin we send a control byte to tell the PCF8591 which ADC we want to read. For ADCs zero to three the control byte is 0×00, 0×01, ox02 and 0×03 respectively. Then we ask for two bytes of data back from the ADC, and store the second byte for use. Why two bytes? The PCF8591 returns the previously measured value first – then the current byte. (See Figure 8 in the data sheet). Finally, if you’re not using all the ADC pins, connect the unused ones to GND.
The following example sketch simply retrieves values from each ADC pin one at a time, then displays them in the serial monitor (download):
// Example 52.3 PCF8591 ADC demo // http://tronixstuff.com/tutorials Chapter 52 // John Boxall June 2013
#include #define PCF8591 (0x90 >> 1) // I2C bus address
#define ADC0 0x00 // control bytes for reading individual ADCs #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03
byte value0, value1, value2, value3;
void setup()
{
Wire.begin();
Serial.begin(9600);
}
void loop()
{
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(ADC0); // control byte - read ADC0
Wire.endTransmission(); // end tranmission
Wire.requestFrom(PCF8591, 2);
value0=Wire.read();
value0=Wire.read();
Wire.beginTransmission(PCF8591); // wake up PCF8591 Wire.write(ADC1); // control byte - read ADC1 Wire.endTransmission(); // end tranmission Wire.requestFrom(PCF8591, 2); value1=Wire.read(); value1=Wire.read();
Wire.beginTransmission(PCF8591); // wake up PCF8591 Wire.write(ADC2); // control byte - read ADC2 Wire.endTransmission(); // end tranmission Wire.requestFrom(PCF8591, 2); value2=Wire.read(); value2=Wire.read();
Wire.beginTransmission(PCF8591); // wake up PCF8591 Wire.write(ADC3); // control byte - read ADC3 Wire.endTransmission(); // end tranmission Wire.requestFrom(PCF8591, 2); value3=Wire.read(); value3=Wire.read();
Serial.print(value0); Serial.print(" ");
Serial.print(value1); Serial.print(" ");
Serial.print(value2); Serial.print(" ");
Serial.print(value3); Serial.print(" ");
Serial.println();
}
Upon running the sketch you’ll be presented with the values of each ADC in the serial monitor. Although it was a simple demonstration to show you how to individually read each ADC, it is a cumbersome method of getting more than one byte at a time from a particular ADC.
To do this, change the control byte to request auto-increment, which is done by setting bit 2 of the control byte to 1. So to start from ADC0 we use a new control byte of binary 00000100 or hexadecimal 0×04. Then request five bytes of data (once again we ignore the first byte) which will cause the PCF8591 to return all values in one chain of bytes. This process is demonstrated in the following sketch (download):
// Example 52.4 PCF8591 ADC demo // http://tronixstuff.com/tutorials Chapter 52 // John Boxall June 2013
#include #define PCF8591 (0x90 >> 1) // I2C bus address
byte value0, value1, value2, value3;
void setup()
{
Wire.begin();
Serial.begin(9600);
}
void loop()
{
Wire.beginTransmission(PCF8591); // wake up PCF8591
Wire.write(0x04); // control byte - read ADC0 then auto-increment
Wire.endTransmission(); // end tranmission
Wire.requestFrom(PCF8591, 5);
value0=Wire.read();
value0=Wire.read();
value1=Wire.read();
value2=Wire.read();
value3=Wire.read();
Serial.print(value0); Serial.print(" ");
Serial.print(value1); Serial.print(" ");
Serial.print(value2); Serial.print(" ");
Serial.print(value3); Serial.print(" ");
Serial.println();
}
Previously we mentioned that the PCF8591 can do something that the Arduino’s ADC cannot, and this is offer a differential ADC. As opposed to the Arduino’s single-ended (i.e. it returns the difference between the positive signal voltage and GND, the differential ADC accepts two signals (that don’t necessarily have to be referenced to ground), and returns the difference between the two signals. This can be convenient for measuring small changes in voltages for load cells and so on.
Setting up the PCF8591 for differential ADC is a simple matter of changing the control byte. If you turn to page seven of the data sheet, then consider the different types of analogue input programming. Previously we used mode ’00′ for four inputs, however you can select the others which are clearly illustrated, for example:
So to set the control byte for two differential inputs, use binary 00110000 or 0×30. Then it’s a simple matter of requesting the bytes of data and working with them. As you can see there’s also combination single/differential and a complex three-differential input. However we’ll leave them for the time being.
Conclusion
Hopefully you found this of interest, whether adding a DAC to your experiments or learning a bit more about ADCs. We’ll have some more analogue to digital articles coming up soon, so stay tuned. And if you enjoy my tutorials, or want to introduce someone else to the interesting world of Arduino – check out my new book “Arduino Workshop” from No Starch Press.
In the meanwhile 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? And join our friendly 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 – the Freetronics CUBE4: RGB LED Cube
Introduction
LED cubes are a fascinating item, no matter where you come from the allure of blinking LEDs in various patterns is always attractive. And making your own is a fun challenge that most people can do after some experience with electronics hardware. However most people use single-colour LEDs, as wiring up RGB units triples the complexity of the circuit. Until now.
After much anticipation Freetronics have released their CUBE4 RGB LED cube kit – a simple to assemble and completely-customisable RGB LED cube:
Unlike other cubes on the market, this one includes an on-board ATmega32u4 microcontroller with Arduino Leonardo-compatible bootloader and a microUSB socket (… and a lot more) – so you don’t need anything extra to get started. And this gives you many more options when you’re ready to expand. But first let’s put it together and then get it working. Furthermore, keep reading to find out how you can have a chance to win your own Cube4.
Assembly
Inside the box are all the parts needed for the kit, even a microUSB cable to power the Cube4 and also communicate with it:
There’s 64 RGB LEDs in that bag, so get ready for some soldering. The base PCB is well laid out, labelled and gives you an idea for the expansion possibilities:
Plenty of room to add your own circuitry – and the bottom:
As you can see in the image above, there’s an XBee-compatible pinout if you want to add communication via wirless serial link, plenty of prototyping space for your own additions and many other ports are brought out to open pads. There’s even a 5V supply pair to test LEDs, and a blue “power on” LED (which can be deactivated if necessary by cutting a track on the PCB).
The first job is to mount the LEDs on their plane PCBs – there are four, one for each horizontal plant. It’s very important to get the LEDs in the right way round, and there’s markers on the PCB that you can match up the longest leg of the LED with:
From experience I found it best to insert all the LEDs:
…and then do a final mass check of the alignment – which is easy if you hold the plane up to one side and compare the legs, for example:
At this stage it’s a great idea to double-check your LED alignment. After a while you’ll have the LEDs soldered in and trimmed nicely:
The next step was getting the vertical sticks aligned in order to hold the LED planes (above). Each stick is for a particular spot on the PCB so check the label on the stick matches the hole on the PCB. It’s incredibly important to make sure you have them perfectly perpendicular to the PCB, so find something like a square-edge or card to help out:
Once you have a row of sticks in you can start with a plane then insert a stick on the other side, for example:
Note the use of the elastic band to hold things together – they really help. Then it’s a simple matter of adding the planes and holding it together with another band:
… at which point you can do a final check that all the planes and sticks are inserted correctly. Then solder all the copper spots together and you’re done.
Don’t forget to turn the cube upside-down as there’s soldering to be done on the bottom of the planes as well:
Although it might look a little scary, the final assembly isn’t that difficult – just take your time so it’s right the first time. You can view the following video which describes the entire process:
Once you’re confident that all the soldering has been completed – double-check for joints that aren’t completely bridged with solder as they will affect the operation of the cube. Then you can plug in the USB cable and watch the preloaded test/demonstration sketch in action:
If all your LEDs are working, awesome. If not – check the soldering. If there’s still some rogues – check your individual LEDs. Some of you are probably thinking “well that isn’t too colourful” – the problem is the camera, not the Cube4. If you see it in real life, it’s much better.
Operation
There are two methods of controlling the Cube4. It is delivered with a preloaded sketch that runs the demonstration showed in the video above, and then accepts commands over a serial/USB connection. So you can simply plug it in, fire up a terminal program (or the Arduino IDE serial monitor) and send text commands to do various things. If you type “help ;” the syntax is returned which explains how you can do things (click image to enlarge):
This serial control mode allows control by any type of software that can write to a serial port. Furthermore any other external hardware that can create or introduce serial text can also control the Cube4. For example by mounting an XBee module underneath and linking it to the TX/RX lines gives you a wireless Cube4. By doing so you can control it with a Raspberry Pi or other system.
Furthermore the Cube4 is also an Arduino Leonardo-compatible board in the same way as a Freetronics LeoStick. With the use of the Cube4 Arduino library you can then create your own sketches which can visualise data with very simple to use functions for the Cube4. There are some great example sketches with the library for some inspiration and fun. Over time I look forward to using the Cube4 in various ways, including adding an Electric Imp IoT device and making another clock (!).
Competition
Would you like the chance to win a Cube4? It’s easy. Clearly print your email address on a postcard, and mail it to:
CUBE4 Competition, PO Box 5435, Clayton 3168, Australia
Entries must be received by the 30th of July 2013. One postcard will then be drawn at random, and the winner will receive one Cube4 delivered by Australia Post standard air mail. You can enter as many times as you like. We’re not responsible for customs or import duties, VAT, GST, postage delays, non-delivery or whatever walls your country puts up against receiving inbound mail.
More demonstrations
Check out this Argot IoT demonstration.
Conclusion
This is the most approachable RGB LED cube kit on the market, and also the easiest to use. You don’t need to understand programming to try it out – and if you do it’s incredibly versatile. A lot of work has gone into the library, API and hardware design so you’ve got an expandable tool and not just some blinking LEDs. For more information visit the Freetronics website. Larger photos available on flickr. And if you made it this far – check out my new book “Arduino Workshop” from No Starch Press.
The CUBE4 in this review is a promotional consideration from Freetronics. In the meanwhile 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? And join our friendly 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.
Tutorial – Arduino and MC14489 LED Display Driver
Learn how to use MC14489 LED display driver ICs with Arduino in chapter fifty-one of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
Updated 12/05/2013
Introduction
Recently we’ve been looking at alternatives to the MAX7219 LED display driver IC due to pricing and availability issues (stay tuned for that one) – and came across an old but still quite useful IC – the MC14489 from Motorola (now Freescale Semiconductor). The MC14489 can drive five seven-segment LED numbers with decimal point, or a combination of numbers and separate LEDs. You can also daisy-chain more than one to drive more digits, and it’s controlled with a simple serial data-clock method in the same way as a 74HC595 shift register. Sourcing the MC14489 isn’t too difficult – it’s available from element14, Newark, Digikey, and so on – or if you’re not in a hurry, try the usual suspects like Futurlec.
For the purpose of the tutorial we’ll show you how to send commands easily from your Arduino or compatible board to control a five-digit 7-segment LED display module - and the instructions are quite simple so they should translate easily to other platforms. Once you have mastered the single module, using more than one MC14489 will be just as easy. So let’s get started.
Hardware
Before moving forward, download the data sheet (pdf). You will need to refer to this as you build the circuit(s). And here’s our subject in real life:
For our demonstration display we’ll be using a vintage HP 5082-7415 LED display module. However you can use almost any 7-segment modules as long as they’re common-cathode - for example, Sparkfun part number COM-11405. If you’re using a four-digit module and want an extra digit, you can add another single digit display. If you want a ruler, the design files are here.
Connecting the MC14489 to an LED display isn’t complex at all. From the data sheet consider Figure 9 (click the image to enlarge):
Each of the anode control pins from the MC14489 connect to the matching anodes on your display module, and the BANK1~5 pins connect to the matching digit cathode pins on the display module. You can find the MC14489 pin assignments on page 1 of the data sheet. Seeing as this is chapter fifty-one - by now you should be confident with finding such information on the data sheets, so I will be encouraging you to do a little more of the work.
Interesting point – you don’t need current-limiting resistors. However you do need the resistor Rx – this controls the current flow to each LED segment. But which value to use? You need to find out the forward current of your LED display (for example 20 mA) then check Figure 7 on page 7 of the data sheet (click image to enlarge):
To be conservative I’m using a value of 2k0 for Rx, however you can choose your own based on the data sheet for your display and the graph above. Next – connect the data, clock and enable pins of the MC14489 to three Arduino digital pints – for our example we’re using 5, 6 and 7 for data, clock and enable respectively. Then it’s just 5V and GND to Arduino 5V and GND – and put a 0.1uF capacitor between 5V and GND. Before moving on double-check the connections – especially between the MC14489 and the LED display.
Controlling the MC14489
To control the display we need to send data to two registers in the MC14489 – the configuration register (one byte) and the display register (three bytes). See page 9 of the data sheet for the overview. The MC14489 will understand that if we send out one byte of data it is to send it the configuration register, and if it receives three bytes of data to send it to the display register. To keep things simple we’ll only worry about the first bit (C0) in the configuration register – this turns the display outputs on or off. To do this, use the following:
digitalWrite(enable, LOW); shiftOut(data, clock, MSBFIRST, B00000001); // used binary for clarity, however you can use decimal or hexadecimal numbers digitalWrite(enable, HIGH); delay(10);
and to turn it off, send bit C0 as zero. The small delay is necessary after each command.
Once you have turned the display on – the next step is to send three bytes of data which represent the numbers to display and decimal points if necessary. Review the table on page 8 of the data sheet. See how they have the binary nibble values for the digits in the third column. Thankfully the nibble for each digit is the binary value for that digit. Furthermore you might want to set the decimal point – that is set using three bits in the first nibble of the three bytes (go back to page 9 and see the display register). Finally you can halve the brightness by setting the very first bit to zero (or one for full brightness).
As an example for that – if you want to display 5.4321 the three bytes of data to send in binary will be:
1101 0101 0100 0011 0010 0001
Let’s break that down. The first bit is 1 for full brightness, then the next three bits (101) turn on the decimal point for BANK5 (the left-most digit). Then you have five nibbles of data, one for each of the digits from left to right. So there’s binary for 5, then four, then three, then two, then one.
digitalWrite(enable, LOW); shiftOut(data, clock, MSBFIRST, B11010101); // D23~D16 shiftOut(data, clock, MSBFIRST, B01000011); // D15~D8 shiftOut(data, clock, MSBFIRST, B00100001); // D7~D0 digitalWrite(enable, HIGH); delay(10);
To demonstrate everything described so far, it’s been neatly packaged into our first example sketch – Example 51.1:
// Example 51.1 // Motorola MC14489 with HP 5082-7415 5-digit, 7-segment LED display // 2k0 resistor on MC14489 Rx pin // John Boxall 2013 CC by-sa-nc
// define pins for data from Arduino to MC14489 // we treat it just like a 74HC595 int data = 5; int clock = 6; int enable = 7;
void setup()
{
pinMode(data, OUTPUT);
pinMode(enable, OUTPUT);
pinMode(clock, OUTPUT);
displayOn(); // display defaults to off at power-up
}
void displayTest1()
// displays 5.4321
{
digitalWrite(enable, LOW); // send 3 bytes to display register. See data sheet page 9
// you can also insert decimal or hexadecimal numbers in place of the binary numbers
// we're using binary as you can easily match the nibbles (4-bits) against the table
// in data sheet page 8
shiftOut(data, clock, MSBFIRST, B11010101); // D23~D16
shiftOut(data, clock, MSBFIRST, B01000011); // D15~D8
shiftOut(data, clock, MSBFIRST, B00100001); // D7~D0
digitalWrite(enable, HIGH);
delay(10);
}
void displayTest2()
// displays ABCDE
{
digitalWrite(enable, LOW); // send 3 bytes to display register. See data sheet page 9
// you can also insert decimal or hexadecimal numbers in place of the binary numbers
// we're using binary as you can easily match the nibbles (4-bits) against the table
// in data sheet page 8
shiftOut(data, clock, MSBFIRST, B10001010); // D23~D16
shiftOut(data, clock, MSBFIRST, B10111100); // D15~D8
shiftOut(data, clock, MSBFIRST, B11011110); // D7~D0
digitalWrite(enable, HIGH);
delay(10);
}
void displayOn()
// turns on display
{
digitalWrite(enable, LOW);
shiftOut(data, clock, MSBFIRST, B00000001);
digitalWrite(enable, HIGH);
delay(10);
}
void displayOff()
// turns off display
{
digitalWrite(enable, LOW);
shiftOut(data, clock, MSBFIRST, B00000000);
digitalWrite(enable, HIGH);
delay(10);
}
void loop()
{
displayOn();
displayTest1();
delay(1000);
displayTest2();
delay(1000);
displayOff();
delay(500);
}
… with the results in the following video:
Now that we can display numbers and a few letters with binary, life would be easier if there was a way to take a number and just send it to the display.
So consider the following function that takes an integer between 0 and 99999, does the work and sends it to the display:
void displayIntLong(long x)
// takes a long between 0~99999 and sends it to the MC14489
{
int numbers[5];
byte a=0;
byte b=0;
byte c=0; // will hold the three bytes to send to the MC14489
// first split the incoming long into five separate digits
numbers[0] = int ( x / 10000 ); // left-most digit (will be BANK5)
x = x % 10000;
numbers[1] = int ( x / 1000 );
x = x % 1000;
numbers[2] = int ( x / 100 );
x = x % 100;
numbers[3] = int ( x / 10 );
x = x % 10;
numbers[4] = x % 10; // right-most digit (will be BANK1)
// now to create the three bytes to send to the MC14489
// build byte c which holds digits 4 and 5
c = numbers[3];
c = c << 4; // move the nibble to the left
c = c | numbers[4];
// build byte b which holds digits 3 and 4
b = numbers [1];
b = b << 4;
b = b | numbers[2];
// build byte a which holds the brightness bit, decimal points and digit 1
a = B10000000 | numbers[0]; // full brightness, no decimal points
// now send the bytes to the MC14489
digitalWrite(enable, LOW);
shiftOut(data, clock, MSBFIRST, a);
shiftOut(data, clock, MSBFIRST, b);
shiftOut(data, clock, MSBFIRST, c);
digitalWrite(enable, HIGH);
delay(10);
}
So how does that work? First it splits the 5-digit number into separate digits and stores them in the array numbers[]. It then places the fourth digit into a byte, then moves the data four bits to the left – then we bitwise OR the fifth digit into the same byte. This leaves us with a byte of data containing the nibbles for the fourth and fifth digit. The process is repeated for digits 2 and 3. Finally the brightness bit and decimal point bits are assigned to another byte which then has the first digit’s nibble OR’d into it. Which leaves us with bytes a, b and c ready to send to the MC14489. Note that there isn’t any error-checking – however you could add a test to check that the number to be displayed was within the parameter, and if not either switch off the display (see example 51.1) or throw up all the decimal points or … whatever you want.
You can download the demonstration sketch for the function – Example 51.2, and view the results in the following video:
You can also display the letters A to F by sending the values 10 to 15 respectivel to each digit’s nibble. However that would be part of a larger application, which you can (hopefully) by now work out for yourself. Furthermore there’s some other characters that can be displayed – however trying to display the alphabet using 7-segment displays is somewhat passé. Instead, get some 16-segment LED modules or an LCD.
Finally, you can cascade more than one MC14489 to control more digits. Just run a connection from the data out pin on the first MC14889 to the data pin of the second one, and all the clock and enable lines together. Then send out more data – see page 11 of the data sheet. If you’re going to do that in volume other ICs may be a cheaper option and thus lead you back to the MAX7219.
Conclusion
For a chance find the MC14489 is a fun an inexpensive way to drive those LED digit displays. We haven’t covered every single possible option or feature of the part – however you will now have the core knowledge to go further with the MC14489 if you need to move further with it. And if you enjoy my tutorials, or want to introduce someone else to the interesting world of Arduino – check out my new book “Arduino Workshop” from No Starch Press.
In the meanwhile 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? And join our friendly 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.
Book – “Arduino Workshop – A Hands-On Introduction with 65 Projects”
Over the last few years I’ve been writing a few Arduino tutorials, and during this time many people have mentioned that I should write a book. And now thanks to the team from No Starch Press this recommendation has morphed into my new book – “Arduino Workshop“:
Although there are seemingly endless Arduino tutorials and articles on the Internet, Arduino Workshop offers a nicely edited and curated path for the beginner to learn from and have fun. It’s a hands-on introduction to Arduino with 65 projects – from simple LED use right through to RFID, Internet connection, working with cellular communications, and much more.
Each project is explained in detail, explaining how the hardware an Arduino code works together. The reader doesn’t need any expensive tools or workspaces, and all the parts used are available from almost any electronics retailer. Furthermore all of the projects can be finished without soldering, so it’s safe for readers of all ages.
The editing team and myself have worked hard to make the book perfect for those without any electronics or Arduino experience at all, and it makes a great gift for someone to get them started. After working through the 65 projects the reader will have gained enough knowledge and confidence to create many things – and to continue researching on their own. Or if you’ve been enjoying the results of my thousands of hours of work here at tronixstuff, you can show your appreciation by ordering a copy for yourself or as a gift
You can review the table of contents, index and download a sample chapter from the Arduino Workshop website.
Arduino Workshop is available from No Starch Press in printed or ebook (PDF, Mobi, and ePub) formats. Ebooks are also included with the printed orders so you can get started immediately.
19/06/2013 – (my fellow) Australians – currently the cheapest way of getting a print version is from the Book Depository … as they have free delivery from the UK.
In the meanwhile 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? And join our friendly 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.
Tutorial – Arduino and ILI9325 colour TFT LCD modules
Learn how to use inexpensive ILI9325 colour TFT LCD modules in chapter fifty of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
Introduction
Colour TFT LCD modules just keep getting cheaper, so in this tutorial we’ll show you how to get going with some of the most inexpensive modules we could find. The subject of our tutorial is a 2.8″ 240 x 320 TFT module with the ILI9325 LCD controller chip. If you look in ebay this example should appear pretty easily, here’s a photo of the front and back to help identify it:
There is also the line “HY-TFT240_262k HEYAODZ110510″ printed on the back of the module. They should cost less than US$10 plus shipping. Build quality may not be job number one at the factory so order a few, however considering the cost of something similar from other retailers it’s cheap insurance. You’ll also want sixteen male to female jumper wires to connect the module to your Arduino.
Getting started
To make life easier we’ll use an Arduino library “UTFT” written for this and other LCD modules. It has been created by Henning Karlsen and can be downloaded from his website. If you can, send him a donation – this library is well worth it. Once you’ve downloaded and installed the UTFT library, the next step is to wire up the LCD for a test.
Run a jumper from the following LCD module pins to your Arduino Uno (or compatible):
- DB0 to DB7 > Arduino D0 to D7 respectively
- RD > 3.3 V
- RSET > A2
- CS > A3
- RW > A4
- RS > A5
- backlight 5V > 5V
- backlight GND > GND
Then upload the following sketch – Example 50.1. You should be presented with the following on your display:
If you’re curious, the LCD module and my Eleven board draws 225 mA of current. If that didn’t work for you, double-check the wiring against the list provided earlier. Now we’ll move forward and learn how to display text and graphics.
Sketch preparation
You will always need the following before void setup():
#include "UTFT.h"
UTFT myGLCD(ILI9325C,19,18,17,16); // for Arduino Uno
and in void setup():
myGLCD.InitLCD(orientation); myGLCD.clrScr();
with the former command, change orientation to either LANDSCAPE to PORTRAIT depending on how you’ll view the screen. You may need further commands however these are specific to features that will be described below. The function .clrScr() will clear the screen.
Displaying Text
There are three different fonts available with the library. To use them add the following three lines before void setup():
extern uint8_t SmallFont[]; extern uint8_t BigFont[]; extern uint8_t SevenSegNumFont[];
When displaying text you’ll need to define the foreground and background colours with the following:
myGLCD.setColor(red, green, blue); myGLCD.setBackColor(red, green, blue);
Where red, green and blue are values between zero and 255. So if you want white use 255,255,255 etc. For some named colours and their RGB values, click here. To select the required font, use one of the following:
myGLCD.setFont(SmallFont); // Allows 20 rows of 40 characters
myGLCD.setFont(BigFont); // Allows 15 rows of 20 characters
myGLCD.setFont(SevenSegNumFont); // allows display of 0 to 9 over four rows
Now to display the text use the function:
myGLCD.print("text to display",x, y);
where text is what you’d like to display, x is the horizontal alignment (LEFT, CENTER, RIGHT) or position in pixels from the left-hand side of the screen and y is the starting point of the top-left of the text. For example, to start at the top-left of the display y would be zero. You can also display a string variable instead of text in inverted commas.
You can see all this in action with the following sketch – Example 50.2, which is demonstrated in the following video:
Furthremore, you can also specify the angle of display, which gives a simple way of displaying text on different slopes. Simply add the angle as an extra parameter at the end:
myGLCD.print(“Hello, world”, 20, 20, angle);
Again, see the following sketch – Example 50.2a, and the results below:
Displaying Numbers
Although you can display numbers with the text functions explained previously, there are two functions specifically for displaying integers and floats.
You can see these functions in action with the following sketch – Example 50.3, with an example of the results below:
Displaying Graphics
There’s a few graphic functions that can be used to create required images. The first is:
myGLCD.fillScr(red, green, blue);
which is used the fill the screen with a certain colour. The next simply draws a pixel at a specified x,y location:
myGLCD.drawPixel(x,y);
Remember that the top-left of the screen is 0,0. Moving on, to draw a single line, use:
myGLCD.drawLine(x1,0,x2,239);
where the line starts at x1,y1 and finishes at x2,y2. Need a rectangle? Use:
myGLCD.drawRect(x1,y2,x2,y2); // for open rectangles
myGLCD.fillRect(x1,y2,x2,y2); // for filled rectangles
where the top-left of the rectangle is x1,y1 and the bottom-right is x2, y2. You can also have rectangles with rounded corners, just use:
myGLCD.drawRoundRect(x1,y2,x2,y2); // for open rectangles
myGLCD.fillRoundRect(x1,y2,x2,y2); // for filled rectangles
instead. And finally, circles – which are quite easy. Just use:
myGLCD.drawCircle(x,y,r); // draws open circle myGLCD.fillCircle(x,y,r); // draws a filled circle
where x,y are the coordinates for the centre of the circle, and r is the radius. For a quick demonstration of all the graphic functions mentioned so far, see Example 50.4 – and the following video:
Displaying bitmap images
If you already have an image in .gif, .jpg or .png format that’s less than 300 KB in size, this can be displayed on the LCD. To do so, the file needs to be converted to an array which is inserted into your sketch. Let’s work with a simple example to explain the process. Below is our example image:
Save the image of the puppy somewhere convenient, then visit this page. Select the downloaded file, and select the .c and Arduino radio buttons, then click “make file”. After a moment or two a new file will start downloading. When it arrives, open it with a text editor – you’ll see it contains a huge array and another #include statement – for example:
Past the #include statement and the array into your sketch above void setup(). After doing that, don’t be tempted to “autoformat” the sketch in the Arduino IDE. Now you can use the following function to display the bitmap on the LCD:
myGLCD.drawBitmap(x,y,width,height, name, scale);
Where x and y are the top-left coordinates of the image, width and height are the … width and height of the image, and name is the name of the array. Scale is optional – you can double the size of the image with this parameter. For example a value of two will double the size, three triples it – etc. The function uses simple interpolation to enlarge the image, and can be a clever way of displaying larger images without using extra memory. Finally, you can also display the bitmap on an angle – using:
myGLCD.drawBitmap(x,y,width,height, name, angle, cx, cy);
where angle is the angle of rotation and cx/cy are the coordinates for the rotational centre of the image.
The bitmap functions using the example image have been used in the following sketch – Example 50.5, with the results in the following video:
Unfortunately the camera doesn’t really do the screen justice, it looks much better with the naked eye.
Running out of space or I/O? Use an Arduino Mega
By now you may have noticed that the library for the LCDs uses up a fair amount of memory, which could be a problem. And using bitmaps eats up memory as well. And the I/O requirements are quite heavy. The solution is to use an Arduino Mega or compatible board – as they have up to eight times the sketch memory available. However the wiring is a little different – so when using a Mega, run a jumper from the following LCD module pins to your Mega (or compatible):
- DB0 to DB7 > Mega D22 to D29 respectively
- RD > 3.3 V
- RSET > D41
- CS > D40
- RW > D39
- RS > D38
- backlight 5V > 5V
- backlight GND > GND
You will also need to change the line
UTFT myGLCD(ILI9325C,19,18,17,16); // for Uno
to
UTFT myGLCD(ILI9325C,38,39,40,41); // for Mega
What about the SD card socket and touch screen?
The SD socket didn’t work, and I won’t be working with the touch screen at this time.
Conclusion
So there you have it – an incredibly inexpensive and possibly useful LCD module. Thank you to Henning Karlsen for his useful library, and if you found it useful – send him a donation via his page.
In the meanwhile 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? And join our friendly 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.
Review – Schmartboard SMT Boards
In this article we review a couple of SMT prototyping boards from Schmartboard.
Introduction
Sooner or later you’ll need to use a surface-mount technology component. Just like taxes and myki* not working, it’s inevitable. When the time comes you usually have a few options – make your own PCB, then bake it in an oven or skillet pan; get the part on a demo board from the manufacturer (expensive); try and hand-solder it yourself using dead-bug wiring or try to mash it into a piece of strip board; or find someone else to do it. Thanks to the people at Schmartboard you now have another option which might cost a few dollars more but guarantees a result. Although they have boards for almost everything imaginable, we’ll look at two of them – one for QFP packages and their Arduino shield that has SOIC and SOP23-6 areas.
QFP 32-80 pin board
In our first example we’ll see how easy it is to prototype with QFP package ICs. An example of this is the Atmel ATmega328 microcontroller found on various Arduino-compatible products, for example:
Although our example has 32 pins, the board can handle up to 80-pin devices. You simply place the IC on the Schmartboard, which holds the IC in nicely due to the grooved tracks for the pins:
The tracks are what makes the Schmartboard EZ series so great – they help hold the part in, and contain the required amount of solder. I believe this design is unique to Schmartboard and when you look in their catalogue, select the “EZ” series for this technology. Moving forward, you just need some water-soluble flux:
then tack down the part, apply flux to the side you’re going to solder – then slowly push the tip of your soldering iron (set to around 750 degrees F) down the groove to the pin. For example:
Then repeat for the three other sides. That’s it. If your part has an exposed pad on the bottom, there’s a hole in the centre of the Schmartboad that you can solder into as well:
After soldering I really couldn’t believe it worked, so probed out the pins to the breakout pads on the Schmartboard to test for shorts or breaks – however it tested perfectly. The only caveat is that your soldering iron tip needs to be the same or smaller pitch than the the part you’re using, otherwise you could cause a solder bridge. And use flux! You need the flux. After soldering you can easily connect the board to the rest of your project or build around it.
Schmartboard Arduino shield
There’s also a range of Arduino shields with various SMT breakout areas, and we have the version with 1.27mm pitch SOIC and a SOT23-6 footprint. SOIC? For example:
This is the AD5204 four-channel digital potentiometer we used in the SPI tutorial. It sits nicely in the shield and can be easily soldered onto the board. Don’t forget the flux! Although the SMT areas have the EZ-technology, I still added a little solder of my own – with satisfactory results:
The SOT23-6 also fits well, with plenty of space for soldering it in. SOT23? Example – the ADS1110 16-bit ADC which will be the subject of a future tutorial:
Working with these tiny components is also feasible but requires a finer iron tip and a steady hand.
Once the SMT component(s) have been fitted, you can easily trace out the matching through-hole pads for further connections. The shield matches the Arduino R3 standards and includes stacking header sockets, two LEDs for general use, space and parts for an RC reset circuit, and pads to add pull-up resistors for the I2C bus:
Finally there’s also three 0805-sized parts and footprints for some practice or use. It’s a very well though-out shield and should prove useful. You can also order a bare PCB if you already have stacking headers to save money.
Conclusion
If you’re in a hurry to prototype with SMT parts, instead of mucking about – get a Schmartboard. They’re easy to use and work well. Full-sized images available on flickr.
In the meanwhile 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? And join our friendly 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 boards used in this article were a promotional consideration supplied by Schmartboard.
Review – LBE “Magpie” Arduino-compatible board
In this article we review the “Magpie” Arduino Uno-compatible board from Little Bird Electronics.
Introduction
Finally I’m back at the office and have a pile of things to write about. Starting with the subject of this review – the “Magpie” board from Little Bird Electronics in Australia. It seems that a new Arduino-compatible board enters the market every week, thanks to the open-source nature of the platform and the availability of rapid manufacturing. However the Magpie isn’t just any old Arduino Uno knock-off, it has something which helps it stand out from the crowd – status LEDs on every digital and analogue I/O pin. You can see them between the stacking header sockets and the silk-screen labels. For example:
and for the curious, the bottom of the Magpie:
At first glance you might think “why’d they bother doing that? I could just wire up some LEDs myself”. True. However having them on the board speeds up the debugging process as you can see when an output is HIGH or LOW – and in the case of an input pin, whether a current is present or not. For the curious the LEDs are each controlled by a 2N7002 MOSFET with the gate connected to the I/O pin, for example:
An LED will illuminate as long as the gate voltage is higher than the threshold voltage – no matter the status of the particular I/O pin. And if an I/O pin is left floating it may trigger the LED if the threshold voltage is exceeded at the gate. Therefore when using the Magpie it would be a good idea to set all the pins to LOW that aren’t required for your particular sketch. Even if you remove and reapply power the floating will still be prevalent, and indicated visually – for example:
Nevertheless you can sort that out in void setup(), and then the benefits of the LEDs become apparent. Consider the following quick demonstration sketch:
// LBE Magpie board LED demo - John Boxall 18 March 2013
// usual blink delay period
int d=100;
void setup()
{
// digital pins to outputs
for (int a=0; a<14; a++)
{
pinMode(a, OUTPUT);
}
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
}
void allOn()
// all LEDs on
{
for (int a=0; a<14; a++)
{
digitalWrite(a, HIGH);
}
digitalWrite(A0, HIGH);
digitalWrite(A1, HIGH);
digitalWrite(A2, HIGH);
digitalWrite(A3, HIGH);
digitalWrite(A4, HIGH);
digitalWrite(A5, HIGH);
}
void allOff()
// all LEDs on
{
for (int a=0; a<14; a++)
{
digitalWrite(a, LOW);
}
digitalWrite(A0, LOW);
digitalWrite(A1, LOW);
digitalWrite(A2, LOW);
digitalWrite(A3, LOW);
digitalWrite(A4, LOW);
digitalWrite(A5, LOW);
}
void clockWise(int r, int s)
// blinks on and off each LED clockwise
// r - # rotations, s - blink delay
{
allOff();
for (int a=0; a<r; a++)
{
for (int b=13; b>=0; --b)
{
digitalWrite(b, HIGH);
delay(s);
digitalWrite(b, LOW);
}
digitalWrite(A5, HIGH);
delay(s);
digitalWrite(A5, LOW);
digitalWrite(A4, HIGH);
delay(s);
digitalWrite(A4, LOW);
digitalWrite(A3, HIGH);
delay(s);
digitalWrite(A3, LOW);
digitalWrite(A2, HIGH);
delay(s);
digitalWrite(A2, LOW);
digitalWrite(A1, HIGH);
delay(s);
digitalWrite(A1, LOW);
digitalWrite(A0, HIGH);
delay(s);
digitalWrite(A0, LOW);
delay(s);
}
}
void anticlockWise(int r, int s)
// blinks on and off each LED anticlockwise
// r - # rotations, s - blink delay
{
allOff();
for (int a=0; a<r; a++)
{
for (int b=0; b<14; b++)
{
digitalWrite(b, HIGH);
delay(s);
digitalWrite(b, LOW);
}
digitalWrite(A0, HIGH);
delay(s);
digitalWrite(A0, LOW);
digitalWrite(A1, HIGH);
delay(s);
digitalWrite(A1, LOW);
digitalWrite(A2, HIGH);
delay(s);
digitalWrite(A2, LOW);
digitalWrite(A3, HIGH);
delay(s);
digitalWrite(A3, LOW);
digitalWrite(A4, HIGH);
delay(s);
digitalWrite(A4, LOW);
digitalWrite(A5, HIGH);
delay(s);
digitalWrite(A5, LOW);
delay(s);
}
}
void loop()
{
anticlockWise(3,50);
clockWise(3,50);
for (int z=0; z<4; z++)
{
allOn();
delay(100);
allOff();
delay(100);
}
}
… and the results are demonstrated in the following video:
Apart from the LEDs the Magpie offers identical function to that of an Arduino Uno R2 – except the USB microcontroller is an Atmel 16U2 instead of an 8U2, and the USB socket is a mini-USB and not the full-size type. For the curious you can download the Magpie design files from the product page.
Conclusion
If you’re often experimenting or working with the Arduino’s I/O pins and find yourself wiring up LEDs for testing purposes – the Magpie was made for you. Having those LEDs on the board really does save you if in a hurry to test or check something.
In the meanwhile 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? And join our friendly 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 Magpie board used in this article was a promotional consideration supplied by Little Bird Electronics.
Introducing Goldilocks – the Arduino Uno-compatible with 1284p and uSD card
[Update 19/03/2013 - the project is now fully funded. When the boards arrive we'll do a full review]
Introduction
It’s a solid fact that there are quite a few variations on the typical Arduino Uno-compatible board. You can get them with onboard wireless, GSM, Zigbee and more – however all with their own issues and specific purposes. But what if you wanted a board that was physically and electrically compatible with an Arduino Uno – but with much more SRAM, more EEPROM, more flash, more speed – and then some? Well that (hopefully) will be a possibility with the introduction of the “Goldilocks” board on Pozible by Phillip Stevens.
What’s Pozible?
Pozible is the Australian version of Kickstarter. However just like KS anyone with a credit card or PayPal can pledge and support projects.
What’s a Goldilocks board?
It’s a board based around the Atmel ATmega1284p microcontroller in an Arduino Uno-compatible physical board with a microSD card socket and a few extras. The use of the ’1284p gives us the following advantages over the Arduino Uno, including:
- 16 kByte SRAM = 8x Uno SRAM – so that’s much more space for variables used in sketches – great for applications that use larger frame buffers such as Ethernet and image work;
- 2 kByte EEPROM = 2 x Uno EEPROM – giving you more space for non-volatile data storage on the main board;
- 128 kByte flash memory = 4 x Uno – giving you much, much more room for those larger sketches;
- Two programmable USARTS – in other words, two hardware serial ports – no mucking about with SoftwareSerial and GSM or GPS shields;
- Timer 3 – the ’1284p microcontroller has an extra 16-bit timer – timer 3, that is not present on any other ATmega microcontroller. Timer 3 does not have PWM outputs (unlike Timer 0, Timer 1, and Timer 2), and therefore is free to use as a powerful internal Tick counter, for example in a RTOS. freeRTOS has already been modified to utilise this Timer 3;
- JTAG interface – yes – allowing more advanced developers the opportunity to debug their code;
- better PWM access – the 1284p brings additional 8-bit Timer 2 PWM outputs onto PD, which creates the option for 2 additional PWM options on this port. It also removes the sharing of the important 16-bit PWM pins with the SPI interface, by moving them to PD4 & PD5, thus simplifying interface assignments;
- Extra I/O pins – the 1284p has additional digital I/O pins on the PB port. These pins could be utilised for on-board Slave Select pins (for example), without stealing on-header digital pins and freeing the Arduino Pin 10 for Shield SPI SS use exclusively;
Furthermore the following design improvements over an Arduino Uno:
- adding through-holes for all I/O – allowing you to solder directly onto the board whilst keeping header sockets;
- replicate SPI and I2C for ease of use;
- microSD card socket – that’s a no-brainer;
- link the ATmega16u2 and ATmega1284p SPI interfaces – this will allow the two devices to work in concert for demanding multi-processing applications, involving USB and other peripherals;
- Fully independent analogue pins, including seperate AVCC and GND – helps reduce noise on the ADC channels for improved analogue measurement accuracy;
- move the reset button to the edge of the board – another no-brainer
- clock the board at 20 MHz – that’s an extra 4 MHz over a Uno. And the use of a through hole precision crystal (not a SMD resonator) allows the use of after market timing choices, eg 22.1184 MHz for more accurate UART timings.
What does it look like?
At the moment the board mock-up looks like this:
If funding is successful (and we hope it will be) the Goldilocks will be manufactured by the team at Freetronics. Apart from being a world-leader in Arduino-compatible hardware and systems, they’re the people behind the hardware for Ardusat and more – so we know the Goldilocks will be in good hands.
Will it really be compatible?
Yes – the Goldilocks will be shipped pre-programmed with an Arduino compatible boot-loader, and the necessary Board description files will be available to provide a 100% compatible Arduino IDE experience.
Conclusion
If you think this kind of board would be useful in your projects, you want to support a good project – or both, head over to Pozible and make your pledge. And for the record – I’ve put my money where my mouth is
Please note that I’m not involved in nor responsible for the Goldilocks project, however I’m happy to promote it as a worthwhile endeavour. In the meanwhile 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? And join our friendly 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.
Project: Clock Four – Scrolling text clock
Introduction
Time for another instalment in my highly-irregular series of irregular clock projects. In this we have “Clock Four” – a scrolling text clock. After examining some Freetronics Dot Matrix Displays in the stock, it occurred to me that it would be neat to display the time as it was spoken (or close to it) – and thus this the clock was born. It is a quick project – we give you enough to get going with the hardware and sketch, and then you can take it further to suit your needs.
Hardware
You’ll need three major items – An Arduino Uno-compatible board, a real-time clock circuit or module using either a DS1307 or DS3232 IC, and a Freetronics DMD. You might want an external power supply, but we’ll get to that later on.
The first stage is to fit your real-time clock. If you are unfamiliar with the operation of real-time clock circuits, check out the last section of this tutorial. You can build a RTC circuit onto a protoshield or if you have a Freetronics Eleven, it can all fit in the prototyping space as such:
If you have an RTC module, it will also fit in the same space, then you simply run some wires to the 5V, GND, A4 (for SDA) and A5 (for SCL):
By now I hope you’re thinking “how do you set the time?”. There’s two answers to that question. If you’re using the DS3232 just set it in the sketch (see below) as the accuracy is very good, you only need to upload the sketch with the new time twice a year to cover daylight savings (unless you live in Queensland). Otherwise add a simple user-interface – a couple of buttons could do it, just as we did with Clock Two. Finally you just need to put the hardware on the back of the DMD. There’s plenty of scope to meet your own needs, a simple solution might be to align the control board so you can access the USB socket with ease – and then stick it down with some Sugru:
With regards to powering the clock – you can run ONE DMD from the Arduino, and it runs at a good brightness for indoor use. If you want the DMD to run at full, retina-burning brightness you need to use a separate 5 V 4 A power supply. If you’re using two DMDs – that goes to 8 A, and so on. Simply connect the external power to one DMD’s terminals (connect the second or more DMDs to these terminals):

The Arduino Sketch
You can download the sketch from here. It was written only for Arduino v1.0.1. The sketch has the usual functions to set and retrieve the time from DS1307/3232 real-time clock ICs, and as usual with all our clocks you can enter the time information into the variables in void setup(), then uncomment setDateDs1307(), upload the sketch, re-comment setDateDs1307, then upload the sketch once more. Repeat that process to re-set the time if you didn’t add any hardware-based user interface.
Once the time is retrieved in void loop(), it is passed to the function createTextTime(). This function creates the text string to display by starting with “It’s “, and then determines which words to follow depending on the current time. Finally the function drawText() converts the string holding the text to display into a character variable which can be passed to the DMD.
And here it is in action:
Conclusion
This was a quick project, however I hope you found it either entertaining or useful – and another random type of clock that’s easy to reproduce or modify yourself. We’re already working on another one which is completely different, so stay tuned.
In the meanwhile 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? And join our friendly 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.
Arduino and KTM-S1201 LCD modules
Learn how to use very inexpensive KTM-S1201 LCD modules in this edition of our Arduino tutorials. This is chapter forty-nine of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
Introduction
After looking for some displays to use with another (!) clock, I came across some 12-digit numeric LCD displays. They aren’t anything flash, and don’t have a back light – however they were one dollar each. How could you say no to that? So I ordered a dozen to try out. The purpose of this tutorial is to show you how they are used with an Arduino in the simplest manner possible.
Moving forward – the modules look like OEM modules for desktop office phones from the 1990s:
With a quick search on the Internet you will find a few sellers offering them for a dollar each. The modules (data sheet) use the NEC PD7225 controller IC (data sheet):
They aren’t difficult to use, so I’ll run through set up and operation with a few examples.
Hardware setup
First you’ll need to solder some sort of connection to the module – such as 2×5 header pins. This makes it easy to wire it up to a breadboard or a ribbon cable:
The rest of the circuitry is straight-forward. There are ten pins in two rows of five, and with the display horizontal and the pins on the right, they are numbered as such:
Now make the following connections:
- LCD pin 1 to 5V
- LCD pin 2 to GND
- LCD pin 3 to Arduino D4
- LCD pin 4 to Arduino D5
- LCD pin 5 to Arduino D6
- LCD pin 6 to Arduino D7
- LCD pin 7 – not connected
- LCD pin 8 – Arduino D8
- LCD pin 9 to the centre pin of a 10k trimpot – whose other legs connect to 5V and GND. This is used to adjust the contrast of the LCD.
The Arduino digital pins that are used can be changed – they are defined in the header file (see further on). If you were curious as to how low-current these modules are:
That’s 0.689 mA- not bad at all. Great for battery-powered operations. Now that you’ve got the module wired up, let’s get going with some demonstration sketches.
Software setup
The sketches used in this tutorial are based on work by Jeff Albertson and Robert Mech, so kudos to them – however we’ve simplified them a little to make use easier. We’ll just cover the functions required to display data on the LCD. However feel free to review the sketches and files along with the controller chip datasheet as you’ll get an idea of how the controller is driven by the Arduino.
When using the LCD module you’ll need a header file in the same folder as your sketch. You can download the header file from here. Then every time you open a sketch that uses the header file, it should appear in a tab next to the main sketch, for example (click to enlarge):
There’s also a group of functions and lines required in your sketch. We’ll run through those now – so download the first example sketch, add the header file and upload it. Your results should be the same as the video below:
So how did that work? Take a look at the sketch you uploaded. You need all the functions between the two lines of “////////////////////////” and also the five lines in void setup(). Then you can display a string of text or numbers using
ktmWriteString();
which was used in void loop(). You can use the digits 0~9, the alphabet (well, what you can do with 7-segments), the degrees symbol (use an asterix – “*”) and a dash (use - “-”). So if your sketch can put together the data to display in a string, then that’s taken care of.
If you want to clear the screen, use:
ktmCommand(_ClearDsp);
Next – to individually place digits on the screen, use the function:
ktmPrnNumb(n,p,d,l);
Where n is the number to be displayed (zero or a positive integer), p is the position on the LCD for the number’s (the positions from left to right are 11 to 0…), d is the number of digits to the right of the decimal point (leave as zero if you don’t want a decimal point), and l is the number of digits being displayed for n. When you display digits using this function you can use more than one function to compose the number to be displayed – as this function doesn’t clear the screen.
To help get your head around it, the following example sketch (download) has a variety of examples in void loop(). You can watch this example in the following video:
Conclusion
So there you have it – an incredibly inexpensive and possibly useful LCD module. Thank you to Jeff Albertson and Robert Mech for their help and original code.
In the meanwhile 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? And join our friendly 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.





















































