Thursday, March 31, 2011

Review – Agilent U1272A True-RMS Digital Multimeter

Hello everyone

The purpose of this article is to initially examine the Agilent Technologies U1272A water and dust resistant digital multimeter. This is an extremely well specifed instrument, and according to the Agilent promotional material a better alternative to the venerable Fluke 87V. So let’s dive in and take a look.

Initial impression

The retail box as always is impressive and well decorated. Opening it up reveals a range of items:


including the meter itself, a calibration certificate and calibration results sheet, probe set, thermocouple, quick start guide and four AAA cells. It was a little disappointing to not find alligator clip adaptors nor a carrying case. For those interested, a full range  of documentation isavailable here.

The meter measures 207 x 92 x 59 mm (hwd) and is quite solid, not too heavy and surrounded by a good orange non-slip rubber layer. This no doubt helps provide some shock resistance, as this unit has survived a 2.5 meter drop from my ceiling to the concrete. It is refreshing to see that the keypad is laid out in an organised way, much better than the random-looking layout on the U1250 series:

The meter

Installing or changing the the battery (four AAA cells) is easily accomplished, and thankfully the fuses are also in the same compartment. The included AAA cells are thecheaper “GP brand”, and should do for the first few months. The dust and moisture protection is evident as shown by the o-ring seal around the perimeter of the compartment:

As mentioned earlier, the U1272A is water and dust resistant to IP54 specifications – 54 meaning “protected against dust limited ingress”/”protection against water sprayed from all directions – limited ingress permitted.”. It is possible to turn the function selector with one hand whether you have the meter standing up or laying on your desk. The included test leads are just over 1200mm in length and are rated at Cat III 1000V, 15A. Two pairs of probes are included, with 4mm and 19mm tips:

Again, it is unfortunate that alligator-clip adaptors nor probes are included – these are very useful especially to those who are colourblind and need to sort resistors or measure tiny through-hole capacitors. Furthermore, a K-tyle thermocouple and non-compensation transfer adaptor are also included:

The thermocouple’s temperature range is -20~200 degrees Celsius, however with an optional thermocouple the maximum temperature can be increased to 1200 degrees C. As for the othermeasurement ranges, they are detailed in the data sheet which you can download here (.pdf).

Furthermore there is a diode test  function, and a continuity beeper. The backlight also flashes when using the continuity function which would be very convenient for those working in a noise environment. There has been some discussion around various forums as to the speed of the continuity function, so here is a small video demonstration of it in action:

In use

Although readers would not have any problem using the meter without reading the manual, doing so will illustrate the particular features of the U1272A as well as operation of the menu system that allow various settings to be changed. These can include: beep frequency (!), backlight duration, data communication parameters, default temperature units, scale conversion values, and activating the low-pass filter available when measuring DC voltage and current.

At the risk of shortening the battery life, I extended the backlight duration immediately to thirty seconds; and set temperature units to degrees Celsius. When taking measurements that only require the main numeric display, the ambient temperature is shown in the secondary numeric display. I must admit to discovering another feature by accident, if the leads are in the current and COM terminals and you select a non-current measurement function – the meter will beep like crazy, blink the backlight and show an error message. This is useful when you’re tired and probably should be doing something else.

Measuring AC voltage provides various data upon request. Apart from the RMS voltage value, you can also turn on a low-pass filter which blocks unwanted voltage above 1 kHz.

The frequency measurement function allows the display the frequency, duty cycle and pulse-width when measuring AC or DC current or voltage. Furthermore, you can display both voltage/current and also display the frequency, pulse-width and duty cycle at the same time, for example:


In a previous article the U1272A was used to measure frequency and duty cycle, which you can observe in the following short clip:

Measuring DC voltage is straightforward, and there is also the option to measure both AC and DC components and display them combined or separately, for example:

You can also display voltage as a decibel value relative to 1 mW (dBm) or a reference value of 1V (dBv). And the dB reference impedance can also be set to fall between 1 and 9999 ohms. Another interesting voltage measurement function is “Zlow”. Using this function, the meter changes to a very low input impedance, and can remove “ghost” voltages from the measurement by dissipating the coupling voltage. This function can also be used to test if a battery is still usable, if the voltage of the battery under test decreases slowly, it doesn’t have the capacity to deliver the required voltage. However I wouldn’t put a battery under this test method for too long due to the meter acting close to a short circuit.

Measuring resistance is simply done with the U1272A, and for more precise measurements one can short the probes to measure their resistance then set a null point so your measurements will not be affected by probe resistance. There is also an Agilent feature called SmartOhm which can be used to remove unexpected DC voltages that can add errors to resistance measurements. You can also use SmartOhm to measure leakage current or reverse current for junction diodes. I look forward to spending more time examining SmartOhm.

Furthermore, one can also measure conductance (the reciprocal of resistance) which is measured in Siemens. According to the manual one can measure extremely high resistance values up to 100 gigaohms. Interesting.

Diode measurement works as expected, the standard setting displays the voltage drop across the diode. However by pressing Shift on the meter, you can use the “Auto-diode” function which forward and reverse bias simultaneously using both numeric displays. For example, measuring a 1N4004 diode produces the following display, the forward voltage and the Good/Not good result:

Measuring capacitance is also quite simple, and the manual recommends setting a null value while the probes are open to compensate for residual capacitance. Interestingly the LCD shows when it is charging and discharging the capacitor under test, using the following segments:

Temperature measurement is possible with the included thermocouple and adaptor. Note that the included K-type thermocouple is only rated for up to 200 degrees Celsius, however with an optional unit the meter can measure up to 1372 degrees C. The display can show Fahrenheit as well as Celsius. The meter also shows ambient temperature using the secondary numeric display when it is not in use with other measurement display functions. Finally, measuring AC or DC current is completed as expected, and as noted earlier when switching to another non-current function, the meter will remind you to change the positive lead.

Compared to other meters, there are a few things that irritated me slightly with this unit. The auto-ranging can be somewhat slower than other meters, especially the frequency measurement – it can take around four seconds to measure a constant frequency… my old Tektronix CFC-250 is faster than that. And the exclusion of alligator-clip adaptors and case was disappointing considering the price of the meter. However on a positive note, the meter is supplied with minimal paper documentation, and a full range of manuals, service guides and so on are available for download from the Agilent website.

Over the last three months I have been using the U1272A and would call it a success. The dual line LCD display really is useful, as well as the low current measurement and especially the Zlow function. There is a short video you can watch that explains a few of the unique features very well. Furthermore, there is a distinct lack of fragility which gives you one less thing to worry about when looking after your tools. Finally there is also the data-logging, however this does require an optional cable. If you are in the market for a full-function electronics multimeter, put this meter on your evaluation list.

The Agilent U1272A True RMS Multimeter is available from your local element-14/Farnell/Newark or other Agilent distributors.

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 on twitterfacebook, or join our Google Group.

High resolution images are available from flickr.

[Disclaimer - the Agilent U1272A in this review is a sample made available by Agilent Technologies via element-14]

Otherwise, have fun, be good to each other – and make something! :)

Update – Upcoming Electronics Industry Documentary

Hello readers

Today I am going to introduce something quite different, yet hopefully interesting to you out there. The renowned director and cinematographer Karl von Muller has just released the roll-call trailer for his upcoming documentary titled “State of Electronics” – a discussion on the Electronics Industry in Australia. Although the focus is on the Australian electronics scene, much of the content and discourse within the documentary can be related to by those from many other countries.

However, Karl can explain it better:

After several months of researching, interviewing and filming, I’m excited to present the first public Trailer to my new Documentary “State of Electronics” – A discussion on the Electronics Industry in Australia. Even though the documentary is focused on Australian Electronics Design and Manufacture, much of it applies to all countries from around the world.

The discussion is focused initially on the world of Hobby Electronics and how it’s decline could affect the Electronics Industry in the future. The Documentary then discusses many issues that face industry including the issue of “Repair and Recycle”, “Education”, “Surface Mount Technology”, “Globalisation”, “Opportunities” and many many more off the cuff & candid comments from Industry professionals.

The Documentary features interviews with famous Australians and Industry professionals including Dick Smith, Dave L Jones, Doug Ford, Leo Simpson, Grant Petty, Matthew Pryor, Jonathan Oxer, Andy Gelme, Andrew Griffiths, Eugene Ruffolo & Bill Petreski. In the future, I am planning to interview just a few more before the final release of the Documentary soon.

Shot completely on the Canon 5DMK2, using the Zoom H4N Audio recorder. Directed, Edited and shot by Karl von Moller, this version of the trailer is largely ungraded and only has an FCP sound mix applied. Music track is composed by Karl von Moller also. Enjoy!

Please visit karlvonmoller.com for more on the progress and information on “State of Electronics”

Here is the new roll-call trailer:

 

 

… and the original trailer for those unfamiliar with the project:

 

 

This will surely be a fascinating and insightful documentary that we are all looking forward to. Nice one Karl!

Tuesday, March 29, 2011

Tutorial: Arduino and Infra-red control

This is chapter thirty-two 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. Please note from November 1, 2010 files from tutorials will be found here.

Welcome back fellow Arduidans!

In this article we will look at something different to the usual, and hopefully very interesting and useful – interfacing our Arduino systems with infra-red receivers. Why would we want to do this? To have another method to control our Ardiuno-based systems, using simple infra-red remote controls.

A goal of this article is to make things as easy as possible, so we will not look into the base detail of how things work - instead we will examine how to get things done. If you would like a full explanation of infra-red, perhaps see the page on Wikipedia. The remote controls you use for televisions and so on transmit infra-red beam which is turned on and off at a very high speed – usually 38 kHz, to create bits of serial data which are then interpreted by the receiving unit. As the wavelength of infra-red light is too high for human eyes, we cannot see it. However using a digital camera – we can. Here is a demonstration video of IR codes being sent via a particularly fun kit – the adafruit TV-B-Gone:

Now to get started. You will need a remote control, and a matching IR receiver device. You can purchase a matching set for a good price,such as this example:

Or you may already have a spare remote laying around somewhere. I kept this example from my old Sony Trinitron CRT TV after it passed away:

It will more than suffice for a test remote. Now for a receiver – if you have purchased the remote/receiver set, you have a nice unit that is ready to be wired into your Arduino, and also a great remote that is compact and easy to carry about. To connect your receiver module – as per the PCB labels, connect Vcc to Arduino 5V, GND to Arduino GND, and D (the data line) to Arduino digital pin 11.

Our examples use pin 11, however you can alter that later on. If you are using your own remote control, you will just need a receiver module. These are very cheap, and an ideal unit is the Vishay TSOP4138 (data sheet .pdf). These are available from element-14RSand the other usual retail suspects. They are also dead-simple to use. Looking at the following example:

From left to right the pins are data, GND and Vcc (to Arduino +5V). So it can be easily wired into a small breadboard for testing purposes. Once you have your remote and receiver module connected, you need to take care of the software side of things. There is a new library to download and install, download it from here. Extract the IRremote folder and place into the ..\arduino-002x\libraries folder. Then restart your Arduino IDE if it was already open.

With our first example, we will receive the commands from our remote control and display them on the serial monitor. Download and run the this sketch (example 32.1). Open the serial monitor box, point your remote control to the receiver and start pressing away. You should see something like this:

What have we here? Lots of hexadecimal numbers. Did you notice that each button on your remote control resulted in an individual hexadecimal number? I hope so. The number FFFFFFFF means that the button was held down. The remote used was from a yum-cha discount TV. Now I will try again with the Sony remote:

This time, each button press resulted in the same code three times. This is peculiar to Sony IR systems. However nothing to worry about. Looking back at the sketch for example 32.1, the

if (irrecv.decode(&results))

section is critical – if a code has been received, the code within the if statement is executed. The hexadecimal code is stored in the variable

results.value

with which we can treat as any normal hexadecimal number. At this point, press a few buttons on your remote control, and take a note of the matching hexadecimal codes that relate to each button. We will need these codes for the next example…

Now we know how to convert the infra-red magic into numbers, we can create sketches to have our Arduino act on particular commands. As the IR library returns hexadecimal numbers, we can use simple decision functions to take action. In the following example, we useswitch…case to examine each inbound code, then execute a function. In this case we have an LCD module connected via I2C, and the sketch is programmed to understand fifteen Sony IR codes. If you don’t have an LCD you could always send the output to the serial monitor.

Furthermore you can substitute your own values if not using Sony remote controls. Finally, this sketch has a short loop after thetranslateIR(); function call which ignores the following two codes – we do this as Sony remotes send the same code three times. Again. you can remove this if necessary. Note that when using hexadecimal numbers in our sketch we preced them with 0x. Download the sketch example 32.2 from here. Now here it is in action:


You might be thinking “why would I want to make things appear on the LCD like that?”. The purpose of the example is to show how to react to various IR commands. You can replace the LCD display functions with other functions of your choosing.

At the start working with infra-red may have seemed to be complex, but with the previous two examples it should be quite simple by now. So there you have it, another useful way to control our Arduino systems. Hopefully you have some ideas on how to make use of this technology. In future articles we will examine creating and sending IR codes from our Arduino. So stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS feed (top-right), twitter or joining our Google Group. Furthermore, a big thanks to Ken Shirriff for his Arduino library.

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!

Sunday, March 27, 2011

Arduino Game: Tic-Tac-Toe

Hello readers

Within this article we will recreate the game of Tic-tac-toe with our Arduino systems. This game is also known as Noughts and Crosses or Three-in-a-row. Whatever we call it, I’m sure you will be familiar with the game from your childhood or general messing about. For the uninitiated, there is an excellent explanation of the game over at Wikipedia.

In the following examples, a human will play against the machine (Arduino). The demonstration sketches are almost identical except for one function – machineMove();. This function contains the method of deciding a move for the machine. By localising the machine’s decision making into that function we can experiment with levels of intelligence without worrying about the rest of the sketch. In writing this article it is assumed the reader has some basic Arduino or programming experience. If not, perhaps read some of my Arduino tutorials indexed here.

However first we will examine the hardware. I have used my well-worn Freetronics Eleven board, which is equivalent to the Arduino Uno and compatible with the Duemilanove. For a display, the Sparkfun LCD shield is used – explanations of the LCD functions can be found in chapter 28 of my Arduino tutorials. For user input we have two buttons connected to digital pins 6 and 7, using 10k pull-down resistors as normal. The buttons are wired via a ScrewShield set. To save time I have used my generic button-board, whose schematic is below:If you were to construct a more permanent example, this could be easily done. One could possibly use a DS touch-screen over their LCD. Perhaps for mark II? Nevertheless, time to move on. Now to explain how the sketch works – please download a copy from here so you can follow along with the explanation.

I have tried to make the sketch as modular as possible to make it easy to follow and modify. The sketch itself is relatively simple. We use an array board[] to map the pieces of the game board in memory – board[0] being the top-left and board[8] being the bottom-right position. We create a graphical representation of the board by drawing rectangles for the horizontal and vertical lines, lines to form crosses, and circles for … circles. The function drawBoard(); takes care of the board lines and calls drawPiece();to place the players’ pieces. drawBoard(); reads the board[] array to determine if a position is blank (zero), a nought (1) or a cross (2).

The flow of the sketch is easy to follow. First the function introScreen() is called – it displays the introductory screen. ThendrawBoard() is called to draw the initially-blank game board. Then the main function playGame(); is called. We have a global variable winner, whose value determine the winner of the game (0 – game still in play, 1 – human, 2 – machine, 3 – draw).playGame(); and other functions will refer to winner throughout the sketch. Within playGame();, the human and machine take turns placing their pieces. The function humanMove(); accepts the human’s choice in piece position, storing it into board[], and not allowing false moves. The function machineMove(); controls the decision-making process for the machine’s moves. In the first example, the machine moves by randomly selecting a board position. If the position is taken, another random position is selected (and so on) until a valid move can be made.

Question – Which IC is the equivalent of two 555 timer ICs?

After each instance of humanMove(); and machineMove();, the function checkWinner(); is called. This function compares the contents of the array board[] against all possible scenarios for a win by either player, and calls the function drawTest(); – which checks for a draw – and stores the result in the variable winner as described earlier. Checking for a win is simple, however checking for a draw was a little more complex. This involves counting the number of 1s and 2s in the board[] array. If there are five 1s and four 2s or four 1s and five 2s ( in other words, the board is full) there is a draw. Easy!

If, after the function checkWinner(); is called, the varible winner >0 – then something to end the game has happened – either a win or a draw. This is determined using the switch…case function at the end of checkWinner();. At this point a function relative to the game status is called, each of which display the outcome and wait for the user to press button A to start a new game. At the end of each of these functions, we call the function clearBoard(); – which resets the array board[] and winner back to zero, ready for the next battle of wits.

Now for our first example in action. The function machineMove() is an example of the simplest form of play – the machine randomly selects blank positions on the board until the game ends. In the following video clip you can see this in action:

For the forthcoming examples, we will allow the choice of who moves first. This is accomplished with the function moveFirst();which sets the variable whofirst to 1 for human first, or 2 for machine first. This is read by playGame() to determine the first move. Now let’s inject some strategy into our machineMove(); function to give the machine a slight edge above sheer randomness.

In the following example, the machine will first only use the centre or corners until those positions have been taken. This is accomplished by placing the position numbers into another array strategy1[]={0,2,4,6,8} which the machine will randomly select from until those positions are used.  Once all those positions have been filled, the machine will revert to random positioning to attempt a win. You can download this example sketch from here. Do you think the machine can win if allowed to move first? Let’s see what happens in the following video clip:

In the second example the player who moves first will generally have the advantage. From this point, how could we strengthen the machine’s level of intelligence to improve its strategy? If you have a better method, and can integrate it into the example sketch, and are happy to publish it under Creative Commons – email the sketch to john at tronixstuff dot com. The best submission will be published and receive an interesting prize. Entries close April 15th 2011 2359h UTC.

So there you have it, some variations on a classic game translated for our Arduino systems. I hope you found it interesting… or at least something different to read about. Stay tuned for future articles by subscribing 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.

Tuesday, March 22, 2011

Happy Birthday

Hello everyone

Well it has been twelve months since my very first post – banging on about replacing the battery in my cordless telephones. The last year has certainly zoomed by very quickly, and with it has seen 135 original posts about all sorts of things. Funnily enough, I had never planned on creating a “blog” at the time… instead a few books of notes were being used to record my thoughts and ideas.

It all started while looking for an electronic kit to build… I thought it would be great to have a website where you could read about others’ experiences in building the kit – in order to decide whether or not you would like to build it yourself. Whilst waiting for the kit to arrive some other ideas evolved into posts, mundane things such as replacing calculator batteries, sourcing cheap electronics books, and the start of a power supply saga.

After writing about the JYE Capacitor meter kit, Madeleine and Marcus from Little Bird Electronics asked me to write about this Arduino thingy that they had, and sent one over to play with. Thanks guys! Things picked up a bit after that – now hundreds of thousands of people regularly visit my Arduino tutorials for fun, guidance, and to rip them apart (the tutorials, not the Arduino). And along the way I have had loads of fun writing about more kits, reviewing various parts and items, sharing myprojects with the world and learning the basics.

One of the best things that has resulted from this blog is the opportunity to come into contact with some very interesting and inspirational people such as Jon Oxer from FreetronicsAndy GelmeDave Jones, Tim Carr from Mindkits, and many others too numerous to mention. Furthermore, it has been great conversing with the many members of the tronixstuff Google Group, answering the thousands of random email questions (well, most of them), interacting with my twitter followers, and giving away things with the regular competitions. Speaking of which:

Question: Name five people from the Arduino development team

Finally, a lot of the content in this blog would not be possible without the generosity of various people and organisations. So a huge thank you to Little Bird ElectronicsFreetronicselement-14, RS DesignsparkAlan ParekhOgi Lumen andGabotronics. And especially to those who were kind enough to make a donation.

The year ahead shall see a few (or more?) more Arduino tutorials, the start of another series concerning a different type of microcontroller, more interesting and inane projects, more reviews, and possibly a book. So stay tuned, and thanks for coming along for the ride.

In the meanwhile, be good to each other and make something :)

Wednesday, March 16, 2011

Tutorial: Your Arduino’s inbuilt EEPROM

This is chapter thirty-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. Please note from November 1, 2010 files from tutorials will be found here.

Welcome back fellow arduidans!

Today we are going to examine the internal EEPROM in our Arduino boards. What is an EEPROM some of you may be saying? An EEPROM is anElectrically Erasable Programmable Read-Only Memory. It is a form of non-volatile memory that can remember things with the power being turned off, or after resetting the Arduino. The beauty of this kind of memory is that we can store data generated within a sketch on a more permanent basis.

Why would you use the internal EEPROM? For situations where data that is unique to a situation needs a more permanent home. For example, storing the unique serial number and manufacturing date of a commercial Arduino-based project – a function of the sketch could display the serial number on an LCD, or the data could be read by uploading a ‘service sketch’. Or you may need to count certain events and not allow the user to reset them – such as an odometer or operation cycle-counter.

What sort of data can be stored? Anything that can be represented as bytes of data. One byte of data is made up of eight bits of data. A bit can be either on (value 1) or off (value 0), and are perfect for representing numbers in binary form. In other words, a binary number can only uses zeros and ones to represent a value. Thus binary is also known as “base-2″, as it can only use two digits.

How can a binary number with only the use of two digits represent a larger number? It uses a lot of ones and zeros. Let’s examine a binary number, say 10101010. As this is a base-2 number, each digit represents 2 to the power of x, from x=0 onwards:

See how each digit of the binary number can represent a base-10 number. So the binary number above represents 85 in base-10 – the value 85 is the sum of the base-10 values. Another example – 11111111 in binary equals 255 in base 10.

Now each digit in that binary number uses one ‘bit’ of memory, and eight bits make a byte. Due to internal limitations of the microcontrollers in our Arduino boards, we can only store 8-bit numbers (one byte) in the EEPROM. This limits the decimal value of the number to fall between zero and 255. It is then up to you to decide how your data can be represented with that number range. Don’t let that put you off – numbers arranged in the correct way can represent almost anything!

There is one limitation to take heed of – the number of times we can read or write to the EEPROM. According to the manufacturer Atmel, the EEPROM is good for 100,000 read/write cycles (see the data sheet). One would suspect this to be a conservative estimate, however you should plan accordingly.

Now we know our bits and and bytes, how many bytes can be store in our Arduino’s microcontroller? The answer varies depending on the model of microcontroller. For example:

  • Boards with an Atmel ATmega328, such as Arduino Duemilanove, UnoUno SMDLilypad or the Freetronics KitTen/Eleven - 1024 bytes (1 kilobyte)
  • Boards with an Atmel ATmega1280 or 2560, such as the Arduino Mega series – 4096 bytes (4 kilobytes)
  • Boards with an Atmel ATmega168, such as the original Arduino Lilypad, old Nano, Diecimila etc – 512 bytes.

If y0u are unsure have a look at the Arduino hardware index or ask your board supplier.

If you need more EEPROM storage than what is available with your microcontroller, consider using an external I2C EEPROM as described in the Arduino and I2C tutorial part two.

Question – Which company manufactures the microcontroller used in our Arduino boards?

At this point we now understand what sort of data and how much can be stored in our Arduino’s EEPROM. Now it is time to put this into action. As discussed earlier, there is a finite amount of space for our data. In the following examples, we will use a typical Arduino board with the ATmega328 with 1024 bytes of EEPROM storage.

To use the EEPROM, a library is required, so use the following library in your sketches:

#include <EEPROM.h>

The rest is very simple. To store a piece of data, we use the following function:

EEPROM.write(a,b);

The parameter a is the position in the EEPROM to store the integer (0~255) of data b. In this example, we have 1024 bytes of memory storage, so the value of a is between 0 and 1023. To retrieve a piece of data is equally as simple, use:

z = EEPROM.read(a);

Where z is an integer to store the data from the EEPROM position a. Now to see an example:

Example 31.1

This sketch (download) will create random numbers between 0 and 255, store them in the EEPROM, then retrieve and display them on the serial monitor. The variable EEsize is the upper limit of your EEPROM size, so (for example) this would be 1024 for an Arduino Uno, or 4096 for a Mega.

/* Example 31.1 - Arduino internal EEPROM demonstration
http://tronixstuff.com/tutorials > chapter 31 | CC by-sa-nc */
#include <EEPROM.h>
int zz;
int EEsize = 1024; // size in bytes of your board's EEPROM
void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(0));
}
void loop()
{
  Serial.println("Writing random numbers...");
  for (int i = 0; i < EEsize; i++)
  {
    zz=random(255);
    EEPROM.write(i, zz);
  }
  Serial.println();
  for (int a=0; a<EEsize; a++)
  {
    zz = EEPROM.read(a);
    Serial.print("EEPROM position: ");
    Serial.print(a);
    Serial.print(" contains ");
    Serial.println(zz);
    delay(25);
  }
}

The output from the serial monitor will appear as such:

So there you have it, another useful way to store data with our Arduino systems. Although not the most exciting tutorial, it is certainly a useful. Stay tuned for upcoming Arduino tutorials by subscribing 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!

Friday, March 11, 2011

The DFRobot LCD4884 LCD Shield

Hello readers

This article is my response to a request on how to use the LCD4884 LCD shield from DFRobot in China. It is a simple way of displaying text and the odd graphic, as well as another way to accept user input. Here is the shield in question:

From a hardware perspective the LCD has a resolution of 84 by 48 pixels, with a blue back light. It can easily display six rows of fourteen alphanumeric characters, or two rows of six very large characters. Furthermore, it can display bitmap images that are appropriately sized. At the top-left of the shield digital pins eight to thirteen have been expanded with matching Vcc and GND pins, and at the bottom right the same has been done with analogue pins one through to five. Therefore if using this shield, you will lose digital pins two through to seven and analogue zero.

Along the bottom-left of the shield are solder pads for some other I/O options, however I couldn’t find any documentation on how these are used. Below the LCD is a small four-way joystick that also has an integral button. This is connected to analog pin zero via a resistor network. This joystick can be used for user input and also to create some nifty menu systems. To the right is a power-on LED which is really too bright, I would recommend sanding it a little to reduce the intensity, or just melting it off with a soldering iron.

The shield requires an Arduino library which can be downloaded from the shield’s wiki page. There is also a good demonstration sketch on the wiki, however some of our readers may find this to be somewhat complex. Therefore where possible I will break down and explain the functions in order to simplify use of the shield, then use them in a demonstration sketch.

Controlling the backlight is very easy, just use digitalWrite(7, HIGH/LOW) to turn it on and off. Don’t forget to put pinMode(7, OUTPUT) in void setup();.

Reading the joystick position is accomplished via analogRead(0);. It returns the following values as such:

  • Up – 505
  • Down – 0
  • Left – 740
  • Right – 330
  • pressed in – 144
  • Idle (no action) – 1023

By using analogRead(0) and if… statements you can read the joystick in a simple way. Don’t forget to allow for some tolerance in the readings. Attempts to press the button while forcing a direction did not return any different values. In the example sketch later on, you can see how this is implemented. Always remember to insert:

lcd.LCD_init();

in void setup() to create an instance of the LCD, and

#include <LCD4884.h>

at the start of your sketch to enable the library.

Now to display text on the LCD. Here is an example of the standard font text:

Using the standard font, we can position text using the following function:

lcd.LCD_write_string(x,y,"insert text here", MENU_NORMAL); // ignore MENU_NORMAL for now

The parameter x is for the x-coordinate of the first character – measured in pixels, not characters. However y is the coordinate in character lines (!). The screen can display six lines of fourteen characters. To display the larger font, for example:

use the following:

lcd.LCD_write_string_big(x,y, "012345", MENU_NORMAL);

Unfortunately the library only supports the digits 0~9, +, – and decimal point. You can modify the file font_big.h in the library folder and create your own characters. Once again the x parameter is the number of pixels across to place the first character, and y is 0 for the top line and 3 for the bottom line. Notice that the characters in this font are proportional, however the maximum number of digits to plan for in one line would be six.

To clear the display, use:

lcd.LCD_clear();

By now you will be able to display text, control the backlight and read the joystick. The following demonstration sketch (download) puts it all together so far:

#include <LCD4884.h>int z=0;int dd=200; void setup()
{
lcd.LCD_init(); // creates instance of LCD
lcd.LCD_clear(); // blanks the display
pinMode(7, OUTPUT);
}
void loop()
{  // first some text display
for (int a=0; a<5; a++)
{
digitalWrite(7, LOW);
delay(300);
digitalWrite(7, HIGH);
delay(300);
}
for (int a=0; a<6; a++)
{
lcd.LCD_write_string(0,a,"01234567980123", MENU_NORMAL); // ignore MENU_NORMAL for now
delay(dd);
}
delay(dd);
lcd.LCD_clear();   // blanks the display
delay(500);
lcd.LCD_write_string_big(0, 0, "012345", MENU_NORMAL);
lcd.LCD_write_string_big(0, 3, "-+-+-+", MENU_NORMAL);
delay(1000);
lcd.LCD_clear();  // now to read the joystick using analogRead(0). Press RESET whien finished
do
{
z=analogRead(0);
if (z==0)
{
lcd.LCD_write_string(2,2,"Down", MENU_NORMAL);
}     else
if (z>0 && z<150)
{
lcd.LCD_write_string(2,2,"OK   ", MENU_NORMAL);
delay(dd);
}       else
if (z>150 && z<350)
{
lcd.LCD_write_string(2,2,"Right", MENU_NORMAL);
delay(dd);
}         else
if (z>350 && z<510)
{
lcd.LCD_write_string(2,2,"Up   ", MENU_NORMAL);
delay(dd);
}         else
if (z>510 && z<750)
{
lcd.LCD_write_string(2,2,"Left ", MENU_NORMAL);
delay(dd);
}           else
if (z>750)
{
lcd.LCD_write_string(2,2,"nil  ", MENU_NORMAL);
delay(dd);
}
}  while (1>0);
}

Question How many standard characters can be displayed on the LCD in this article?

Next is to create and display bitmap images. Images can be up to 84 x 48 pixels in size. There are no shades of grey in the images, just pixels on or off. To display a bitmap is a convoluted process but can be mastered. We need to convert a bitmap image into hexadecimal numbers which are then stored in a text file for inclusion into the sketch. To do so, follow these steps:

Create your monochrome image using an editor such as Gimp. Make sure your file name ends with .bmp. Such as:

Next, download the BMP2ASM program from this website. [Sorry, could only find a Windows version]. Open your .bmp file as created above, and you will see a whole bunch of hexadecimal numbers at the bottom of the window:

Turn on the check boxes labelled “Stretch”, “Use Prefix” and “Use suffix”. Then click “Convert”. Have a look in your folder and you will find a text file with an extension .asm. Open this file in a text editor such as Notepad. Remove all the instances of “dt”, as well as the top line with the file path and name. Finally, put commas at the end of each line.

You should now be left with a file of hexadecimal numbers. Encase these numbers in the form of an array as such:

What we have done is places the hexadecimal numbers inside the

unsigned char hellobmp[]= {}

declaration. To make life simpler, ensure the filename (ending with .h) is the same as the variable name, as in this example it is called hellobmp(.h). And make sure you have saved this file in the same folder as the sketch that will use it.

Finally, we include the hellobmp.h file in our example sketch to display the image:

#include "LCD4884.h"
#include "hellobmp.h" // this file needs to be in the same folder as your sketch
void setup()
{
  lcd.LCD_init(); // creates instance of LCD
  lcd.LCD_clear(); // blanks the display
}
void loop()
{
   lcd.LCD_draw_bmp_pixel(0,0, hellobmp, 84,48);
   do { } while (1>0); // do nothing
}

Notice in the function lcd.LCD_draw_bmp_pixel the filename hellobmp is the same as in the #include declaration is the same as the hellobmp.h file we created. They all need to match. Furthermore, the four numerical parameters are the bitmap’s top-left x-y and bottom-right x-y coordinates on the LCD. So after all that, here is the result:

So there you have it. If you have any questions about this LCD shield contact DF Studio, or ask a question in our Google Group. If anyone from DFStudio or DFRobot is reading this, shame on you for not publishing easy to understand documentation for your own products.

Nevertheless, have fun, stay safe, be good to each other – and make something! :)