t r o n i x s t u f f

fun and learning with electronics

Tutorial: Arduino Port Manipulation

This is chapter forty-three of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – a series of articles on the Arduino universe. The first chapter is here, the complete series is detailed here. Any files from tutorials will be found here.

Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice. 

Welcome back fellow arduidans!

In this article we are going to revisit the I/O pins, and use what is called “Port Manipulation” to control them in a much faster manner than using digitalWrite()/digitalRead().

Why?

Speed! Using this method allows for much faster I/O control, and we can control or read groups of I/O pins simultaneously, not one at a time;

Memory! Using this method reduces the amount of memory your sketch will use.

Once again I will try and keep things as simple as possible. This article is written for Arduino boards that use the ATmega168 or ATmega328 microcontrollers (used in Arduino Duemilanove/Uno, Freetronics TwentyTen/Eleven/EtherTen, etc). My Arduino Mega is out at the moment, so I will update the tutorial for Mega users when it is replaced.

First, we’ll use the I/O as outputs. There are three port registers that we can alter to set the status of the digital and analogue I/O pins. A port register can be thought of  as a special byte variable that we can change which is read by the microcontroller, therefore controlling the state of various I/O ports. We have three port registers to work with:

  • D – for digital pins seven to zero (bank D)
  • B – for digital pins thirteen to eight (bank B)
  • C – for analogue pins five to zero (bank … C!)

Register C can control analogue pins seven to zero if using an Arduino with the TQFP style of ATmega328, such as the Nano or Freetronics EtherTen). For example:

It is very simple to do so. In void setup(), we use

DDRy = Bxxxxxxxx

where y is the register type (B/C/D) and xxxxxxxx are eight bits that determine if a pin is to be an input or output. Use 0 for input, and 1 for output. The LSB (least-significant bit [the one on the right!]) is the lowest pin number for that register. Next, to control a bank of pins, use

PORTy = Bxxxxxxxx

where y is the register type (B/C/D) and xxxxxxxx are eight status bits – 1 for HIGH, 0 for LOW. This is demonstrated in the following example:

// Example 43.1
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// Digital 0~7 set to outputs, then on/off using port manipulation

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
  PORTD = B11110000; // digital 4~7 HIGH, digital 3~0 LOW
  delay(1000);
  PORTD = B00001111; // digital 4~7 LOW, digital 3~0 HIGH
  delay(1000);
}

It sets digital pins 7~0 to output in void setup(). Then it alternates turning on and off alternating halves of digital pins 0~7.

At the start I mentioned that using port manipulation was a lot faster than using regular Arduino I/O functions. How fast? To test the speed of port manipulation vs. using digitalWrite(), we will use the following circuit:

… and analyse the output at digital pins zero and seven using a digital storage oscilloscope. Our first test sketch turns on and off digital pins 0~7 without any delay between PORTD commands – in other words, as fast as possible. The sketch:

// Example 43.1.1
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// Digital 0~7 set to outputs, then on/off using port manipulation

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
  PORTD = B11111111;
  PORTD = B00000000;
}

In the image below, digital zero is channel one, and digital seven is channel three:

Wow – check the frequency measurements – 1.1432 MHz! Interesting to note the longer duration of time when the pins are low vs. high.

[Update] Well it turns out that the extra time in LOW includes the time for the Arduino to go back to the top of void loop(). This can be demonstrated in the following sketch. We turn the pins on and off five times instead of once:

// Example 43.1.2
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
  PORTD = B11111111;
  PORTD = B00000000;
  PORTD = B11111111;
  PORTD = B00000000;
  PORTD = B11111111;
  PORTD = B00000000;
  PORTD = B11111111;
  PORTD = B00000000;
  PORTD = B11111111;
  PORTD = B00000000;
}

And the results from the MSO. You can see the duty cycle is much closer to 50% until the end of the sketch, at which point around 660 nanoseconds is the time used between the end of the last LOW period and the start of the next HIGH:

Next we do it the normal way, using this sketch:

// Example 43.2
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// Digital 0~7 set to outputs, then on/off using digitalWrite()

void setup()
{
  for (int a=0; a<8; a++)
  {
    pinMode(a, OUTPUT);
  }
}

void loop()
{
  for (int a=0; a<8; a++)
  {
    digitalWrite(a, HIGH);
  }
  for (int a=0; a<8; a++)
  {
    digitalWrite(a, LOW);
  }
}

And the results:

That was a lot slower – we’re down to 14.085 kHz, with a much neater square-wave output. Could some CPU time be saved by not using the for loop? We tested once more with the following sketch:

// Example 43.3
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// Digital 0~7 set to outputs, then on/off using individual digitalWrite() 

void setup()
{
  for (int a=0; a<8; a++)
  {
    pinMode(a, OUTPUT);
  }
}

void loop()
{
  digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
}

and the results:

A small speed boost, the frequency has increased to 14.983 kHz. Hopefully you can now understand the benefits of using port manipulation. However there are a few things to take note of:

  • You can’t control digital pins 0 and 1 (in bank D) and use the serial monitor/port. For example if you set pin zero to output, it can’t receive data!
  • Always document your sketch – take pity on others who may need to review it later on and become puzzled about wchich bits are controlling or reading what!
Now to waste some electron flows by blinking LEDs. Using the circuit described earlier, the following sketch will create various effects for someone’s enjoyment (download):
// Example 43.4
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// Fun with 8 LEDs on digital 7~0

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0)
  //  to output
}

byte a = B11111111;
byte b = B00000001;
byte c = B10000000;
byte e = B10101010;

void krider()
{
  for (int k=0; k<5; k++)
  {
    for (int z=0; z<8; z++)
    {
      PORTD = b << z;
      delay(100);
    }

    for (int z=0; z<8; z++)
    {
      PORTD = c >> z;
      delay(100);
    }
  }
}

void onOff()
{
  for (int k=0; k<10; k++)
  {
    PORTD = a;
    delay(100);
    PORTD = 0;
    delay(100);
  }
}

void invBlink()
{
  for (int z=0; z<10; z++)
  {
    PORTD = e;
    delay(100);
    PORTD = ~e;
    delay(100);
  }
}

void binaryCount()
{
  for (int z=0; z<256; z++)
  {
    PORTD = z;
    delay(100);
  }
  PORTD=0;
}

void loop()
{
  invBlink();
  delay(500);
  binaryCount();
  delay(500);
  krider();
  delay(500);
  onOff();
}

And here it is in real life:

Now to use the I/O pins as inputs. Again, it is very simple to do so. In void setup(), we use

DDRy = Bxxxxxxxx

where y is the register type (B/C/D) and xxxxxxxx are eight bits that determine if a pin is to be an input or output. Use 0 for input. The LSB (least-significant bit [the one on the right!]) is the lowest pin number for that register. Next, to read the status of the pins we simply read the byte:

PINy

where y is the register type (B/C/D).

So if you were using port B as inputs, and digital pins 8~10 were high, and 11~13 were low, PINB would be equal to B00000111. Really, that’s it!

Now for another demonstration using both inputs and outputs. We will use a push-wheel switch from Chapter 40 on our inputs (digital pins 8~11), and a seven segment LED display for output (on digtal pins 7~0 – segments dp then a~f). The following sketch reads the input from the switch, which returns 0~9 in binary-coded decimal. This value is then used in the function void disp() to retrieve the matching byte from the array “segments”, which contains the appropriate outputs to drive the seven segment LED display unit. Here is the sketch (download):

// Example 43.5
// tronixstuff.wordpress.com/tutorials > chapter 43
// John Boxall - October 2011
// inputs and outputs

byte segments[] = {
  B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000, B01111111, B01111011};
// digital pins 7~0 connected to display pins dp,a~g
void setup()
{
  DDRB = B00000000; // set PORTB (digital 13~8) to inputs
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void disp(int z)
{
  PORTD = segments[z];
}

void loop()
{
    disp(PINB);
    delay(100);
}

And the ubiquitous demonstration video:


By now I hope you have an understanding of using port manipulation for your benefit. With a little effort your sketches can be more efficient in terms of speed and memory space, and also allow nifty simultaneous reading of input pins.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

October 22, 2011 Posted by | arduino, education, microcontrollers | , , , , , , , , , , , , , , , | 27 Comments

October 2011 Competition

Hello Readers!

The October competition has now closed and the entries will be judged very soon. Stay tuned for the results and the forthcoming November competition!

— *** Prize One *** —

Prize One consists of a Freetronics USBDroid and one Terminal Shield:

Designed in Australia and manufactured to the highest quality standards the USBDroid combines the functionality of the Freetronics Eleven along with a USB host-mode controller and a microSD memory card slot all merged together into a single, integrated board that is 100% Arduino compatible. This is the ideal platform for developing peripherals or projects based around Android devices with ADK (Android Developer Kit) functionality, but without requiring a USB host controller shield stacked onto an Arduino. Connect your Android phone for all kinds of controller and networking features, and other USB devices like game controllers, Bluetooth dongles, digital cameras, etc. All the good things about the Eleven are included:

  • Gold-plated PCB.
  • Top and bottom parts overlays.
  • Top-spec ATmega328P MCU.
  • D13 pin isolated with a MOSFET so you can use it as an input.
  • Robust power filtering.
  • Sexy rounded corners.
  • PC communications with the Mini-USB connector: no more shorts against shields!
  • And of course the USB Host connector to go out to your Android phone and other USB devices.

In addition we’ve included a high current onboard power supply so you can charge your Android device directly off the USBDroid. Available now from a Freetronics reseller near you.

The Terminal Shield breaks out all the Arduino headers to handy screw terminals, making it really easy to connect external wires without using a soldering iron. Ideal for quick experiments or for robust connections! The center area of the shield is also a huge prototyping area, allowing you to add your own parts to suit your project. A blue “power” LED shows when your Arduino is powered up, and there are also red, green, and blue general-purpose LEDs with current-limiting resistors. The Terminal Shield comes with all the supporting components already fitted as surface-mount parts so you can start using it right away, and we even provide stackable headers to allow you to mount another shield on top.

Features

  • Gold-plated surface: solders easily and very resistant to finger oil, etc.
  • Large prototyping area with through-plated holes.
  • Clearly marked GND and 5V rails beside prototyping area.
  • Blue surface-mount “power on” LED.
  • 2 × 100nF power supply smoothing capacitors pre-fitted as surface-mount parts.
  • Reset button wired through to the Arduino so you can reset it even with the shield mounted over the top.
  • 3 general-purpose surface-mount LEDs (red, green, blue) with current limiting resistors pre-fitted: driveHIGH to illuminate.
  • Overlay printed on both the top and the bottom of the board so you don’t have to turn it over to see what you’re soldering onto.
  • Sexy rounded corners.

— *** Prize Two*** —

Prize Two consists of  a Freetronics EtherTen and the new AM3X 3-Axis Accelerometer Module:

This is the mother of all Arduino-compatible boards. Designed in Australia and manufactured to the highest quality standards the EtherTen replaces three boards – consider having an Arduino Uno SMD, Ethernet shield with PoE, and a microSD shield – all on the one board. From the Freetronics website:

The EtherTen is a 100% Arduino compatible board that can talk to the world. Do Twitter updates automatically, serve web pages, connect to web services, display sensor data online, and control devices using a web browser. The Freetronics EtherTen uses the same ATmega328P as the Duemilanove and the same Wiznet W5100 chip used by the official Arduino Ethernet Shield, so it’s 100% compatible with the Ethernet library and sketches. Any project you would previously have built with an Arduino and an Ethernet shield stacked together, you can now do all in a single, integrated board.

We’ve even added a micro SD card slot so you can store web content on the card, or log data to it.

All the good things about the Eleven and the Ethernet Shield have been combined into this one device so please see those pages for all the specific details, but the highlights include:

  • Gold-plated PCB.
  • Top and bottom parts overlays.
  • Top-spec ATmega328P MCU.
  • Mini-USB connector: no more shorts against shields!
  • D13 pin isolated with a MOSFET so you can use it as an input.
  • Power-over-Ethernet support, both cheapie DIY or full 802.3af standards-compliant.
  • Ethernet activity indicators on the PCB and the jack.
  • 10/100base-T auto-selection.
  • Fully compatible with standard Ethernet library.
  • Reset management chip.
  • Fixed SPI behavior on Ethernet chipset.
  • Robust power filtering.
  • Sexy rounded corners.

Note that just like our Ethernet Shield with PoE support, the EtherTen provides a number of options for different Power over Ethernet. You can use the supplied jumpers and feed 7-12Vdc down the wire for cheap DIY version, or you can fit our PoE Regulator 24V and feed a bit more voltage down the wire, or you can use our PoE Regulator 802.3AF along with a proper commercial PoE injector or switch. It’s up to you.

Which way is up?

This tiny 3-axis accelerometer module can operate in either +/-1.5g or +/-6g ranges, giving your project the ability to tell which way is up. Ideal for robotics projects, tilt sensors, vehicle dataloggers, and whatever else you can dream up. It has independent X, Y, and Z axis outputs ready to connect directly to analog inputs on an Arduino, and we’ve included an onboard 3.3V regulator so that you can run it from either 5V or 3.3V. It even has a “zero g!” output to detect when the device is in free-fall, so you could connect that to an “interrupt” pin on an Arduino to have your project react immediately if it’s dropped!

Very cool.

The module includes mounting holes suitable for M3 or 1/8″ bolts, and a flat rear face so you can easily glue it to any surface. Available here now or at a Freetronics reseller near you.

— *** Prize Three *** —

Prize Three consists of not one, not two – but three Snootlab Zombadge kits:

With Trippy RGB sketch uploaded, this is the Snootlab games platform based on the Mitch Altman original design, it can receive original Snootlab collaborative games. This badge can be used for soldering workshop and electronic board programming. Being a badge, it can be worn as a pendant. More details on the dedicated website zombadge.com.

— *** How to Enter *** —

In thirty words or less explain what you would do with your preferred prize if you received it. Use your imagination and have some fun – perhaps try your hand at Haiku or some nerdy poetry. You can enter once for each prize bundle, however you can only win one out of three prizes.

Email your submission along with your name, email address and postal address to competition at tronixstuff dot com with the subject heading October. Entries will be accepted until 01/11/2011 (that’s November the first) 0005h GMT.

As with any other competition, there needs to be some rules:

  • The winners’ entry, first name and country will be announced publicly;
  • Entries that contain text not suitable for minors or insulting to the competition will be rejected;
  • Prizes will be delivered via Australia Post domestic or regular international air mail;
  • Winners outside of Australia will be responsible for any taxes, fees or levies imposed by your local Governments (such as import levies, excise, VAT, etc.) upon importation of purchased goods;
  • Prizes may take up to 45 days to be received;
  • If you have met John Boxall in person, or you have won a previous tronixstuff.com competition you cannot enter;
  • No disputes will be entered in to;
  • Incomplete entries will be rejected;
  • Prizes carry no warranty nor guarantee – and are to be used or abused at entirely your own risk;
  • Entries will be accepted until 0005h GMT on 1st November 2011.

So have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

October 14, 2011 Posted by | arduino, competition | , , , , , , , , , , , , , , | Leave a Comment

Review – Tenma 72-7222 Digital Clamp Multimeter

Hello readers

The purpose of this article is to examine the Tenma 72-7222 Digital Clamp Multimeter supplied for review by element-14/Farnell/Newark. The Tenma is a strongly featured yet inexpensive piece of test equipment – and considerably good value when you consider there is a current clamp for measuring high AC currents. So let’s have a look and see what we have.

Initial Impression

The Tenma arrives in a retail box, and generally nicely packaged. Naturally this has nothing to do with the performance of the meter at all, but at least they made an effort:

Opening up we find a nicely rounded group of items: the meter itself, some no-name AAA cells, test leads, a thermocouple for temperature measurement, a surprisingly articulate and well-written user manual, and the unit itself – all within a nice pouch. Wow – a pouch. Agilent? Fluke? All that money for a DMM and you don’t include a pouch?

Recent test equipment reviewers have made pulling apart the unit part of the review – so here goes… the back comes off easily:

No user-replaceable fuses… instead a PTC. A closer look at the PCB:

A very neat and organised PCB layout. There are plastic tabs that hold the PCB in along with a screw, however the case flexed too much for me to warrant removing the PCB completely. The spring for the clamp meter is locked in nicely and very strong, it won’t give up for a long time. Pulling the clamp base out reveals the rest of the PCB:

Installation of the battery is two stage procedure, first you need to remove a screw and then slide out the rear door:

… then insert the AAA cells into a frame, which is then inserted inside the unit:

The physical feel of the unit is relative to the purchase price, the plastic is simple and could be quite brittle if the unit was dropped from a height. The user manual claims the unit can be dropped from up to a height of one metre. Onto carpet? Yes. Concrete? Perhaps not. However like all test equipment one would hope the user would take care of it whenever possible. The clamp meter is very strong due to the large spring inside the handle, which can be opened up to around 28mm. The included leads are just on one meter long including the length of the probe:

The leads are rated to Category I 1000V (overkill – the meter can’t go that high) and 600 V Category II – “This category refers to local-level electrical distribution, such as that provided by a standard wall outlet or plug in loads (for example, 115 AC voltage for U.S. or 200 AC voltage for Europe). Examples of Measurement Category II are measurements performed on household appliances, portable tools, and similar modules” – definition from from National Instruments.  Unlike discount DMMs from unknown suppliers you can trust the rating to be true – otherwise element-14 wouldn’t be selling it.

Unit Specifications

  • Voltage Measuring Range DC:200mV, 2V, 20V, 200V, 600V
  • Voltage Measuring Range AC:2V, 20V, 200V, 600V
  • Current Measuring Range AC:2A, 20A, 200A, 400A
  • Resistance Measuring Range:200ohm, 2kohm, 20kohm, 200kohm, 2Mohm, 20Mohm
  • Temperature Measuring Range:-40°C to +1000°C
  • DMM Response Type:True RMS
  • DMM Functions:AC Current, AC/DC Voltage, Resistance, Temperature
  • Ranging:Auto
  • Display Count:1999
  • AC Current Range Accuracy:± (1.5% + 5d)
  • AC Voltage Range Accuracy:± (1.2% + 5d)
  • Accuracy:± (1.0% + 3d)
  • Current AC Max:400A
  • Current Range AC:2A, 20A, 200A, 400A
  • DC Voltage Range Accuracy1:± (0.8% + 1d)
  • Resistance Range Accuracy:± (1.0% + 2d)
  • Temperature Measuring Range:-40°C to +1000°C

The only measurement missed out on is DC current, however there is the Tenma 72-7224 which has DC current and frequency ranges. Finally, all the modes and buttons can be selected while holding the meter with one hand – for both left- and right-handed folk.

Measurement experience

Normally I would compare the measurements against my Agilent U1272A, however it’s out to lunch. Instead, a Fluke 233. First, AC voltage from the mains:

Next, a few DC voltage measurements:

Now for some resistance measurements. Higher values near the maximum of 20M Ohm can take around four seconds to measure:

Forward voltage of a 1N4004 diode:

Now off to the kitchen for some more measurements – first with the thermocouple:

The boiling water test – 100 degrees Celsius (you can also select Fahrenheit if so inclined):

And now to test out the AC current clamp meter function with a 10A kettle at boiling point. First, using the 20A current range:

And then again on the 400A current range:

As always, it’s best to use the multimeter range that more closely corresponds with the current under test. The meter also has a continuity test with a beeper, however it was somewhat slow and would often take around one second to register – so nothing too impressive on that front. The meter can record the maximum value with the grey button, or hold a reading using the yellow button.

Conclusion

The Tenma 72-7222 works as advertised, and as expected. It is a solid little unit that if looked after should last a few years at a minimum. It certainly has a few limitations, such as the 1999 count display, lack of backlight, and the average continuity function. But don’t let that put you off. For the price – under Au$30 – it is a certified deal. If you need a clamp current meter for odd jobs or a casual-use multimeter and you are on a limited budget, the Tenma will certainly prove a worthwhile purchase. Full-size images are available on Flickr.

You can purchase a Tenma 72-7222 from element-14Farnell and Newark.

Thanks for reading! Have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

[Note - The Tenma 72-7222 Digital Clamp Multimeter was a promotional consideration from element-14/Farnell/Newark]

October 11, 2011 Posted by | review, test equipment | , , , , , , , , , , , , , , , , | 2 Comments

Repurposing Cat5E Network Cable

Hello readers

Just some random notes from my Saturday afternoon. While cleaning up the garage I found a rather long network cable hiding from a long-forgotten project in the past:

However after trying to use it between my EtherTen and the router, the cable turned out to have a break in it somewhere. So what to do? Twentieth-century me would have just thrown it out, but that would be irresponsible. But inside that blue insulation are four twisted-pairs of 24AWG wire – perfect for prototyping and general low-voltage use:

So time to strip back the outer insulation and give the twisted-pairs their freedom:

They are a little thinner than first imagined, but how thin are they? Not being one to memorise the American Wire Gauge data I took a few quick measurements:

A quick measurement of the wire diameter without insulation. AWG specification is 0.511mm. Those digital vernier calipers were pretty sensitive so that will do. Excellent – now I have almost 120 metres of perfectly good hook-up wire. Just have to remember to test each piece before using it – that break was in there somewhere! What would that have cost me new? Local retailers (ugh) can charge over 25 centre per metre. So that’s a free lunch.

Next time you have some broken network cable… don’t throw it out – reuse it. What else can we do with the cable? Leave your suggestions in the comments below.

So have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

October 9, 2011 Posted by | hardware hacking, recycling, repurposing | , , , , , , | 18 Comments

Kit Review – Snootlab DeuLigne LCD Arduino Shield

Hello everyone

Another month and time for another kit review :) Once again we have another kit from the team at Snootlab in France – their DeuLigne LCD Arduino shield. Apart from having a two row, sixteen character backlit LCD there is also a five-way joystick (up, down, left, right and enter) which is useful for data entry and so on.

This LCD shield is different to any others I have seen on the market as it uses the I2C bus for interface with the LCD screen – thereby not using any digital pins at all. The interfacing is taken care of by a Microchip MCP23008 8-bit port expander IC, and Snootlab have written a custom LCD library which makes using the LCD very simple. Furthermore the joystick uses the analog input method, using analogue pin zero. But for now, let’s examine construction.

Please note that the kit assembled in this article is a version 1.0, however the shield is now at version 1.1. Construction is very easy, starting with the visual and easy to follow instructions (download). The authors really have made an effort to write simple, easy to follow instructions. The kit arrives as expected, in a reusable anti-static pouch:

As always everything was included, including stacking headers for Arduino. It’s great to see them included, as some other companies that should know better sometimes don’t. (Do you hear me Sparkfun?)

The PCB is solid and fabricated very nicely – the silk screen is very descriptive, and the PCB is 1.7mm thick. The joystick is surface-mounted and already fitted. Here’s the top:

… and the bottom:

Using a Freetronics EtherTen as a reference,  you can see that the DeuLigne PCB is somewhat larger than the standard Arduino shield:

The first components to solder in are the resistors:

… followed by the transistor and MCP23008. Do not use an IC socket, as this will block the LCD from seating properly…

After fitting the capacitor, contrast trimpot, LCD header pins and stacking sockets the next step is to bolt in the LCD with the standoffs:

The plastic bolts can be trimmed easily, and then glued to the nuts to stay tight. Or you can just melt them together with the barrel of your soldering iron :) Finally you can solder in the LCD data pins and the shield is finished:

The only thing that concerned me was the limited space between LCD pins twelve~sixteen and the stacking header sockets. It may be preferable to solder the stacking sockets last to avoid possibly melting them when soldering the LCD. Otherwise everything was simple and construction took just under twenty minutes.

Now to get the shield working. Download and install the DeuLigne Arduino library, and then you can test your shield with the included examples. The LCD contrast can be adjusted with the trimpot between the joystick and the reset button. Note that this shield is fully Open Hardware compliant, and all the design files and so on are available from the ‘download’ tab of the shield product page.

Initialising the LCD requires the following code before void Setup():

#include "Wire.h"; // include I2C library for MCP23008
#include "Deuligne.h"; // include shield library
Deuligne lcd; // create instance of LCD "lcd"

Then in void Setup():

  Wire.begin(); // initialise I2C
  lcd.init(); // initialise LCD

Now you can make use of the various LCD functions, including:

lcd.backLight(true); // turns backlight on (or false for off)
lcd.print(); // displays text (using "") or data on the LCD
lcd.setCursor(column, row); // positions cursor on column 0~15, row 0~1
lcd.clear(); // clears display

Reading the joystick position is easy, the function

int pos=lcd.get_key();

returns an integer to pos representing the position. Right = 0, left = 3, up = 1, down = 2, enter = 4.

Automatic text scrolling can be turned on and off with:

lcd.Autoscroll();
lcd.noAutoscroll();

Creating custom characters isn’t that difficult. Each character consists of eight rows of five pixels. Create your character inside a byte array, such as:

byte box  [8]={
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11111
};

There is an excellent tool to create these bytes here. Then allocate the custom character to a position number (0~7) using:

lcd.createChar(0,box);

Then to display the custom character, just use:

lcd.write(0); // for character in position 0

And the resulting character filling the display:

Now for an example sketch to put it all together. Using my modified Freetronics board with a DS1307 real-time clock IC, we have a simple clock that can be set by using the shield’s joystick. For a refresher on the clock please read this tutorial. And for the sketch (download):

/*
  Clock with menu demonstration
  for Snootlab DeuLigne LCD shield
  John Boxall - http://tronixstuff.wordpress.com/kitreviews > Snootlab LCD shield
*/

#include "Wire.h"
#include "Deuligne.h"
#define DS1307_I2C_ADDRESS 0x68
Deuligne lcd;

int a=0;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

// define custom characters for up/down/left/right arrow
byte ua[8] = {  B00100, B01110, B11111, B10101,  B00100, B00100,B00100,B00100};
byte da[8] = {B00100, B00100, B00100, B00100, B10101,B11111,B01110,B00100};
byte la[8] = {B00011, B00110, B01100, B11111, B11111, B01100, B00110, B00011};
byte ra[8] = {B11000, B01100, B00110, B11111, B11111, B00110, B01100, B11000 };  

void setup()
{
  Wire.begin();
  lcd.init();
  lcd.createChar(0,ua);
  lcd.createChar(1,da);
  lcd.createChar(2,la);
  lcd.createChar(3,ra);
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void setDateDs1307(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-28/29/30/31
byte month,         // 1-12
byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour));
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.send(00010000); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
  Wire.endTransmission();
}

void showTime()
{
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  lcd.clear(); // clear LCD screen
  lcd.setCursor(0,0);
  lcd.print("    ");
  lcd.print(hour, DEC);
  lcd.print(":");
  if (minute<10)
  {
    lcd.print("0");
  }
  lcd.print(minute, DEC);
  lcd.print(":");
  if (second<10)
  {
    lcd.print("0");
  }
  lcd.print(second, DEC);
}

void setTime()
{
  int escape=0;
  int h=0;
  int m=0;
  do
  {
    escape=lcd.get_key();
    delay(100); // for debounce
    if (escape==0)
    {
      --m;
      if (m<0)
      {
        m=59;
      }
    } else
    if (escape==1)
    {
      h++;
      if (h>23)
      {
        h=0;
      }
    } else
    if (escape==2)
    {
      --h;
      if (h<0)
      {
        h=23;
      }
    } else
    if (escape==3)
    {
      m++;
      if (m>59)
      {
        m=0;
      }
    }
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.write(0);
    lcd.write(1);
    lcd.print(":h ");
    lcd.write(2);
    lcd.write(3);
    lcd.print(":m Ent=OK");
    lcd.setCursor(5,1);
    if (h<10)
    {
      lcd.print("0");
    }
    lcd.print(h);
    lcd.print(":");
    if (m<10)
    {
      lcd.print("0");
    }
    lcd.print(m);
  } while (escape<4);
  setDateDs1307(0, m, h, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  lcd.clear();
  showTime();
  a=lcd.get_key();
  if (a==4) // someone pressed 'enter'
  {
    delay(200); // for debounce
    setTime();
  }
  delay(400); // delay to stop LCD flicker
}

As you can see, the last delay statement is for 400 milliseconds. Due to the extra overhead required by using I2C on top of the LCD library, it slows down the refresh rate a little. Moving forward, a demonstration video:


So there you have it. Another useful, fun and interesting Arduino shield kit to build and enjoy. Although it is no secret I like Snootlab products, it is a just sentiment. The quality of the kit is first rate, and the instructions and support exists from the designers. So if you need an LCD shield, consider this one.

For support, visit the Snootlab website and customer forum in French (use Google Translate). However as noted previously the team at Snootlab converse in excellent English and have been easy to contact via email if you have any questions. Snootlab products including the Snootlab DeuLigne are available directly from their website. High-resolution images available on flickr.

So have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

[Disclaimer - the products reviewed in this article are promotional considerations made available by Snootlab]

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

October 7, 2011 Posted by | arduino, I2C, kit review, LCD | , , , , , , , , , , , , , , , , | 2 Comments

September 2011 Competition Results

Hello readers

September has now passed by and it is time to announce the winners of the September competition. Congratulations to all those who entered – there was some great examples of creativity and enthusiasm. We narrowed it down to six entries, and then randomly selected two winners – so here they are:

First Prize

Jeremías from Buenos Aires, Argentina submitted:

Receiving Zigduinos, I will be very happy.
I will move a robot from far away.
I will fly a copter around a way.
Yeah! I’ll be the king that day.

Congratulations Jeremías, you won two Zigduinos:

For more information, please visit the Logos Electromechanical website.

Second Prize

Tim from Baskerville, Western Australia submitted:

zigduino keep baci safe
from koi thieves and poisoners
light with solar flood

Congratulations Tim, you have won the LoL Shield:

LoL Shields are available from Little Bird Electronics

Well that’s another competition for the year. In September we received quite a few invalid entries – always read the instructions and the rules when entering any future competitions. Otherwise have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

October 6, 2011 Posted by | competition | , , , , , , , , , | Leave a Comment

Tutorial: Arduino and Numeric Keypads

This is chapter forty-two of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – a series of articles on the Arduino universe. The first chapter is here, the complete series is detailed here. Any files from tutorials will be found here.

Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice. 

Welcome back fellow arduidans!

This is part one of two chapters that will examine another useful form of input – the numeric keypad; and some applications that hopefully may be of use.  Here is the example we will be working with:

It seems quite similar to the keypad from a 1980s-era Dick Smith Electronics cordless phone. Turning the keypad over we find seven pins:

Personally I like this type of connection, as it makes prototyping very easy using a breadboard – you just push it in. Looking at the back the pins are numbered seven to one (left to right). My example was from Futurlec of all places. You can also find types that have solder pads, such as this one. At this point you need to download the data sheet.pdf, as it shows the pinouts for the rows and columns. At first glance trying to establish a way of reading the keypad with the Arduino does seem troublesome – however the basic process is to ‘scan’ each row and then test if a button has been pressed.

If your keypad has more than seven pins or contacts – and the data sheet was not supplied, you will need to manually determine which contacts are for the rows and columns. This can be done using the continuity function of a multimeter (the buzzer). Start by placing one probe on pin 1, the other probe on pin 2, and press the keys one by one. Make a note of when a button completes the circuit, then move onto the next pin. Soon you will know which is which. For example, on the example keypad pins 1 and 5 are for button “1″, 2 and 5 for “4″, etc…

In the interest of keeping things simple and relatively painless we will use the numeric keypad Arduino library. Download the library from here, copy the “Keypad” folder into your ../arduino-002x/libraries folder, then restart the Arduino IDE.

Now for our first example. From a hardware perspective you will need

Connect the keypad to the Arduino in the following manner:
  • Keypad row 1 to Arduino digital 5
  • Keypad row 2 to Arduino digital 4
  • Keypad row 3 to Arduino digital 3
  • Keypad row 4 to Arduino digital 2
  • Keypad column 1 to Arduino digital 8
  • Keypad column 2 to Arduino digital 7
  • Keypad column 3 to Arduino digital 6
Now for the sketch. You can download it here

Example 42.1

/* Example 42.1 - Numeric keypad and I2C LCD
   http://tronixstuff.wordpress.com/tutorials > chapter 42
   Uses Keypad library for Arduino

http://www.arduino.cc/playground/Code/Keypad

   by Mark Stanley, Alexander Brevig */

#include "Keypad.h"
#include "Wire.h" // for I2C LCD
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module http://bit.ly/eNf7jM
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

// keypad type definition
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
 {{'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}};
byte rowPins[ROWS] = {
  5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  8, 7, 6}; // connect to the column pinouts of the keypad
int count=0;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
  lcd.init();          // initialize the lcd
  lcd.backlight(); // turn on LCD backlight
}

void loop()
{
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    lcd.print(key);
    count++;
    if (count==17)
    {
      lcd.clear();
      count=0;
    }
  }
}

For the non-believers, here it is in action:


As you can see the library really does all the work for us. In the section below the comment “keypad type definition” we have defined how many rows and columns make up the keypad. Furthermore which digital pins connect to the keypad’s row and column pins. If you have a different keypad such as a 16-button version these will need to be modified. Furthermore you can also map out what the buttons will represent in the array “keys”. Then all of these variables are passed to the library in the function Keypad keypad = Keypad() etc.

Reading the buttons pressed is accomplished in void loop()… it reads the keypad by placing the current value into the char variable “key”. The if… statement tests if a button has been pressed. You can reproduce this loop within your own sketch to read values and then move forward to other functions. Let’s do that now in our next example.

Keypad Switch

Using our existing example hardware we can turn something on or off by using the keypad – replicating what can be found in some alarm systems and so on. Our goal with this example is simple – the systems waits for a PIN to be entered. If the PIN is correct, do something. If the PIN is incorrect, do something else. What the actions are can be up to you, but for the example we will turn on or off a digital output. This example is to give you a concept and framework to build you own ideas with.

The hardware is the same as the previous example but without the LCD. Instead, we have a 560 ohm resistor followed by an LED to GND from digital pin ten. Now for the sketch. You can download it from here.

Example 42.2

// Example 42.2 - Six-digit keypad switch
// http://tronixstuff.wordpress.com/tutorials > chapter 42

#include "Keypad.h"

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{{'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}};
byte rowPins[ROWS] = {
  5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char PIN[6]={'1','2','3','4','5','6'}; // our secret (!) number
char attempt[6]={
  0,0,0,0,0,0}; // used for comparison
int z=0;

void setup()
{
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  incorrectPIN();
}

void correctPIN() // do this if correct PIN entered
{
  digitalWrite(11, LOW);
  digitalWrite(10, HIGH);
}

void incorrectPIN() // do this if incorrect PIN entered
{
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH);
}

void checkPIN()
{
  int correct=0;
  for (int q=0; q<6; q++)
  {
    if (attempt[q]==PIN[q])
    {
      correct++;
    }
  }
  if (correct==6)
  {
    correctPIN();
  } else
  {
    incorrectPIN();
  }
  for (int zz=0; zz<6; zz++) // wipe attempt
  {
    attempt[zz]=0;
  }
}

void readKeypad()
{
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    switch(key)
    {
    case '*':
      z=0;
      break;
    case '#':
      delay(100); // for extra debounce
      checkPIN();
      break;
    default:
      attempt[z]=key;
      z++;
    }
  }
}

void loop()
{
  readKeypad();
}

And the ubiquitous demonstration video:

This sketch is somewhat more complex. It starts with the usual keypad setting up and so on. We have two arrays, attempt and PIN. PIN holds the number which will successfully activate the switch, and attempt is used to store the key presses entered by the user. Users must press ‘*’ then the PIN then ‘#’ to activate the switch.

The comparison to check for accuracy is in the function checkPIN(). It compares the contents of PIN against attempt. If they match, the function correctPIN() is called. If the entered PIN is incorrect, the function incorrectPIN() is called. We also call the function incorrectPIN() in void setup to keep things locked down in case of a power failure or a system reset.

You can now see that such a complex device can be harnessed very easily, and could have a variety of uses. In part two, we will look at the 16-digit 

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

October 4, 2011 Posted by | arduino, learning electronics, microcontrollers | , , , , , , , , , , , , , | 18 Comments

   

Follow

Get every new post delivered to your Inbox.

Join 2,588 other followers