t r o n i x s t u f f

fun and learning with electronics

July 2011 Competition

Hello Readers

The July competition has now closed and the winners have been announced. Thank you to all those who entered and stay tuned for the next competition in August!

Time for another competition! To enter is very easy. There will be six questions hidden within articles published in the month of July (but not this one!). Once you have answers to all six, email them to competition at tronixstuff dot com with “July 2011″ in the subject line before 05/08. On the 5th of August, I will compile a list of people with the correct answers, and randomly select two winners. Please note competition rules at the end of this article.

The first winner drawn will receive an ex-review Ikalogic “Scanalogic2” PC-based logic analyser and signal generator:

With the Scanalogic2, you can capture and analyse all sorts of signals, including I2C, CAN bus, SPI, UART, and more. The firmware is user-upgradable and allows the design team to add more features when they are developed. You can even capture data and play it back to recreate situations in the future, or transfer the data to other users for their analysis. For more information please visit the Ikalogic website, or read my quick review of the Scanalogic.

The second winner drawn will receive one brand new Gravitech Arduino Nano:

Made in the USA, the Gravitech Arduino Nano is a very, very small version of our Arduino Duemilanove boards. It contains the same microcontroller (ATmega328) but in SMD form; has all the I/O pins (plus two extra analogue inputs); and still has a USB interface via the FT232 chip. The prize version will have the pins soldered as shown above.

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

  • Prizes will be delivered via Australia Post domestic or regular international air mail. Winners may elect for other methods upon payment of real cost;
  • Winners outside of Australia will be responsible for any taxes, fees or levies imposed by your local Governments (such as import levies, excise, VAT, etc.) upon importation of purchased goods;
  • Prizes may take up to 45 days to be received;
  • If you have won a previous competition you cannot enter;
  • The Judge’s decision is final with regards to any dispute;
  • Entries will be accepted until 2359h GMT on 4th August 2011.

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

July 28, 2011 Posted by | arduino, competition, microcontrollers, test equipment | , , , , , , , , , , , , , | Leave a Comment

Tutorial: Arduino and the NXP SAA1064 4-digit LED display driver

This is chapter thirty-nine 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.

Updated 19/01/2013

In this article we investigate controlling the NXP (formerly Philips) SAA1064 4-digit LED display driver IC with Arduino and the I2C bus interface. If you are not familiar with using the I2C bus, please read my tutorials (parts one and two) before moving on. Although the SAA1064 is not the newest on the market, it is still popular, quite inexpensive and easy to source. Furthermore as it is controlled over the I2C bus – you don’t waste any digital I/O pins on your Arduino, and you can also operate up to four SAA1064s at once (allowing 16 digits!). Finally, it has a constant-current output – keeping all the segments of your LED display at a constant brightness (which is also adjustable).  So let’s get started…

Here is an example of the SAA1064 in SOIC surface mount packaging:

It measures around 15mm in length. For use in a solderless breadboard, I have soldered the IC onto a through-hole adaptor:

The SAA1064 is also available in a regular through-hole DIP package. At this point, please download the data sheet (.pdf) as you will need to refer to it during the article. Next, our LED display examples. We need common-anode displays, and for this article we use two Agilent HDSP521G two-digit modules (data sheet [.pdf]) as shown below:

For the uninitiated – a common anode display has all the segments’ anodes connected together, with the cathodes terminated separately. For example, our LED displays are wired as such:

Notice the anodes for the left digit are pin 14, and the right digit pin 13. A device that is connected to all the cathodes (e.g. our SAA1064) will control the current flow through each element – thereby turning each segment on (and controlling the brightness) or off. Our SAA1064 is known as a current-sink as the current flows through the LED, and then sinks into the IC.

Now, let’s get it connected. There is an excellent demonstration circuit on page twelve of the data sheet that we will follow for our demonstrations:

It looks pretty straight-forward, and it is. The two transistors are standard NPN-type, such as PN2222. The two transistors are used to each turn on or off a pair of digits – as the IC can only drive digits 1+3 or 2+4 together. (When presented in real life the digits are numbered 4-3-2-1). So the pairs are alternatively turned on and off at a rapid rate, which is controlled by the capacitor between pin 2 and GND. The recommended value is 2.7 nF. At the time of writing, I didn’t have that value in stock, so chose a 3.3 nF instead. However due to the tolerance of the ceramic capacitor it was actually measured to be 2.93 nF:

So close enough to 2.7 nF will be OK. The other capacitor shown between pins 12 and 13 is a standard 0.1 uF smoothing capacitor. Pin 1 on the SAA1064 is used to determine the I2C bus address – for our example we have connected it straight to GND (no resistors at all) resulting in an address of 0×70. See the bottom page five of the data sheet for other address options. Power for the circuit can be taken from your Arduino’s 5V pin – and don’t forget to connect the circuit GND to Arduino GND. You will also use 4.7k ohm pull-up resistors on the SDA and SCL lines of the I2C bus.

The last piece of the schematic puzzle is how to connect the cathodes of the LED displays to the SAA1064. Display pins 14 and 13 are the common anodes of the digits.

The cathodes for the left-hand display module:

  • LED display pins 4, 16, 15, 3, 2, 1, 18 and 17 connect to SAA1064 pins 22, 21, 20, 19, 18, 17, 16 and 15 respectively (that is, LED pin 4 to IC pin 22, etc.);
  • LED display pins 9, 11, 10, 8, 6, 5, 12 and 7 also connect to SAA1064 pins 22, 21, 20, 19, 18, 17, 16 and 15 respectively.
The cathodes for the right-hand display module:
  • LED display pins 4, 16, 15, 3, 2, 1, 18 and 17 connect to SAA1064 pins 3, 4, 5, 6, 7, 8, 9 and 10 respectively;
  • LED display pins  9, 11, 10, 8, 6, 5, 12 and 7 also connect to SAA1064 pins 3, 4, 5, 6, 7, 8, 9 and 10 respectively.
Once your connections have been made, you could end up with spaghetti junction like this…
Now it is time to consider the Arduino sketch to control out SAA1064. Each write request to the SAA1064 requires several bytes. We either send a control command (to alter some of the SAA1064 parameters such as display brightness) or a display command (actually display numbers). For our example sketches the I2C bus address “0×70 >> 1″ is stored in the byte variable saa1064. First of all, let’s look at sending commands, as this is always done first in a sketch to initiate the SAA1064 before sending it data.
As always, we send the address down the I2C bus to awaken the SAA1064 using
Wire.beginTransmission(saa1064);
Then the next byte is the instruction byte. If we send zero:
Wire.write(B00000000);
… the IC expects the next byte down the bus to be the command byte. And finally our command byte:
Wire.write(B01000111);
The control bits are described on page six of the data sheet. However – for four-digit operation bits 0, 1 and 2 should be 1; bit 3 should be 0; and bits 4~6 determine the amount of current allowed to flow through the LED segments. Note that they are cumulative, so if you set bits 5 and 6 to 1 – 18 mA of current will flow. We will demonstrate this in detail later on.
Next, to send actual numbers to be displayed is slightly different. Note that the digits are numbered (from left to right) 4 3 2 1. Again, we first send the address down the I2C bus to awaken the SAA1064 using
Wire.beginTransmission(saa1064);
Then the next byte is the instruction byte. If we send 1, the next byte of data will represent digit 1. If that follows with another byte, it will represent digit 2. And so on. So to send data to digit 1, send
Wire.write(B00000001);
Although sending binary helps with the explanation, you can send decimal equivalents. Next, we send a byte for each digit (from right to left). Each bit in the byte represents a single LED element of the digit as well as the decimal point. Note how the elements are labelled (using A~G and DP) in the following image:
The digit bytes describe which digit elements to turn on or off. The bytes are described as such: Bpgfedcba. (p is the decimal point). So if you wanted to display the number 7, you would send B00000111 – as this would turn on elements a, b and c. To add the decimal point with 7 you would send B10000111. You can also send the byte as a decimal number. So to send the digit 7 as a decimal, you would send 7 – as 00000111 in base-10 is 7. To include the decimal point, send 135 – as 100000111 in base-10 is 135. Easy! You can also create other characters such as A~F for hexadecimal. In fact let’s do that now in the following example sketch (download):
/*
 Example 39.1 - NXP SAA1064 I2C LED Driver IC Demo I
 Demonstrating display of digits
 http://tronixstuff.wordpress.com/tutorials > chapter 39
 John Boxall July 2011 | CC by-sa-nc
 */
#include "Wire.h" // enable I2C bus
byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064 (pin 1 to GND) ****
int digits[16]={63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57, 94, 121, 113};
// these are the byte representations of pins required to display each digit 0~9 then A~F
void setup()
{
 Wire.begin(); // start up I2C bus
 delay(500);
 initDisplay();
}
void initDisplay()
// turns on dynamic mode and adjusts segment current to 12mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B01000111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 12mA segment current
 Wire.endTransmission();
}
void displayDigits()
// show all digits 0~9, A~F on all digits of display
{
 for (int z=0; z<16; z++)
 {
 Wire.beginTransmission(saa1064);
 Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
 Wire.write(digits[z]); // digit 1 (RHS)
 Wire.write(digits[z]); // digit 2
 Wire.write(digits[z]); // digit 3
 Wire.write(digits[z]); // digit 4 (LHS)
 Wire.endTransmission();
 delay(500);
 }
// now repeat but with decimal point
 for (int z=0; z<16; z++)
 {
 Wire.beginTransmission(saa1064);
 Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
 Wire.write(digits[z]+128); // digit 1 (RHS)
 Wire.write(digits[z]+128); // digit 2
 Wire.write(digits[z]+128); // digit 3
 Wire.write(digits[z]+128); // digit 4 (LHS)
 Wire.endTransmission();
 delay(500);
 }
}
void clearDisplay()
// clears all digits
{
 Wire.beginTransmission(saa1064);
 Wire.write(1); // instruction byte - first digit to control is 1 (right hand side)
 Wire.write(0); // digit 1 (RHS)
 Wire.write(0); // digit 2
 Wire.write(0); // digit 3
 Wire.write(0); // digit 4 (LHS)
 Wire.endTransmission();
}
void loop()
{
 displayDigits();
 clearDisplay();
 delay(1000);
}
/* **** We bitshift the address as the SAA1064 doesn't have the address 0x70 (ADR pin
to GND) but 0x38 and Arduino uses 7-bit addresses- so 8-bit addresses have to
be shifted to the right one bit. Thanks to Malcolm Cox */

In the function initDisplay() you can see an example of using the instruction then the control byte. In the function clearDisplay() you can see the simplest form of sending digits to the display – we send 0 for each digit to turn off all elements in each digit. The bytes that define the digits 0~9 and A~F are stored in the array digits[]. For example, the digit zero is 63 in decimal, which is B00111111 in binary – which turns on elements a,b,c,d,e and f. Finally, notice the second loop in displayDigits() – 128 is added to each digit value to turn on the decimal point. Before moving on, let’s see it in action:

Our next example revisits the instruction and control byte – we change the brightness of the digits by setting bits 4~6 in the control byte. Each level of brightness is separated into a separate function, and should be self-explanatory. Here is the sketch (download):

/*
 Example 39.2 - NXP SAA1064 I2C LED Driver IC Demo II
 Demonstrating brightness levels via adjusting segment current
 http://tronixstuff.wordpress.com/tutorials > chapter 39
 John Boxall July 2011 | CC by-sa-nc
*/
#include "Wire.h" // enable I2C bus
byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064 (pin 1 to GND)
int digits[16]={63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57, 94, 121, 113};
// these are the byte representations of pins required to display each digit 0~9 then A~F
void setup()
{
 Wire.begin(); // start up I2C bus
 delay(500);
 init12ma();
}
void init3ma()
// turns on dynamic mode and adjusts segment current to 3mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B00010111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 3mA segment current
 Wire.endTransmission();
}
void init6ma()
// turns on dynamic mode and adjusts segment current to 6mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B00100111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 6mA segment current
 Wire.endTransmission();
}
void init9ma()
// turns on dynamic mode and adjusts segment current to 9mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B00110111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 9mA segment current
 Wire.endTransmission();
}
void init12ma()
// turns on dynamic mode and adjusts segment current to 12mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B01000111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 12mA segment current
 Wire.endTransmission();
}
void init18ma()
// turns on dynamic mode and adjusts segment current to 12mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B01100111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 18mA segment current
 Wire.endTransmission();
}
void init21ma()
// turns on dynamic mode and adjusts segment current to 12mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B01110111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 21mA segment current
 Wire.endTransmission();
}
void loop()
{
 int d=250; // for delay
 // first, light up all segments
 Wire.beginTransmission(saa1064);
 Wire.write(0); // instruction byte - Zero means the next byte is the control byte
 Wire.write(B01001111); // set current and bit 3 to 1 for all segments on
 Wire.endTransmission();
// now loop through the brightness levels
 do
 {
 init3ma();
 delay(d);
 init6ma();
 delay(d);
 init9ma();
 delay(d);
 init12ma();
 delay(d);
 init18ma();
 delay(d);
 init21ma();
 delay(d);
 }
 while (1>0);
}

And again, see it in action:

For our final example, there is a function displayInteger(a,b) which can be used to easily display numbers from 0~9999 on the 4-digit display. The parameter a is the number to display, and b is the leading-zero control – zero – off, one – on. The function does some maths on the integet to display and separates the digits for each column, then sends them to the SAA1064 in reverse order. By now you should be able to understand the following sketch (download):

/*
 Example 39.3 - NXP SAA1064 I2C LED Driver IC Demo III
 Displaying numbers on command
 http://tronixstuff.wordpress.com/tutorials > chapter 39
 John Boxall July 2011 | CC by-sa-nc
 */
#include "Wire.h" // enable I2C bus
byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064 (pin 1 to GND)
int digits[17]={
 63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57, 94, 121, 113, 0};
// these are the byte representations of pins required to display each digit 0~9 then A~F, and blank digit
void setup()
{
 Wire.begin(); // start up I2C bus
 delay(500);
 initDisplay();
}
void initDisplay()
// turns on dynamic mode and adjusts segment current to 12mA
{
 Wire.beginTransmission(saa1064);
 Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
 Wire.write(B01000111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 12mA segment current
 Wire.endTransmission();
}
void clearDisplay()
{
 Wire.beginTransmission(saa1064);
 Wire.write(1); // start with digit 1 (right-hand side)
 Wire.write(0); // blank digit 1
 Wire.write(0); // blank digit 2
 Wire.write(0); // blank digit 3
 Wire.write(0); // blank digit 4
 Wire.endTransmission();
}
void displayInteger(int num, int zero)
// displays the number 'num'
// zero = 0 - no leading zero
// zero = 1 - leading zero
{
 int thousand, hundred, ten, one;
 // breakdown number into columns
 thousand = num/1000;
 hundred = (num-(thousand*1000))/100;
 ten = (num-((thousand*1000)+(hundred*100)))/10;
 one = num-((thousand*1000)+(hundred*100)+(ten*10));
 if (zero==1) // yes to leading zero
 {
 Wire.beginTransmission(saa1064);
 Wire.write(1);
 Wire.write(digits[one]);
 Wire.write(digits[ten]);
 Wire.write(digits[hundred]);
 Wire.write(digits[thousand]);
 Wire.endTransmission();
 delay(10);
 }
 else
 if (zero==0) // no to leading zero
 {
 if (thousand==0) { thousand=16; }
 if (hundred==0 && num<100) { hundred=16; }
 if (ten==0 && num<10) { ten=16; }
 Wire.beginTransmission(saa1064);
 Wire.write(1);
 Wire.write(digits[one]);
 Wire.write(digits[ten]);
 Wire.write(digits[hundred]);
 Wire.write(digits[thousand]);
 Wire.endTransmission();
 delay(10);
 }
}
void loop()
{
 for (int a=0; a<251; a++)
 // display 0~250 without leading zero
 {
 displayInteger(a,0);
 delay(20);
 }
 delay(1000);
 clearDisplay();
 delay(1000);
for (int a=0; a<1000; a++)
 // display 0~999 with leading zero
 {
 displayInteger(a,1);
 delay(5);
 }
}

And the final example in action:

So there you have it – another useful IC that can be used in conjunction with our Arduino systems to make life easier and reduce the required digital output 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.

July 21, 2011 Posted by | arduino, education, I2C, microcontrollers | , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 26 Comments

Kit Review – Snootlab Mémoire SD card/RTC/prototyping shield

Hello Readers

In this article we will examine another product from a bundle sent for review by Snootlab, a Toulouse, France-based company that in their own words:

… designs and develops electronic products with an Open Hardware and Open Source approach. We are particularly specialized in the design of new shields for Arduino. The products we create are licensed under CC BY-SA v3.0 (as shown in documents associated with each of our creations). In accordance with the principles of the definition of Open Source Hardware (OSHW), we have signed it the 10th February 2011. We wish to contribute to the development of the ecosystem of “do it yourself” through original designs of products, uses and events.

Furthermore, all of their products are RoHS compliant and as part of the Open Hardware commitment, all the design files are available from the Snootlab website.

The subject of the review is the Snootlab Mémoire – an SD card data logging shield with on-board DS1307 real time clock [and matching backup battery] and prototyping area. It uses the standard SdFat library to write to normal SD memory cards formatted in FAT16 or FAT32. You can download the library from here. The real time clock IC is an easy to use I2C-interface model, and I have documented its use in great detail in this tutorial.

Once again, shield assembly is simple and quite straightforward. You can download an illustrated assembly guide from here, however it is in French. But everything you need to know is laid out on the PCB silk-screen, or the last page of the instructions. The it arrives in a reusable ESD bag:

… and all the required parts are included – including an IC socket and the RTC backup battery:

… the PCB is thick, with a very detailed silk-screen. Furthermore, it arrives with the SD card and 3.3V LDO (underneath) already pre-soldered – a nice touch:

The order of soldering the components is generally a subjective decision, and in this case I started with the resistors:

… and then worked my way out, but not fitting the battery nor IC until last. Intrestingly, the instructions require the crystal to be tacked down with some solder onto the PCB. Frankly I didn’t think it would withstand the temperature, however it did and all is well:

Which leaves us with a fully-assembled Mémoire shield ready for action:

Please note that a memory card is not included with the kit. If you are following along with your own Mémoire, the first thing to do after inserting the battery, IC and shield into your Arduino board and run some tests to ensure all is well. First thing is to test the DS1307 real-time clock IC. You can use the following sketch from chapter seven of my Arduino tutorial series: (download sketch file)

/*
 Example 7.3
 reading and writing to the Maxim DS1307 real time clock IC
 tronixstuff.com/tutorials
 based on code by Maurice Ribble
 17-4-2008 - http://www.glacialwanderer.com/hobbyrobotics
*/

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// 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) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock

// Assumes you're passing in valid numbers

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();
}

// 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 setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);

  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.

  second = 0;
  minute = 33;
  hour = 22;
  dayOfWeek = 2;
  dayOfMonth = 4;
  month = 07;
  year = 11;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  Serial.print(hour, DEC);// convert the byte variable to a decimal number when being displayed
  Serial.print(":");
  if (minute<10)
  {
      Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
      Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print("  ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print("  Day of week:");
  switch(dayOfWeek){
  case 1:
    Serial.println("Sunday");
    break;
  case 2:
    Serial.println("Monday");
    break;
  case 3:
    Serial.println("Tuesday");
    break;
  case 4:
    Serial.println("Wednesday");
    break;
  case 5:
    Serial.println("Thursday");
    break;
  case 6:
    Serial.println("Friday");
    break;
  case 7:
    Serial.println("Saturday");
    break;
  }
  //  Serial.println(dayOfWeek, DEC);
  delay(1000);
}

If you are unsure about using I2C, please review my tutorial which can be found here.

Don’t forget to update the time and date data in void setup(), and also comment out the setDateDS1307() function and upload the sketch a second time. The sketch output will be found on the serial monitor box – such as:

Those of you familiar with the DS1307 RTC IC know that it can generate a nice 1 Hz pulse. To take advantage of this the SQW pin has an access hole on the PCB, beetween R10 and pin 8 of the IC:

For instruction on how to activate the SQW output, please visit the last section of this tutorial.

The next test is the SD card section of the shield. If you have not already done so, download and install the SdFat libary. Then, in the Arduino IDE, select File > Examples > SdFat > SdFatInfo. Insert the formatted (FAT16/32) SD card into the shield, upload the sketch, then open the serial monitor. You should be presented with something like this:

As you can see the sketch has returned various data about the SD card. Finally, let’s log some data. You can deconstruct the excellent example that comes with the SdFat library titled SdFatAnalogLogger (select File > Examples > SdFat > SdFatAnalogLogger). Using the functions:

file.print();
file.println();

you can “write” to the SD card in the same way as you would the serial output (that is, the serial monitor).

If you have reached this far without any errors – Congratulations! You’re ready to log. If not, remove the battery, SD card and IC from your shield (you used the IC socket, didn’t you?). Check the polarised components are in correctly, double-check your soldering and then reinsert the IC, shield and battery and try again. If that fails, support is available on the Snootlab website, and there is also a 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. Stay tuned for the final Snootlab product review.

Snootlab products including the Snootlab Mémoire are available directly from their website.

High-resolution images available on flickr.

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.

[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! 

July 18, 2011 Posted by | arduino, education, kit review | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 1 Comment

Learn to solder with David L. Jones!

Hello Readers

How is your soldering? Have you always wanted to improve your soldering skills, or never heated an iron in your life and didn’t know where to start? No matter your level of skill you could do a lot worse than review the following video blogs in this article by David L. Jones.

Who? 

[David] shares some of his 20 years experience in the electronics design industry in his unique non-scripted naturally overly enthusiastic and passionate style.
Bullsh!t and political correctness don’t get a look-in.

Dave started out in hobby electronics over 30 years ago and since then has worked in such diverse areas as design engineering, production engineering, test engineering, electro-mechanical engineering, that wacky ISO quality stuff, field service, concept design, underwater acoustics, ceramic sensors, military sonar systems, red tape, endless paperwork trails, environmental testing, embedded firmware and software application design, PCB design (he’s CID certified), power distribution systems, ultra low noise and low power design, high speed digital design, telemetry systems, and too much other stuff he usually doesn’t talk about.

He has been published in various magazines including: Electronic Today International, Electronics Australia, Silicon Chip, Elektor, Everyday Practical Electronics (EPE), Make, and ReNew.

Few people know Dave is also a world renowned expert and author on Internet Dating, a qualified fitness instructor, geocacher, canyoner, and environmentalist.

Regular readers of this website would know that I rarely publish outside material – however the depth and quality of the tutorials make them a must-see for beginners and experienced people alike. Furthermore, if you have the bandwidth they can be viewed in 1080p. And as a fellow Australian I’m proud to support Dave and his efforts. So I hope you can view, enjoy and possibly learn from the following videos:

The first covers the variety of tools you would use:

And the second covers through-hole PCB soldering:

The third covers surface-mount soldering:

Finally, watch the procedure for soldering a tiny SMD IC using the ‘dead bug’ method:

And for something completely different:

If you enjoyed those videos then don’t forget to check out what’s new on Dave’s eevblog website and forum. Videos shown are (C) David L. Jones 2011 and embedded with permission.

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.

[Disclaimer - I really enjoy the content at eevblog.com]

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

July 14, 2011 Posted by | education, hardware hacking, learning electronics | , , , , , , , , , , , , , , , , , | 2 Comments

Review: The Gravitech Arduino Nano family

Hello Readers

In this article we will examine a variety of products received for review from Gravitech in the United States – the company that designed and build the Arduino Nano. We have a Nano and some very interesting additional modules to have a look at.

So let’s start out review with the Arduino Nano. What is a Nano? A very, very small version of our Arduino Duemilanove boards. It contains the same microcontroller (ATmega328) but in SMD form; has all the I/O pins (plus two extra analogue inputs); and still has a USB interface via the FT232 chip. But more on that later. Nanos arrive in reusable ESD packaging which is useful for storage when not in use:

Patriotic Americans should note that the Nano line is made in the USA. Furthermore, here is a video clip of Nanos being made:

For those who were unsure about the size of the Nano, consider the following images:

You can easily see all the pin labels and compare them to your Duemilanove or Uno board. There is also a tiny reset button, the usual LEDs, and the in circuit software programmer pins. So you don’t miss out on anything by going to a Nano. When you flip the board over, the rest of the circuitry is revealed, including the FTDI USB>serial converter IC:

Those of you familiar with Arduino systems should immediately recognise the benefit of the Nano – especially for short-run prototype production. The reduction in size really is quite large. In the following image, I have traced the outline of an Arduino Uno and placed the Nano inside for comparison:

So tiny… the board measures 43.1mm (1.7″) by 17.8mm (0.7″). The pins on this example were pre-soldered – and are spaced at standard 2.54mm (0.1″) intervals – perfect for breadboarding or designing into your own PCB -  however you can purchase a Nano without the pins to suit your own mounting purposes. The Nano meets all the specifications of the standard Arduino Duemilanove-style boards, except naturally the physical dimensions.

Power can be supplied to the Nano via the USB cable; feeding 5V directly into the 5V pin, or 7~12 (20 max, not recommended) into the Vin pin. You can only draw 3.3V at up to 50 mA when the Nano is running on USB power, as the 3.3V is sourced from the FTDI USB>serial IC. And the digital I/O pins still allow a current draw up to 40 mA each. From a software perspective you will not have any problems, as the Nano falls under the same board classification as the (for example) Arduino Duemilanove:

Therefore one could take advantage of all the Arduino fun and games – except for the full-size shields. But as you will read soon, Gravitech have got us covered on that front. If the Arduino system is new to you, why not consider following my series of tutorials? They can be found here. In the meanwhile, to put the size into perspective – here is a short video of a Nano blinking some LEDs!

Now back to business. As the Nano does not use standard Arduino shields, the team at Gravitech have got us covered with a range of equivalent shields to enable all sorts of activities. The first of this is their Ethernet and microSD card add-on module:

and the underside:

Again this is designed for breadboarding, or you could most likely remove the pins if necessary. The microSD socket is connected as expected via the SPI bus, and is fully compatible with the default Arduino SD library. As shown in the following image the Nano can slot directly into the ethernet add-in module:

The Ethernet board requires an external power supply, from 7 to 12 volts DC. The controller chip is the usual Wiznet 5100 model, and therefore the Ethernet board is fully compatible with the default Ethernet Arduino library. We tested it with the example web server sketch provided with the Arduino IDE and it all just worked.

The next add-on module to examine is the 2MOTOR board:

… and the bottom:

Using this module allows control of two DC motors with up to two amps of current each via pulse-width modulation. Furthermore, there is a current feedback circuit for each motor so you measure the motor load and adjust power output – interesting. So a motorised device could sense when it was working too hard and ease back a little (like me on a Saturday). All this is made possible by the use of the common L298 dual full-bridge motor driver IC. This is quite a common motor driver IC and is easy to implement in your sketches. The use of this module and the Nano will help reduce the size of any robotics or motorised project. Stay tuned for use of this board in future articles.

Next in this veritable cornucopia of  add-on modules is the USBHOST board:

turning it over …

Using the Maxim MAX3421E host controller IC you can interface with all sorts of devices via USB, as well as work with the new Android ADK. The module will require an external power supply of between 7 and 12 volts DC, with enough current to deal with the board, a Nano and the USB device under control – one amp should be more than sufficient. I will be honest and note that USB and Arduino is completely new to me, however it is somewhat fascinating and I intend to write more about using this module in the near future. In the meanwhile, many examples can be found here.

For a change of scene there is also a group of Xbee wireless communication modules, starting with the Xbee add-on module:

The Xbee itself is not included, only shown for a size comparison. Turning the module over:

It is nice to see a clearly-labelled silk screen on the PCB. If you are unfamiliar with using the Xbee wireless modules for data communication, you may find my introductory tutorial of interest. Furthermore, all of the Gravitech Nano modules are fully software compatible with my tutorial examples, so getting started will be a breeze. Naturally Gravitech also produce an Xbee USB interface board, to enable PC communication over your wireless modules:

Again, note that the Xbee itself is not included, however they can be supplied by Gravitech. Turning the board over reveals another highly-detailed silk screen:

All of the Gravitech Xbee modules support both series 1.0 and 2.5 Xbees, in both standard and professional variants. The USB module also supports the X-CTU configuration software from Digi.

Finally – leaving possibly the most interesting part until last, we have the MP3 Player add-on board:

and on the B-side:

The MP3 board is designed around the VS1053B MP3 decoder IC. It can also decode Ogg Vorbis, AAC, WMA and MID files. There is a 3.5mm stereo output socket to connect headphones and so on. As expected, the microSD card runs from the SPI pins, however SS is pin 4. Although it may be tempting to use this to make a home-brew MP3 player, other uses could include: recorded voice messages for PA systems such as fire alarm notices, adding sound effects to various projects or amusement machines, or whatever else you can come up with.

Update – We have examined the MP3 board in more detail with a beginner’s tutorial.

The Arduino Nano and related boards really are tiny, fully compatible with their larger brethren, and will prove very useful. Although this article was an introductory review, stay tuned for further projects and articles that will make use of the Nano and other boards. If you have any questions or enquiries please direct them to Gravitech via their contact page. Gravitech products including the Arduino Nano family are available directly from their website or these 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.

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

High resolution photos are available on flickr.

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

July 11, 2011 Posted by | arduino, ethernet, microcontrollers, mp3, supplier review, xbee | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment

Tutorial: Arduino and a Thermal Printer

Use inexpensive thermal printers with Arduino in chapter thirty-eight 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.

Updated 05/02/2013

In this article we introduce the inexpensive thermal printer that has recently become widely available from Sparkfun and their resellers. The goal of the article is to be as simple as possible so you can get started without any problems or confusion. In the past getting data from our Arduino to a paper form would either have meant logging it to an SD card then using a PC to finish the job, or perhaps viewing said data on an LCD then writing it down. Not any more – with the use of this cheap and simple serial printer. Before we get started, here is a short demonstration video of it in action:


Not bad at all considering the price. Let’s have a look in more detail. Here is the printer and two matching rolls of thermal paper:

… and the inside of the unit:

Loading paper is quite simple, just drop the roll in with the end of the paper facing away from you, pull it out further than the top of the front lip, then close the lid. The paper rolls required need to be 57mm wide and have a diameter of no more than 39mm. For example. There is a piece of white cardboard stuck to the front – this is an economical cover that hides some of the internals. Nothing of interest for us in there. The button next to the LED on the left is for paper advance, and the LED can blink out the printer status.

From a hardware perspective wiring is also very simple. Looking at the base of the printer:

… there are two connections. On the left is DC power, and data on the right. Thankfully the leads are included with the printer and have the plugs already fitted – a great time saver. You may also want to fit your own rubber feet to stop the printer rocking about.

Please note – you need an external power supply with a voltage of between 5 and 9 volts DC that can deliver up to 1.5 amps of current. When idling the printer draws less than 10 milliamps, but when printing it peaks at around 1.47 A. So don’t try and run it from your Arduino board. However the data lines are easy, as the printer has a serial interface we only need to connect printer RX to Arduino digital 3, and printer TX to Arduino digital 2, and GND to … GND! We will use a virtual serial port on pins 2 and 3 as 0 and 1 will be taken for use with the serial monitor window for debugging and possible control purposes.

If you want to quickly test your printer – connect it to the power, drop in some paper, hold down the feed button and turn on the power. It will quickly produce a test print.

Next we need to understand how to control the printer in our sketches. Consider this very simple sketch (download):

/*
 Example 38.1 - Sparkfun Thermal Printer Test (COM-10438)
 http://tronixstuff.wordpress.com/tutorials > chapter 38
 Based on code by Nathan Seidle of Spark Fun Electronics 2011
*/
#include <SoftwareSerial.h>
SoftwareSerial Thermal(2, 3);
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15; 
char printBreakTime = 15;
void setup() 
{
 Serial.begin(57600); // for debug info to serial monitor
 Thermal.begin(19200); // to write to our new printer
 initPrinter();
}
void initPrinter()
{
 //Modify the print speed and heat
 Thermal.write(27);
 Thermal.write(55);
 Thermal.write(7); //Default 64 dots = 8*('7'+1)
 Thermal.write(heatTime); //Default 80 or 800us
 Thermal.write(heatInterval); //Default 2 or 20us
 //Modify the print density and timeout
 Thermal.write(18);
 Thermal.write(35);
 int printSetting = (printDensity<<4) | printBreakTime;
 Thermal.write(printSetting); //Combination of printDensity and printBreakTime
 Serial.println();
 Serial.println("Printer ready"); 
}
void loop()
{
 Thermal.println(" Visit http://tronixstuff.com ");
 Thermal.write(10); //Sends the LF to the printer, advances the paper
 Thermal.print(" Millis = ");
 Thermal.println(millis()); 
 Thermal.write(10);
 Thermal.write(10); 
 do { } while (1>0);
}

After ensuring your printer is connected as described earlier, and has the appropriate power supply and paper – uploading the sketch will result in the following:

Now that the initial burst of printing excitement has passed, let’s look at the sketch and see how it all works. The first part:

#include <SoftwareSerial.h>
SoftwareSerial Thermal(2, 3); // printer RX to digital 2, printer TX to digital 3

configures the virtual serial port and creates an instance for us to refer to when writing to the printer. Next, four variables are defined. These hold parameters used for configuring the printer. As the printer works with these settings there is no need to alter them, however if you are feeling experimental nothing is stopping you. Next we have the function initPrinter(). This sets a lot of parameters for the printer to ready itself for work. We call initPrinter() only once – in void setup(); For now we can be satisfied that it ‘just works’.

Now time for action – void loop(). Writing text to the printer is as simple as:

Thermal.print("text");

You can also use .println to advance along to the next line. Generally this is the same as writing to the serial monitor with Serial.println() etc. So nothing new there. Each line of text can be up to thirty-two characters in length.

The next thing to concern ourselves with is sending commands to the printer. You may have noticed the line

     Thermal.write(10);

This sends the command to advance to the next line (in the old days we would say ‘carriage return and line feed’). There are many commands available to do various things.  At this point you will need to refer to the somewhat amusing user manual.pdf. Open it up and have a look at section 5.2.1 on page ten. Notice how each command has an ASCII, decimal and hexadecimal equivalent? We will use the decimal command values. So to send them, just use:

Thermal.write(value);

Easy. If the command has two or more values (for example, to turn the printer offline [page 11] ) – just send each value in a separate statement. For example:

Thermal.write(27);
Thermal.write(61);
int zero=0;
Thermal.write(zero);

… will put the printer into offline mode. Notice how we used the variable “zero” for 0 – you can’t send a zero by itself. So we assign it to the variable and send that instead. Odd.

For out next example, let’s try out a few more commands:

  • Underlined text (the printer seemed to have issues with thick underlining, however your experience may vary)
  • Bold text
  • Double height and width
Here is the sketch (download):
/*
 Example 38.2 - Sparkfun Thermal Printer Test II (COM-10438)
 http://tronixstuff.wordpress.com/tutorials > chapter 38
 Based on code by Nathan Seidle of Spark Fun Electronics 2011
 */
#include <SoftwareSerial.h>
SoftwareSerial Thermal(2, 3);
int zero=0;
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15; 
char printBreakTime = 15;
void setup() 
{
 Serial.begin(57600); // for debug info to serial monitor
 Thermal.begin(19200); // to write to our new printer
 initPrinter();
}
void initPrinter()
{
 //Modify the print speed and heat
 Thermal.write(27);
 Thermal.write(55);
 Thermal.write(7); //Default 64 dots = 8*('7'+1)
 Thermal.write(heatTime); //Default 80 or 800us
 Thermal.write(heatInterval); //Default 2 or 20us
 //Modify the print density and timeout
 Thermal.write(18);
 Thermal.write(35);
 int printSetting = (printDensity<<4) | printBreakTime;
 Thermal.write(printSetting); //Combination of printDensity and printBreakTime
 Serial.println();
 Serial.println("Printer ready"); 
}
void loop()
{
 // underline - one pixel
 Thermal.write(27);
 Thermal.write(45); 
 Thermal.write(1);
 Thermal.println("Underline - thin");
 Thermal.println("01234567890123456789012345678901"); 
 Thermal.write(10);
// underline - two pixels
 Thermal.write(27); 
 Thermal.write(45);
 Thermal.write(2); 
 Thermal.println("Underline - thick");
 Thermal.println("01234567890123456789012345678901"); 
 Thermal.write(10);
// turn off underline
 Thermal.write(27); 
 Thermal.write(45);
 Thermal.write(zero);
 delay(3000);
 Thermal.write(10);
// bold text on
 Thermal.write(27); 
 Thermal.write(32);
 Thermal.write(1);
 Thermal.println(" #### Bold text #### ");
 Thermal.println("01234567890123456789012345678901"); 
 delay(3000);
// bold text off
 Thermal.write(27); 
 Thermal.write(32);
 Thermal.write(zero);
 Thermal.write(10); //Sends the LF to the printer, advances the paper
 delay(3000);
// height/width enlarge
 Thermal.write(29); 
 Thermal.write(33);
 Thermal.write(255);
 Thermal.println("ABCDEF");
 Thermal.println("012345"); 
 delay(3000);
// back to normal
 Thermal.write(29); 
 Thermal.write(33);
 Thermal.write(zero);
 delay(3000);
Thermal.write(10);
 Thermal.println("Back to normal...");
 Thermal.write(10);
 Thermal.write(10); 
 do { } while (1>0); // do nothing
}

And the results:

Frankly bold doesn’t look that bold, so I wouldn’t worry about it too much. However the oversized characters could be very useful, and still print relatively quickly.

Next on our list are barcodes. A normal UPC barcode has 12 digits, and our little printer can generate a variety of barcode types – see page twenty-two of the user manual. For our example we will generate UPC-A type codes and an alphanumeric version. Alphanumeric barcodes need capital letters, the dollar sign, percent sign, or full stop. The data is kept in an array of characters named … barCode[]  and barCode[]2. Consider the functions printBarcode(), printBarcodeThick()  and printBarcodeAlpha() in the following example sketch (download):

/*
 Example 38.3 - Sparkfun Thermal Printer Test III (COM-10438)
 http://tronixstuff.wordpress.com/tutorials > chapter 38
 Based on code by Nathan Seidle of Spark Fun Electronics 2011
 */
#include <SoftwareSerial.h>
SoftwareSerial Thermal(2, 3);
int heatTime = 80;
int heatInterval = 255;
char printDensity = 15; 
char printBreakTime = 15;
char barCode[]={ '9','2','3','0','5','6','4','8','9','8','4','4'};
char barCode2[]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P' };
int zero=0;
void setup() 
{
 Serial.begin(57600); // for debug info to serial monitor
 Thermal.begin(19200); // to write to our new printer
 initPrinter();
}
void initPrinter()
{
 //Modify the print speed and heat
 Thermal.write(27);
 Thermal.write(55);
 Thermal.write(7); //Default 64 dots = 8*('7'+1)
 Thermal.write(heatTime); //Default 80 or 800us
 Thermal.write(heatInterval); //Default 2 or 20us
 //Modify the print density and timeout
 Thermal.write(18);
 Thermal.write(35);
 int printSetting = (printDensity<<4) | printBreakTime;
 Thermal.write(printSetting); // Combination of printDensity and printBreakTime
 Serial.println();
 Serial.println("Printer ready"); 
}
void printBarcode(char zz[])
{
 Thermal.write(29); //GS
 Thermal.write(107); //k
 Thermal.write(zero); //m = 0
 for (int z=0; z<12; z++)
 {
 Thermal.write(zz[z]);
 }
 Thermal.write(zero); // bar code terminator
 delay(3000); // necessary delay
 Thermal.write(10); 
 Thermal.write(10); 
 Thermal.write(10); 
}
void printBarcodeThick(char zz[])
{
 Thermal.write(29); // specified height of barcode
 Thermal.write(104); 
 Thermal.write(200); // 200 pixels high (default is 50)

 Thermal.write(29); //GS
 Thermal.write(107); //k
 Thermal.write(zero); //m = 0
 for (int z=0; z<12; z++)
 {
 Thermal.write(zz[z]);
 }
 Thermal.print(zero); // bar code terminator
 delay(3000); // necessary delay
 Thermal.write(29); // specified height of barcode
 Thermal.write(104); 
 Thermal.write(50); // need to set back to 50 pixel height
 delay(3000);
 Thermal.write(10); 
 Thermal.write(10); 
 Thermal.write(10); 
}
void printBarcodeAlpha(char zz[])
{
 Thermal.write(29); //GS
 Thermal.write(107); //k
 Thermal.write(4); //m = 0
 for (int z=0; z<16; z++)
 {
 Thermal.write(zz[z]);
 }
 // Thermal.print(zero); // bar code terminator
 delay(3000); // necessary delay
 Thermal.write(10); 
 Thermal.write(10); 
 Thermal.write(10); 
}
void loop()
{
 printBarcode(barCode);
 printBarcodeThick(barCode);
 printBarcodeAlpha(barCode2);
 do { } while (1>0); // do nothing
}

Notice in printBarcodeThick() we make use of the ability to change the vertical size of the barcode – the height in pixels is the third parameter in the group. And here is the result:

So there you have it – another practical piece of hardware previously considered to be out of our reach – is now under our control. Now you should have an understanding of the basics and can approach the other functions in the user guide with confidence. Please keep in mind that the price of this printer really should play a large part in determining suitability for a particular task. It does have issues printing large blocks of pixels, such as the double-width underlining and inverse text. This printer is great but certainly not for commercial nor high-volume use. That is what professional POS printers from Brother, Star, Epson, etc., are for. However for low-volume, personal or hobby use this printer is certainly a deal. As always, now it is up to you and your imagination to put this to use or get up to other shenanigans.

This article would not have been possible without the example sketches provided by Nathan Seidle, the founder and CEO of Sparkfun. If you meet him, shout him a beer.  Please don’t knock off bus tickets or so on. I’m sure there are heavy penalties for doing so if caught.

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.

July 8, 2011 Posted by | arduino, COM-10438, COM-10560, education, microcontrollers, printer, sparkfun, thermal, tutorial | , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment

Kit Reviews: Snootlab Power ScrewShield and I2C Power Protoshield

Hello Readers

In this article we will examine the first two products from a bundle sent for review by Snootlab, a Toulouse, France-based company that in their own words:

… designs and develops electronic products with an Open Hardware and Open Source approach. We are particularly specialized in the design of new shields for Arduino. The products we create are licensed under CC BY-SA v3.0 (as shown in documents associated with each of our creations). In accordance with the principles of the definition of Open Source Hardware (OSHW), we have signed it the 10th February 2011. We wish to contribute to the development of the ecosystem of “do it yourself” through original designs of products, uses and events.

Furthermore, all of their products are RoHS compliant and as part of the Open Hardware commitment, all the design files are available from the Snootlab website.

First, let’s examine the Power Screwshield kit. This is a feature-laden prototyping shield suitable for Arduino Uno and compatible series boards. It can be used with the Mega, however not all of the I/O pins will be available.

Apart from obvious use as a prototyping shield, there are also three other useful features:

  • space for a 16-pin SOIC SMD part in the prototyping area;
  • a full line of screw terminals that connect to all the shield pin connections (in a similar way to the Wingshield Screwshield);
  • and a socket to allow power to be sourced from a standard computer ATX power supply, which brings 5V and 12V DC to the shield. I have never seen this implemented on a shield in the past – a very novel and useful idea.
If you are unfamiliar with the ATX power supply options, consider this image of the tronixstuff bench PC’s internals:
.
.
The connector we would use is the one with the four round pins in a single row. In recent times using PC power supplies as bench power supply units has become quite common, so the designers at Snootlab have taken advantage of this in a very clever way by allowing their Power ScrewShield to use these power supplies.
Assembly of the shield is simple and well documented. Although it is self-explanatory, you can download an illustrated guide from here. The kit is packaged in a reusable ESD bag:

… which contains all the necessary parts:

… and a very high quality PCB:

The PCB thickness is over 1mm, and as you can see from the image above the silk-screening describes all the areas of the PCB in a detailed manner. Note that this shield is much larger than a standard Arduino shield – this becomes obvious when compared with a standard prototyping shield:

Assembly was very smooth and quick. There are a couple of things to watch out for, for example you need to slide the terminal blocks together so that they are flush on the sides, such as:

… if you want to enable the 12V DC rail from the ATX power lead, short out the jumper SJ1 with a blob of solder:

… when soldering the PC power connector, be sure to make the clamp bracket flush with the socket, for example:

… and finally, to enable use of the shield’s LED, you need to cut the track in this area on the underside of the PCB:

Although at first the introduction of another Arduino prototyping shield may not have seemed that interesting – this version from Snootlab really goes all out to cover almost every possible need in a shield all at the same time. Sure, it is a lot larger – but none of the board space is wasted – and those terminal blocks would be very hand for making some more permanent-style prototypes with lots of external wiring.  And the ability to accept power from a PC ATX-style power supply unit is certainly original and possibly very useful depending on your application. So if you need to create something that needs a lot of power, a lot of prototyping space, and a lot of wiring – this is the protoshield for you.

For the second half of the review we have the Snootlab I2C Power Protoshield. This is another example of an Arduino prototyping shield with some interesting twists. Apart from employing the same PC power connector as used with the Power ScrewShield, this shield is designed for hard-core I2C-bus enthusiasts. (What’s I2C? Check my tutorials). This is due to the 10-pin HE connector on the edge of the board – it contains pins for SCL, SDA, 3.3V, 5V and GND. With this you could use you own cable connections to daisy-chain other devices communicating via the I2C bus. Again, the shield is a kit and assembly was simple.

Like other Snootlab products, the kit arrives in a reusable ESD bag:

… with a high-quality thick PCB that has a very detailed silk-screen layer:

… and all the required parts are included:

When soldering in the shield connectors, using another shield as a jig can save time:

And we’re finished:

One could also mount a small solderless breadboad on the I2C Power Protoshield:

One great feature is the inclusion of an NCP1117DT33 3.3V 1A voltage regulator. Using this you can source 3.3 volts at up to one amp of current (only) when using the PC power supply connection. This is a great idea, as in the past it can be too easy to accidentally burn out the FTDI chip on an Arduino Duemilanove by drawing too much current from the 3.3V pin. The use of the external 3.3V supply is controlled by a jumper on the header pins here:

Finally, in the image above you can see the area for external I2C pull-up resistors. Generally with our Arduino the internal pull-up resistors in the microcontroller are adequate, however with many I2C devices in use (e.g. eight 24LC512 EEPROMS!) external pull-ups are required.

After examining the two shields I am impressed with the quality of the components and PCBs, as well as the interesting features described in the review. Theyare certainly unique and very much useful if required, especially the PC power supply connections. Support is available on the Snootlab website, and there is also a customer forum in French (use Google Translate). However the people at Snootlab converse in excellent English and have been easy to contact via email if you have any questions. Stay tuned for more interesting Snootlab product reviews.

Snootlab products including the I2C Power Protoshield and the Power ScrewShield are available directly from their website.

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.

[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! 

July 4, 2011 Posted by | arduino, kit review, microcontrollers | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 13 Comments

Project – Single button combination lock

Time for something different  - a single button combination lock. Allow me to explain…

Updated 18/03/2013

Normally a combination lock would require the entry of a series of unique numbers in order to unlock something or start an action. For example:

(image information)

A more contemporary type of lock could be controlled electronically, for example by a keypad where the user enters a series of digits to cause something to happen. Such as the keypad on this dodgy $30 safe from Officeworks:

As you can see there is a button for each digit. You would think that this would be a good idea –  however people can watch you enter the digits, or users can be silly enough to write down the combination somewhere. In some cases the more cunning monkeys have even placed cameras that can observe keypads to record people entering the combination. There must be a better way. Possibly! However in the meanwhile you can consider my idea instead – just have one button. Only one button – and the combination is made up of the time that elapses between presses of the button. There are many uses for such an odd lock:

  • A type of combination lock that controls an electric door strike, or activates a device of some sort;
  • A way of testing mind-hand coordination for skill, or the base of a painfully frustrating game;
  • Perhaps an interlock on motor vehicle to prevent drink driving. After a few drinks there’s no way you could get the timing right. Then again, after a double espresso or two you might have problems as well.
How does it work? Consider the following:

We measure the duration of time between each press of the button (in this case – delay 1~4). These delay times are then compared against values stored in the program that controls the lock. It is also prudent to allow for some tolerance in the user’s press delay – say plus or minus ten to fifteen percent. We are not concerned with the duration of each button press, however it is certainly feasible.

To create this piece of hardware is quite easy, and once again we will use the Arduino way of doing things. For prototyping and experimenting it is simple enough to create with a typical board such as a Uno or Eleven and a solderless breadboard – however to create a final product you could minimise it by using a bare-bones solution (as described here). Now let’s get started…

For demonstration purposes we have a normally-open button connected to digital pin 2 on our Arduino-compatible board using the 10k ohm pull down resistor as such:

The next thing to do is determine our delay time values. Our example will use five presses, so we measure four delays. With the following sketch, you can generate the delay data by pushing the button yourself – the sketch will return the delay times on the serial monitor (download).

/*
  Single-button combination lock
  Delay Time data generation sketch - John Boxall June 2011
  http://tronixstuff.wordpress.com/projects | CC by-sa-nc
*/

int count=0;
unsigned long a[]={0,0,0,0,0,0};
unsigned long del[]={0,0,0,0,0};

void setup()
{
  pinMode(2, INPUT);
  Serial.begin(115200);
  Serial.println("Ready...");
}

void dataCapture()
{
  a[count]=millis();
  delay(500); // for button debounce, your value may differ
  count++;
}

void displayData()
{
    // calcualate delays between keypresses
    del[0]=a[1]-a[0];
    del[1]=a[2]-a[1];
    del[2]=a[3]-a[2];
    del[3]=a[4]-a[3];

    // display delay data for use in combination lock sketch
    for (int a=0; a<4; a++)
    {
      Serial.println();
      Serial.print("Delay ");
      Serial.print(a);
      Serial.print(" use ");
      Serial.print(del[a]);
      Serial.println(" ms");
    }
    Serial.println("- - - - - - - - -");
    count=0;
}

void loop()
{
  if (digitalRead(2)==HIGH)
  {
    dataCapture();
  }
  if (count>4)
  {
    displayData();
  }
}

So what’s going on the this sketch? Each time the button is pressed a reading of millis() is taken and stored in an array. [More on millis() in the tutorial]. Once the button has been pressed five times, the difference in time between each press is calculated and stored in the array del[]. Note the use of a 500 ms delay in the function dataCapture(), this is to prevent the button bouncing and will need to be altered to suit your particular button. Finally the delay data is then displayed on the serial monitor. For example:

The example was an attempt to count one second between each press. This example also illustrates the need to incorporate some tolerance in the actual lock sketch. With a tolerance of +/- 10% and delay values of one second, the lock would activate. With 5% – no. Etcetera.

Now for the lock sketch. Again it measures the millis() value on each button press and after five presses calculates the duration between each press. Finally in the function checkCombination() the durations are compared against the stored delay values (generated using the first sketch) which are stored in the array del[]. In our example lock sketch we have values of one second between each button press. The tolerance is stored as a decimal fraction in the variable tolerance; for example to have a tolerance of ten percent, use 0.1.

Download link

/*
  Single-button combination lock - John Boxall June 2011
  http://tronixstuff.wordpress.com/projects | CC by-sa-nc
*/

int count=0;
unsigned long a[]={0,0,0,0,0};
unsigned long b[]={0,0,0,0,0};
unsigned long del[]={1000,1000,1000,1000}; // these are the values obtained from running combilock1.pde
// delay between each button press is 1000 ms
float tolerance=.2;

void setup()
{
  pinMode(2, INPUT);
  Serial.begin(115200); // for testing purposes
  Serial.println("Start"); // for testing purposes
}

void dataCapture()
{
  a[count]=millis();
  delay(500); // for button debounce, your value may differ
  count++;
}

void checkCombination()
{
    int compare=0;
    count=0;
    // calcualate delays between keypresses
    b[0]=a[1]-a[0];
    b[1]=a[2]-a[1];
    b[2]=a[3]-a[2];
    b[3]=a[4]-a[3];

    // compare the button delay values
    if (b[0]<=(del[0]*(1+tolerance)) && b[0]>=(del[0]*(1-tolerance))) { compare++; }
    if (b[1]<=(del[1]*(1+tolerance)) && b[1]>=(del[1]*(1-tolerance))) { compare++; }
    if (b[2]<=(del[2]*(1+tolerance)) && b[2]>=(del[2]*(1-tolerance))) { compare++; }
    if (b[3]<=(del[3]*(1+tolerance)) && b[3]>=(del[3]*(1-tolerance))) { compare++; }
    if (compare==4) { success(); }
    if (compare!=4) { failure(); }
}

void success()
{
   // contains code to run when combination successfully entered
   Serial.println("Success!");
   delay(5000);
   Serial.println("- - - - -");
}

void failure()
{
   // contains code to run when combination unsuccessfully entered
   Serial.println("Failure!");
   delay(5000);
   Serial.println("- - - - -");
}

void loop()
{
  if (digitalRead(2)==HIGH)
  {
    dataCapture();
  }
  if (count>4)
  {
    checkCombination();
  }
}

When choosing your time delays, ensure they are larger than the value used for button debounce (the delay() function call) in the dataCapture() function. Notice the two functions success() and failure() – these will contain the results of what happens when the user successfully enters the combination or does not.

For a demonstration of the final product, I have connected an LCD to display the outcomes of the entry attempts. You can download the sketch from here. The key used in this example is 1,2,3,4 seconds:

Although there are four buttons on the board used in the video, only one is used. Well I hope someone out there found this interesting or slightly useful…

In the meanwhile 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? 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.

 

July 2, 2011 Posted by | arduino, education, learning electronics, microcontrollers, projects, tutorial, twitter | , , , , , , , , , , , , , , , , , , , , , | 6 Comments

   

Follow

Get every new post delivered to your Inbox.

Join 4,007 other followers

%d bloggers like this: