Quantcast
Channel: SparkFun Tutorials
Viewing all 1114 articles
Browse latest View live

Tiny AVR Programmer Hookup Guide

0
0

Tiny AVR Programmer Hookup Guide a learn.sparkfun.com tutorial

Introduction

Arduino is awesome. The boards are solid, the programming language and IDE are easy, and the community is awesome. But for a lot of electronics projects, an Arduino is overkill. If you’re just blinking a few LEDs, and reading a single sensor, you can get the job done smaller and cheaper using a simple IC, like the ATtiny85.

ATtiny85 (quarter included for size comparison)

Our hero! The ATtiny85.

Unfortunately, the ATtiny85 doesn’t have a well-known, ubiquitous development platform like Arduino’s Uno or Leonardo. And 8kB of program space doesn’t leave much room for a bootloader, so an extra programmer is usually required. On top of that, standard Arduino doesn’t support the chip. That doesn’t mean programming the ATtiny85 in Arduino isn’t possible, though! Enter the Tiny AVR Programmer

Tiny AVR Programmer ISO

The Tiny AVR Programmer is a general AVR programmer, but it’s specifically designed to allow quick-and-easy programming of ATtiny85’s (as well as 45’s). It has an on-board socket, where the little 8-pin IC can be plugged in and directly programmed. No messy wires or soldering required! Once you’ve programmed the ATtiny85, just remove it from the Programmer, and stick it into a breadboard or prototyping board.

The Tiny AVR Programmer can also be used as a general purpose AVR programmer. It can directly program almost all AVR’s (including the ATmega328 and ATmega32U4) whether they’re on Arduino boards or in a breadboard.

Covered In This Tutorial

In this hookup guide, we’ll show how you can program ATtiny85’s using the Tiny AVR Programmer and Arduino. We’ll cover everything from driver installation to Arduino programming tips.

Required Materials

In addition to the Tiny AVR Programmer, you’ll also need the following items to follow along with this tutorial:

  • ATtiny85– To be programmed by the programmer.
  • A computer or laptop with:
  • Optional:
    • USB Extension Cable– If your USB port is out of reach, this may help make the Programmer easier to reach.

Suggested Reading

Board Overview

The image below provides a quick overview of the components on the Tiny AVR Programmer:

Programmer with annotated components

The “brain” of the Tiny AVR Programmer is an ATtiny84 (not to be confused with the 85), – the 16-pin surface-mount chip – which comes preprogrammed with some firmware that makes it look like an AVR programmer. Unless your writing custom AVR ISP firmware, you shouldn’t ever have to mess with this chip. It’s a black box. Program data comes into it from your computer, over USB, and it spits out the proper sequence of bytes to load that program into your ATtiny85.

In this tutorial, we’ll mostly concern ourselves with the components on the right half of the board. The ATtiny85 programming socket, pin 0 LED, and prototyping pins.

ATtiny85 Socket and Prototyping Pins

The socket and the pins broken out to the sides are what make the Tiny AVR Programmer unique. The 8-pin socket fits both the ATtiny85 and the ATtiny45 DIP packages. Just plug your IC-to-program into this socket, and a-programming you will go!

Programmer plugged into USB, ATtiny85 plugged into programmer

A Tiny AVR Programmer with an ATtiny85 inserted.

When plugging your ATtiny into the socket, take note of the notch on both the socket and the white silkscreen on the PCB. This should match the polarity of the ATtiny85. Usually the ATtiny85 has a dot next to pin 1 of the IC, this should be placed up towards the notch.

The +, -, and numerical labels on the side of the socket reference the pin numbers and voltage supply inputs of the ATtiny85. These pin numbers can be called in the Arduino IDE as we’ll show later in this tutorial.

The 4-pin headers on either side of the socket help for prototyping the ATtiny85 out to external circuitry. You can easily plug male jumper wires into these pins, which can be routed to breadboards or other prototyping circuits.

Using the prototyping pins

An ATtiny85 being prototyped out to a potentiometer (analog input), button (digital input), and RGB LED (analog/digital output).

Finally, there’s an on-board amber LED connected to pin 0 of the ATtiny85. This is super-helpful when you’re uploading the “Hello, world” blink sketch to an ATtiny85.


That covers the fundamental stuff on the Tiny AVR Programmer. If you plan on doing more advanced stuff with the board, or just want to know more, feel free to read on. Otherwise, skip ahead to the next page.


Output Programming Pins

The Tiny ISP Programmer is not limited to ATtiny85’s. It’s a full-fledged AVR programmer. This row of six pins can be connected to other AVRs via the standard 2x3- or 2x5-pin ISP headers. You could, for example, connect these pins to your Arduino Uno, Leonardo, etc. to re-flash a bootloader, or upload code using a programmer.

Refer to the pin labels in the image above if you’re connecting the Tiny AVR Programmer to another AVR chip. Most AVR development boards break out either a 2x3 or 2x5 programming header, which have the following pin-outs:

AVR ISP Pinout

Just match up the labels on the Tiny Programmer to the pins on your AVR board/chip, and get ready to program!

The Jumpers

There are two jumpers on the top side of the Tiny AVR Programmer. One is labeled RST and the other is VCC. A little bit on each of those:

The VCC jumper is normally closed. It controls the flow of power to the socketed ATtiny85. As long as the jumper remains closed, the tiny85 will be powered by 5V from the Tiny AVR Programmer’s USB port. If the jumper is opened, you’ll need to supply an external power source for the ATtiny85. (This all pertains to the 5V pin on the output programming header too.)

If you need to power the ATtiny85 at some voltage other than 5V or just need it to be on an isolated supply, consider grabbing some solder wick to desolder the jumper, and supply your own voltage source.

The RST jumper is more advanced. This header connects the ATtiny84’s reset pin to the to the 2x3-pin ISP header in the middle of the board. The Programmer ships with this jumper open. If you ever need to reprogram the ATtiny84 (which, for standard use cases, you shouldn’t), you’ll have to close this jumper to enable programming it.


Enough talk. Let’s start using the programmer. On the next few pages we’ll cover driver installation (for Windows users) and show how you can use the Tiny AVR Programmer to program an ATtiny85 in Arduino.

Driver Installation

Before you can start using the Tiny AVR Programmer, you may need to set it up on your computer. If you’re using a Mac or Linux machine, you don’t need to install drivers. Just plug the board in, and skip to the Programming in Arduino page.

If you’re using any version of Windows, you’ve got a few steps to follow before you can join your Mac/Linux comrades:

Step 1: Plug the Programmer In

To begin, locate an empty USB port on your computer, and plug the Tiny AVR Programmer into it. You’ll probably want to have the programmer close by. If you’re using a PC, or your USB ports aren’t close by, a USB Extension Cable might help get the programmer into a more convenient spot on your desk.

Step 2: Wait for Windows to Automatically Fail/Succeed

After plugging in your Tiny AVR Programmer, Windows will try to look for a driver that matches it. Keep an eye on the notification area in the bottom-right corner. Wait for Windows to try to install the driver on its own. There’s a chance that, after searching, Windows will find the driver. If you get a Device driver software installed successfully notification (lucky you!), you can ignore the next few steps. But, if you got something like this:

Driver installation failed

Continue on to step 3…

Step 3: Download the Driver

If Windows couldn’t find the driver for you, you’ll need to download it. There are two versions, make sure you grab the one that matches your system:

After downloading your driver, extract it from the zip folder. Don’t forget where you put it!

Step 4: Open the Device Manager

To install the driver, you’ll need to first open up the Device Manager. From the Control Panel, go to the System and Security section, click System, and click on Device Manager. (Alternatively you can Rundevmgmt.msc).

In the Device Manager, open up the LibUSB-Win32 Devices tree and you should find a USBTinyProgrammer with a yellow warning triangle hovering over the icon.

Right-click on the USBTinyProgrammer device, and select Update Driver Software…

The device manager

Step 5: Driver Pointing

On the Update Driver Software window that appears, select Browse my computer for driver software.

On the next window, Browse for driver software on your computer, set the driver search location to the folder you downloaded and unzipped in step 3. The folder should be named something like usbtinyisp_libusb-win32_1.2.1.0:

Browse for drivers

Then click Next, and the driver will begin updating. Shortly after that, though, a Windows Security window should pop up to let you know the driver isn’t “signed”. Click Install this driver software anyway. We promise it won’t damage your computer!

Then play the waiting game for a moment, and wait for a happy Windows has successfully updated your driver software window.

After closing that success window, your Device Manager should have an entry for USBtiny under LibUSB-Win32 Devices.

Programming in Arduino

Everyone loves Arduino! The simplified language makes programming AVRs and more complicated microcontrollers incredibly easy. Unfortunately, Arduino doesn’t have any built-in functionality to program tiny AVRs, but that doesn’t mean we can’t add it!

On this page we’ll go over all of the steps necessary to enable ATtiny45/85 programming in Arduino, using the Tiny AVR Programmer.

Step 0: Install Arduino

If you’ve never used Arduino before (where have you been?!), make sure you follow our What is an Arduino? and Installing Arduino tutorials before continuing on.

Step 1: Download the ATtiny Addon

To add ATtiny’s to the standard Arduino IDE Board menu, you’ll need to add a few files that help define the hardware. The ATtiny hardware definitions are kept in a repository on GitHub. You can download them from there, or simply click here to download them in a ZIP folder.

Extract the ZIP folder, and don’t forget where you put it!

Step 2: Move the attiny Folder

There should be an attiny folder living within the attiny-master folder you downloaded. Copy that folder and paste it into a hardware folder within your Arduino Sketchbook directory.

If you’re not sure where your Arduino sketchbook is, open Arduino and go to File>Preferences. The Sketchbook location should be the topmost entry in the Preferences dialog. By default, the sketchbook is usually an Arduino folder within your home folder (e.g. C:\Users\userName\Arduino on Windows, or /Users/userName/Documents/Arduino on Mac).

If there’s not a hardware directory already in your Sketchbook make one. After placing the attiny folder in there, your directory structure should look a little something like this:

attiny and hardware folder directory structure

Step 3: Open and Configure Arduino

Almost to the fun part! Open Arduino. If you opened Arduino in the last step, close it and restart it.

Under the Tools>Board menu, you’ll find the effects of the attiny folder. There should be twelve new entires in the board list, which allow you to program ATtiny45’s, 85’s, 44’s and 84’s. Each microcontroller can be set to a variety of clock speeds – internal 1MHz or 8MHz or external 20MHz.

If you’re using a bare, previously untouched ATtiny85 select ATtiny85 (internal 1 MHz clock). Be careful selecting here, selecting the 8 MHZ option will only make your sketch run slow, but selecting the 20 MHz option can “brick” your ATtiny. Do not select the 20 MHz option unless you have an external clock attached!

Arduino board selection

Unlike other Arduino boards, you don’t have to select a Serial Port when using the Tiny AVR Programmer. But you do need to select a Programmer. Under the Tools>Programmer menu, select USBtinyISP.

Arduino programmer selection

Step 4: Plug in the ATtiny

Getting close to blinking! When you plug the ATtiny into your Programmer, make sure you get the polarity correct. The small, etched circle on the IC should line up with the “notch” on the Programmer’s socket and silkscreen.

ATtiny85 polarity dot matches notch location

To get the IC into the socket, you may need to bend the legs on each side inwards a tad.

Step 5: Upload Code!

Time for the Blink sketch! The Tiny AVR Programmer has an on-board LED, connected to the ATtiny, which we can use to verify that code on the IC is running. The LED is connected to pin 0 in the Arduino environment. Copy/paste this code into your Arduino window:

language:c
int blinkPin = 0;

void setup()
{
  pinMode(blinkPin, OUTPUT);
}

void loop()
{
  digitalWrite(blinkPin, HIGH);
  delay(500);
  digitalWrite(blinkPin, LOW);
  delay(500);
}

Then click Upload just as you would with any Arduino board. The code will compile, and then it should upload insanely fast. That’s the wonders of direct in-system programming for you.

If successful, the on-board amber LED should start blinking.

ATtiny85 Use Hints

The ATtiny85 isn’t your everyday Arduino IC. It packs a lot of punch for its small size, but there are some things it can’t do.

On this page, we’ll provide a quick overview of the ATtiny85 as it pertains to Arduino and the Tiny AVR Programmer.

Pinout

Just like any Arduino board, each I/O pin on the ATtiny85 is assigned a numerical identifier. These pins are documented on the board as well, but you can also refer to the image below if you forget.

ATtiny85 Pin Map

Each of the I/O pins on the ATtiny85 are capable of digital input and output. Beyond that, some pins have special functionality.

Analog Input and Output

There are two analog outputs and three analog inputs. Use them just as you would with any Arduino board. Use analogWrite([pin], [0-255]) to do PWM output. This functionality is available on pins 0 and 1. For example:

language:c
int pwmPin = 0;

pinMode(pwmPin, OUTPUT);

for (int i=0; i<=255; i+=5)
{
  analogWrite(pwmPin, i);
  delay(5);
}

And use analogRead([pin]) to read an analog voltage between 0 and 5V, and turn it into a 10-bit representation of that voltage. Pins 2, 3, and 4 are capable of analog input, but, when using them as such, they should be referenced as A1, A3, or A2 respectively. For example:

language:c
int pwmPin = 0;
int analogInPin = A1;

pinMode(pwmPin, OUTPUT);
pinMode(analogInPin, INPUT);

int analogIn = analogRead(analogInPin); // Read analog voltage on pin 2 (A1)

analogWrite(pwmPin, analogIn / 4); // Output analog reading to dimmable LED

No Serial (UART). Yes SPI and I2C.

You may notice, on the listing of special pin functions there are no UART RX’s or TX’s. That’s because the ATtiny85 doesn’t have a built in hardware UART. If you try to compile any Arduino code with Serial.begin(9600)’s or Serial.print()’s you’ll get an error.

So you’re out one of the more useful Arduino debugging tools. You can’t print to the Serial Monitor. But the ATtiny85 does still have I2C and SPI, which are much more commonly used for sensor communication these days. Unfortunately, the Arduino libraries for these interfaces haven’t yet been written for the ATtiny85, but there are some user contributed libraries around the web. USIi2c is an Arduino library which enables I2C on the ATtiny85.

There are other ATtiny85-focused libraries out there too. Like a Servo8Bit, a servo library.

Prototyping with the Tiny AVR Programmer

There’s only so much excitement you can get out of dimming a single, yellow LED. You’ll eventually want to branch out, and start connecting your tiny85 to other electronic components. There are a few ways to do this.

The easiest, least permanent prototyping route is to use the prototyping headers on either side of the socket. You can connect standard, male jumper wires to these pins, which can in turn be routed to breadboards or other components.

alt text

For more permanent projects, it’s easy enough to gently remove the IC from the socket, and plug it into a PCB or breadboard. Eventually, once you’ve iterated enough on your sketch, this is probably where you’ll want to go. Eventually you arrive at finished designs like the H2OhNo! or the LectroCandle.

Resources & Going Further

Resources

  • Tiny AVR Programmer Design Files

    • Schematic– A PDF of the Tiny AVR Programmer’s schematic.
    • Eagle Files– If you want to look at the PCB design, or modify it to make a version of your own, check these files out.
    • Tiny AVR Programmer Firmware– If you want to dig into the code that lives on the Programmer itself, check this out.
    • GitHub Repository– Go here to find the latest, greatest version of the Tiny AVR Programmer’s hardware and firmware. Or modify it and contribute your changes back!
  • Drivers, etc.

  • ATtiny85 Resources

Going Further

  • H2OhNo!– The H2OhNo! water alarm and development board uses an ATtiny85 to sense the presence of water. This tutorial goes deep into getting the ATtiny85 into a very low power mode.
  • Shift Registers– If you’re feeling restrained by the ATtiny’s lack of pins, you may be able to use a shift register to expand on that I/O count.
  • Using the Arduino Pro Mini 3.3V– If you’re looking for small, but need more pins and functionality check out the Arduino Pro Mini.
  • Installing an Arduino Bootloader– You can use the Tiny AVR Programmer to program all sorts of AVRs, including those on most Arduino-compatible boards. If you ever find yourself needing to reprogram your Arduino bootloader, the Tiny AVR Programmer should be all you need.

learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado


PCA9306 Level Translator Hookup Guide

0
0

PCA9306 Level Translator Hookup Guide a learn.sparkfun.com tutorial

PCA9306 Overview

The PCA9306 is a dual bidirectional voltage translator for the I2C-bus and SMBus. It works at a range of voltages between 1.0 and 5.0V and doesn’t require a direction pin to function.

PCA9306 Breakout Board

PCA9306 Breakout Board

This is a great board for shifting voltages between sensors and your microcontroller.

Suggested Reading

These level converters are pretty easy to start using, but you may want to check out some of the additional reading material below if you are unfamiliar with logic level shifting or haven’t worked with Arduino boards prior to this.

Hardware Hookup

The breakout board has seven pins that need to be connected to function properly. VREF1, SCL1, and SDA1 all connect to your lower voltage part. VREF2, SCL2, and SDA2 connect to your higher voltage part. The GND pin needs to be connected to ground in your system. The final through-hole on the board labeled NC does not need to be connected to anything.

To connect the board, solder headers into the through-holes, and use jumper wires between devices. Or, you could just solder some hookup wire to all your boards.

For this example, we are going to use an Arduino Pro Mini 5V to connect to an HMC5883L magnetometer breakout board, which runs at 3.3V and communicates over I2C.

Connections:

HMC5883L → PCA9306

  • 3.3V → VREF1
  • SCL → SCL1
  • SDA → SDA1
  • GND → GND

PCA9306 → Pro Mini (5V)

  • VREF2 → 5V
  • SCL2 → A5
  • SDA2 → A4

Here is a Fritizing diagram showing the actual connections between the HMC5883L, the PCA9306 breakout and the Pro Mini.

Fritzing Diagram of Connections

Fritzing diagram showing the connections between the three boards.

The diagram shows the HMC5883L running off of a 3V power supply, and the Pro Mini running off of a 5V barrel jack connector. Keep in mind your power supplies could be different than the ones pictured above (for example, using a Lipo battery instead of AA batteries), but you will still need to have a power supply for the lower voltage side of the system and a separate supply for the higher voltage side.

Once you have the boards physically connected, you are good to go! You don’t need to use any special code with the PCA9306 board, and you can simply use any example sketch available for your sensors. In this case, we are using the example HMC5883.ino sketch.

Going Further

Now that you know how to use the logic level shifter, it’s time to go and use this in your own project! Check out the additional resources below if you have any questions, or leave us feedback on the tutorial itself. Best of luck interfacing with all of your sensors!

Resources

Need more level shifting?! Check out these other level shifting hookup guides:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Data Types in Arduino

0
0

Data Types in Arduino a learn.sparkfun.com tutorial

Introduction

Computers, including the Arduino, tend to be highly data agnostic. At their core, the heart of the device is an arithmetic-logic unit (ALU), which performs (fairly) simple operations on locations in memory: R1+R2, R3*R7, R4&R5, etc. The ALU doesn’t care what that data represents to a user, be it text, integer values, floating point values, or even part of the program code.

All of the context for these operations comes from the compiler, and the directions for the context get to the compiler from the user. You, the programmer, tell the compiler that this value is an integer and that value is a floating point number. The compiler, then, is left trying to figure out what I mean when I say “add this integer to that floating point.” Sometimes that’s easy, but sometimes it’s not. And sometimes it seems like it should be easy, but it turns out to yield results you might not anticipate.

This tutorial will cover the basic data types available in Arduino, what they’re typically used for, and will highlight the effects of using different data types on the size and performance speed of your programs.

Suggested Reading

You may want to familiarize yourself with a few concepts before we get started:

Defining Data Types

The Arduino environment is really just C++ with library support and built-in assumptions about the target environment to simplify the coding process. C++ defines a number of different data types; here we’ll talk only about those used in Arduino with an emphasis on traps awaiting the unwary Arduino programmer.

Below is a list of the data types commonly seen in Arduino, with the memory size of each in parentheses after the type name. Note: signed variables allow both positive and negative numbers, while unsigned variables allow only positive values.

  • boolean (8 bit) - simple logical true/false
  • byte (8 bit) - unsigned number from 0-255
  • char (8 bit) - signed number from -128 to 127. The compiler will attempt to interpret this data type as a character in some circumstances, which may yield unexpected results
  • unsigned char (8 bit) - same as ‘byte’; if this is what you’re after, you should use ‘byte’ instead, for reasons of clarity
  • word (16 bit) - unsigned number from 0-65535
  • unsigned int (16 bit)- the same as ‘word’. Use ‘word’ instead for clarity and brevity
  • int (16 bit) - signed number from -32768 to 32767. This is most commonly what you see used for general purpose variables in Arduino example code provided with the IDE
  • unsigned long (32 bit) - unsigned number from 0-4,294,967,295. The most common usage of this is to store the result of the millis() function, which returns the number of milliseconds the current code has been running
  • long (32 bit) - signed number from -2,147,483,648 to 2,147,483,647
  • float (32 bit) - signed number from -3.4028235E38 to 3.4028235E38. Floating point on the Arduino is not native; the compiler has to jump through hoops to make it work. If you can avoid it, you should. We’ll touch on this later.

This tutorial will NOT cover arrays, pointers, or strings; those are more specialized datatypes with more involved concepts that will be covered elsewhere.

Time and Space

The processor at the heart of the Arduino board, the Atmel ATmega328P, is a native 8-bit processor with no built-in support for floating point numbers. In order to use data types larger than 8 bits, the compiler needs to make a sequence of code capable of taking larger chunks of data, working on them a little bit at a time, then putting the result where it belongs.

This means that it is at its best when processing 8-bit values and at its worst when processing floating point. To demonstrate this fact, I’ve written a simple Arduino sketch which does some very simple math and can easily be altered to use different data types to perform the same calculations.

First, up, let’s dump the code as-is into an Arduino Uno and see what results we get on the serial console.

Screen capture of the console doing a byte oriented add

Okay, lots of stuff there. Let’s take things a bit at a time.

First, if you’re following along, check the compiled size of the code. For addition with bytes, we end up with 2458 bytes of code. Not a lot, and, frankly, most of that is taken up with the serial output stuff. This data point will become important later on, however.

Next, let’s look at the serial port output. What’s the deal with the squares instead of a number for the printed variable values? That happens because the Serial.print() function changes the way it operates based on the type of data which is passed to it. For an 8-bit value (be it a char or byte), it will simply pipe out that value, in binary. The serial console is then going to try to interpret that data as an ASCII character, and the ASCII characters for 1, 2, and 3 are ‘START OF HEADING’, ‘START OF TEXT’, and ‘END OF TEXT’. Hmm. Not particularly useful, are they, nor easy to display in one character? Hence the square: the serial console is throwing up its hands and saying, ‘I don’t know how to print this, so I made a square for you’. So, lesson one in Arduino datatype finesse: to get the decimal representation of an 8-bit value from Serial.print(), you must add the DEC switch to the function call, like this:

Serial.print(x, DEC);

Finally, observe the ‘Elapsed time’ measurement. Discounting the inaccuracies from using the micros() function to measure elapsed time, which we’ll do on all these tests, so we should get a very good RELATIVE measure of the time required for operations, if not a good absolute measure, you can see that adding two 8-bit values requires approximately 4 microseconds of the processor’s time to achieve.

Testing Data Types (Addition)

Okay, let’s move on to test some more data types. If you’re following along at home, you’ll want to change your code, as seen below:

Code snippet for byte programCode snippet for int code

Now, load the code onto your Arduino board. Check the compile size: 2488 bytes for int versus 2458 bytes for byte. Not a lot bigger, but it IS bigger. Again, this is because using data types which require more than 8 bits of storage (like int, long, or float also requires the compiler to generate more actual machine code for the addition to be realized - the processor itself simply doesn’t have the capability of supporting larger data natively. Now, open the serial console and you should see something like this:

Addition with ints serial port capture.

Next observation: this time the values printed correctly. That’s because the new datatype we’ve introduced, the int, is correctly interpreted by the compiler as a numeric datatype, and Serial.print() correctly formats the output data to reflect that in the console. So, second lesson of Arduino datatype finesse: if you WANT to send the binary equivalent of a numeric datatype, say, as a means of sharing data with another computing device rather than a user looking at a console, use the Serial.write() function.

Next, let’s check out “Elapsed time” again. We’re up to 12 microseconds now - about 3 times as long! Still pretty short, but this is due to the previously mentioned fact that this is an 8-bit processor, so it needs to jump through some hoops to do 16-bit math, which is what’s required when adding int variables together.

Onward and upward! Now let’s check out the long datatype. Repeat the last code change, except this time replace the two incidents of int with long. Load the code and open your serial console and see what’s happened.

Serial capture of addition with longs

Before we dive into the serial capture, let’s revisit the compile size. I got 2516 bytes, this time- 28 bytes more than using int and 58 more than using byte. Still a pretty small difference but a difference nonetheless, and a difference which could add up if you do a lot of math with long instead of int or byte.

Okay, now on to the serial results. Again, notice that the elapsed time changed. This time, however, it DECREASED from 12 microseconds to 8! How does that work? This is your third lesson in Arduino datatype finesse: what you think is happening may not be what is actually happening. I’m not sure why this occurs - it may be due to some compiler optimization, or due to some run-time optimization which saves time on small value additions which is not present in the int code. Regardless, long is faster than int is not necessarily a safe takeaway here, as we’ll see when we get into multiplication and division.

Okay, last stop, floating point math. Floating point math on the Arduino is tricky because the Arduino lacks a floating point unit, which is fancy-talk for a dedicated section of the processor which handles math with an arbitrary number of digits after a decimal point. Floating point math is also a sticky concept, because while humans can deal well with arbitrary numbers of zeros after the decimal point, computers can’t. This is the origin of the infamous 1 is not 1 bug that some early generation Pentium processors suffered from.

Alter the code as above again, but replace long with float in the two pertinent locations. Load the code and check out the compile size: 3864 bytes! What happened is that by including the floating point data type, you forced the compiler to include the floating point handling code. Clearly, that’s a pretty big chunk of code - it increased the size by a fair margin. Datatype finesse lesson four: don’t use floating point math unless you really, really have to. Most times, that’s going to be limited to giving users feedback about something which is fairly meaningless as an arbitrary integer value: the ADC will return a value like 536, which is cryptic, but converted into floating point it would be something like 2.62V, which is much more useful.

Serial capture of addition with floating points

Now look at the run time on this code - back up to 12 microseconds. Also, note that the printed value now includes two zeros after the decimal place. If you want more (or fewer) digits after the decimal, you can add a number of digits into your print command:

Serial.print(x, 3); // print floating point number x with three digits after the decimal.

Testing Data Types (Multiplication/Division)

Now let’s look at what happens with ‘harder’ math - multiplication and division.

Here are some screen grabs for multiplication:

Multiply with bytes screen capture[(https://dlnmh9ip6v2uc.cloudfront.net/tutorialimages/datatypes/mult_int.jpg)

Multiply with bytes screen capture[(https://dlnmh9ip6v2uc.cloudfront.net/tutorialimages/datatypes/mult_float.jpg)

Check out the elapsed times: 4µs for byte, 8 for int or long, and 12 for float - longer for larger data types, and also what we expect to see in terms of ‘harder’ math taking longer. Multiplication is still hardware supported, though - there is a native multiply instruction in the processor which makes multiply operations relatively easy. But what about division?

Divide with bytes screen captureDivide with ints screen capture

Divide with longs screen captureDivide with floats screen capture

Oh, my. byte division isn’t too bad at 16µs, but 48 for long? Ouch. The problem here is that division does NOT have a native instruction in the Atmega instruction set, so the compiler has to do some back flips to create one. So, final lesson: not all mathematical operations are created equal. Divide takes a lot longer than multiply or add (or subtract, but that’s really just add with a minus sign), and something like finding a square root or a sine would take even longer. So long, in fact, that it’s often easier just to maintain a list of values for square roots or sine/cosine/tangent and look up the value that you want than it is to calculate it.

Resources and Going Further

I’m going to leave it here for now. I hope I’ve demonstrated clearly the benefits of using appropriate data types for your variables. The next tutorial will go into some of the really ugly pitfalls that are hiding in mixing data types and using INAPPROPRIATE data types - for instance, data types that are too small for the largest number that you may encounter.

All of the context for these operations comes from the compiler, and the directions for the context get to the compiler from the user. You, the programmer, tell the compiler that THIS value is an integer and THAT value is a floating point number. The compiler, then, is left trying to figure out what I mean when I say “add this integer to that floating point”. Sometimes that’s easy, but sometimes it’s not. And sometimes it SEEMS like it SHOULD be easy, but it turns out to yield results you might not anticipate.

Here’s some further reading you may want to explore with your new knowledge of data types:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Pro Micro & Fio v3 Hookup Guide

0
0

Pro Micro & Fio v3 Hookup Guide a learn.sparkfun.com tutorial

Introduction

Welcome to the new frontier of Arduino-compatible boards, made possible by the ATmega32U4. No longer does your Arduino need to be harnessed by an FTDI Cable, or an ATmega8U2, or any chip who’s sole purpose is acting as an intermediary between your Arduino and your computer.

Pro Micro iso

The SparkFun Pro Micro is a really cool, little development board. It’s an Arduino-compatible microcontroller, micro-sized, and it accomplishes with one single chip what old Arduino Unos, Duemilanoves, and Diecimeilllas could never dream of: true USB functionality.

This tutorial also covers the Fio v3, which works a lot like the Pro Micro but adds features like easy XBee interfacing and LiPo charging.

Fio v3 iso

Covered In This Tutorial

This tutorial aims to introduce you to both the hardware and firmware sides of the Pro Micro (and Fio v3). We’ll also dedicate a few pages to helping install the boards on Windows and Mac. Here’s a summary of what will be covered:

Suggested Reading

Before delving into this tutorial, here are some concepts you should be familiar with. If you’re not, consider checking out the related tutorial first.

Hardware Overview: Pro Micro

Before we get into installing and using the Pro Micro, let’s quickly look at the board – examine its inputs, outputs, and other hardware quirks.

The Pinout

All of the Pro Micro’s I/O and power pins are broken out to two, parallel headers. Some pins are for power input or output, other pins are dedicated I/O pins. Further, the I/O pins can have special abilities, like analog input. Here’s a map of which pin is where, and what special hardware functions it may have:

Pro Micro Pinout

Delving a little further into which pins do what…

Power Pins

There are a variety of power and power-related nets broken out:

  • RAW is the unregulated voltage input for the Pro Micro. If the board is powered via USB, the voltage at this pin will be about 4.8V (USB’s 5V minus a schottkey diode drop). On the other hand, if the board is powered externally, through this pin, the applied voltage can be up to 12V.
  • VCC is the voltage supplied to the on-board ATmega32U4. This voltage will depend on whether you’re using a 3.3V/8MHz Pro Micro or a 5V/16MHz version, it’ll be either 3.3V or 5V respectively. This voltage is regulated by the voltage applied to the RAW pin. If the board is powered through the ‘RAW’ pin (or USB), this pin can be used as an output to supply other devices.
  • RST can be used to restart the Pro Micro. This pin is pulled high by a 10k&Ohm; resistor on the board, and is active-low, so it must be connected to ground to initiate a reset. The Pro Micro will remain “off” until the reset line is pulled back to high.
  • GND, of course, is the common, ground voltage (0V reference) for the system.

I/O Pins

The Pro Micro’s I/O pins – 18 in all – are multi-talented. Every pin can be used as a digital input or output, for blinking LEDs or reading button presses. These pins are referenced in the Arduino IDE via an integer value between 0 and 21. (The A0-A3 pins can be referenced digitally using either their analog or digital pin number).

Nine pins feature analog to digital converters (ADCs) and can be used as analog inputs. These are useful for reading potentiometers or other analog devices using the analogRead([pin]) function.

There are five pins with pulse width modulation (PWM) functionality, which allows for a form of analog output using the analogWrite([pin], [value]) function. These pins are indicated on-board with a faint, white circle around them.

There are hardware UART (serial), I2C, and SPI pins available as well. These can be used to interface with digital devices like serial LCDs, XBees, IMUs, and other serial sensors.

On-Board LEDs

There are three LEDs on the Pro Micro. One red LED indicates whether power is present.

The other two LEDs help indicate when data is transferring over USB. A yellow LED represents USB data coming into (RX) the the Pro Micro, and a green LED indicates USB data going out (TX).

3.3V or 5V? 8MHz or 16MHz?

Pro Micros come in two flavors, which vary by system voltage and operating frequency. The standard 5V Pro Micro runs at 16MHz, and is very comparable to an Arduino Leonardo, while the 3.3V version of the Pro Micro runs at half the speed (to remain in the safe operating zone at the lower voltage) – 8MHz.

The operating voltage of your Pro Micro determines the maximum allowable voltage on any of the I/O pins. For example, if you have a 3.3V Pro Micro, don’t interface it with something that outputs 5V.

Back operating voltage marking

Don’t forget which version you have! We’ll need to differentiate between the two when we get to uploading code in Arduino. If you’re not sure which version you have, check the back corner of the board. One of two boxes should be checked to indicate the operating voltage.

How to Power the Pro Micro

As the Pro Micro’s main feature is its innate USB functionality, the most common way to power it is via USB. In this setup, a 5V Pro Micro will be powered directly from the USB bus and a 3.3V Pro Micro will regulate the 5V supply coming in from USB down. The other end of the USB cable can be connected to either a computer, USB hub, or a USB wall adapter, which can (in most cases) provide more power.

Alternatively, if your Pro Micro is living out in the wild, out of reach of USB cables, it can be powered through either the ‘RAW’ or ‘VCC’ pins. A supply going into the ‘RAW’ pin will be regulated down to the correct operating voltage (5V or 3.3V). To be safe, it shouldn’t be any higher than 12V, and it should be at least 1V more than the Pro Micro’s operating voltage (e.g. >6V for a 5V Pro Micro).

alt text

Pro Micro powered through the RAW pin by a set of four, series AA batteries.

If you power the Pro Micro through the ‘VCC’ pin, keep in mind that this signal is unregulated. Only use this if you have a clean, regulated 3.3V or 5V supply to connect to it.

How, exactly, you power your project is up to you and the demands of your project. If you’re making something battery powered, you may want to opt for the 3.3V Pro Micro, which could be powered by a LiPo battery or a couple alkalines.

Hardware Overview: Fio v3

On this page we’ll examine the hardware half of the Fio v3, looking at the pinout, layout, and schematic of the board.

The Fio v3 is like an elongated Pro Micro. On one end, it’s shape and pinouts are similar to it’s ATmega32U4 sibling. The other end of the Fio v3 is what makes it unique: a footprint for an XBee on the bottom, and a LiPo charging circuit on the top.

The Pinout

All of the Fio v3’s pins are broken out to either side of the board. Some pins are for power input or output, other pins are dedicated I/O pins. Further, the I/O pins can have special abilities, like analog input, or serial input/output. Here’s a map of which pin is where, and what special capabilities it may have:

Fio v3 pinout

Power Pins

The pins labeled ‘3.3V’ break out the operating voltage source of the ATmega32U4. As long as the board is powered through the white JST connector or USB, this voltage is regulated down to 3.3V. These pins can be used as outputs to supply 3.3V to other devices.

The ‘RST’ pin can be used to restart the Fio. This pin is pulled high by a 10kΩ resistor on the board, and is active-low, so it must be connected to ground to initiate a reset. The Fio will remain off until the reset line is pulled back to high.

I/O Pins

Many of the Fio’s I/O pins are multi-talented. Every pin can be used as a digital input or output, for blinking LEDs or reading button presses. These pins are referenced in the Arduino IDE via an integer value between 0 and 23. (The A0-A10 pins can be referenced digitally via either their analog pin number or digital pin number).

Eleven pins feature analog to digital converters (ADCs) and can be used as analog inputs. These are useful for reading potentiometers or other analog devices using the analogRead([pin]) function.

There are six pins with pulse width modulation (PWM) functionality, which allows for a form of analog output using the analogWrite([pin], [value]) function. These pins are indicated on-board with a faint white circle around the pin.

There are also hardware UART (serial), I2C, and SPI pins available. These can be used to interface with digital devices like serial LCDs, IMUs, and other serial sensors.

On-Board LEDs

There are a variety of LEDs on the Fio, the simplest of which is the red power indicator. Two LEDs towards the bottom – labeled RX and TX – help indicate when data is transferring to and from the Fio through USB. A blue LED represents USB data coming into (‘RX’) the the Pro Micro, and a yellow LED indicates USB data going out (‘TX’).

There are three LEDs tied to the XBee interface in particular: stat, RSSI, and associate. The red LED labeled ‘ON’ is connected to the XBee’s pin 13 – DIO9 – which is, by default, set to indicate the XBee module’s ON/OFF status. An ‘RSSI’ LED connects to XBee pin 6 (PWM0) which defaults to indicate RSSI (received signal strength) – a brighter LED means a stronger received signal. Lastly, the ‘ASO’ LED connects to XBee pin 15, which will blink if the module is associated.

Finally, there’s a yellow LED labeled ‘CHG’ which indicates if an attached lithium polymer battery is charging. If a battery is not connected to the Fio, the LED will be in an undefined state, and most likely be illuminated.

How to Power the Fio v3

The suggested power supply for the Fio v3 is any single-cell lithium polymer (LiPo) battery. These batteries have a nominal voltage of 3.7V, which is perfect for supplying power to the 3.3V-operating Fio. LiPos are awesome, because they’re rechargeable and still pack a lot of power into a tiny space. Any of our single cell LiPos with JST terminators can connect directly to the Fio’s onboard JST connector.

As an (immobile) alternative to batteries, the Fio can be powered directly through the USB connector.

Using the LiPo Charger

The Fio v3 has a LiPo charge management circuit (based around the MCP73831) built onto it, which handles the signal conditioning required to safely charge a single-cell LiPo battery.

To use the charge circuit, you’ll obviously need a single-cell LiPo battery plugged into the Fio. Then connect the board up via USB, so the charge circuit has a primary voltage source to supply charge to the battery.

Fio v3 powered by a LiPo battery

The ‘CHG’ LED will indicate the status of the battery charge. If it’s on, the battery is still charging. Once the ‘CHG’ LED goes off, the battery is fully charged.

The charge circuit is programmed to charge the battery at 500mA, so, to be safe, the battery should be no smaller than 500mAH in capacity.

Connecting An XBee

The XBee-footprint connectors on the bottom of the Fio v3 are what make it so unique. This product is designed to provide a simple interface between Arduino and XBee, as such a few of the XBee pins come wired up to the ATmega32U4. Most significantly, the serial interfaces of both devices are wired – the XBee’s ‘DOUT’ pin is connected to the ATmega32U4’s ‘RX’, and ‘DIN’ is connected to ‘TX’.

XBee in Fio v3

XBee’s are controlled and configured over a serial interface. To learn more about using XBee’s check out their datasheet and varioustutorials for help getting started with these awesomely simple wireless transceivers.

Installing: Windows

Getting the Pro Micro or Fio v3 set up on your computer and in your Arduino environment can be difficult. Follow along on this page for a step-by-step guide through the driver installation and Arduino-enabling process.

Windows Driver Installation

Step 1: Download the Driver

Before plugging your board in, get a head start by downloading the drivers. The same driver file works for both the Pro Micro and the Fio v3.

Unzip that zip file, and don’t forget where you’ve left its contents. In that zip file, you should find an INF file, which contains all the information Windows needs to install the Pro Micro’s driver.

Step 2: Plug in the Pro Micro / Fio v3

When you initially plug the board in, an “Installing device driver software” bubble notification should pop up in the lower-right corner of your taskbar. After the green dot circles the grey box a number of times, you’ll probably get a sad bubble like this:

Driver install failed

Never fear! Windows just doesn’t know where to find our driver.

Step 3: Open the Device Manager

From here, the most straightforward way to install the driver is through the Device Manager. To get to the Device Manager, click the Start button, then open the Control Panel. In the Control Panel, click System and Maintenance, and then open the Device Manager.

Alternatively, you can open the Run prompt (Windows key+R) and type ‘devmgmt.msc’ and click OK.

Run prompt opening device manager

In the Device Manager, expand the ‘Other devices’ tree, where you should find a ‘USB IO Board’ with a yellow warning sign over its icon. Right-click the ‘USB IO Board’ and select Update Driver Software….

Updating driver in device manager

This should spawn an ‘Update Driver Software - USB IO Board’ window.

Step 4: Finding the Driver

In the first window that pops up, click ‘Browse my computer for driver software’. On the next window, click ‘Browse…’ to search for the driver you just downloaded. It should be a folder named ‘SFE32U4_Drivers’. After you’ve selected the ‘driver’ folder, click OK, then select Next.

Driver install steps 1 through 5

Windows will attempt to do its driver install thing, but not before complaining about the driver being unsigned. It’s safe to select ‘Install this driver software anyway’ on the warning dialog.

After watching the progress bar beam by a few times, you should get a happy ‘Windows has successfully updated your driver software’ window. And the ‘Device Manager’ should have a new entry for the ‘SparkFun Pro Micro (COM ##)’ (or ‘SparkFun Fio V3 (COM##)’ if you have one of those) under the ‘Ports’ tree.

alt text

Take note of which COM port your Pro Micro was assigned. We’ll need it soon.

Installing the Arduino Addon

We’re still not completely ready for Arduino, but this is the final stretch. Before you can use the ProMicro in the Arduino IDE, you need to enable it and activate some super-secret Arduino files.

To begin, download this zip folder, and unzip it into a ‘hardware’ directory within your Arduino sketchbook.

Where’s your Arduino sketchbook? Well, by default, it should an ‘Arduino’ folder in your home directory, but to double check you can go to ‘File’ >‘Preferences’ within Arduino and check the ‘Sketchbook location’ text box. Just make sure you close all Arduino windows once you’re done.

Finding the sketchbook location

Once you’ve unzipped that folder into the ‘hardware’ folder within your Arduino sketchbook (you may actually have to create a hardware folder), your directory structure should look something like this:

Windows directory structure

There’s a lot going on in that addon, but one of the most important files is ‘boards.txt’, which will add a few new entries to your ‘Tools > Board’ menu.

To double-check that the board definitions have been added to Arduino, open up Arduino, and check under the ‘Tools > Board’ menu. There should be some new entires for ‘SparkFun Pro Micro 8MHz/3.3V’, ‘SparkFun Pro Micro 16MHz/5V’, and other 32U4 boards.

Pro Micros showing up in Arduino board selection

Notice there are two options for Pro Micro - 8MHz and 16MHz. It’s very important that you select the Pro Micro option that matches your board’s voltage and speed. Don’t know which board you have? Check the bottom of the board, where you should find either a ‘5V’ or ‘3.3V’ box checked.

You should also see your Pro Micro’s COM port under the ‘Tools > Serial Port’ menu. Select it, and head over to the Example 1 page where we’ll upload our first piece of code.

Installing: Mac & Linux

If you’re using Mac or Linux, follow the steps below to get your Pro Micro (or Fio v3) ready to go on your computer. We’re not going to name names here, but installing the Pro Micro on Mac OS X and Linux is a lot easier than on other OS’s…

Following these directions is critical to getting your Pro Micro supported within your Arduino environment!

Board Installation

When you initially plug your Pro Micro into a Mac, it’ll pop up a “Keyboard Setup Assistant” window. This stems from the Pro Micro’s ability to emulate an HID USB device (e.g. keyboards and mice) – the Mac thinks your Pro Micro is a human input device (which it could be! but isn’t yet).

Mac keyboard setup assistant

There’s nothing to configure in this window, so just click the big, red, ‘X’ to close it.

That’s all there is to it! The CDC (communication device class) portion of your Pro Micro (the part that handles USB to Serial conversion) should automatically install on your computer.

Installing the Arduino Addon

In order to use the Pro Micro or Fio v3 in your Arduino IDE, you need to add a few board definition files to it. That’s what we’ll do in this section. Begin by downloading the Pro Micro addon files.

With that downloaded, follow these steps to enable the Pro Micro in your Arduino environment:

  1. The addon files are supplied in a zip folder, so you’ll need to extract the files within first.
  2. Find your Arduino sketchbook folder. If you don’t know where it is, you can locate your sketchbook by looking at the preferences dialog in your Arduino IDE.
  3. If there isn’t already one, create a folder in your sketchbook called ‘hardware’.
  4. Copy the ‘SF32u4_boards’ folder that was unzipped in the first step into the ‘hardware’ folder.
  5. Restart Arduino, and look under the Tools > Board menu. You should see a few new options, including ‘SparkFun Pro Micro 5V/16MHz’, ‘SparkFun Pro Micro 3.3V/8MHz’, and ‘'SparkFun Fio V3 3.3V/8MHz’.

If the boards are visible, select the option that matches your board. If you have a Pro Micro, make sure you select the correct operating speed and voltage! Then head over to the next page where we’ll upload our first sketch!

Example 1: Blinkies!

The Arduino-standard Blink sketch won’t have any visible effect on the Pro Micro – there’s no LED on pin 13. In fact, the only LEDs on the board are the power indicator, and RX/TX blinkies. Unlike other Arduino boards, though, we can control the RX/TX LEDs in our sketch. So let’s get blinking!

Upload the RX/TX Blinky Sketch

Copy and paste the code below, and upload* it to your Pro Micro.

language:c
/* Pro Micro Test Code
   by: Nathan Seidle
   modified by: Jim Lindblom
   SparkFun Electronics
   date: September 16, 2013
   license: Public Domain - please use this code however you'd like.
   It's provided as a learning tool.

   This code is provided to show how to control the SparkFun
   ProMicro's TX and RX LEDs within a sketch. It also serves
   to explain the difference between Serial.print() and
   Serial1.print().
*/

int RXLED = 17;  // The RX LED has a defined Arduino pin
// The TX LED was not so lucky, we'll need to use pre-defined
// macros (TXLED1, TXLED0) to control that.
// (We could use the same macros for the RX LED too -- RXLED1,
//  and RXLED0.)

void setup()
{
 pinMode(RXLED, OUTPUT);  // Set RX LED as an output
 // TX LED is set as an output behind the scenes

 Serial.begin(9600); //This pipes to the serial monitor
 Serial1.begin(9600); //This is the UART, pipes to sensors attached to board
}

void loop()
{
 Serial.println("Hello world");  // Print "Hello World" to the Serial Monitor
 Serial1.println("Hello!");  // Print "Hello!" over hardware UART

 digitalWrite(RXLED, LOW);   // set the LED on
 TXLED0; //TX LED is not tied to a normally controlled pin
 delay(1000);              // wait for a second
 digitalWrite(RXLED, HIGH);    // set the LED off
 TXLED1;
 delay(1000);              // wait for a second
}

With the code uploaded you should see the RX and TX LEDs take turns blinking on and off every second. You can also open up the serial monitor (set to 9600 bps) and see every programmer’s favorite two-word phrase.

Understanding the Sketch

The RX LED is tied to Arduino’s pin 17. You can control it just as you would any other digital pin. Set it as an OUTPUT, and digitalWrite([pin], [level]) it HIGH or LOW. The TX LED was not provided as an Arduino-defined pin, unfortunately, so you’ll have to use a pair of macros to control it. TXLED1 turns the LED on, and TXLED0 turns the LED off.

In that sketch, you’ll also notice a pair of Serial initialization statements: Serial.begin(9600), Serial1.begin(9600). That ‘1’ makes a huge difference. Think of the Pro Micro having two separate serial ports. The one without the ‘1’ is for communication to and from the computer over USB; this is what is visible in the Serial Monitor. The Serial1 port is a bonafide, hardware UART, where your Pro Micro can talk to any serial-enabled piece of hardware.

If you open up the Serial Monitor, you should only see ‘Hello world’ printed. ‘Hello!’ is being sent out over the hardware UART, where, presumably, nothing is listening. This begs the age-old question: “if a Pro Micro is saying ‘Hello!’ over the hardware serial port, and nothing is there to hear it, does the Pro Micro really say anything at all?.”

Why Does My Board Re-Enumerate Every Upload?

In order to communicate serially, the Pro Micro emulates a virtual serial port. Actually, it emulates two different serial ports – one for the bootloader, and one for the sketch. Since the bootloader and sketch run individually. Only one of these serial ports is visible at any one time.

When you click ‘Upload’ in the Arduino IDE, the Pro Micro resets itself and starts its bootloader program. (The bootloader is a low-level program on the Pro Micro which enables self-programming via serial.) To our operating system, the bootloader looks like a completely different device, so it gets its own serial port number. While the Pro Micro is being programmed, the bootloader serial port will be open. When the sketch upload is finished, the bootloader will exit, that serial port will be closed, and the regular Pro Micro serial port will open up.

What this all boils down to is the fact that you have to be patient with Pro Micros. Every time you upload a new sketch, your OS will need to work its driver magic before you can open up the COM port. This can take a few seconds after the code has finished uploading.


* Note for Windows users: The first time you upload a sketch, it may fail and give you an error. On top of that Windows will pop up that familiar ‘Device driver software was not successfully installed’ notification. Don’t let this worry you too much. If you get the error, wait about a minute, and try uploading again.

Hopefully the upload will succeed the second time, but if it continues to fail, check out the how to enter the bootloader section of the FAQ. Windows needs to install the same driver we’ve already installed for the Pro Micro’s bootloader, but it’s unable to get everything set up before the bootloader exits.

Example 2: HID Mouse and Keyboard

By far, the Pro Micro’s most revolutionary feature (as far as Arduinos go) is its true USB functionality. The Pro Micro can be programmed to emulate any USB device you could imagine. You can even program it to act just like a mouse, keyboard, or other HID-class USB device.

What is HID? It’s one of the many defined USB device classes. Every USB device is assigned a class, which defines what its general purpose is. There are loads of classes – printers, hubs, speakers, and webcams to mention a few, but in this example we’ll be emulating HID – Human Interface Device. The ATmega32U4 takes care of the USB-hardware hurdle, but we’ve still got to clear the firmware one. Time for some example code!

USB Keyboards Made Simple

To emulate a USB keyboard, we’ll be making use of the Keyboard class. Here are some of the functions made available to us by this class:

  • Keyboard.write(char) - This function will send a single character over USB. The character passed can be any standard, printable, ASCII-defined character: 0-9, a-z, A-Z, space, symbols, etc. Here’s an example line of code:

Keyboard.write('z') // This will send a single 'z' character to your computer.

  • Keyboard.print(string) - If you need to perform a series a Keyboard.write()’s, consider using just a single Keyboard.print(). This works similar to Serial.print()– give it a string of characters and it’ll send that stream of characters over USB. Keyboard.println(string) is also defined, if you want a newline/linefeed to close out your string. An example:

Keyboard.print("Hello, world"); // This'll send your computer an 'H', followed by 'e', followed by...

  • Keyboard.press(byte) and Keyboard.release(byte) give you more precise control over key presses. They do exactly what you’d expect. One presses a button down, the other releases a button. Make sure you release any buttons you press, otherwise you’ll encounter some wiggyness on your computer.

That’s it. You don’t need to include any libraries or anything, just invoke any of those functions. Here’s an example sketch to try it out:

language:c
int buttonPin = 9;  // Set a button to any pin

void setup()
{
  pinMode(buttonPin, INPUT);  // Set the button as an input
  digitalWrite(buttonPin, HIGH);  // Pull the button high
}

void loop()
{
  if (digitalRead(buttonPin) == 0)  // if the button goes low
  {
    Keyboard.write('z');  // send a 'z' to the computer via Keyboard HID
    delay(1000);  // delay so there aren't a kajillion z's
  }
}

In this sketch, connecting pin 9 to ground will make the Pro Micro spit out a ‘z’ character. If you have a simple, momentary button handy, tie one end to pin 9 and the other to ground. Otherwise, just use a wire to short 9 to GND.

After a Keyboard.write() or Keyboard.print() function has been performed by the Pro Micro, your computer will have to decide what to do with it. What your computer does with that character, or string of characters, is entirely dependent on what program it’s running at the time. If you have a text editor open and active, it’ll print it out there.

USB Mouse Functionality

That covers about half of USB HID library. How about we add a mouse to the mix now? Implementing a USB HID mouse requires a few more functions, but it’s still crazy simple. There are five functions provided by Arduino’s HID class that can be used to implement a mouse:

  • Mouse.move(x, y, wheel) tells the computer to move the mouse a certain number of pixels along either the x, y and/or wheel axis. Each variable can be any value between -128 and +127, with negative numbers moving the cursor down/left, positive numbers move the right/up.

  • Mouse.press(b) sends a down-click on a button or buttons. The button(s) will remain “pressed” until you call Mouse.release(b). The b variable is a single byte, each bit of which represents a different button. You can set it equal to any of the following, or OR (|) them together to click multiple buttons at once:

    • MOUSE_LEFT - Left Mouse button
    • MOUSE_RIGHT - Right Mouse button
    • MOUSE_MIDDLE - Middle mouse button
    • MOUSE_ALL - All three mouse buttons
  • Mouse.click(b) sends a down-click (press) followed immediately by an up-click (release) on button(s) b. For example, to click the left and right buttons simultaneously, try this:

Mouse.click(MOUSE_LEFT | MOUSE_RIGHT); // Press and release the left and right mouse buttons

Here’s some example code to show off these functions:

language:c
/* HID Joystick Mouse Example
   by: Jim Lindblom
   date: 1/12/2012
   license: MIT License - Feel free to use this code for any purpose.
   No restrictions. Just keep this license if you go on to use this
   code in your future endeavors! Reuse and share.

   This is very simplistic code that allows you to turn the
   SparkFun Thumb Joystick (http://www.sparkfun.com/products/9032)
   into an HID Mouse. The select button on the joystick is set up
   as the mouse left click.
 */
int horzPin = A0;  // Analog output of horizontal joystick pin
int vertPin = A1;  // Analog output of vertical joystick pin
int selPin = 9;  // select button pin of joystick

int vertZero, horzZero;  // Stores the initial value of each axis, usually around 512
int vertValue, horzValue;  // Stores current analog output of each axis
const int sensitivity = 200;  // Higher sensitivity value = slower mouse, should be <= about 500
int mouseClickFlag = 0;

void setup()
{
  pinMode(horzPin, INPUT);  // Set both analog pins as inputs
  pinMode(vertPin, INPUT);
  pinMode(selPin, INPUT);  // set button select pin as input
  digitalWrite(selPin, HIGH);  // Pull button select pin high
  delay(1000);  // short delay to let outputs settle
  vertZero = analogRead(vertPin);  // get the initial values
  horzZero = analogRead(horzPin);  // Joystick should be in neutral position when reading these

}

void loop()
{
  vertValue = analogRead(vertPin) - vertZero;  // read vertical offset
  horzValue = analogRead(horzPin) - horzZero;  // read horizontal offset

  if (vertValue != 0)
    Mouse.move(0, vertValue/sensitivity, 0);  // move mouse on y axis
  if (horzValue != 0)
    Mouse.move(horzValue/sensitivity, 0, 0);  // move mouse on x axis

  if ((digitalRead(selPin) == 0) && (!mouseClickFlag))  // if the joystick button is pressed
  {
    mouseClickFlag = 1;
    Mouse.press(MOUSE_LEFT);  // click the left button down
  }
  else if ((digitalRead(selPin))&&(mouseClickFlag)) // if the joystick button is not pressed
  {
    mouseClickFlag = 0;
    Mouse.release(MOUSE_LEFT);  // release the left button
  }
}

This sketch is set up so that an analog joystick connected to analog pins A0 and A1 can be used to move your mouse cursor.

The loop() of this code continuously monitors the horizontal and vertical analog values of the joystick and sends the Mouse.move() command based on what it reads. It’ll move the mouse in steps, depending on what the sensitivity variable is set to. With sensitivity set to 2, the cursor will move in either 1 or 2 pixel steps.

The select switch on the joystick is used to control the mouse left click. Notice this code is using Mouse.press() and Mouse.release(), rather than just calling a single Mouse.click(). This requires a bit more coding, but it allows you to do things like drag-and-drop, double click, etc.


For more HID example code, check out the Arduino-supplied examples under the ‘File’ >‘Examples’ >‘09.USB’ menu.

Troubleshooting and FAQ

On this page you’ll find troubleshooting tips and FAQs. Here’s a directory of the subjects covered:


Serial Port Not Showing Up in ‘Tools > Board’ Menu

The Pro Micro can be a finicky little thing. There are a few series of events that can lead to its serial port being removed from the Arduino IDE’s Serial Port selection menu. If you can’t see your Pro Micro’s serial port, give these steps a try:

  1. Close all Arduino windows. (Don’t forget to save!)
  2. Unplug Pro Micro from your computer.
  3. Wait a few seconds for the device to be detached.
  4. Plug Pro Micro back in.
  5. Open Arduino back up, check the Serial Ports menu again.

Reset to Bootloader

We ship the Pro Micro with a modified version of the Arduino Leonardo bootloader, with one major enhancement. When a Leonardo (or any device using the “stock” bootloader) is externally reset, it goes back into the bootloader…and waits there eight seconds before it starts running the sketch. For some embedded projects, waiting eight seconds before a program runs isn’t acceptable, so we modified the bootloader run time.

Leonardo bootloader functionality

Leonardo bootloader on reset functionality.

When a Pro Micro is externally reset (by pulling the RST pin low), it’ll only briefly (<750ms) start the bootloader before continuing on to the sketch. If you need the bootloader to run longer, resetting twice quickly will get the Pro Micro to enter bootloader mode for eight seconds.

Pro Micro bootloader functionality

Pro Micro and Fio v3 reset functionality. Press reset twice, quickly to enter bootloader mode.

Resetting the Pro Micro’s, in particular, can be tricky, because there’s no reset button. The ‘RST’ pins needs to be connected to ground to initiate a reset. This can be done with a small piece of wire, or an externally connected button.

Reset pin location

Why would you need to enter bootloader mode in the first place. Glad you asked…

How to Revive a “Bricked” Pro Micro

Incorporating all of the USB tasks on a single chip is an awesome feature that makes the Pro Micro and boards like it truly unique. But it also places more stress on a single chip, and if anything goes wrong with that chip, the board becomes nearly unusable. It’s not uncommon for Pro Micro’s to become “bricked” and unprogrammable. But, in most cases, the bricking is reversible!

The most common source of Pro Micro “bricking” is uploading code to it with an incorrectly set board (e.g. programming a 16MHz/5V Pro Micro with the board set to 8MHz/3.3V). Also, make sure your sketch doesn’t mess with the ATmega32U4’s PLLCSR register, or any other register that sets up USB functionality on the ATmega32U4. The Pro Micro will actually take code compiled for the wrong operating speed, but when it tries to re-enumerate, you’ll be greeted with a notification like this:

USB device not recognized

To revive the Pro Micro, you’ll need to find a way to upload a sketch to it with the board option correctly set. We can do this with a little help from the bootloader.

First, you’ll need to set the serial port to the bootloader. But that port is only visible when the board is in bootloader mode, so pull the reset line low twice quickly to invoke the bootloader reset feature discussed above. On Pro Micro’s, or other devices which don’t have a reset button, you can either use a wire to quickly short ‘RST’ to ‘GND’ twice, or wire up a temporary reset button. While the Pro Micro is in the bootloader change the ‘Tools > Serial Port’ menu to the bootloader COM port. Quick! You’ve only got eight seconds. On Windows, the bootloader’s COM port number is usually one number higher than the Pro Micro’s regular port number.

With the serial port set, we’re just about ready to re-upload our sketch. But first, double check that the board is correctly set. Then reset to bootloader again, and quickly upload your sketch. Again, you’ll have to be quick…you’ve only got eight seconds. It may help to press the Upload keybind – CTRL+U / CMD+U – immediately after resetting.

It can take a few tries to get the timing right. Since the code has to compile first, it may help to hit upload first and then reset.


Frequently Asked Questions

If you’re having technical difficulties with your Pro Micro or Fio v3, see if any of the answers to these FAQs help. If not, please get in touch with our tech support team.

What are VID and PIDs?

VID is short for ‘Vender Identification’ and PID is short for ‘Part Identification’. In other words, this pair of IDs defines the device. This is how your computer knows what you’ve plugged in, what drivers to use with it, what COM port is assigned to it, etc. All native USB devices have a VID/PID.

All SparkFun ATmega32U4 boards share the same VID – 0x1B4F, and they all have unique PIDs. 5V Pro Micros lay claim to PIDs 0x9205 and 0x9206 (one for the bootloader, one for the sketch). 3.3V Pro Micros will show up as 0x9203 and 0x9204 for bootloader and sketch, respectively. And the Fio v3 has 0xF100 and 0xF101.

How Can I Change the VID and PID on an ATMega32U4 Board?

Every time you upload code the VID and PID are uploaded to the device. These values are located in the ‘boards.txt’ file and will therefore be determined by the board you have selected. Keep in mind that if you select the wrong board you will get the wrong VID/PID uploaded which means the computer can’t recognize, and program the board. The VID/PID for the bootloader is part of the bootloader file. To change this you will need to recompile the bootloader with the new VID/PID, and upload it.

Why Does my ATMega32U4 Board Show up Twice in Device Manager?

Both the bootloader and the sketch have their own VID/PIDs. When you plug in a board the bootloader starts running for a few seconds, and you will see the board show up in Device Manager based on those VID/PIDs. After a few seconds, the sketch will start running, and you will see Device Manager disconnect from the bootloader and connect to the sketch.

How Does the IDE Know Which COM Port to Use?

When the IDE resets the board, the COM port is disconnected from the computer. The IDE then looks for a new COM port. This is the port it uses. This is one of those weird things Arduino did to get things to work on this chip.

How Do I Reinstall the Bootloader?

Check out or reinstalling the bootloader tutorial, which should work for both ATMega32U4 and ATMega328 boards. If you have the tools to do so, reinstalling the bootloader is often easier then trying to stay in the bootloader. Since reinstalling the bootloader puts the board back in factory settings this will reset the VID/PID numbers allowing your board to work again.

Resources & Going Further

Thanks for checking out our Pro Micro and Fio v3 Hookup Guide! If you’re looking for more resources related to these boards, here are some links:

Going Further

Thanks for reading along with our Pro Micro hookup guide! Hopefully now you’re fully prepared to begin using the Pro Micro in a project of your own. Here are some tutorials that might be worth checking out as you continue down the rabbit hole:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Arduino Comparison Guide

0
0

Arduino Comparison Guide a learn.sparkfun.com tutorial

Introduction

Let’s face it, there are a a lot of different Arduino boards out there. How do you decide which one you need for your project? In this tutorial, we’ll take a look at the diverse world of Arduino boards. We’ll begin with a tabular overview of the features each board has. Then we’ll delve deeper into each board, examining the pros, cons, and example use-cases.

Fistful of Arduinos

Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It’s intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments. Or more simply, you load on some code and it can read sensors, perform actions based on inputs from buttons, control motors, and accept shields to further expand it’s capabilities. Really, you can do almost anything.

All Arduino boards have one thing in common: they are programmed through the Arduino IDE. This is the software that allows you to write and upload code. Beyond that, there can be a lot of differences. The number of inputs and outputs (how many sensors, LEDs, and buttons you can use on a single board), speed, operating voltage, and form factor are just a few of the variables. Some boards are designed to be embedded and have no programming interface (hardware) which you would need to buy separately. Some can run directly from a 3.7V battery, others need at least 5V. Check the chart on the next page to find the right Arduino for your project.

Suggested Reading

  • If you don’t know what Arduino is but found yourself here, you may want to start with our What is an Arduino tutorial.
  • You should also have a good understanding of the Arduino IDE. If you need help installing it, visit this tutorial.

Totally Tabular

For a quick cross-comparison of the available Arduinos, here’s a (totally tubular) tabular look at the variety of boards. The boards are sorted by their main microcontroller, which is what defines most of the characteristics for each of them.


ItemSystem VoltageClock SpeedDigital I/OAnalog InputsPWMUARTProgramming
Interface
Cost
ATmega328 Boards — 32kB Program Space // 1 UART // 6 PWM // 4-8 Analog Inputs // 9-14 Digital I/O
[UnoR3]
Arduino Uno - R3
5V 16MHz 14 6 6 1 USB via ATMega16U2$29.95
[UnoSMD]
Arduino Uno R3 SMD
5V 16MHz 14 6 6 1 USB via ATMega16U2$29.95
[RedBoard]
RedBoard
5V 16MHz 14 6 6 1 USB via FTDI$24.95
[Pro 3V]
Arduino Pro 3.3V/8MHz
3.3V 8MHz 14 6 6 1 FTDI-Compatible Header$14.95
[Pro 5V]
Arduino Pro 5V/16MHz
5V 16MHz 14 6 6 1 FTDI-Compatible Header$14.95
[Mini05]
Arduino Mini 05
5V 16MHz 14 8 6 1 FTDI-Compatible Header$33.95
[ProMini3]
Arduino Pro Mini 3.3V/8MHz
3.3V 8MHz 14 8 6 1 FTDI-Compatible Header$9.95
[ProMini5]
Arduino Pro Mini 5V/16MHz
5V 16MHz 14 8 6 1 FTDI-Compatible Header$9.95
[Arduino Ethernet]
Arduino Ethernet
5V 16MHz 14 6 6 1 FTDI-Compatible Header$59.95
[Fio]
Arduino Fio
3.3V 8MHz 14 8 6 1 FTDI-Compatible Header or Wirelessly via XBee$24.95
[LilyMain]
LilyPad Arduino 328 Main Board
3.3V 8MHz 14 6 6 1 FTDI-Compatible Header$21.95
[LilySimp]
LilyPad Arduino Simple Board
3.3V 8MHz 9 4 5 0 FTDI-Compatible Header$19.95
ATmega32U4 Boards — 32kB Program Space // 1 UART // 5-7 PWM // 12 Analog Inputs // 9-20 Digital I/O
[Leo]
Arduino Leonardo
5V 16MHz 20* 12 7 1 Native USB$24.95
[ProMicro5]
Pro Micro 5V/16MHz
5V 16MHz 12 12 5 1 Native USB$19.95
[ProMicro3]
Pro Micro 3.3V/8MHz
3.3V 8MHz 12 12 5 1 Native USB$19.95
[LilyUSB]
LilyPad Arduino USB
5V 16MHz 9 12 5 0 Native USB$24.95
ATmega2560 Arduino Mega's — 256kB Program Space // 4 UARTs // 14 PWM // 16 Analog Inputs // 54 Digital I/O
[2560R3]
Arduino Mega 2560 R3
5V 16MHz 54 16 14 4 USB via ATMega16U2$58.95
[MegaPro3]
Mega Pro 3.3V
3.3V 8MHz 54 16 14 4 FTDI-Compatible Header$44.95
[MegaPro5]
Mega Pro 5V
5V 16MHz 54 16 14 4 FTDI-Compatible Header$44.95
[MegaProMini]
Mega Pro Mini 3.3V
3.3V 8MHz 54 16 14 4 FTDI-Compatible Header$49.95
AT91SAM3X8E Arduino Due — 512kB Program Space // 4 UARTs // 12 PWM (2 DAC) // 12 Analog Input // 54 Digital I/O
[Due]
Arduino Due
3.3V 84MHz 54 12 12 4 USB native$49.95


*The Arduino Leonardo has the same GPIO pin-count as the other “Uno” style boards, but more of the pins play “double duty” as both analog and digital pins, hence the higher numbers.

The miniUSB connector on the Arduino Fio is used for battery charging only. An Xbee module is not included with this board.

The LilyPad Simple Board does have one UART but the pins aren't broken out to pads. Serial communication can be achieved through the FTDI header.

Glossary of Terms:

Microcontroller (MCU): The microcontroller is the heart (or, more appropriately, the brain) of the Arduino board. The Arduino development board is based on AVR microcontrollers of different types, each of which have different functions and features.

Input Voltage: This is the suggested input voltage range for the board. The board may be rated for a slightly higher maximum voltage, but this is the safe operating range. A handy thing to keep in mind is that many of the Li-Po batteries that we carry are 3.7V, meaning that any board with an input voltage including 3.7V can be powered directly from one of our Li-Po battery packs.

System Voltage: This is the system voltage of the board, i.e. the voltage at which the microcontroller is actually running. This is an important factor for shield-compatibility since the logic level is now 3.3V instead of 5V. You always want to be sure that whatever outside system with which you’re trying to communicate is able to match the logic level of your controller.

Clock Speed: This is the operating frequency of the microcontroller and is related to the speed at which it can execute commands. Although there are rare exceptions, most ATmega microcontrollers running at 3V will be clocked at 8MHz, whereas most running at 5V will be clocked at 16MHz. The clock speed of the Arduino can be divided down for power savings with a few tricks if you know what you’re doing.

Digital I/O: This is the number of digital input/output (I/O) pins that are broken out on the Arduino board. Each of these can be configured as either an input or an output. Some are capable of PWM, and some double as serial communication pins.

Analog Inputs: This is the number of analog input pins that are available on the Arduino board. Analog pins are labeled "A" followed by their number, they allow you to read analog values using the analog-to-digital converter (ADC) in the ATMega chip. Analog inputs can also be configured as more digital I/O if you need it!

PWM: This is the number of digital I/O pins that are capable of producing a Pulse-width modulation. (PWM) signal. A PWM signal is like an analog output; it allows your Arduino to “fake” an analog voltage between zero and the system voltage.

UART: This is the number of separate serial communication lines your Arduino board can support. On most Arduino boards, digital I/O pins 0&1 double as your serial send and receive pins and are shared with the serial programming port. Some Arduino boards have multiple UARTs and can support multiple serial ports at once. All Arduino boards have at least one UART for programming, but some aren't broken out to pins that are accessible.

Flash Space: This is the amount of program memory that the chip has available for your to store your sketch. Not all of this memory is available as a very small portion is taken up by the bootloader (usually between 0.5 and 2KB).

Programming Interface: This is how you hook up the Arduino board to your computer for programming. Some boards have a USB jack on-board so that all you need to do is plug them into a USB cable. Others have a header available so that you can plug in an FTDI Basic breakout or FTDI Cable. Other boards, like the Mini, break out the serial pins for programming but aren’t pin-compatible with the FTDI header. Any Arduino board that has a USB jack on-board also has some other hardware that enables the serial to USB conversion. Some boards, however, don’t need additional hardware because their microcontrollers have built-in support for USB.


This table serves to overview all of the Arduino boards. You may have an idea of which Arduino board is right for you now. On the next few pages we’ll split into different categories of Arduinos and explore their differences more closely.

ATmega328 Boards

The ATmega328 (and the ATmega168 before that, and ATmega8 before that,…) is a staple of the Arduino platform. 32kB of flash (program space), up to 23 I/Os – eight of which can be analog inputs – operating frequencies of up to 20 MHz. None of it’s specifications are flashy, but this is still a solid 8-bit microcontroller. For many electronics projects, what the 328 provides is still more than enough.

The Arduino boards on this page all feature the ATmega328 as their main MCU brain. The microcontroller alone makes every board on this page nearly identical in terms of I/O count and memory. Their differences stem from things like programming interfaces, form factors, and operating voltages.

The Main Event: Arduino Uno

The Arduino Uno is the “stock” Arduino. It’s what we compare every, other, Arduino-compatible board to. If you’re just getting into Arduino, this is the board to start with.

Arduino Uno

The Uno comes in two flavors, through-hole and SMD, which use either a through-hole or surface-mount ATmega328. The through-hole version (pictured above) is nice because you can take the chip out and swap in a new one (in case the magic, blue smoke is released), but the SMD version has the potential to be more readily available (PTH chips are increasingly being phased out of existence).

The Arduino Uno can be powered through either the USB interface, or an external barrel jack. To connect it to a computer you’ll need a type-B-to-A USB cable (like the USB connector on most printers).

A Modification: RedBoard

One of the greatest things about Arduino is the fact that the entire project is open-source. The schematics, hardware design files, and source code are all freely available for viewing and modification. Released under a Creative Commons Share Alike license, anyone is free to riff on the hardware design and produce their own version. That’s how a product like the RedBoard comes to be. It still looks and acts just like an Arduino Uno, but is slightly modified to make the board better-suited to certain purposes.

RedBoard

The RedBoard is nearly identical to the Uno, but there are a few key differences:

  • USB connector: The Redboard uses the smaller mini-B connector, so you’ll need a mini-B-to-A USB cable to connect it to your computer.
  • USB-to-Serial Transciever: The Arduino Uno uses an ATmega16U4 loaded with custom firmware to convert between USB and serial. The RedBoard uses the FTDI FT232RL. This difference is only really prevalent when installing drivers because each requires a different driver file.
  • SMD vs PTH: The RedBoard is only offered in a SMD version, and it takes SMD a step further by making every component surface-mount. No sharp edges on the bottom of the board!
  • Color: True to it’s name, the RedBoard comes in Ferarri SparkFun red. It won’t have any real influence on the operation of the Arduino, but it certainly affects the board’s swag-factor.
  • Price: Because we manufacture the board in-house, here in Boulder, CO, we can afford to keep the price-tag a tad lower.

Like the Uno, the RedBoard is great for beginners. On the whole, it should offer the same Arduino experience as an Uno might. For a deeper comparison between the RedBoard and Uno, check out our RedBoard vs. Uno tutorial.

For the Pros

Arduino Pros are a scaled-down version of the Uno. There’s still an ATmega328 on there, but removed are the connectors and USB-to-serial-converting circuitry. Basically, this is the bare-minimum an Arduino needs to still be an Arduino. As the name would imply, these boards are intended for use by more experienced Arduino-ers.

Arduino Pro

You’ll need more than just a USB cable to program an Arduino Pro; an external board is required to convert USB from your computer to serial that the Arduino understands. There are various boards and cables that can accomplish this task, we recommend the FTDI Basic Breakout.

FTDI Basic

This board mates up to the 6-pin, right-angle connector on the edge of the board. When you’re done programming and ready to stick the board into a project, just unplug the FTDI Basic.

The smaller form factor and absence of connectors means this board can be more custom-tailored to fit into a project. You can solder wires or connectors directly onto the pins you need. Then again, it has the same pin footprint as the Uno, so it’s still shield compatible.

The Pros come in two varieties: 5V/16MHz and 3.3V/8MHz. The 5V/16MHz board runs at the same voltage and speed as the Arduino Uno. The 3.3V/8MHz board is unique, though, because it can operate at a lower voltage. A lower operating voltage makes the board easier to power with batteries (LiPos specifically), but it also means the clock speed has to be turned down. The 3.3V/8MHz board runs at half the speed a regular Arduino Uno…but 8MHz is still pretty darn fast for many applications. You can still turn an LED on and off more than a million times per second!

Of course, if this board is still to big, you can shrink it down even further…

Pro Mini’s

The Mini boards pack all of the remaining punch of the Arduino Pro into a much smaller footprint. Every pin is still broken out (actually, more pins are broken out), they’re just in a very different footprint.

Pro Mini with attached FTDI Basic

An Arduino Pro Mini attached to an FTDI Basic, which provides power and uploads code.

Obviously, these boards aren’t shield-compatible, but they are breadboard-compatible. You can solder male headers into the Pros, and straddle it across the breadboard’s middle strip. The small form-factor also makes them very conducive to embedding into projects (like in the H2O pH Probe).

Like the regular Pro boards, these are offered in 5V/16MHz and 3.3V/8MHz varieties. And you still have to program them with an FTDI Basic.

The Arduino Mini 05 could also be lumped into this category. It shares a lot in common with the Pro Minis, except it comes with male headers pre-soldered in.

Arduino Mini

Etcetera

There are innumerable Arduino-compatible boards out there which make use of the ATmega328. Many, like the Arduino Pros, require an FTDI Basic to receive code, but they add on extra hardware to make them unique. The Arduino Ethernet, where the Arduino Uno and an Ethernet Shield are smashed onto a single board, is a good example of this.

Arduino Ethernet

And, the Arduino Fio too. This board wires up the ATmega328 to an XBee (or XBee-compatible) wireless transceiver, so your Arduino can communicate wirelessly with other devices.

Arduino Fio

The list could go on and on. If you see a board with that recurring, six-pin, serial header, and an ATmega328 doing all of the processing, its specifications probably aren’t all that different from an Arduino Pro.

ATmega32U4 Boards

The next step in the Arduino evolutionary chain was merging the USB-to-Serial programming part of the board onto the main MCU. That meant we had to leave the ATmega328 behind – becuase it doesn’t natively support USB – in favor of the ATmega32U4. Aside from the additional USB support, the 32U4 is largely similar to the 328. Both are 8-bit AVRs with 32kB of flash memory, 22-ish I/O lines, ADCs, UARTs, timers, etc.

These ATmega32U4 boards often have the benefit of being cheaper than the ATmega328-based boards – there’s one less costly IC to put on there. They can also do things regular Arduino boards can’t, like emulate a USB keyboard/mouse. On the downside, they can be less reliable, and more difficult to use.

Arduino Leonardo

The Leonardo is the patriarch of all ATmega32U4 Arduino boards. It shares the same form factor and I/O placement (analog, PWM, I2C pins in the same place) as the Arduino Uno, so it remains shield compatible.

Arduino Leonardo

Differences between the Leonardo and the Uno? Aside from the new microcontroller, and lack of a second USB-to-Serial-converting IC, there’s not many. The USB connector is different, the Leonardo connects to a computer via a micro-B USB cable. The driver installation process is also a bit more involved – sometimes it can take a little extra fidgeting to get the board installed on your computer.

Pro Micro

Just as the Pro Mini took the guts of the Arduino Uno and shrunk them down, the Pro Micro works as a miniature version of the Leonardo. Unlike the Pro Mini, the Pro Micro doesn’t require an external board to upload a sketch – the 32U4 takes care of everything!

Pro Micro

The Pro Micro comes in the standard 5V/16MHz operating range or a more unique 3.3V/8MHz variant.

Pro Micros are among the more complicated Arduino boards to get up and running. There are extra steps required to enable them in your Arduino environment, and a misstep can (at least temporarily) “brick” the Pro Micro.

These boards are a good choice if you’re an advanced Arduino-er and have a small USB-oriented project in mind (a mini USB keyboard/mouse?).

More Variants!

There are plenty of other riffs on the Leonardo design as well. There’s the Fio v3, for any Arduino Leonardo project you might want to add an XBee to.

Fio v3

And there are more unique Leonardo-compatible boards, like the MaKey MaKey, which can turn almost anything (from tin foil to Play-Doh to bananas) into a keyboard key.

MaKey MaKey

The ATmega32U4 can make some very cool USB-integrated Arduino projects.

Wearable Arduinos

The e-textiles segment of the Arduino market is ruled by LilyPads. These are identifiable as unique purple, flowery-looking, circular boards. The pins on LilyPads are called “petals”, they have bigger holes and copper filled to the edge of the board. These are designed so conductive thread can be sewn through the holes, and make electrical contact with the exposed copper on the petal.

LilyPad sewn into fabric

LilyPads are great for e-texitles – projects which combine electronics and fabric wizardy. They can be used to make nifty talking aprons, dice gauntlets, or more simple trinkets like light-up firefly jars.

ATmega328 LilyPads

The O.G. LilyPad is the LilyPad Arduino. This is basically a purple Arduino Pro 3.3V/8MHz. All of the pins – 14 digital and six analog – are arranged around the outer edge of the board. There are also inputs for power at the ‘+’ and ‘-’ pins.

LilyPad Arduino

Like the Arduino Pro, the ATmega328 LilyPads are all programmed using an external FTDI Basic. There’s even a purple one especially for LilyPads!

Keep it Simple

True to its name, the LilyPad Arduino Simple is an easier-to-use version of the standard LilyPad Arduino. Fewer pins are broken out – nine digital and four analog – but the LilyPad Simple has some added functionality too. This board is designed specifically to be powered by a Lithium Polymer battery. There’s an on-board JST connector for the battery to plug into, and there’s even a special circuit dedicated to charging the battery.

LilyPad Arduino Simple

This Board is recommended for beginners and experts alike. As long as you’re OK with having less I/O pins, the extra functionality of the Simple makes it well worth it.

Make it Snappy

The LilyPad Arduino SimpleSnap is an offshoot of the Simple. The layout is the same, the battery-charging functionality is still there, but instead of an array of petals around the board there are snaps.

LilyPad Arduino SimpleSnap

These snaps can be plugged into the mating snaps on a SimpleSnap ProtoBoard, or any size 1/0 snap already sewn into a fabric.

A permanently attached battery on the SimpleSnap also sets it far apart from other LilyPad boards. Just flick the switch to “ON” and the board should start running its sketch. To charge the battery, plug an FTDI Basic into the SimpleSnap.

This board is an awesome choice if you want the added ability of easily removing your LilyPad from an e-textiles project. You can unsnap the board and wash your textile, or even share it with another project.

LilyPads with USB Built-In

The boards above – all with an ATmega328 as the brain – all require an external FTDI Basic to have code uploaded to them. The LilyPad Arduino USB– which uses an ATmega32U4 – has all of the USB functionality on-board. It has a micro-B USB connector, so you just plug the cable in, attach it to your computer, and program away!

LilyPad Arduino USB

The LilyPad Arduino USB is comparable to other ATmega32U4 boards, like the Leonardo. It’s got nine digital I/O’s and 12 analogs. Like the LilyPad Simple, this board has an on-board JST connector and LiPo battery charge circuit. So it’s very easy to pair with a LiPo battery and embed into your project.

Megas, ARMs, Yúns...Oh My!

Need some extra “beef” in your Arduino? Need more I/O pins, or a faster processor? That’s where Arduino’s like the Mega or the Due come into the picture.

Arduino Mega: The Souped Up Uno

The Arduino Mega is what you might get if you packed four Arduino Uno’s into one board. There are 54 I/O pins, instead of the 14 an Uno gives you. That’s a whole lot of extra LEDs! Instead of one hardware serial port, there are four. And the Mega sports a whopping 256 kB of flash program space. Not to mention 16 analog inputs, and 14 PWM outputs. The Mega just has more of everything.

Arduino Mega 2560 R3

The brain of the Mega is an ATmega2560, a fully souped up ATmega328. Aside from the massive processor overhaul, the Mega still shares a lot in common with the Arduino Uno. There’s a secondary IC on-board (an ATmega16U2) to convert USB-to-serial to allow USB programming. It runs at the same speed – 16 MHz. All of the pins are broken out in a way that keeps the board shield-compatible. Because of these similarities, the Mega is a good option for Arduino beginners and experts alike.

If your Arduino project is hitting a wall because you don’t have enough I/O, or if you’re running out of program space, consider stepping up to the Mega.

Mega Pros

This seems to be a trend, doesn’t it? If you’re looking for a stripped-down version of the Mega – no USB-to-serial converter, no connectors – there’s the Mega Pro 5V and 3.3V/8MHz variants.

Mega Pro

With all of those I/O’s it’s hard to make a “mini” version, but the Mega Pro Mini 3.3V gets close. This board breaks out each of the pins to sets of small 8-pin connectors. A special cable is required to interface with them.

Mega Pro Mini

Like other Pro Arduinos before them, the Mega Pros all require an FTDI Basic for programming.

Arduino Due: Arduino Harder

You thought the Mega was powerful? The Arduino Due is a revolutionary take on the Arduino platform. It sports an entirely different processor architecture – ARM instead of AVR. It’s a 32-bit processor, clocks in at 84 MHz, and has native USB support.

Arduino Due

This thing sports many unique features that other boards don’t have. Stuff like:

  • Two digital-to-analog converters (DACs), which allow the board to output true analog values (instead of PWM). This means you can play audio out it!
  • USB on-the-go (OTG) capability allows the Due to act as both a USB device and a host. So you can hook up other USB devices – like flash drives, WiFi modules, or phones – to the Due.
  • Direct Memory Access (DMA) allows the microcontroller to offload memory-access tasks, so it can perform other operations at the same time.

There are also some new things to watch out for. The Due’s processor – an ATSAM3X8E – can’t work at 5V, so the board only runs at 3.3V This means it may not be compatible with all shields.

The Due has some amazing functionality, but it’s also a more advanced board. It’s not recommended for beginners, but if you have a project that might take advantage of the Due’s unique characteristics, check it out!

Arduino Yún

The Arduino Yún has true microprocessor power. It actually runs Linux! It works over WiFi! It’s awesome.

Arduino Yún

The Yún combines an ATmega32U4 (the same MCU on Leonardos) and an embedded Linux machine running the OpenWRT Linux OS. The two processors are “bridged” together. You program the ATmega32U4, just like you program an Arduino Leonardo, over USB. The 32U4 can send commands to the Linux processor, just as you might send commands to your Linux computer in a terminal.

This board is packed full of all sorts of neat features. It can be programmed over-the-air, as long as your computer is on the same WiFi network. It’s designed to easily interact with the Internet, so if your intend on making an “Internet-of-Things”-type project, the Yún may be the perfect Arduino.

Going Further

Have you picked the perfect Arduino for your project? Looking for more Arduino tutorials? Check these out:

  • Installing Arduino– Gotta get the software and drivers installed before you can start programming!
  • Arduino Programming 101– Learn the basics of Arduino programming – digitalReads, digitalWrites, analogReads, analogWrites and more!
  • Data Types in Arduino– Learn the difference between int, char, float, and long.
  • Arduino Shields– Give your Arduino a little extra something with a shield. You could give the Arduino GPS, or allow it to communicate wirelessly with other devices.
  • E-Textile Basics– If you’re intrigued by the possibilities of the wearable LilyPad Arduinos, check out this tutorial to learn the basics of e-textiles.

learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

ELastoLite Hookup Guide

0
0

ELastoLite Hookup Guide a learn.sparkfun.com tutorial

Introduction to ELastoLite

ELastoLite Lamp and Inverter

In this tutorial, we will be discussing ELastoLite EL Lamps from Oryon Technologies, and we will be showing you how to connect a single ELastoLite lamp to a single inverter. ELastoLite is desirable for use in E-textiles and wearable applications due to it’s waterproof outer covering and extreme flexibility. In addition, the circuitry is contained in an iron on casing that allows you to attach it to the inside of the garment or material eliminating free floating wires that can become disconnected easily or are just all around an inconvenience. It is imperative that you read this whole tutorial before attempting to add ELastolite to your garments as the process is not as straight forward as it seems, and there is lots of room for irreversible mistakes.

Now, you’re probably reading this tutorial because you’re confused about which parts you’ll need for your project. We didn’t put together a kit for ELastoLite because the parts needed will vary so much that a standard starter kit would benefit very few people. This tutorial aims to help you decide which parts you’ll need and how to connect them all.

NOTE: ELastoLite runs off of AC, similer to EL wire, and it can give you a slight shock if not handled properly. Please handle ELatsoLite panels, connectors, and inverters with care.

You Will Learn

Topics covered in this tutorial include:

  • Plotting your design
  • Choosing the correct parts
  • Assembly techniques
  • Proper care.

There will be a small amount of math, but I promise, we will make it as easy as possible. We understand not everyone likes math as much as us.

Suggested Reading

This tutorial builds on some previously discussed concepts. If you are unfamiliar with any of these, please check out the corresponding tutorial.

Required Materials

The very first thing you’re going to want to do is gather all the materials you’ll need. Here’s our recommended list of tools and supplies to work with ELastoLite.

Tools Required

Iron

You’ll need an iron. Not a soldering iron, rather a fabric iron. The iron needs a cotton setting as that will be the optimum temperature to bond the connectors.

Hobby Knife

The circuitry will need to be stripped of it’s cover where the connections will be made. A hobby knife will make this easy.

Wax Paper

While some situations warrant the connector connection and ironing everything into the garment happening at once, others might go easier one at a time. Wax paper will help keep the iron on material sticking to your work surface. In addition, placing wax paper over top the circuitry when ironing it helps should you apply too much pressure or hold the iron on for too long.

Wire Strippers

There’s a small chance you may have to strip the inverter wires a little. So while not required, you might want to have a pair handy.

Patience

This can be a bit of a frustrating process. Keep your mind on the goal, and stay patient with yourself.

Choosing an Inverter

When choosing ELastoLite products, it’s very important to take into account how much power your inverter can provide. Therefor, before you begin buying ELastoLite panels, you should look at the inverter options to make sure you have enough juice to power all the panel you want in your project.

ELastoLite Lamp Options

An assortment of ELastoLite panels.

Oryon technologies have provided SparkFun with these great inverters designed specifically for ELastoLite. In addition to being rechargeable, the button is perfect for use in a garment. To cut down on the likelihood of false presses in a garment pocket, a prolonged press of the button is needed to change the flash rate or turn it on or off . There are two sizes of inverter, the INV133 and the INV135. Don’t let the numbers fool you, the INV133 is the more powerful of the two.

Inverter Choices

The INV133 inverter with connector (left), and the INV135 inverter with connector (right).

Which one you use will be dictated by how much lamp (panel space) you are using in your project. If the total area of the ELastoLite lamps you are using falls under 8 in2 then you want to use the INV135. It’s important that you use this inverter for the smaller areas as the built in circuit protection of the inverter could trip should load not be large enough. If your total area falls between 8 in2 and 20 in2, then you want to use the INV133. Any area above that will be too much for a single inverter and will need a combination of two or more. Here’s a set of equations to use to calculate this:

If Σ A1 + A2 + … ≤ 8 in² where A = Length*Width use INV135 and an Orange Molex Connector.

If 20 in² ≥ Σ A1 + A2 + … > 8 in² where A = Length*Width use INV133 and a Green Molex Connector.

The dimensions on the product page for each panel should include the area of each lamp. If not, the numbers in the product title will suffice (example: 3x5 inch lamp has an area of 3*5 or 15 in²).

Once you have the correct inverter(s) selected, you need to choose Molex connectors to go with the inverters. If you haven’t started already, I recommend start writing down the bill of materials. There are two colors that are associated with the two inverters respectively. I highly recommend buying the correct color as this will serve as an excellent reference for which inverter your circuit needs to be properly powered. The inverters have fantastic safety features, so a smaller area of lamps might not draw enough current to turn off the safety feature of the INV133. Additionally, the INV135 won’t have enough power to power some of the larger lamp configurations. Buying the correct color Molex connector will save you a lot of frustration down the road.

The INV135 corresponds to the orange Molex connector and the INV133 corresponds to the green one. You can double check this by the colors denoted on the label on the inverters.

inverter colors

Charging the Inverter

The inverters ship discharged, so you need to charge them before the first use. Simply plug the supplied USB Mini B cable to the Mini B USB connector on the inverter. This is the same method for re-charging when the inverter gets low on juice. Both the INV133 and the INV135 charge at 3.7V with a 1100mAh current. There is internal circuitry that regulates a 5V input down to the required 3.7V, so you can charge from a computer USB port or from a USB wall wart.

charge

Choosing the Right Circuitry

You should now have lamps, an inverter, and a Molex Connector picked out. We now need to buy the circuitry and connectors to connect them all. Below is the exploded view of the connection to be made between the Molex connector and the iron on circuitry.

Exploded View of the Molex Connection Parts

To make this connection you will need two of the straight connectors. One goes on the top, the other on the bottom. Those will be encased in an outer layer of iron-on tape. You will only need 1 unit of that. We sell them in 2 inch lengths. When cut in half, it provides the proper amount needed for the top and bottom.

The next part needed is the circuit tape which will provide the connection between the Molex connector and the actual ELastoLite lamp. We sell these in 3 foot lengths. I don’t recommend making connections longer than that. However, if you wish to, repeat the straight connector connection outlined above in the exploded view. Rather than the Molex leads on the one end, use another length of the iron-on circuitry. The lengths will become fully enclosed, and the conductive thread in the circuitry will need to be exposed (which we will cover later).

The contact patches that will help establish the connection between the iron on circuitry and the Lamp will be included with the Lamp (the little dots off to the side). Each Lamp comes with three patches. Two of the three will be used. The first will be used to establish the connection between the iron on circuitry and the lamp. The second one will do the same if there is a chain of more than one lamp. If not, the contact patch will be used to cover up the contact points on the Lamp which will be live when powered.

Closeup of Contact Patches

Buy ELastoLite Parts For Your Project

That’s an overview of the parts and their purpose. For this tutorial, I’m going to assemble a circuit of one 3x5 inch lamp and the INV133 inverter. Below is the wishlist for the parts that we’re going to use in the next section. Feel free to add or subtract parts as you see fit.

Once you have figured out the parts you will need for this, place your order and get excited. There is an additional T-junction part that can be used, but we will not be covering this piece in the Assembly. If you wish to add a T-connector, instructions can be found in the Going Further section.

Assembly

Now that you have all the parts and tools necessary, lets start assembling. First, plug the inverter into the USB cable and charge the inverter (you can use your computer port or a USB to wall socket power adapter). Lay out your fabric, and plot the path you’re going to want the circuitry to follow. Maintaining the shortest path possible is the main thing to conside. Also, do your best to route in a manner that keeps the connectors out of harms way such as areas where there with be lots movement, eg. shoulders, elbows, knees, etc. Another thing to consider is inverter placement. If it’s a garment, route it into a pocket. If not, make some form of support for it such as a pouch or straps. The circuitry will supply very little structural support for the heavy inverter, so you’re going to want to provide support to the inverter in another manner.

Once you have the circuitry cut to the length you need, you need to strip the ends. You’ll want about ⅕ of an inch on the end that will attach to the lamp and about ⅓ of inch on the end that will connect with the Molex connector. To strip the ends, simply take a hobby knife and make three incisions in the iron-on material perpendicular to the conductive thread. Be sure not to nick the thread as this could easily lead to a break in the thread after use. Once you have your three incisions, pull firmly yet lightly on the end of the iron-on sheath until it comes off, exposing the aforementioned lengths of thread.

Stripped end of Circuitry

Next, you need to decide whether you’re going to iron in the circuitry when making the connector or not. The process will be slightly easier if you do so now. If not, skip ahead to the part about making the inverter connection.

It’s time for some ironing. Go ahead and set the iron to the cotton setting. Once you have the circuitry path established, go ahead, and start ironing. Be sure to apply very little pressure as the weight of the iron will do most of the work, and keep everything as crease free as possible. Leave a couple of inches free at each end as it will be easier to work with when making the connections.

Ironing in the Circuitry

With the circuitry ironed in, we can start the molex connector assembly. Below is the exploded view of how it will go together. PLEASE READ THIS NEXT PART. The wire coming off molex connector is a bit deceiving. There are four wires, only two get used. The two wires we we’ll be using are the red and tan wires. The other wires need to be clipped off. The remaining wires should be stripped. If not, gently strip ¼ of an inch of the wire with wire strippers. It doesn’t matter which wire goes on which side as we’re supplying AC power from the inverter to the lamp.

Exploded View of the Molex Connection Parts

The straight connectors are going to be labeled with a “top” facing the direction that will go on the inside on the connection (the part you want touching the exposed wires). The iron-on tape that will form the outer layer of the connection needs to face a specific direction as well. You want the curve of the tape facing inward. If you can’t tell which side faces in, pinch it between your fingers and rub it back and forth. The side that sticks to your finger will face inward, and the side that faces out will slide across your finger. This is also the time to cut the tape in two equal pieces if you haven’t already.

If you’re not ironing this directly into the garment immediately, put some wax paper underneath before you bond the connector pieces. It’s imperative that the leads off the circuitry and the molex connector get sandwiched between the gray strips on each of the straight connectors. If they don’t sit in those strips, the connection won’t be made. Once you have everything in place like in the diagram above, place the iron over top for 10-15 seconds, then remove. Let it cool before handling it, the connection should be tightly secure. If you ironed the connection into the fabric when bonding it, make sure there’s no pockets of the circuitry that haven’t gotten ironed in (leave the lamp side loose still).

Completed Molex to Yarn Connection

Here we can see the Molex connector attached to the ELastoLite wires via the circuitry connector.

As I mentioned, the circuitry isn’t going to provide any support for the inverter, and you don’t want to risk the inverter pulling apart the bonded connection we just made between the circuitry and the molex connector. So, we’re going to sew in some support for the molex connector. I usually just sew an “X” over the outer insulation for the wire coming off the molex connector.

Now, we need to make the connection to the lamp. This connection is much more simple, thankfully. First, remove the lamp from the hard backing. If heat is applied too long, it could cause the lamp to bond to the backing. You’ll want the back (the side with the text on it) facing up, exposing the connection points (shown in the picture below).

Connection Points on the Lamp

Place the conductive thread over top the connection points then place the connection patch overtop with the letters “C P” facing up. Just like with the molex connection, sit the iron on top of the connection points for 10-15 seconds to make the bond. Let it cool, and insure the bond occurred and is stable. If not, there’s an extra connection patch that can be used to redo the bond.

Finally, if this is the last lamp in the daisy chain, you’ll want use the third connection patch to close the exposed connection points as they will be live. Follow the steps previously outlined to make the connection to the conductive thread. Just omit the conductive thread from the process.

ELastoLite Complete and Illuminated

Fastening the ELastoLite Lamp to your garment requires a little bit of sewing. It is possible to purchase more of the conductive tape and iron it to the back of the lamp then iron that onto the garment (this is an approved method from Oryon Tech). However, you will still have the edges exposed. I personally recommend sewing a fabric frame around the lamp. This will also allow you to create a shape for the lamp as cutting it and retaining it’s waterproofing is not possible. If you want to create a shape where a lot of the lamp will be hidden, use a heavier fabric to prevent the lamp from shining through. Sewing in a frame will also allow for the potential to swap out lamps should something unfortunate happen to original.

Resources and Going Further

You should know have a blinky, glowy awesome ELastoLite panel. You should also have a good understanding of how to use the various ELastoLite parts to make your project come to life. Be sure to check out these other great resources:

For more e-textile awesomeness, you can check out these tutorials:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Graphic LCD Hookup Guide

0
0

Graphic LCD Hookup Guide a learn.sparkfun.com tutorial

Introduction

Remember the days when cell phones were still “dumb,” and they had physical keypads and just a tiny monochrome LCD for a display? Now that iPhones, Galaxies, and the like have revolutionized that market, those little LCDs have to find a new purpose in life: adding customized graphical displays to projects!

Graphic LCD Lit Up

These 84 by 48 pixel black and white LCDs are what you might have found in an old Nokia 3310. They’re not flashy, and they don’t have a lot of display real-estate. But, they are easy to control. If you’re looking to step up your project’s user interface (UI) game from simple displays or LEDs, this graphic LCD is a good place to start.

In this tutorial we’ll show how to control these graphic LCDs with just an Arduino and a few wires in between. We’ll cover everything from hardware assembly to example code, and beyond.

Required Materials

Suggested Reading

Display Overview

Before diving into hookup and example code, let’s first take a look at the LCD and its breakout board. On this page we’ll cover everything from the pinout of the board to the interface used to control the display.

The Pinout

To interface with and power the graphic LCD, there are two, parallel 8-pin headers above and below it. Flipping the board over, you’ll find the labels for each of the pins.

Backside of the LCD

As you may be able to tell by the faint traces connecting them, each pin on one header is connected to the parallel pin on the other side. Here are the eight unique pins along with an overview of their purpose:

Pin NumberPin LabelPin FunctionInput/Output?Notes
1VCCPositive power supplyInputSupply range is between 2.7V and 3.3V
2GNDGroundInput
3SCEChip selectInputActive low
4RSTResetInputActive high
5D/CMode selectInputSelect between command mode (low) and data mode (high).
6DN(MOSI)Serial data inInput
7SCLKSerial clockInput
8LEDLED backlight supplyInputMaximum voltage supply is 3.3V.

Power Supplies

There are two different supply voltages on the LCD. The most important supply voltage – VCC– supplies the logic circuits inside the LCD. The datasheet states this should be between 2.7 and 3.3V. In a normal state, the LCD will consume about 6 or 7mA.

The second voltage supply is required for the LED backlights on the board. If you were to remove the LCD from the PCB (not that you should, or need to), you’d see that these are backlights in their simplest form – four white LEDs spaced around the edges of the board. You may also notice that there aren’t any current limiting resistors.

LCD removed from PCB

This means you have to be careful with this voltage supply. Either stick a current limiting resistor in series with the ‘LED’ pin, or limit the supply to 3.3V max. The LEDs can pull a lot of current! With nothing to limit them, they’ll pull about 100mA at 3.3V.

The Control Interface

Built into this LCD is a Philips PCD8544 display controller, which converts the massive parallel interface of the raw LCD to a more convenient serial one. The PCD8544 is controlled through a synchronous serial interface similar to SPI. There are clock (SCLK) and data (DN) input lines, and an active-low chip select (SCE) input as well.

On top of those three serial lines, there is another input – D/C– which tells the display whether the data it’s receiving is a command or displayable data.

For a list of commands, check out the “Instructions” section of the PCD8544 datasheet (page 11). There are instructions to enable clearing of the display, inverting the pixels, powering it down, and more.

Hardware Assembly & Hookup

Before we get to uploading code and sending data to the display, let’s take care of the hardware stuff first. That includes assembling the display, and hooking it up to the Arduino.

Assembly

To “assemble” the LCD, you’ll need to solder something to one (or both) of the 8-pin headers. There are plenty of options available here. To make the LCD breadboard-compatible, straight or right-angle male headers can be soldered in.

Headers plugged in example

LCD with strait male headers soldered in, plugged into a mini blue breadboard.

Otherwise, wires or other connectors can be soldered to the display pins.

Hookup

In this example we’ll be connecting the LCD up to an Arduino, but this hookup should be easily adaptable to other development platforms. For the data transmission pins – SCLK and DN(MOSI) – we’ll use the Arduino’s hardware SPI pins, which will help to achieve a faster data transfer. The chip select (SCE), reset (RST), and a data/command (D/C) pins can be connected to any digital I/O pin. Finally, the LED pin should be connected to a PWM-capable Arduino pin, so we can dim the backlight as we please.

Unfortunately, the LCD has a maximum input voltage of 3.6V, so we can’t hook up a standard 5V Arduino straight to it. We need to shift levels. This leads us to a few options for hookup:

Direct Connect

The easiest hookup is to connect the Arduino pins directly to the LCD. To allow for this easy hookup, you’ll need a 3.3V-operating Arduino like the 3.3V/8MHz Pro or 3.3V Pro Mini.

This setup can work for 5V Arduino’s, ignoring the 3.6V limit on the VCC and data lines. We’ve done this. It works. But it may decrease your LCD’s life.

Direct connect fritzing

The data pins are connected as follows:

LCD PinArduino PinNotes
1 - VCC3.3V (VCC)3.3V only (not 5V!)
2 - GNDGND
3 - SCE7Can be any digital pin.
4 - RST6Can be any digital pin.
5 - D/C5Can be any digital pin.
6 - DN(MOSI)11Can’t be moved.
SCLK13Can’t be moved.
LED9Can be any PWM pin. 330Ω resistor in between the pins.

Limiting Resistors

Sticking resistors in-line with the data signals is a cheap, and easy way to add some protection to the 3.3V lines. If you have an Arduino Uno (or similar 5V ‘duino) and some 10kΩ and 1kΩ resistors lying around, try this:

Connect via resistors

The pins are connected the same as in the above example, however each signal has an inline resistor. There are 10kΩ resistors between the SCLK, DN, D/C, and RST pins. A 1kΩ resistor between SCE and pin 7. And the 330Ω resistor remains between pin 9 and the LED pin.

Level Converters

Finally, a third option for hookup is to use actual level converters to switch between 5V and 3.3V. Boards like the Bi-Directional Logic Level Converter and the TXB0104 are perfect for something like this.

Level Shifter Example

Unfortunately, the LCD has five 3.3V signal inputs and the level shifters only have four channels. If you want to keep the circuit to a single shifter, you can permanently tie RST high (through a 10kΩ resistors), and run the other signals through the shifter. You lose remote reset capability, but the rest of the control remains.

Check out the hook up guides for those boards for more help in shifting the signal between Arduino and LCD.

Example Code 1: LCD Demo

With the hardware all hooked up, we’re ready to upload a sketch and start drawing on the LCD!

The Sketch

Here is a sketch-full of example LCD control code. This small novella of a sketch shows off an array of graphics driver functions, character drawing tools, and other useful functions to help you get started using the LCD. Copy/paste from below, or download the sketch by clicking here.

If you don’t have the Codebender plugin installed on your browser, you can view the same skecth below.

language:c
/* Nokia 5100 LCD Example Code
   Graphics driver and PCD8544 interface code for SparkFun's
   84x48 Graphic LCD.
   https://www.sparkfun.com/products/10168

  by: Jim Lindblom
    adapted from code by Nathan Seidle and mish-mashed with
    code from the ColorLCDShield.
  date: October 10, 2013
  license: Beerware. Feel free to use, reuse, and modify this
  code as you see fit. If you find it useful, and we meet someday,
  you can buy me a beer.

  This all-inclusive sketch will show off a series of graphics
  functions, like drawing lines, circles, squares, and text. Then
  it'll go into serial monitor echo mode, where you can type
  text into the serial monitor, and it'll be displayed on the
  LCD.

  This stuff could all be put into a library, but we wanted to
  leave it all in one sketch to keep it as transparent as possible.

  Hardware: (Note most of these pins can be swapped)
    Graphic LCD Pin ---------- Arduino Pin
       1-VCC       ----------------  5V
       2-GND       ----------------  GND
       3-SCE       ----------------  7
       4-RST       ----------------  6
       5-D/C       ----------------  5
       6-DN(MOSI)  ----------------  11
       7-SCLK      ----------------  13
       8-LED       - 330 Ohm res --  9
   The SCLK, DN(MOSI), must remain where they are, but the other
   pins can be swapped. The LED pin should remain a PWM-capable
   pin. Don't forget to stick a current-limiting resistor in line
   between the LCD's LED pin and Arduino pin 9!
*/
#include <SPI.h> // We'll use SPI to transfer data. Faster!

/* PCD8544-specific defines: */
#define LCD_COMMAND  0
#define LCD_DATA     1

/* 84x48 LCD Defines: */
#define LCD_WIDTH   84 // Note: x-coordinates go wide
#define LCD_HEIGHT  48 // Note: y-coordinates go high
#define WHITE       0  // For drawing pixels. A 0 draws white.
#define BLACK       1  // A 1 draws black.

/* Pin definitions:
Most of these pins can be moved to any digital or analog pin.
DN(MOSI)and SCLK should be left where they are (SPI pins). The
LED (backlight) pin should remain on a PWM-capable pin. */
const int scePin = 7;   // SCE - Chip select, pin 3 on LCD.
const int rstPin = 6;   // RST - Reset, pin 4 on LCD.
const int dcPin = 5;    // DC - Data/Command, pin 5 on LCD.
const int sdinPin = 11;  // DN(MOSI) - Serial data, pin 6 on LCD.
const int sclkPin = 13;  // SCLK - Serial clock, pin 7 on LCD.
const int blPin = 9;    // LED - Backlight LED, pin 8 on LCD.

/* Font table:
This table contains the hex values that represent pixels for a
font that is 5 pixels wide and 8 pixels high. Each byte in a row
represents one, 8-pixel, vertical column of a character. 5 bytes
per character. */
static const byte ASCII[][5] = {
  // First 32 characters (0x00-0x19) are ignored. These are
  // non-displayable, control characters.
   {0x00, 0x00, 0x00, 0x00, 0x00} // 0x20
  ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 0x21 !
  ,{0x00, 0x07, 0x00, 0x07, 0x00} // 0x22 "
  ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 0x23 #
  ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 0x24 $
  ,{0x23, 0x13, 0x08, 0x64, 0x62} // 0x25 %
  ,{0x36, 0x49, 0x55, 0x22, 0x50} // 0x26 &
  ,{0x00, 0x05, 0x03, 0x00, 0x00} // 0x27 '
  ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 0x28 (
  ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 0x29 )
  ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 0x2a *
  ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 0x2b +
  ,{0x00, 0x50, 0x30, 0x00, 0x00} // 0x2c ,
  ,{0x08, 0x08, 0x08, 0x08, 0x08} // 0x2d -
  ,{0x00, 0x60, 0x60, 0x00, 0x00} // 0x2e .
  ,{0x20, 0x10, 0x08, 0x04, 0x02} // 0x2f /
  ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 0x30 0
  ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 0x31 1
  ,{0x42, 0x61, 0x51, 0x49, 0x46} // 0x32 2
  ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 0x33 3
  ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 0x34 4
  ,{0x27, 0x45, 0x45, 0x45, 0x39} // 0x35 5
  ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 0x36 6
  ,{0x01, 0x71, 0x09, 0x05, 0x03} // 0x37 7
  ,{0x36, 0x49, 0x49, 0x49, 0x36} // 0x38 8
  ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 0x39 9
  ,{0x00, 0x36, 0x36, 0x00, 0x00} // 0x3a :
  ,{0x00, 0x56, 0x36, 0x00, 0x00} // 0x3b ;
  ,{0x08, 0x14, 0x22, 0x41, 0x00} // 0x3c <
  ,{0x14, 0x14, 0x14, 0x14, 0x14} // 0x3d =
  ,{0x00, 0x41, 0x22, 0x14, 0x08} // 0x3e >
  ,{0x02, 0x01, 0x51, 0x09, 0x06} // 0x3f ?
  ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 0x40 @
  ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 0x41 A
  ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 0x42 B
  ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 0x43 C
  ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 0x44 D
  ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 0x45 E
  ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 0x46 F
  ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 0x47 G
  ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 0x48 H
  ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 0x49 I
  ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 0x4a J
  ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 0x4b K
  ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 0x4c L
  ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 0x4d M
  ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 0x4e N
  ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 0x4f O
  ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 0x50 P
  ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 0x51 Q
  ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 0x52 R
  ,{0x46, 0x49, 0x49, 0x49, 0x31} // 0x53 S
  ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 0x54 T
  ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 0x55 U
  ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 0x56 V
  ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 0x57 W
  ,{0x63, 0x14, 0x08, 0x14, 0x63} // 0x58 X
  ,{0x07, 0x08, 0x70, 0x08, 0x07} // 0x59 Y
  ,{0x61, 0x51, 0x49, 0x45, 0x43} // 0x5a Z
  ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 0x5b [
  ,{0x02, 0x04, 0x08, 0x10, 0x20} // 0x5c \
  ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 0x5d ]
  ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 0x5d ]
  ,{0x04, 0x02, 0x01, 0x02, 0x04} // 0x5e ^
  ,{0x40, 0x40, 0x40, 0x40, 0x40} // 0x5f _
  ,{0x00, 0x01, 0x02, 0x04, 0x00} // 0x60 `
  ,{0x20, 0x54, 0x54, 0x54, 0x78} // 0x61 a
  ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 0x62 b
  ,{0x38, 0x44, 0x44, 0x44, 0x20} // 0x63 c
  ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 0x64 d
  ,{0x38, 0x54, 0x54, 0x54, 0x18} // 0x65 e
  ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 0x66 f
  ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 0x67 g
  ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 0x68 h
  ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 0x69 i
  ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 0x6a j
  ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 0x6b k
  ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 0x6c l
  ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 0x6d m
  ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 0x6e n
  ,{0x38, 0x44, 0x44, 0x44, 0x38} // 0x6f o
  ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 0x70 p
  ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 0x71 q
  ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 0x72 r
  ,{0x48, 0x54, 0x54, 0x54, 0x20} // 0x73 s
  ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 0x74 t
  ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 0x75 u
  ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 0x76 v
  ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 0x77 w
  ,{0x44, 0x28, 0x10, 0x28, 0x44} // 0x78 x
  ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 0x79 y
  ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 0x7a z
  ,{0x00, 0x08, 0x36, 0x41, 0x00} // 0x7b {
  ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 0x7c |
  ,{0x00, 0x41, 0x36, 0x08, 0x00} // 0x7d }
  ,{0x10, 0x08, 0x08, 0x10, 0x08} // 0x7e ~
  ,{0x78, 0x46, 0x41, 0x46, 0x78} // 0x7f DEL
};

/* The displayMap variable stores a buffer representation of the
pixels on our display. There are 504 total bits in this array,
same as how many pixels there are on a 84 x 48 display.

Each byte in this array covers a 8-pixel vertical block on the
display. Each successive byte covers the next 8-pixel column over
until you reach the right-edge of the display and step down 8 rows.

To update the display, we first have to write to this array, then
call the updateDisplay() function, which sends this whole array
to the PCD8544.

Because the PCD8544 won't let us write individual pixels at a
time, this is how we can make targeted changes to the display. */
byte displayMap[LCD_WIDTH * LCD_HEIGHT / 8] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,0)->(11,7) ~ These 12 bytes cover an 8x12 block in the left corner of the display
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,0)->(23,7)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, // (24,0)->(35,7)
  0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0x1E, 0x0E, 0x02, 0x00, // (36,0)->(47,7)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (48,0)->(59,7)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,0)->(71,7)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,0)->(83,7)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,8)->(11,15)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,8)->(23,15)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // (24,8)->(35,15)
  0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, // (36,8)->(47,15)
  0xF8, 0xF0, 0xF8, 0xFE, 0xFE, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, // (48,8)->(59,15)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,8)->(71,15)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,8)->(83,15)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,16)->(11,23)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,16)->(23,23)
  0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xF3, 0xE0, 0xE0, 0xC0, // (24,16)->(35,23)
  0xC0, 0xC0, 0xE0, 0xE0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // (36,16)->(47,23)
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x00, 0x00, 0x00, // (48,16)->(59,23)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,16)->(71,23)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,16)->(83,23)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,24)->(11,31)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,24)->(23,31)
  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // (24,24)->(35,31)
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // (36,24)->(47,31)
  0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, // (48,24)->(59,31)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,24)->(71,31)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,24)->(83,31)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,32)->(11,39)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,32)->(23,39)
  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, // (24,32)->(35,39)
  0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, // (36,32)->(47,39)
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (48,32)->(59,39)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,32)->(71,39)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,32)->(83,39)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,40)->(11,47)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,40)->(23,47)
  0x00, 0x00, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, // (24,40)->(35,47)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (36,40)->(47,47)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (48,40)->(59,47)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,40)->(71,47)
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,40)->(83,47) !!! The bottom right pixel!
};

/* This array is the same size as the displayMap. We'll use it
as an example of how to draw a bitmap. xkcd comic transposing
makes for an excellent display application.
For reference, see: http://xkcd.com/149/ */
char xkcdSandwich[504] = {
0xFF, 0x8D, 0x9F, 0x13, 0x13, 0xF3, 0x01, 0x01, 0xF9, 0xF9, 0x01, 0x81, 0xF9, 0xF9, 0x01, 0xF1,
0xF9, 0x09, 0x09, 0xFF, 0xFF, 0xF1, 0xF9, 0x09, 0x09, 0xF9, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01,
0xF9, 0xF9, 0x09, 0xF9, 0x09, 0xF9, 0xF1, 0x01, 0xC1, 0xE9, 0x29, 0x29, 0xF9, 0xF1, 0x01, 0xFF,
0xFF, 0x71, 0xD9, 0x01, 0x01, 0xF1, 0xF9, 0x29, 0x29, 0xB9, 0xB1, 0x01, 0x01, 0x01, 0xF1, 0xF1,
0x11, 0xF1, 0xF1, 0xF1, 0xE1, 0x01, 0xE1, 0xF1, 0x51, 0x51, 0x71, 0x61, 0x01, 0x01, 0xC1, 0xF1,
0x31, 0x31, 0xF1, 0xFF, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x01, 0x60, 0xE0, 0xA0, 0x01, 0x01, 0x81,
0xE1, 0x61, 0x60, 0xC0, 0x01, 0xE1, 0xE1, 0x21, 0x21, 0xE0, 0xC1, 0x01, 0xC1, 0xE1, 0x20, 0x20,
0xFC, 0xFC, 0xE0, 0xE0, 0xC1, 0xE1, 0xE0, 0xC1, 0xE0, 0xE1, 0x01, 0xFC, 0xFC, 0x21, 0x21, 0xE1,
0xC1, 0xE5, 0xE4, 0x01, 0xC1, 0xE0, 0x20, 0x21, 0x20, 0x00, 0x01, 0xFD, 0xFD, 0x21, 0x20, 0xE0,
0x00, 0x00, 0x01, 0x01, 0xC0, 0x61, 0x31, 0x31, 0x21, 0x20, 0xC0, 0x81, 0x01, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02,
0x03, 0x01, 0x00, 0x01, 0x03, 0xF2, 0x1A, 0x0B, 0x08, 0x0B, 0x1B, 0x10, 0x60, 0xE3, 0x03, 0x00,
0x01, 0x03, 0x02, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03,
0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01, 0x03, 0x02, 0x02, 0x03, 0x01, 0x00, 0x03,
0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x80, 0x80, 0x80, 0x80, 0x60, 0x3F, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x01, 0x01, 0x02, 0x03, 0x3E, 0xE8, 0xF8, 0xF0, 0xD0, 0x90,
0x18, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0xFF,
0x0C, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x5F, 0x8F, 0x84, 0x05, 0x07, 0x06, 0x0C, 0x0E, 0x0E, 0x0C, 0x14, 0x34, 0x68, 0x88, 0xD8, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0xE0, 0x00, 0xF0, 0xF0, 0x00, 0x80,
0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x20, 0x38,
0x0E, 0x01, 0xC0, 0x3F, 0xE0, 0x00, 0x00, 0x03, 0x0E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xB6, 0xED, 0xC0, 0xC0,
0xC0, 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xE1, 0xE1, 0xC1,
0xEF, 0xBB, 0x83, 0x86, 0x88, 0xB0, 0x80, 0x80, 0x80, 0x8F, 0x90, 0x90, 0x90, 0x9F, 0x8F, 0x80,
0x9F, 0x9F, 0x87, 0x8D, 0x98, 0x80, 0x8C, 0x9E, 0x92, 0x92, 0x9F, 0xC0, 0xC7, 0xFF, 0xB8, 0x8F,
0x80, 0x90, 0x90, 0xC0, 0xF0, 0x8E, 0x81, 0x80, 0x81, 0x8F, 0xB8, 0xE0, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF,
};

void setup()
{
  Serial.begin(9600);

  lcdBegin(); // This will setup our pins, and initialize the LCD
  setContrast(55); // Pretty good value, play around with it

  updateDisplay(); // with displayMap untouched, SFE logo
  delay(2000);

  lcdFunTime(); // Runs a 30-second demo of graphics functions

  // Wait for serial to come in, then clear display and go to echo
  while (!Serial.available())
    ;
  clearDisplay(WHITE);
  updateDisplay();
}

// Loop turns the display into a local serial monitor echo.
// Type to the Arduino from the serial monitor, and it'll echo
// what you type on the display. Type ~ to clear the display.
void loop()
{
  static int cursorX = 0;
  static int cursorY = 0;

  if (Serial.available())
  {
    char c = Serial.read();

    switch (c)
    {
    case '\n': // New line
      cursorY += 8;
      break;
    case '\r': // Return feed
      cursorX = 0;
      break;
    case '~': // Use ~ to clear the screen.
      clearDisplay(WHITE);
      updateDisplay();
      cursorX = 0; // reset the cursor
      cursorY = 0;
      break;
    default:
      setChar(c, cursorX, cursorY, BLACK);
      updateDisplay();
      cursorX += 6; // Increment cursor
      break;
    }
    // Manage cursor
    if (cursorX >= (LCD_WIDTH - 4))
    { // If the next char will be off screen...
      cursorX = 0; // ... reset x to 0...
      cursorY += 8; // ...and increment to next line.
      if (cursorY >= (LCD_HEIGHT - 7))
      { // If the next line takes us off screen...
        cursorY = 0; // ...go back to the top.
      }
    }
  }
}

/* This function serves as a fun demo of the graphics driver
functions below. */
void lcdFunTime()
{
  clearDisplay(WHITE); // Begin by clearing the display
  randomSeed(analogRead(A0));

  /* setPixel Example */
  const int pixelCount = 100;
  for (int i=0; i<pixelCount; i++)
  {
    // setPixel takes 2 to 3 parameters. The first two params
    // are x and y variables. The third optional variable is
    // a "color" boolean. 1 for black, 0 for white.
    // setPixel() with two variables will set the pixel with
    // the color set to black.
    // clearPixel() will call setPixel with with color set to
    // white.
    setPixel(random(0, LCD_WIDTH), random(0, LCD_HEIGHT));
    // After drawing something, we must call updateDisplay()
    // to actually make the display draw something new.
    updateDisplay();
    delay(10);
  }
  setStr("full of stars", 0, LCD_HEIGHT-8, BLACK);
  updateDisplay();
  delay(1000);
  // Seizure time!!! Err...demoing invertDisplay()
  for (int i=0; i<5; i++)
  {
    invertDisplay(); // This will swap all bits in our display
    delay(200);
    invertDisplay(); // This will get us back to where we started
    delay(200);
  }
  delay(2000);

  /* setLine Example */
  clearDisplay(WHITE); // Start fresh
  int x0 = LCD_WIDTH/2;
  int y0 = LCD_HEIGHT/2;
  for (float i=0; i<2*PI; i+=PI/8)
  {
    // Time to whip out some maths:
    const int lineLength = 24;
    int x1 = x0 + lineLength * sin(i);
    int y1 = y0 + lineLength * cos(i);

    // setLine(x0, y0, x1, y1, bw) takes five variables. The
    // first four are coordinates for the start and end of the
    // line. The last variable is the color (1=black, 0=white).
    setLine(x0, y0, x1, y1, BLACK);
    updateDisplay();
    delay(100);
  }
  // Demo some backlight tuning
  for (int j=0; j<2; j++)
  {
    for (int i=255; i>=0; i-=5)
    {
      analogWrite(blPin, i); // blPin is ocnnected to BL LED
      delay(20);
    }
    for (int i=0; i<256; i+=5)
    {
      analogWrite(blPin, i);
      delay(20);
    }
  }

  /* setRect Example */
  clearDisplay(WHITE); // Start fresh

  // setRect takes six parameters (x0, y0, x1, y0, fill, bw)
  // x0, y0, x1, and y0 are the two diagonal corner coordinates
  // fill is a boolean, which determines if the rectangle is
  // filled in. bw determines the color 0=white, 1=black.
  for (int x=0; x<LCD_WIDTH; x+=8)
  { // Swipe right black
    setRect(0, 0, x, LCD_HEIGHT, 1, BLACK);
    updateDisplay();
    delay(10);
  }
  for (int x=0; x<LCD_WIDTH; x+=8)
  { // Swipe right white
    setRect(0, 0, x, LCD_HEIGHT, 1, WHITE);
    updateDisplay();
    delay(10);
  }
  for (int x=0; x<12; x++)
  { // Shutter swipe
    setRect(0, 0, x, LCD_HEIGHT, 1, 1);
    setRect(11, 0, x+12, LCD_HEIGHT, 1, BLACK);
    setRect(23, 0, x+24, LCD_HEIGHT, 1, BLACK);
    setRect(35, 0, x+36, LCD_HEIGHT, 1, BLACK);
    setRect(47, 0, x+48, LCD_HEIGHT, 1, BLACK);
    setRect(59, 0, x+60, LCD_HEIGHT, 1, BLACK);
    setRect(71, 0, x+72, LCD_HEIGHT, 1, BLACK);
    updateDisplay();
    delay(10);
  }
  // 3 Dee!
  setRect(25, 10, 45, 30, 0, WHITE);
  setRect(35, 20, 55, 40, 0, WHITE);
  setLine(25, 10, 35, 20, WHITE);
  setLine(45, 30, 55, 40, WHITE);
  setLine(25, 30, 35, 40, WHITE);
  setLine(45, 10, 55, 20, WHITE);
  updateDisplay();
  delay(2000);

  /* setCircle Example */
  clearDisplay(WHITE);
  // setCircle takes 5 parameters -- x0, y0, radius, bw, and
  // lineThickness. x0 and y0 are the center coords of the circ.
  // radius is the...radius. bw is the color (0=white, 1=black)
  // lineThickness is the line width of the circle, 1 = smallest
  // thickness moves in towards center.
  for (int i=0; i<20; i++)
  {
    int x = random(0, LCD_WIDTH);
    int y = random(0, LCD_HEIGHT);

    setCircle(x, y, i, BLACK, 1);
    updateDisplay();
    delay(100);
  }
  delay(2000);

  /* setChar & setStr Example */
  // setStr takes 4 parameters: an array of characters to print,
  // x and y coordinates for the top-left corner. And a color
  setStr("Modern Art", 0, 10, WHITE);
  updateDisplay();
  delay(2000);

  /* setBitmap Example */
  // setBitmap takes one parameter, an array of the same size
  // as our screen.
  setBitmap(xkcdSandwich);
  updateDisplay();
}


// Because I keep forgetting to put bw variable in when setting...
void setPixel(int x, int y)
{
  setPixel(x, y, BLACK); // Call setPixel with bw set to Black
}

void clearPixel(int x, int y)
{
  setPixel(x, y, WHITE); // call setPixel with bw set to white
}

// This function sets a pixel on displayMap to your preferred
// color. 1=Black, 0= white.
void setPixel(int x, int y, boolean bw)
{
  // First, double check that the coordinate is in range.
  if ((x >= 0) && (x < LCD_WIDTH) && (y >= 0) && (y < LCD_HEIGHT))
  {
    byte shift = y % 8;

    if (bw) // If black, set the bit.
      displayMap[x + (y/8)*LCD_WIDTH] |= 1<<shift;
    else   // If white clear the bit.
      displayMap[x + (y/8)*LCD_WIDTH] &= ~(1<<shift);
  }
}

// setLine draws a line from x0,y0 to x1,y1 with the set color.
// This function was grabbed from the SparkFun ColorLCDShield
// library.
void setLine(int x0, int y0, int x1, int y1, boolean bw)
{
  int dy = y1 - y0; // Difference between y0 and y1
  int dx = x1 - x0; // Difference between x0 and x1
  int stepx, stepy;

  if (dy < 0)
  {
    dy = -dy;
    stepy = -1;
  }
  else
    stepy = 1;

  if (dx < 0)
  {
    dx = -dx;
    stepx = -1;
  }
  else
    stepx = 1;

  dy <<= 1; // dy is now 2*dy
  dx <<= 1; // dx is now 2*dx
  setPixel(x0, y0, bw); // Draw the first pixel.

  if (dx > dy)
  {
    int fraction = dy - (dx >> 1);
    while (x0 != x1)
    {
      if (fraction >= 0)
      {
        y0 += stepy;
        fraction -= dx;
      }
      x0 += stepx;
      fraction += dy;
      setPixel(x0, y0, bw);
    }
  }
  else
  {
    int fraction = dx - (dy >> 1);
    while (y0 != y1)
    {
      if (fraction >= 0)
      {
        x0 += stepx;
        fraction -= dy;
      }
      y0 += stepy;
      fraction += dx;
      setPixel(x0, y0, bw);
    }
  }
}

// setRect will draw a rectangle from x0,y0 top-left corner to
// a x1,y1 bottom-right corner. Can be filled with the fill
// parameter, and colored with bw.
// This function was grabbed from the SparkFun ColorLCDShield
// library.
void setRect(int x0, int y0, int x1, int y1, boolean fill, boolean bw)
{
  // check if the rectangle is to be filled
  if (fill == 1)
  {
    int xDiff;

    if(x0 > x1)
      xDiff = x0 - x1; //Find the difference between the x vars
    else
      xDiff = x1 - x0;

    while(xDiff > 0)
    {
      setLine(x0, y0, x0, y1, bw);

      if(x0 > x1)
        x0--;
      else
        x0++;

      xDiff--;
    }
  }
  else
  {
    // best way to draw an unfilled rectangle is to draw four lines
    setLine(x0, y0, x1, y0, bw);
    setLine(x0, y1, x1, y1, bw);
    setLine(x0, y0, x0, y1, bw);
    setLine(x1, y0, x1, y1, bw);
  }
}

// setCircle draws a circle centered around x0,y0 with a defined
// radius. The circle can be black or white. And have a line
// thickness ranging from 1 to the radius of the circle.
// This function was grabbed from the SparkFun ColorLCDShield
// library.
void setCircle (int x0, int y0, int radius, boolean bw, int lineThickness)
{
  for(int r = 0; r < lineThickness; r++)
  {
    int f = 1 - radius;
    int ddF_x = 0;
    int ddF_y = -2 * radius;
    int x = 0;
    int y = radius;

    setPixel(x0, y0 + radius, bw);
    setPixel(x0, y0 - radius, bw);
    setPixel(x0 + radius, y0, bw);
    setPixel(x0 - radius, y0, bw);

    while(x < y)
    {
      if(f >= 0)
      {
        y--;
        ddF_y += 2;
        f += ddF_y;
      }
      x++;
      ddF_x += 2;
      f += ddF_x + 1;

      setPixel(x0 + x, y0 + y, bw);
      setPixel(x0 - x, y0 + y, bw);
      setPixel(x0 + x, y0 - y, bw);
      setPixel(x0 - x, y0 - y, bw);
      setPixel(x0 + y, y0 + x, bw);
      setPixel(x0 - y, y0 + x, bw);
      setPixel(x0 + y, y0 - x, bw);
      setPixel(x0 - y, y0 - x, bw);
    }
    radius--;
  }
}

// This function will draw a char (defined in the ASCII table
// near the beginning of this sketch) at a defined x and y).
// The color can be either black (1) or white (0).
void setChar(char character, int x, int y, boolean bw)
{
  byte column; // temp byte to store character's column bitmap
  for (int i=0; i<5; i++) // 5 columns (x) per character
  {
    column = ASCII[character - 0x20][i];
    for (int j=0; j<8; j++) // 8 rows (y) per character
    {
      if (column & (0x01 << j)) // test bits to set pixels
        setPixel(x+i, y+j, bw);
      else
        setPixel(x+i, y+j, !bw);
    }
  }
}

// setStr draws a string of characters, calling setChar with
// progressive coordinates until it's done.
// This function was grabbed from the SparkFun ColorLCDShield
// library.
void setStr(char * dString, int x, int y, boolean bw)
{
  while (*dString != 0x00) // loop until null terminator
  {
    setChar(*dString++, x, y, bw);
    x+=5;
    for (int i=y; i<y+8; i++)
    {
      setPixel(x, i, !bw);
    }
    x++;
    if (x > (LCD_WIDTH - 5)) // Enables wrap around
    {
      x = 0;
      y += 8;
    }
  }
}

// This function will draw an array over the screen. (For now) the
// array must be the same size as the screen, covering the entirety
// of the display.
void setBitmap(char * bitArray)
{
  for (int i=0; i<(LCD_WIDTH * LCD_HEIGHT / 8); i++)
    displayMap[i] = bitArray[i];
}

// This function clears the entire display either white (0) or
// black (1).
// The screen won't actually clear until you call updateDisplay()!
void clearDisplay(boolean bw)
{
  for (int i=0; i<(LCD_WIDTH * LCD_HEIGHT / 8); i++)
  {
    if (bw)
      displayMap[i] = 0xFF;
    else
      displayMap[i] = 0;
  }
}

// Helpful function to directly command the LCD to go to a
// specific x,y coordinate.
void gotoXY(int x, int y)
{
  LCDWrite(0, 0x80 | x);  // Column.
  LCDWrite(0, 0x40 | y);  // Row.  ?
}

// This will actually draw on the display, whatever is currently
// in the displayMap array.
void updateDisplay()
{
  gotoXY(0, 0);
  for (int i=0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++)
  {
    LCDWrite(LCD_DATA, displayMap[i]);
  }
}

// Set contrast can set the LCD Vop to a value between 0 and 127.
// 40-60 is usually a pretty good range.
void setContrast(byte contrast)
{
  LCDWrite(LCD_COMMAND, 0x21); //Tell LCD that extended commands follow
  LCDWrite(LCD_COMMAND, 0x80 | contrast); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
  LCDWrite(LCD_COMMAND, 0x20); //Set display mode
}

/* There are two ways to do this. Either through direct commands
to the display, or by swapping each bit in the displayMap array.
We'll leave both methods here, comment one or the other out if
you please. */
void invertDisplay()
{
  /* Direct LCD Command option
  LCDWrite(LCD_COMMAND, 0x20); //Tell LCD that extended commands follow
  LCDWrite(LCD_COMMAND, 0x08 | 0x05); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
  LCDWrite(LCD_COMMAND, 0x20); //Set display mode  */

  /* Indirect, swap bits in displayMap option: */
  for (int i=0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++)
  {
    displayMap[i] = ~displayMap[i] & 0xFF;
  }
  updateDisplay();
}

// There are two memory banks in the LCD, data/RAM and commands.
// This function sets the DC pin high or low depending, and then
// sends the data byte
void LCDWrite(byte data_or_command, byte data)
{
  //Tell the LCD that we are writing either to data or a command
  digitalWrite(dcPin, data_or_command);

  //Send the data
  digitalWrite(scePin, LOW);
  SPI.transfer(data); //shiftOut(sdinPin, sclkPin, MSBFIRST, data);
  digitalWrite(scePin, HIGH);
}

//This sends the magical commands to the PCD8544
void lcdBegin(void)
{
  //Configure control pins
  pinMode(scePin, OUTPUT);
  pinMode(rstPin, OUTPUT);
  pinMode(dcPin, OUTPUT);
  pinMode(sdinPin, OUTPUT);
  pinMode(sclkPin, OUTPUT);
  pinMode(blPin, OUTPUT);
  analogWrite(blPin, 255);

  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);

  //Reset the LCD to a known state
  digitalWrite(rstPin, LOW);
  digitalWrite(rstPin, HIGH);

  LCDWrite(LCD_COMMAND, 0x21); //Tell LCD extended commands follow
  LCDWrite(LCD_COMMAND, 0xB0); //Set LCD Vop (Contrast)
  LCDWrite(LCD_COMMAND, 0x04); //Set Temp coefficent
  LCDWrite(LCD_COMMAND, 0x14); //LCD bias mode 1:48 (try 0x13)
  //We must send 0x20 before modifying the display control mode
  LCDWrite(LCD_COMMAND, 0x20);
  LCDWrite(LCD_COMMAND, 0x0C); //Set display control, normal mode.
}

For help understanding the sketch, check the comments in the code. Most of the action takes place in the lcdFunTime() function.

The Sketch in Action

Once uploaded to your Arduino, the sketch will begin by running the demo – a set of basic animations and graphics functions. To begin, we’ll draw some random pixels on the screen (“It’s full of stars…”). Then we’ll move on to examples of drawing lines, rectangles, and circles. Throughout there are examples of drawing characters and strings. Finally the demo closes out with an homage to a monochrome comic which seems a perfect fit for this little monochrome LCD.

Sandwich example

This is a demo of drawing bitmaps on the screen, which is one of the more rewarding tasks we can accomplish with the ‘duino/LCD combo.

After the demo runs its course, the sketch will enter into a serial echo mode. Open the serial monitor (set the baud rate to 9600 bps), and type stuff over to the Arduino. It should start printing everything you send it onto the LCD.


If you’re intrigued by the possibilites of drawing bitmaps on the screen, check out the next page! We’ll show you how to import your own 84x48 bitmap and draw it on the screen.

Example Code 2: Drawing Bitmaps

If the last demo has you chomping at the bit to design your own 84x48 bitmaps and display them, continue reading through this example. We’ll show you how to scale and import a bitmap, then compile it into your Arduino code and send it to the LCD, so you can have your own, sillly graphic.

alt text

Find/Make/Modify a Bitmap

To begin, find a bitmap image that you’d like to print to the LCD. 84x48 monochrome pixels doesn’t give you a lot of room, but you can still get some fun stuff on there. Here are a few examples:

RTFM exampleArduino exampleBender ExampleFlame exampleXKCD example

After you’ve picked an image, you’ll need to massage it to make it both monochrome (2-bit color) and 84 x 48 pixels. Most standard image editors can help with this. For Windows users, Paint is all you need to scale the image. Then save it as a monochrome bitmap.

Convert Bitmap to Array

The next step is converting that regular image file to a 504-byte array of char’s. There are a number of programs that can help with this around the web. We recommend LCD Assistant.

To load up an image in LCD Assistant, go to File>Load Image. A preview of the image should open up, make sure it’s the right size – 84 pixels wide, 48 pixels tall. Also make sure the Byte orientation is set to Vertical and the Size endianness is set to Little. The rest of the default settings (8 pixels/byte, etc.) should already be set correctly:

LCD Assistant Settings

Then go to File>Save output to generate a temporary text file. Open that text file to have a look at your shiny new array. You’ll need to modify the type of the array to be just a char (no unsigned or const). Also make sure the array has the proper naming conventions (no dashes, don’t start with a number, etc.).

Import into the Sketch and Draw!

With that array created, copy the entire table over to your Arduino sketch. Use the same sketch from Example 1. Paste the array wherever you’d like. Now, to test out your drawing, replace the setup() and loop() in the last sketch with the below (making sure the rest of the functions and variables remain in the sketch):

language:c

// ...LCD definitions, variables, and bitmap array defined above.

void setup()
{
  lcdBegin(); // This will setup our pins, and initialize the LCD
  setContrast(60); // Good values range from 40-60
  setBitmap(flameBitmap); // flameBitmap should be replaced with the name of your BMP array
  updateDisplay();  // Update the display to make the array show up.
}

void loop()
{
}

// LCD control and graphics functions defined below...

Fun stuff! Now you can overlay text, or draw on on your bitmap. You can even try importing multiple graphics to create animations!

Resources & Going Further

Thanks for checking out our Monochrome 84 x 48 Graphic LCD Hookup Guide! Should you require any further resources to get your LCD up and running, here are some handy places to look:

Going Further

Now that you’ve got control of your graphic LCD, you can embed it into all sorts of cool projects. If you need some inspiration, here are some related tutorials to help you out:

  • OLED Display Hookup Guide– While not exactly an LCD, this OLED provides a nice, crisp text display to your project.
  • MP3 Player Shield Music Box– This MP3 Player Music Box could be well served by a sweet graphic display. Hmm…
  • ITG-3200 Hookup Guide– The ITG-3200 is a fully-featured 3-axis gyroscope sensor. This display could be used to create a visual angular velocity meter.

learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

INA169 Breakout Board Hookup Guide

0
0

INA169 Breakout Board Hookup Guide a learn.sparkfun.com tutorial

Introduction

Have a project where you want to measure the current draw? Need to carefully monitor low current through an LED? The INA169 is the chip for you!

INA169 Current Sense Breakout Board

The INA169 is a “high-side current monitor,” which means that you place a resistor (a “shunt resistor”) on the positive power rail and the INA169 measures the voltage drop across that resistor. The INA169 outputs a small current based on the measured voltage drop. If you place a resistor from the output of the INA169 to ground, you can measure the voltage at the output. With some basic math, the output voltage gives you the current through the shunt resistor.

Covered In This Tutorial

In this tutorial, we cover how the board should be used. The Board Overview section covers some theory and math on how the current sensing works, so feel free to skip to the Hookup Example if you just want to see the board in action. The Hookup Example shows how to connect the board to an Arduino in order to measure the current through an LED, and the Example Code provides a quick Arduino sketch for displaying the measured current to the Serial Monitor.

Required Materials

Suggested Reading

Board Overview

Take a look at the schematic, and you will notice that the breakout board consists of a shunt resistor (RS), the INA169 chip, and an output resistor (RL). While RS and RL might appear to have 2 resistors, only one is populated on the board. If you would like to change the values of the resistors, you can replace them or put another resistor in parallel.

INA169 Breakout Schematic

INA169 Current Sensing Breakout Schematic

As current passes from VIN+ through RS to VIN-, it creates a current drop across RS. The op-amp inside of the INA169 chip measures the difference between the VIN+ and VIN- voltages and outputs a voltage based on that difference. The output of the op-amp is amplified through the internal transistor, which sources a current out of the INA169 chip. As that current passes through RL to ground, a voltage level is generated at VOUT.

IMPORTANT: The INA169 is configured to measure DC only. The VIN+ pin must be at a higher potential than the VIN- pin, which means that the INA169 cannot measure AC.

Measuring Current

The voltage at VOUT can be measured using an oscilloscope or an analog-to-digital converter. A bit of math is needed to convert to the source current (IS):

alt text

IS is the current we want to measure.

VOUT is the voltage we measured at the output of the INA169.

1kΩ is a constant resistance value we need to include due to the internals of the INA169.

RS is the value of the shunt resistor. If you do not modify the board, then this is set at 10Ω.

RL is the value of the output resistor. If you do not modify the board, then this is set at 10kΩ.

Example

For example, let’s say that you hook up the board and you measure 2.8V at VOUT. Plugging this into our equation, we would get:

alt text

This shows that you have 0.028A (or 28mA) flowing through your line.

The Pinout

There are only 5 pins on the breakout board.

Pinout of INA169 Breakout Board

GND should be connected to ground of the circuit you are trying to measure

VIN+ needs to be connected to the positive side of the source (e.g. battery, output pin, etc.)

VIN- needs to be connected to the positive side of the load (e.g. VCC on Arduino, positive side of an LED, etc.)

VOUT is the measured output and should be connected to something that measures voltage levels, such as a multimeter, oscilloscope, or an Arduino ADC pin

VCC is the supply power to the INA169, which needs to be connected to 3.3V, 5V, etc. This can be anywhere from 0 to 75V. Note that the VOUT range depends on the voltage supplied by VCC.

In addition to the pins on VIN+ and VIN-, the board also has two large pads around RS, which are capable of taking alligator clips should you want to have a temporary hookup. Note that GND and VCC will still need to be connected for the board to function.

Modifying Functionality

The INA169 cannot sense any differences across RS greater than 500mV, and the output error increases once the voltage across RS dips below 35mV. If you include the voltage drop across the internal transistor, this means that the default setup of the breakout board is limited to measuring a current range of about 3.5mA to 35mA.

If you would like to change that range, RS and RL can be replaced with resistors of different values. RS can be removed and replaced with another resistor fairly easily. RL is a bit more difficult as it is a small, surface mount resistor. Changing either of the resistors changes the equation from above.

With RL at 10kΩ, changing RS gives us the following ranges:


RSCurrent Sense Range
10Ω3.5mA - 35mA
35mA - 350mA
0.1Ω350mA - 3.5A

IMPORTANT: Be careful with the power rating on the resistor! If you choose a 0.1Ω resistor for RS and expect to see 3.5A through it, this can result in 1.2W of heat being generated - way too much for your average ¼W resistor! You will need a resistor that can handle at least 2W. The following power resistors are recommended:

Hookup Example

Assembly

You will need to solder either wires or straight male headers to the 5 header holes on the board. If you need to measure over 35mA, you will need to desolder the RS resistor and solder a lower value (e.g. 1Ω), higher power (e.g. 3W) resistor to the holes around RS.

Headers on the INA169 board

Headers are optional but recommended if you are using a breadboard.

Connecting the INA169 Breakout Board

Simple circuit using the INA169

Fritzing of the INA169 connected to an Arduino

As shown in the diagram, connect the Arduino 5V to the INA169 VCC and the Arduino GND to the INA169 GND. To read the output voltage level, we need to run a jumper cable from the Arduino A0 to the INA169 VOUT pin.

Use a jumper wire to connect the INA169 VCC and VIN+ pins, as we want to power the LED with the Arduino 5V. If you use a different power source (other than the Arduino 5V or 3.3V) through VIN+ and VIN-, make sure you connect the ground of the power source to the ground of the INA169 board. Just ensure that the voltage level as measured from VIN+ to ground does not exceed 60V. Bad things will happen to the board if you do.

Connect a 330Ω resistor from the INA169 VIN- to the anode of the LED and a jumper wire from the LED’s cathode to GND.

All the wires!

Actual circuit example

If you want to measure the current going to something else, you can use alligator clips on the bare metal pads around RS. Make sure that the INA169 board is inline with the positive power rail and that the INA169 GND is connected to the target’s GND.

Example Code

Open the Arduino program and paste the following code into the sketch:

language:c
/*
 11-14-2013
 SparkFun Electronics 2013
 Shawn Hymel

 This code is public domain but you buy me a beer if you use this
 and we meet someday (Beerware license).

 Description:

 This sketch shows how to use the SparkFun INA169 Breakout
 Board. As current passes through the shunt resistor (Rs), a
 voltage is generated at the Vout pin. Use an analog read and
 some math to determine the current. The current value is
 displayed through the Serial Monitor.

 Hardware connections:

 Uno Pin    INA169 Board    Function

 +5V        VCC             Power supply
 GND        GND             Ground
 A0         VOUT            Analog voltage measurement

 VIN+ and VIN- need to be connected inline with the positive
 DC power rail of a load (e.g. an Arduino, an LED, etc.).

 */

// Constants
const int SENSOR_PIN = A0;  // Input pin for measuring Vout
const int RS = 10;          // Shunt resistor value (in ohms)
const int VOLTAGE_REF = 5;  // Reference voltage for analog read

// Global Variables
float sensorValue;   // Variable to store value from analog read
float current;       // Calculated current value

void setup() {

  // Initialize serial monitor
  Serial.begin(9600);

}

void loop() {

  // Read a value from the INA169 board
  sensorValue = analogRead(SENSOR_PIN);

  // Remap the ADC value into a voltage number (5V reference)
  sensorValue = (sensorValue * VOLTAGE_REF) / 1023;

  // Follow the equation given by the INA169 datasheet to
  // determine the current flowing through RS. Assume RL = 10k
  // Is = (Vout x 1k) / (RS x RL)
  current = sensorValue / (10 * RS);

  // Output value (in amps) to the serial monitor to 3 decimal
  // places
  Serial.print(current, 3);
  Serial.println(" A");

  // Delay program for a few milliseconds
  delay(500);

}

Plug in the Arduino and upload the code. You should see the LED light up as soon as you apply power.

INA169 in action

The INA169 will measure the current through the LED.

Select the appropriate board (Arduino Uno in this case) from Tools->Board and the correct COM port from Tools->Serial Port. Click the upload button, and wait for the program to be compiled and uploaded to the Arduino. Open the Serial Monitor from Tools->Serial Monitor and you should see current measurements being printed.

Output of Serial Monitor

If you are using a basic red LED, a 330Ω resistor, and a 5V supply, you should see 0.009A (9mA) on the Serial Monitor.

If we want to verify this reading, we can use a multimeter to measure the voltage across the 330Ω resistor. You should see around 3V across the resistor. Using Ohm’s Law, we can calculate the current flowing through the resistor and LED is 0.00909 A, which matches the reading from the INA169.

Going Further

The INA169 is a useful chip if you want to know how much current something is using. For example:

  • On The Uncertain 7-Cube, you can connect the INA169 inline with the battery’s positive power wire (that’s the red wire!) and measure the current draw to figure out how long your battery will last.
  • Similarly, connect the INA169 to the HUB-ee Buggy’s power and determine how much time you get before you need to replace those AA batteries.
  • Or use the INA169 to determine how much power is being consumed if the Humidor Control Box is left on all the time.

Resources


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado


HTU21D Humidity Sensor Hookup Guide

0
0

HTU21D Humidity Sensor Hookup Guide a learn.sparkfun.com tutorial

HTU21D Overview

The HTU21D is a low-cost, easy to use, highly accurate, digital humidity sensor. All you need is two lines for I2C communication and you’ll have relative humidity readings such as “45.2%” or “23.1%” and very accurate temperature readings as a bonus!

HTU21D Breakout Board

Things you should know about this sensor:

  • Uses the I2C interface
  • Typical humidity accuracy of ±2%
  • Typical temperature accuracy of ±0.3C
  • Operates from 0 to 100% humidity but this sensor isn’t recommended for harsh environments where it could come in contact with water (such as rain).
  • 3.3V sensor - use inline logic level converters or 10k resistors to limit 5V signals
  • Here’s the datasheet
  • Only one HTU21D sensor can reside on the I2C bus at a time

This sensor is ideal for environmental sensing and data logging. Perfect for a weather station or humidor control system. It is a very good replacement for digital humidity sensors such as the SHT15, SHT21, SHT25, HIH-4030, HIH6130 and capacitive humidity sensors such as the HH10D.

Suggested Reading

Things you might need to know:

Hooking It Up

Wiring up the HTU21D humidity sensor is very easy! We recommend soldering four male headers to the breakout board and using the HTU21D in a breadboard.

HTU21D in bread board

Connections: Breakout board to Arduino

  • VCC → 3.3V
  • GND → GND
  • SDA → A4
  • SCL → A5

There are only four pins that need to be hooked up in order to start using this sensor in a project. One for VCC, one for GND, and two data lines for I2C communication. On an Arduino board connect the SDA pin on the breakout board to A4 and SCL to A5. If you’re using a 5V Arduino Uno we recommend putting 10k resistors in line to limit the 5V signal going into the sensor and prevent damage to the sensor. If you have a newer Arduino, you can connect the SDA and SCL lines directly to the SDA and SCL lines broken out on the Arduino headers.

This board runs at 3.3V. Be sure to power the board from the 3.3V pin, and use inline resistors if you’re using a 5V Arduino.

Note: This breakout board has built in 4.7k pull up resistors for I2C communications. If you’re hooking up multiple I2C devices on the same bus, you may want to disable these resistors.

HTU21D Library and Functions

We’ve written an Arduino library and some example code to make using the HTU21D easy to get up and running. Grab the HTU21D library for Arduino here. Copy and paste the folder “HTU21D_Humidity” into your Arduino libraries folder. Not sure how to install an Arduino library? Read here for more information.

Humidity example menu

The examples menu expanded to show Humidity example

Once the library is installed, open Arduino, and expand the examples menu. You should see the HTU21D_Humidity submenu.

Load this example onto the Arduino. Open the serial terminal at 9600bps. You will see the current humidity and temperature in the room!

Explanation of Functions:

The library and example code demonstrate some of the smaller functions supported by the HTU21D. These are generally not used by regular users but are documented here in case you need them:

  • myHumidity.ReadHumidity() will return a float containing the humidity. Ex: 54.7
  • myHumidity.ReadTemperature() will return a float containing the temperature in Celsius. Ex: 24.1
  • myHumidity.SetResolution(byte: 0b.76543210) sets the resolution of the readings.
  • myHumidity.check_crc(message, check_value) verifies the 8-bit CRC generated by the sensor.
  • myHumidity.read_user_register() returns the user register. Used to set resolution.

When you call the ReadHumidity or ReadTemperature functions you will get a float with the sensor reading or an error code:

  • 57.8 is an example of a valid reading. 0.0 to 100.0 for humidity and -40.0 to 125.0 for temperature.
  • 998 indicates that I2C timed out (100ms max). Check your connections.
  • 999 CRC was wrong. The HTU21D calculates an internal CRC and transmits it along with the temperature and humidity readings. It’s highly unlikely that you will ever see a bad CRC, but the library supports CRC checking.

SetResolution() allows the user to change the humidity and temperature resolution. The vast majority of users do not need to change the resolution. By default the sensor will be in its highest resolution settings. This function is useful if you need to decrease the amount of time between readings or to save power. See page 12 of the datasheet. As an example, to change the resolution to 11 bit RH and 11 bit temperature, you would call myHumidity.SetResolution(0b10000001); to set bit 7 and bit 0.

check_crc() inputs the message and check_value from the HTU21D and then does a 8-bit polynomial CRC to verify that the message the sensor sent was valid. It’s extremely rare that you will see a bad CRC but if you’re looking into how to decipher a 8-bit CRC, this is a good example. The HTU21D uses the same CRC as 1-wire products.

Disabling I2C Resistors

There are two 4.7k resistors on the breakout board that pull-up the SDA and SCL lines. If you’ve got other devices on the I2C bus you may need to disable the on-board resistors. To do this you need to clear the solder jumper on the board. This will disconnect the resistors from VCC and from the I2C bus.

Resources and Going Further

You should now have a good idea of how to add humidity and temperature sensing into your next project. Need some inspiration? Check out these other tutorials:

Resources:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Raspberry Pi Twitter Monitor

0
0

Raspberry Pi Twitter Monitor a learn.sparkfun.com tutorial

The Twitterverse

Like it or not, Twitter is a force to be reckoned with. Millions of people use Twitter to talk about general happenings in the world and their lives. Large events like conventions, elections, and uprisings have a habit of crashing the Twitter servers.

You, an avid DIY hacker, want to know how to use that massive stream of digital social media. There are plenty of fun projects built around Tweeting something that happens. Today, we offer you an alternative: make something happen when a specific Tweet occurs.

This is a basic project that will walk you through the steps to get an LED flashing when a specific hashtag appears in the Twitter stream. While a blinking LED might not be the most exciting of outcomes, attaching Twitter to the physical world will get you started on creating that Twitter controlled robot.

A new kind of blinky!

Blink an LED whenever specific hashtag appears in a Tweet

Suggested Reading

We need to build a rather simple LED circuit to connect to the Raspberry Pi’s GPIO header. Be sure you are familiar with LEDs and resistors.

Required Components

You will need to have a Raspberry Pi running Linux of some sort. We recommend the latest version of Raspbian, as it comes pre-loaded with Python and GPIO libraries. Additionally, the Pi will need to be connected to the Internet so that you can monitor the Twitter stream. This can be accomplished using an Ethernet cable or a USB WiFi dongle. If you like checklists, this is for you:

Hardware Hookup

Connect an LED to your Raspberry Pi following this diagram:

Raspberry Pi to LED Hookup

Additionally, you will want to plug in the rest of your peripherals (keyboard, monitor, SD card, Ethernet/WiFi) to your Pi. If you are not using a keyboard and monitor, then you will need to find some way to access your Pi, such as SSH.

Raspberry Pi GPIO to LED

The GPIO pins connected to an LED

Register Your Twitter App

In order to interact with Twitter (including searching, monitoring, posting, etc.), you will need to register your application. This is accomplished by going to https://dev.twitter.com/.

Click the “Sign In” button at the top-right of the screen and enter your Twitter credentials (you can also sign up if you don’t have a Twitter account).

Sign in to Twitter

Once you have signed in, click on your user icon, and select “My Applications.”

Go to My Applications

Click the “Create a new application” button, and you will be presented with a form to fill out about your application. Fill out the name and description fields. For “Website,” you can put something random, like http://github.com or something else that looks legitimate. At the bottom of the page, click the checkbox to agree to the rules, fill out the Captcha, and click the “Create your Twitter application” button.

Create app

Once completed, you will be presented with a dashboard for your registered application. You need to create an access token, so click the “Create my access token” button at the bottom of the screen.

Create Token

Wait a few seconds and then refresh the page. You should see a section titled “Your access token” at the bottom. Copy down the “Consumer key,” “Consumer secret,” “Access token,” and “Access token secret.” We will need these for our application. Note that we set up this Twitter application as an example. It will have been deleted by the time you read this, so don’t be trying to use our tokens!

Copy access tokens

Install Required Packages

If you are using a relatively new release of Raspbian, it should already contain Python and the necessary modules to talk to the Pi’s GPIO pins. We will still need to install modules to search Twitter with Python. Several exist, but I recommend Twython if you are following this tutorial. Boot up your Pi and connect to the Internet (Ethernet, WiFi, etc.). If you use the X Windows interface, open up a console window and install Twython:

sudo apt-get update
sudo apt-get install python-pip
sudo pip install twython

Code

With our packages installed, we can write our program. Open up a text editor and make a new Python script. For example:

nano TweetBlinky.py

In the new file, enter the code below.

import time
import RPi.GPIO as GPIO
from twython import TwythonStreamer

# Search terms
TERMS = '#lol'

# GPIO pin number of LED
LED = 22

# Twitter application authentication
APP_KEY = 'erRilYZd8UzsXEFycmg'
APP_SECRET = 'Yt0fGlNvCyr1sFaC6ymdNhphHchaWbz0ECdotEXIQQ'
OAUTH_TOKEN = '1969690717-6a2RgVPXanSBaAjuie7EmUWZh78me8UZ6UxcM8V'
OAUTH_TOKEN_SECRET = 'UIrYV2XbYZC3vHzer6ZxIDwqVa0VvynQLDJYnSQV0R3xt'

# Setup callbacks from Twython Streamer
class BlinkyStreamer(TwythonStreamer):
        def on_success(self, data):
                if 'text' in data:
                        print data['text'].encode('utf-8')
                        print
                        GPIO.output(LED, GPIO.HIGH)
                        time.sleep(0.5)
                        GPIO.output(LED, GPIO.LOW)

# Setup GPIO as output
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, GPIO.LOW)

# Create streamer
try:
        stream = BlinkyStreamer(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
        stream.statuses.filter(track=TERMS)
except KeyboardInterrupt:
        GPIO.cleanup()

Alternatively, you can download a zip file of the script here.

IMPORTANT: You will need to change the Twitter authentication tokens! Right now, they are set to my example application. Copy the strings from the your dev.twitter.com page (the single quotes are needed):

APP_KEY = ‘<Your Consumer Key>’
APP_SECRET = ‘<Your Consumer Secret>’
OAUTH_TOKEN = ‘<Your Access Token>’
OAUTH_TOKEN_SECRET = '<Your Access Token Secret>’'

Save and exit (ctrl + X and ‘y’ if you are using nano).

Dissecting the Code

We could just give you the code to copy-and-paste into your Pi (which we did). However, the Python script is a bit more complicated than just blinking an LED, so we should take a moment to discuss what is going on.

At the top of the code, we import our necessary Python modules. We need “time” to call our ½ second delay when we blink our LED. “RPi.GPIO” is a pre-build Python package for the Raspberry Pi that gives us access to the GPIO pins. This is why we recommend the Raspbian build of Linux. Finally, “twython” is the package that connects us to Twitter allowing us to monitor the stream, search, and post.

import time
import RPi.GPIO as GPIO
from twython import TwythonStreamer

Next, we add our global constants. TERMS holds a string (or strings) of things we want to search for on Twitter. LED contains the pin number for the GPIO header. Note that this is the pin number of the header and not the GPIO number. The Twitter authentication constants hold the token strings that we copied from the dev.twitter.com page. Remember: you need to change this section to your specific Twitter token strings.

# Search terms
TERMS = '#lol'

# GPIO pin number of LED
LED = 22

# Twitter application authentication
APP_KEY = ‘<Your Consumer Key>’
APP_SECRET = ‘<Your Consumer Secret>’
OAUTH_TOKEN = ‘<Your Access Token>’
OAUTH_TOKEN_SECRET = '<Your Access Token Secret>’'

The next section is the crux of the Twitter monitor. If you have never dealt with class inheritance or callbacks before, we recommend brushing up on those concepts in order to really understand this section of code.

We create a new class that inherits TwythonStreamer (a class within Twython). While TwythonStreamer handles a bunch of stuff in the background (including communicating with the Twitter API), we are only concerned with the callback on_success(). This is a specially named method that gets called whenever a Tweet appears matching our search terms criteria. The important thing to understand is that we never call this method from within our script. An outside force (e.g. thread, program) calls on_success() for us. We just have to define what happens when that method is called. To use it, we create a BlinkyStreamer object and Twython handles the rest.

Inside of on_success() is what we want to happen whenver a successful Twitter hit occurs. In this case, we make sure there is a ‘text’ field within the Tweet (meaning that the Tweet contains actual text from a user), and we print the Tweet’s text to the console and flash the LED for ½ second.

# Setup callbacks from Twython Streamer
class BlinkyStreamer(TwythonStreamer):
        def on_success(self, data):
                if 'text' in data:
                        print data['text'].encode('utf-8')
                        print
                        GPIO.output(LED, GPIO.HIGH)
                        time.sleep(0.5)
                        GPIO.output(LED, GPIO.LOW)

For those of you that are code-savvy, you might say, “Hey, wait a minute! That sleep function is blocking! You can’t receive tweets while flashing the LED.” And you would be correct. This is just a plain simple way to monitor Tweets. To “properly” do this, you would want to set up a separate thread in Python that monitors Tweets and puts them into a queue. Another thread would read that queue and flash the LED as quickly as Tweets are put into the queue. Threading is a bit too much for this tutorial, but if you would like to learn how, feel free to check out Threading in Python.

The GPIO setup section should look familiar if you have ever played with an Arduino or other microcontrollers. We need to tell the Raspberry Pi that we will be referencing its GPIO headers by board number (pin 1, pin 2, pin 3, etc.), that we want our LED pin to be an output, and initialize the LED to off (logic LOW).

# Setup GPIO as output
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, GPIO.LOW)

Finally, we create an instance of our BlinkyStreamer class and let it do its thing. When we create a TwythonStreamer object (remember: our BlinkyStreamer inherits TwythonStreamer), we need to feed it our Twitter authentication information that we set earlier. Twython uses this information to connect to the Twitter servers. We provide the filter() method within TwythonStreamer some search terms and the streamer begins to monitor Twitter. Whenever one of the terms appears in the Twitter stream, the on_success() method (defined above) is called.

# Create streamer
try:
        stream = BlinkyStreamer(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
        stream.statuses.filter(track=TERMS)
except KeyboardInterrupt:
        GPIO.cleanup()

Because the filter() method is blocking, the program will run forever until we manually kill it. We can terminate the program by pressing ctrl+c keys. We wrap the streamer calls in a try/catch statement so that the GPIO pins can be released when we tell Python to exit. If we do not do this, Python will issue a stern warning that the GPIO pins are in use by another program.

Run!

This is important. In order to use the GPIO pins from a Python script, you need to run the script with superuser privileges. So, enter the following command:

sudo python TweetBlinky.py

Sit back and watch the fun! As people issue the ubiquitous #lol hashtag, you will see the Tweets appear in your console.

DISCLAIMER: This is Twitter we are talking about. We can make no guarantee regarding the appropriateness of comments that might appear on your screen.

Tweets!

Now, look over at your Raspberry Pi. That LED that you hooked up should flash with every incoming Tweet that contains the hashtag #lol.

Incoming Tweet!

The LED flashes for ½ second on an incoming Tweet with the appropriate hashtag

When you want to end the program, press ctrl+c.

Going Further

So, you got something that flashed to notify you of Tweets. Great! The LED is just a start. Just about anything can be hooked up to the Raspberry Pi to notify you of Twitter activity. Let your imagination run wild…

Car horn!

A car horn to alert you of incoming Tweets? Why not?!

If you want to dig deeper into the Twython package, check out the Github repository here: https://github.com/ryanmcgrath/twython

The Raspberry Pi may not be as good at connecting to low-level peripherals as the Arduino, but it does offer a number of options on its 26-pin header. If you are looking to hook up additional hardware to the Pi, take a look at the RPi’s Low-Level Peripherals page. Remember: the Pi uses 3.3V logic!


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

XBee WiFi Hookup Guide

0
0

XBee WiFi Hookup Guide a learn.sparkfun.com tutorial

Introduction

Digi’s XBee WiFi modules are a nifty, all-in-one solution to get your project connected to a wireless network and up into the <wavy hands>Cloud<\wavy hands>. These modules may look just like “normal” XBee’s – they’re even the same size and pinout – but they’re built to seamlessly connect to 802.11b/g/n networks.

XBee WiFi with Whip Antenna

An XBee WiFi Module with Whip Antenna. They’re also offered with PCB antennas and RPSMA and U.FL connector options.

Aside from talking over a different wireless standard, these modules work just like any XBee. You can set them up using X-CTU (which also helps get it connected to a network). You can toggle I/O pins, read analog and digital inputs, and set the module to sleep. They can operate completely on their own, without the need for an external controlling microcontroller. That said, if you want to hook up an Arduino, or another processor, it can be easily done through the serial port.

You can use these modules just as you would any other XBee – to set up a local wireless serial gateway. One XBee WiFi module can easily talk to another, as long as it has the local IP address of the other.

But these modules have another, more unique application: to make Internet-of-Things projects super-easy. Using the Etherios™ Device Cloud service, you can quickly get them connected to the Cloud, where they can publish data and receive commands as well.

Covered in This Tutorial

In this tutorial we’ll provide a quick overview of the XBee WiFi modules. We’ll then go over some examples. We’ll show you how to use X-CTU to connect them to a nearby wireless network – including setting the SSID and encryption protocols.

In the last example, we’ll show you how to connect the XBee WiFi up to the Device Cloud. This allows you to control the XBee through a web app loaded up in your web browser. You could control your XBee from across the sea (or from the table across your room).

Required Materials

To follow along with this tutorial, you’ll need the following items:

Suggested Reading

  • Serial Communication– XBees use serial to communicate and receive data. Having some basic knowledge of serial (baud rate, RX, TX, etc.) goes a long way.
  • How to Use a Breadboard– On the last page of this tutorial we’ll build a circuit on a breadboard to control the XBee WiFi from the cloud.
  • Logic Levels– The maximum operating voltage of the XBee WiFi is 3.3V. Don’t go attaching 5V controllers and sensors to it!

An Overview

The XBee WiFi modules all share the same footprint and pinout as most “normal” XBees. They’ve got 20 through-hole pins, each spaced by 2mm. The pin functions range from power input to GPIO to analog input to SPI. Here, from the datasheet, is the table of pins and their function:

Pinout Table

XBee WiFi Pinout table. Click to embiggen.

XBee WiFi modules can be connected to another microcontroller via their serial port, but what makes them special is they’ve got a whole host of I/O pins of their own. An XBee alone can toggle LEDs, or motors, or relays, and it can read digital or analog inputs as well. We’ll take advantage of the XBee I/O capabilities in the To the Cloud! page, connecting LEDs and buttons directly to the little WiFi module.

Choosing an Antenna

There are a variety of XBee WiFi modules, each with their own antenna termination. Two of the module have integrated antennas: the PCB antenna and wire (whip) antenna. These are the best choice if you’re looking for cheap, but they’ll also have less range.

XBee WiFi PCB AntennaXBee WiFi Whip Antenna

XBee WiFi modules with PCB antenna (left) and whip antenna (right). No external antenna needed!

If you need more range, consider going with the modules with a U.FL connector or an RPSMA connector. Either of these will require an compatible external 2.4GHz antenna.

U.FL AntennaRPSMA antenna

XBee WiFi modules with a U.FL (left) and SMA (right) antenna connector.

For the U.FL version, the Adhesive 2.4GHz antennas make a nice, low-profile choice. For the SMA version, duck antennas (large and regular) make a nice, stylish choice.

Choosing a Breakout Board

The easiest way to use these modules is to plug them into a mating breakout board. For the next pages of this tutorial, we recommend you get an XBee Explorer, which will let you communicate to the XBee from your computer. The Explorers come in mini-B USB, USB Dongle and RS-232 Serial (if you’ve got an ancient computer with a serial port) versions. Any of the three will work!

XBee plugged into a USB explorer

As alternatives to the USB and Serial explorers, there are more simple XBee breakout boards. There’s theXBee Breakout Board, which simply breaks out the 2mm-spaced XBee to a more breadboard-friendly 0.1" pitch. Then there’s the XBee Explorer Regulated, which breaks out the pins and has onboard voltage regulating to help mesh with the 3.3V XBee. Either of these are great for embedding into a project, but may be a little more difficult to interface with your computer.


On the next few pages we’ll show you how to use the XBee WiFi with X-CTU and Digi’s Cloud Service. This isn’t the only way to use these modules, but it’s the easiest to get them up-and-running quickly. If you follow along, you can very easily have an XBee communicating with the “cloud”.

Using X-CTU

X-CTU is Digi’s XBee configuration software. It makes communicating with XBees very easy, and provides a nice interface to modify all of the module’s settings. When using it with the XBee WiFi’s, it even provides a WiFi network scanning and connection interface to make connecting to networks a breeze.

The current release of X-CTU is available on Digi’s website, unfortunately it’s only available for Windows. For Mac OS X users, there is a beta version of X-CTU 6.0.0 available, which we’ve tested and found to work flawlessly with the XBee WiFi’s. (Windows users can check it out too, it’s pretty slick.) Go ahead and download X-CTU to follow along.

For this section we’ll also assume you have an XBee connected to your computer via a USB Explorer or something similar. The Explorer should have enumerated as a COM port on your computer. This is the port we’ll use to communicate with the XBee.

Connecting to a WiFi Network With X-CTU

Before we can begin using the XBee WiFi, we need to set it up to connect to our WiFi network. This is a process made simple with X-CTU. Follow the steps below:

  1. Plug your XBee into your XBee Explorer, and plug the Explorer into your computer.
  2. Open X-CTU. It should open up on the “PC Settings” tab. On there, select your XBee Explorer’s COM port and make sure the port settings are as below (9600 8-N-1).

    XCTU PC Settings tabFirst, setup your COM port and make sure the settings are correct.
  3. Hit Test/Query to make sure you can communicate with your XBee WiFi. You should get a response like:

    XBee Communication SuccessfulThis is a good sign! Means we’re communicating with the XBee.
  4. Click over to the “Modem Configuration” tab. And click “Read” to display your XBee WiFi’s stored settings.

    Modem configuration settingsA view of the XBee WiFi’s default parameters.
  5. Select “Active Scan” near the top of the scrolling window. Then click the “Scan” button** that appears. This will open the network scan utility.

  6. Click the “Scan” button at the bottom of the scan window. If all goes well, your network should appear above. The “Link Margin” value represents the strength of the signal (bigger is better). And the “Security” value indicates the encryption mode of the network.

    Scan windowSelect your network’s SSID, enter a passkey if necessary, and click “Select AP”.
  7. Select your network. If it is encrypted, enter your Security Key. Then click “Select AP” (not “Done”!). X-CTU will configure your XBee, and it’ll try lease a DHCP address if your network is set up for it.

    • This step can take a while. Be patient. Hopefully, once connected, you’ll see a window telling you the XBee connected to your network in “x milliseconds”.
  8. After successfully connecting, click “Read” at the top of the window again. This will update all of the XBee’s settings, including GW (the gateway IP), MK (the subnet mask), and MY (the module’s assigned IP). If these values all make sense, then congratulations, your XBee is connected to your WiFi network!

    IP settingsOur XBee WiFi module’s IP address is 192.168.0.101.

Yay! What now? There are a few directions you can go:

Communicating with Other XBees

If you’ve ever used XBees before, you probably think of them as easy-to-setup wireless transceivers. Two XBees, configured correctly, can seamlessly pass data to each other from one serial port to another. XBee WiFi’s are no different!

Following that same set of steps, you can set up a second XBee WiFi module to also connect to your wireless network. It’ll get a unique IP address (usually assigned via DHCP). Take note of that.

To setup two XBees to communicate to each other, you’ll need to modify the DL – Destination IP Address– of each to the other XBee. You can open a second X-CTU window, or configure each one at a time.

alt text

Imagine two XBees connected to a computer, each with it’s own USB explorer and X-CTU window open. If you want to configure them to talk with each other, set the “DL” property of each, to the other’s IP address.

Then you can click over to the Terminal tab to type characters and have them sent from your computer, through one XBee, into the other XBee and out to a second terminal.


Another optional application for these modules is to use them on the cloud. Digi’s Device Cloud service makes this very easy. Click over to the next page to see an example setup.

To the Cloud!

XBee WiFi’s are built to enable simple communication with Device Cloud by Etherios ™. The Device Cloud service allows you to interface your XBee WiFi with the web, where you can control the I/O pins and read its status from the comfy confines of your web browser (anywhere in the world!).

Now, Device Cloud is a paid service, but it’s pretty reasonably priced (down to $0.50 per device per month). They also provide a free 30 day trial if you just want to try it out, which is what we’ll do here.

Setting up Device Cloud

To begin, we’ll need to set up the Device Cloud to communicate with our XBee WiFi. Follow the steps below to set this up:

  1. Go to the Device Cloud Login Page. Login or make an account if you don’t already have one. If you’re just looking to try it free, don’t worry – you won’t have to enter any payment info.
  2. In Device Cloud click to the Device Management tab.
  3. In the Device Management section, click the Add Devices button near the top. This is where we’ll point our XBee WiFi module to our Device Cloud ID.
  4. There are two methods for adding your XBee. We recommend the manual method:
    • Make sure you’re on the “Manual” half of the Add Device window.
    • Find your XBee WiFi’s MAC address. This is listed in X-CTU under the SL and SH (serial number low and high) entries. You’ll need to concatenate the two values to get your MAC address.
      XBee MAC addressIn X-CTU, this is where you’ll find the MAC address.
    • Set the drop down menu to MAC address. Then type your XBee’s address into the text box nearby. You may need to add a couple leading 0’s to make it 6-bytes long. Then click Add.
      Adding XBee MAC address
    • After some thumb-twiddling your XBee and its MAC address should appear in the list below. Click OK.
  5. Now you should have an entry for your XBee in Device Cloud now. Right-click on the XBee and select Properties (or select the XBee and click the “Properties” button above).

XBee property window

Here you can view and control just about everything as it relates to your XBee. You can set pins direction and value in the Input and Output Settings tab. Try setting a pin to “Output High”, then click Save. The pins should have been driven to 3.3V, but how do you know? Time to whip a circuit together!

Take an Circuit Assembly Break!

Here’s the circuit we’ll use to get the most of XBee’s example cloud dashboard. You don’t have to hook up every part, but we recommend at least trying the LED connected to pin 13.

XBee Cloud Breadboard Diagram

The schematic and breadboard diagram for the cloud example. Click to embiggen!

You’ll still need to power the XBee WiFi module. It can remain in the XBee Explorer, or you can plug it into a separate XBee Breakout Board. Here’s an image of our hookup using:

Real Circuit

Now that we’ve attached some buttons and LEDs, it’s time to take it to the cloud!

Setting Up XBee Dashboard

You can use Digi’s Example App to test out your Device Cloud setup. Follow these steps to get up-and-running:

  1. Log in to the XBee WiFi Cloud Kit. Use the same login as the Device Cloud earlier.
  2. On the next page, under the “Select a Device” heading, you should see a dropdown menu with your XBee address already selected. Then just click “Yes (recommended)” to configure your XBee for this example.
    Setting up the XBee Cloud
  3. Choose a layout preset and then Create Dashboard! You should see something like this on the next screen.
    XBee Cloud Kit App

Play around with it! Try turning the LED on remotely. Then read some buttons and potentiometers. Pretty cool! Now ask a friend from across the ocean to do it. Even cooler!

If you want to build out your own app, all of the required code is viewable by clicking the </> button on a widget. It looks like everything’s hosted on Digi’s GitHub page, which we’re huge fans of.

Resources & Going Further

Now that you’ve taken your XBee to the cloud, what nifty Internet-of-Things app are you going to make? If you need any help, or this tutorial didn’t answer all of your question, consider checking out these resources as well:

Going Further

If you need some inspiration, or just want to keep reading tutorials, check these related guides out:

  • ATmega128RFA1 Development Board Hookup Guide– ATmega128RFA1 Dev Boards are like fully customizable XBees. They operate on the same standard as Zigbee (so no WiFi), but they supply you with tons and tons of I/O, and even Arduino capability.
  • Bluetooth Basics– Another wireless option, if WiFi isn’t the best fit for your project, is Bluetooth. Learn all about Bluetooth in this technology tutorial.
  • RN-52 Hookup Guide– If Bluetooth is your thing, we recommend either the RN-52 for audio or the…
  • BlueSMiRF Hookup Guide– The BlueSMiRF is a fantastically easy Bluetooth module, perfect for passing low data rate serial data over the air.

learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

H2OhNo!

0
0

H2OhNo! a learn.sparkfun.com tutorial

Tiny Power

H2OhNo! is a water sensor alarm. When water is detected across the sense pins an alarm goes off and an LED starts blinking. If you’ve ever had a water heater explode or tried to create submersible electronics you know how important it is to be able to detect when water is around! You can buy one here.

Assembled H2OhNo!

The assembled H2OhNo! ATtiny development board

Underneath the default function of H2OhNo! is a small but powerful development board for the ATtiny85 microcontroller. The board includes a buzzer, LED, a coin cell battery, and the ability to detect analog and digital sensors. This mixture of create a great low-cost tool to learn how to program and how to sense things!

Please note that this kit is not a professional water sensor kit and should not be used in crucial or life support applications. It’s a great educational kit and can be used for a large number of applications including sensing when water has gotten too high or two low (like in a fish tank), or it can be programmed to detect an analog voltage and turn on an LED when the voltage has gotten too low (like a low battery indicator).

Suggested Reading

Before going further with this guide, you should be familiar with the topics covered in these tutorials:

Assembly

The H2OhNo! is a great beginner soldering kit and a great way to learn electronics and microcontrollers. It’s very easy to put together and should take around 20 minutes or less. If you’ve never soldered before consider reading the How to Solder tutorial.

Before you dive in and begin soldering, please review the Remote Water Sensor and Remote LED sections below!

Kit Contents:

H2OhNo kit parts

The kit contents

Optional materials:

  • Wire to locate the status LED off the board
  • Heat shrink to cover up solder joints and strength connections

Remote Water Sensor

Remote water sensor

Water sense pins on a 3" extension

The water sensor works best when it is located a few inches from the board. This is accomplished by cutting the jumper wire in half and heat shrinking the two pins next to each other.

Remote LED

LED off the board

LED on a 2" extension

If the sensor will be installed in a remote location (like the inside of an underwater camera enclosure), you may want to locate the LED off the board to allow better visibility.

Stress Relief

alt text

Stress relief holes

There are two small holes located next to the sense and LED pins to relieve stress on the solder connection. Route the wires through these holes before soldering the wires in place.

Basic Assembly

Solder in cap, switch and buzzer

Step 1: Cap, switch and buzzer

Step 1) All parts go into the top side of the PCB. Start with the 0.1uF capacitor, slide switch, and buzzer. None of these parts are polarized meaning they can go in either way. Using flush cutters, clip off any excess.

solder battery holder

Step 2: Battery holder

Step 2) Solder the battery holder in place. This part is polarized, but it’s easy to see how it should fit; just be sure the holder lines up with the silkscreen outline. Don’t insert the battery yet.

alt text

DIP socket with notch pointing up. ATtiny aligned correctly with pin one.

fold legs over on dip socket to hold it in place

Step 3: Insert DIP socket then fold over two pins to hold it in place

Step 3) Solder the 8-pin DIP socket in place. This part is polarized. Be sure the notch at the top of the socket is on the same end where the dot is. You can now insert the ATtiny85. Be sure to align the small dot on the ATtiny85 with the dot of the silkscreen and notch of the socket.

LED off the board

Step 4b: LED located off board

Step 4a) Now decide if you want the LED on or off the board. If you want the LED located on the board, line up the flat side of the LED with the flat line on the silkscreen. Solder the LED into place, and cut off any excess.

alt text

Insert wires through stress relief holes before soldering the wires to the PCB

Step 4b) If you want the LED located off the board, cut two pieces of wire the same length. Strip both ends of the wires about 5mm. Cut the legs of the LED to about 5mm of exposed metal. Then, solder the wire to the short LED legs. Use heat shrink to cover up the joints. Now, insert the other end of the wires into the stress relief holes. Solder the wires into the LED pins. Remember that LEDs are polarized, so you’ll need to solder the wire that extends from the flat side of the LED to the hole next to the flat line on the silkscreen. Once both wires are soldered, cut off any excess wire.

Remote water sensor

Step 5: Sense pins held together with heat shrink

Step 5) To create the water sensor cut the jumper wire in half, and strip 5mm from both wires. Insert the cut and stripped ends through the stress relief holes, then solder them into place. Use a piece of heat shrink to hold the pins next to each other.

fully assembled H2OhNo!

Step 6: Battery installed with label pointing up

Step 6) Once you’ve got everything soldered together, insert the coin cell battery into the holder. The label on the battery goes up.

Flip the switch to on and you should hear the buzzer emit two short beeps. To test the water sensor, lick your finger, and touch the two pins. The LED should start blinking, and the alarm should go off. Congratulations! You’ve got a water alarm.

Installation

We recommend the board be located at least an inch away from where water might be. CR2032 batteries are wonderful in that they can take a lot of abuse, but the kit will last much longer in a nice, dry environment.

Screws and Nutsalt text

Use 4-40 screws and nuts to attach your kit to the surrounding environment.

Reprogramming

H2OhNo! will work as a water alarm out of the box, but the real fun begins when you start to re-purpose the device!

H2OhNo is programmed using the Arduino IDE, but Arduino doesn’t support the ATtiny series by default. To get Arduino to work with ATtiny microcontrollers you need to install a David Mellis' mod. Checkout the AVR Tiny Programmer tutorial for a full description of how to get the drivers and software setup.

Programming the ATtiny

Once you’ve got the Arduino IDE configured, we need to get our new code onto the ATtiny. The H2OhNo! development board was designed to be programmed with the Tiny AVR Programmer (originally designed by David Mellis - he’s a wizard).

Tiny AVR Programmer

AVR Tiny Programmer with DIP support

To load a new sketch onto the ATtiny, remove the 8-pin DIP from the H2OhNo!, and insert it into the DIP socket on the Tiny AVR Programmer. Plug the programmer into your computer’s USB port. Select the ATtiny85 (internal 8MHz clock) from the Tools > Board menu, then hit upload. If you plan to use SoftwareSerial with your ATtiny, you will need to increase the internal clock to 8MHz by setting the fuse bits through the Burn Bootloader function. See Configuring the ATtiny to run at 8MHz on David’s tutorial for more information.

Hardware Connections

H2OhNo Hardware connections

Basic schematic for the H2OhNo!

When loading new code you’ll need to know where each pin is connected. This simplified schematic should help. You can also grab the schematic here. Be sure to checkout the H2OhNo! github repo for the open source hardware design files, as well as the example firmware.

Thank you David Mellis and Mark Sproul for building ATtiny support into the Arduino IDE!

Now that you’ve got your programmer setup and working we can load fun new code onto the H2OhNo!.

Basic Blink Firmware

Basic Blink demonstrates how to blink the LED and make some noise. It’s a great starting point. Copy and paste this code into the Arduino IDE, and reprogram your ATtiny.

language:c
//Pin definitions for ATtiny
const byte buzzer1 = 0;
const byte buzzer2 = 1;
const byte statLED = 4;

void setup()
{
  pinMode(buzzer1, OUTPUT);
  pinMode(buzzer2, OUTPUT);
  pinMode(statLED, OUTPUT);
}

void loop()
{
  digitalWrite(statLED, HIGH);
  alarmSound();
  delay(1000);

  digitalWrite(statLED, LOW);
  alarmSound();
  delay(1000);
}

//This is just a unique (annoying) sound we came up with, there is no magic to it
//Comes from the Simon Says game/kit actually: https://www.sparkfun.com/products/10547
//250us to 79us
void alarmSound(void)
{
  // Toggle the buzzer at various speeds
  for (byte x = 250 ; x > 70 ; x--)
  {
    for (byte y = 0 ; y < 3 ; y++)
    {
      digitalWrite(buzzer2, HIGH);
      digitalWrite(buzzer1, LOW);
      delayMicroseconds(x);

      digitalWrite(buzzer2, LOW);
      digitalWrite(buzzer1, HIGH);
      delayMicroseconds(x);
    }
  }
}

Original H2OhNo! Firmware

If you’re reprogramming the ATtiny you may want to get back to the original code that shipped with the kit. Grab the latest code by going to the H2OhNo! github repo. Click ‘raw’, then copy and paste the code into Arduino.

Annoy-A-Tron Firmware

We know you will eventually come across the idea of an Annoy-a-tron. The original Annoy-A-Tron was created by Think Geek, and everyone knows how annoying a low-battery beep of a fire alarm can be. This is a very basic Annoy-A-Tron example that will beep every 5 minutes. We intentionally didn’t build in low-power control so that if you happen to use this code you will only annoy your enemy for a few hours before the coin cell battery gives out.

language:c
//Pin definitions for ATtiny
const byte buzzer1 = 0;
const byte buzzer2 = 1;

void setup()
{
  pinMode(buzzer1, OUTPUT);
  pinMode(buzzer2, OUTPUT);
}

void loop()
{
  alarmSound();

  delay((long)1000 * 60 * 5); //5 minute delay
}

//This is just a unique (annoying) sound we came up with, there is no magic to it
//Comes from the Simon Says game/kit actually: https://www.sparkfun.com/products/10547
//250us to 79us
void alarmSound(void)
{
  // Toggle the buzzer at various speeds
  for (byte x = 250 ; x > 70 ; x--)
  {
    //for (byte y = 0 ; y < 3 ; y++)
    for (byte y = 0 ; y < 1 ; y++) //Slightly modified to be a shorter beep
    {
      digitalWrite(buzzer2, HIGH);
      digitalWrite(buzzer1, LOW);
      delayMicroseconds(x);

      digitalWrite(buzzer2, LOW);
      digitalWrite(buzzer1, HIGH);
      delayMicroseconds(x);
    }
  }
}

A very broken H2OhNo board

This is what happened to an Annoy-A-Tron after it was discovered by the victim. The board met its end in the jaws of a vice with a pipewrench and a cheater pipe extension. Please annoy responsibly.

Creating projects to prank people is a fantastic way to learn electronics! Annoying them with incessant beeping is an ok start, but consider getting a lot more creative with your pranks.

Low-Power ATtiny

The firmware behind H2OhNo! is simple in theory and long in practice. We need to establish that when water is present then sound the alarm. But what do we do for the weeks and months when there is no water detected? Let’s go to sleep and save power!

We’ve written some lengthier tutorials on getting the ATmega328 into very low power sleep. In this tutorial we will show you how to get the ATtiny into sleep mode as well.

Under normal conditions the ATtiny will consume 10-12mA running at 8MHz. Assuming the CR2032 battery contains 200mAh, that gives us (200mAh / 20mA) 10 hours of run time. Pretty good. But what if I told you I could get you 4,000 hours?

Watchdog Sleepy Time

The ATtiny can reach about 1uA in low-power sleep. Because we only need to periodically check for water let’s put the ATtiny into sleep and wake it up every once and awhile.

A watchdog timer is good for two things:

  • A watchdog can reset the processor when it gets locked into an endless loop - also known as going off into the weeds. This is a good way to protect a project needs to run all the time without user intervention. If the device ever gets locked up, the watchdog can cause the system to reset and (hopefully) return to regular operation.
  • A watchdog can wake the processor from deep sleep. When we put a microcontroller into deep sleep, we can use the watchdog timer as an interrupt, causing the processor to return to normal 8MHz (without a full reset).

The watchdog is just a counter. When that counter gets to the size the user specifies, the processor will either reset or an interrupt will fire. Reset can be useful (as explained above), but an interrupt is what we need.

Watchdog behavior table

The watchdog behavior in different states

This table is key to the whole operation. If the watchdog is enabled (WDE) and the watchdog interrupt enable (WDIE) is not set, then the processor will reset. However, if the interrupt enable is set (WDIE = 1), then an interrupt occurs. As long as we set WDIE before we go to sleep, we’ll wake up from an interrupt, and the program will continue from the point in the code where the sleep command was issued.

Here’s the program operation we’re aiming for:

  • Go to sleep for a few seconds
  • When the watchdog counter overflows use the interrupt to wake us up (not reset)
  • Once awake, take a analog reading to check for water
  • If there’s no water, go back to sleep until the watchdog wakes us up again

Additional information about how to configure the watchdog timer can be found on the AVR Libc page on sleep.h. While sleep.h is good for getting us to sleep, it was Lab III’s tutorial that provided the code that allows us to use the watchdog without resetting.

Here’s the basic code that puts the ATtiny to sleep in the main loop():

language:c
setup_watchdog(6); //Setup watchdog to go off after 1sec
sleep_mode(); //Go to sleep! Wake up 1sec later and check water

Putting the ATtiny to sleep for a second then waking up and doing something means it will be at 0.250mA for 1sec and 10mA for 0.0001 second. Overall, this is much lower power than the original 10mA.

But we can go even lower! There are a few peripherals that also use power, namely the analog to digital converter. Because we will not be doing any ADC while sleeping, we can shut it down as well:

language:c
void loop()
{
    ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
    setup_watchdog(6); //Setup watchdog to go off after 1sec
    sleep_mode(); //Go to sleep! Wake up 1sec later and check water
    ADCSRA |= (1<<ADEN); //Enable ADC

    //Now check for water!
    checkForWater();
}

This is basically how H2OhNo! works. Power everything off, go to sleep, wakeup, do something useful (check for water), go back to sleep. By disabling the ADC during sleep, we can get the sleep current consumption down to 5uA! That’s 0.005mA, or 2000 times lower than our original rate.

Remember that while the ATtiny is doing work (checking for water or making noise or blinking an LED) it will use the normal 10mA while it’s awake. So between sleeping at 0.005mA and doing work every second at 10mA, on average we found the H2OhNo! uses about 50uA. That means on a 200mAh coin cell we should expect the board to run for (200mAh / 0.050mA = ) 4,000 hours or about 167 days.

The H2OhNo! will wake up every second and check for water. This is probably far more often than a real-world application needs. The longest period the watchdog can be configured to fire is 8 seconds. To sleep for longer periods of time and squeeze even longer battery life from your board, try using a counter within the watchdog interrupt:

language:c
//This runs each time the watch dog wakes us up from sleep
ISR(WDT_vect) {
  watchdog_counter++;
}

void loop()
{
  sleep_mode(); //Go to sleep!

  if(watchdog_counter > 30)
  {
    watchdog_counter = 0;

    alarmSound(); //Make noise!!
    digitalWrite(buzzer1, LOW);
    digitalWrite(buzzer2, LOW);
  }
}

This will wake the board up every second but immediately go back to sleep until 30 seconds have gone by.

Resources and Going Further

The ATtiny is a wonderful simple workhorse. With a coin cell battery and low-power sleep modes you can create some really amazing projects. For your next project consider building:

  • An intrusion detection system
  • A temperature alarm for a reptile habitat
  • Use the internal EEPROM to datalog 512 light levels
  • Count the number of times your front door is opened

Resources


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Serial Graphic LCD Hookup

0
0

Serial Graphic LCD Hookup a learn.sparkfun.com tutorial

Introduction

Welcome to the hookup guide for the Serial Graphic LCD Backpack. In this tutorial, you will learn how to use the backpack to its full potential. We’ll start with the basic hardware overview, then move on to hooking the backpack up to a microcontroller. By the end, you should know all the capabilities of the backpack and how to implement them with any host device.

alt text

Suggested Reading

Before reading this hookup guide, you should be familiar with the following topics in order to get the most out of this tutorial. Please have a look if any of these concepts are unfamiliar to you.

Backpack Overview

The Serial Graphic LCD backpack was designed to provide a simple, serial interface for large, graphic liquid-crystal displays (LCDs). Besides writing text, the backpack allows the user to draw lines, circles and boxes, set or reset individual pixels, erase specific blocks of the display, and control the backlight. There’s also a reverse mode that swaps the colors of the pixels and the background.

Although SparkFun sells the backpack individually, it is also sold with the 128x64 pixel Graphic LCD and the 160x128 pixel Graphic LCD. For the purposes of this tutorial, we will be using both of these LCDs to demonstrate the functionality of the backpack.

alt text

The backpack is controlled with an ATmega168 microcontroller running at 5V/16MHz. This product is primarily intended for embedded applications, but it can easily be connected to a computer and written to with a terminal emulator. Both methods will be covered in this tutorial.

Power Requirements

Voltages of up to 9V may be used to power the backpack, however, care should be taken to reduce the backlight duty cycle in such cases to reduce the chance of overloading the voltage regulator on the backpack. To avoid complication with the voltage regulator, it’s best to power the backpack at 6V. You can also get away with powering the backpack from another 5V source. Keep in mind that anything below 5V will result in issues with the backlight and/or the display. If you are powering the backpack from a computer USB port or a microcontroller, make sure the output is actually 5V and not something like 4.5V.

Other Hardware Features

alt text

Here the contrast potentiometer (left) and the solder jumper (right) are highlighted.

Contrast Potentiometer

There is a small potentiometer on the backpack that allows for contrast adjustments. This should already be adjusted for you, but if text is not readily apparent or otherwise does not suit your needs, feel free to adjust to your liking. If at anytime the text on your LCD becomes unreadable, ALWAYS check the contrast potentiometer first. It is very sensitive, and, if it gets bumped, even just slightly, it can throw off the contrast of the LCD making it unreadable.

Solder Jumper

There is a solder jumper on the backpack that determines which display is used. When the solder jumper is closed, code for the 128x64 display will run. If the jumper is open, code for the 160x128 display will run. This jumper is soldered during production according to which LCD the backpack is being attached. However, if you wish to use the backpack with your own LCD, you may need to handle this jumper accordingly.

TX Line

The TX line from the backpack has been left in the final design for future code revisions, debugging and user development, but it is not currently utilized as of this writing.

LCD Overview

Let’s briefly discuss how these LCDs operate in order to better understand how the firmware we will be using later in this tutorial works. First, let’s talk about how the pixels on the LCDs are mapped out.

The graphic LCD is mapped out in Cartesian coordinates as shown in the following picture:

alt text

Or, if you are using the 64x128 pixel LCD, it’s more like this:

alt text

ASCII characters are printed to the screen with respect to two user-changeable settings, x_offset and y_offset. These two settings define the top-left corner bit of a character space, which is 6x8 bits. By changing x_offset and y_offset the user can place test anywhere on the screen.

alt text

Here is a capital letter ‘B’ as created in the character space.

Printing characters to the screen happens left to right, top to bottom, without adjusting x_offset and y_offset. Further, changing the offsets will change the entire frame of the text, meaning that writing to the end of one line and onto the next will happen seamlessly as the text has no predefined locations where it can or can’t be written (except for locations close to the left and bottom edges of the display).

Backspace is also functional and tries to maintain the reference frame as set by the user.

ASCII Commands

The Graphic Serial LCD Backpack is designed to be controlled by a variety of means. One of which is through a serial terminal. This can be useful if you want to use a personal computer as your control device. You can also send commands to the backpack in real time using the ASCII commands. This is useful for testing the LCD before embedding it into a project. Here is a full list of the ASCII commands.

Note: There are several instances where you will need to send ASCII values that require certain, unusual key presses. Anywhere you see /, this means that you have to press both the Control key and that character on your keyboard at the same time. If you are using a Mac, some of these commands need to be issued in a slightly different manner. For any command that doesn’t work using control, try using the unicode version of that character.

All commands are preceded with “|”, or ASCII decimal 124 (0x7C). This tells the display that a command sequence follows. Before any of the following commands are given, they must be preceded with “|”. The actual character “|” is not (and cannot) be printed to the screen.

Clear Screen

Sending “<control>@ (0x00)” clears the screen of all written pixels. If you’re operating in normal mode, all pixels are reset. If you’re operating in reverse mode, all pixels are set. An example of a “clear screen” command would be to send 0x7C 0x00, or from a keyboard send “|” and <control>@.

Demo Mode

Sending “<control>d (0x04)” runs demonstration code. This is in the firmware just as an example of what the display can do. To see the demonstration, send 0x7C 0x04, or from a keyboard send “|” and <control>d.

Reverse Mode

Sending “<control>r (0x12)” toggles between white on blue and blue on white on the 160x128 pixel display and black on green and green on black on the 128x64 pixel display. Setting the reverse mode causes the screen to immediately clear with the new background. To set the reverse mode, send 0x7C 0x12 , or from a keyboard send “|” and <control>r. This setting is saved between power cycles. If the display is turned off while in reverse mode, it will next power up in reverse mode.

Splash Screen

Sending “<control>s (0x13)” allows or disallows the SparkFun logo to be displayed at power up. The splash screen serves two purposes. One is to put our mark on the product, but the second is to allow a short time at power up where the display can be recovered from errant baud rate changes (see Baud Rate for more info). Disabling the splash screen suppresses the logo, but the delay remains active. To disable the splash screen, send 0x7C, 0x13, or from a keyboard send “|” and <control>s.

Set Backlight Duty Cycle

Sending “<control>b (0x02)” followed by a number from 0 to 100 will change the backlight intensity (and therefore current draw). Setting the value to zero turns the back light off, setting it at 100 or above turns it full on, and intermediate values set it somewhere in- between. The number setting in the command sequence is an 8-bit ASCII value. As an example, to set the backlight duty cycle to 50, send 0x7C 0x02 0x32, or from a keyboard send “|”, <control>b and “2”.

Change Baud Rate

Sending “<control>g (0x07)” followed by an ASCII character from “1” to “6” changes the baud rate. The default baud rate is 115,200bps, but the backpack can be set to a variety of communication speeds:

CharacterBaud Rate
"1"4800
"2"9600
"3"19200
"4"38400
"5"57600
"6"115200

As an example, to set the baud rate to 19,200bps, send 0x7C 0x07 0x33, or from a keyboard send “|”, <control>g and “3”. The baud rate setting is retained during power cycling, so if it powers down at 19,200bps, it will next power up with that setting.

In a pinch, the baud rate can be reset to 115,200. During the one second delay at power up, send the display any character at 115,200bps.

Set X or Y Coordinates

Sending “<control>x (0x18)” or “<control>y (0x19)” followed by a number representing a new reference coordinate changes the X or Y coordinates. The X and Y reference coordinates (x_offset and y_offset in the source code) are used by the text generator to place text at specific locations on the screen. As stated earlier, the coordinates refer to the upper left most pixel in the character space. If the offsets are within 6 pixels of the right edge of the screen or 8 pixels of the bottom, the text generator will revert to the next logical line for text so as to print a whole character and not parts. As an example, to set x_offset to 80 (the middle of the horizontal axis of the 160x128 pixel display) send 0x7C 0x18 0x50, or from a keyboard send “|”, <control>x and “P”. Attempting to set values greater than the length of each axis result in maximizing the respective offsets.

Set/Reset Pixel

Sending “<control>p (0x10)” followed by x and y coordinates and a 0 or 1 to determine setting or resetting of that pixel. Any pixel on the display can independently set or reset with this command. As an example, to set the pixel at (80, 64) send 0x7C 0x10 0x50 0x40 0x01, or from a keyboard send “|”, <control>p, “P”, “@” and <control>a. Remember that setting a pixel doesn’t necessarily mean writing a one to that location, it means to write the opposite of the background. So if you’re operating in reverse mode, setting a pixel actually clears the pixel and sets it apart from the white background. Resetting that pixel causes it to be white like the background.

Draw Line

Sending “<control>l (0x0C)” followed by two sets of (x, y) coordinates defining the line’s start and stop, followed by a 0 or 1 determines whether to draw or erase the line. As an example, to draw a line from (0,10) to (50,60) send 0x7C 0x0C 0x00 (x1) 0x0A (y1) 0x32 (x2) 0x3C (y2) 0x01, or from a keyboard send “|”, <control>l, <control>@, <control>j, “2”, “<” and <control>a. To erase the line (and leave surrounding text and graphics unchanged), submit the same command but changing the last <control>a to<control>@.

Draw Circle

Sending “<control>c (0x03)” followed by x and y coordinates defining the center of the circle, followed by a number representing the radius of the circle, followed by a 0 or 1 determines whether to draw or erase the circle. As an example, to draw a circle at center (80, 64) with radius 10 send 0x7C 0x03 0x50 0x40 0x0A 0x01, or from a keyboard send “|”, <control>c, “P”, “@”, <control>j and <control>a. To erase the circle (and leave surrounding text and graphics unchanged), submit the same command but changing the last <control>a to <control>@. Circles can be drawn off-grid, but only those pixels that fall within the display boundaries will be written.

Draw Box

Sending “<control>o (0x0F)” followed by two sets of (x, y) coordinates defining opposite corners of the box, followed by a 0 or 1 determines whether to draw or erase the box. This command is exactly like the draw line command, but instead of drawing a line you get a box that exactly contains the line between the given coordinates. As an example, to draw a rectangular box around the line from (0,10) to (50,60) send 0x7C 0x0F 0x00 (x1) 0x0A (y1) 0x32 (x2) 0x3C (y2) 0x01, or from a keyboard send “|”, <control>o,<control>@, <control>j, “2”, “<” and <control>a. To erase the box (and leave surrounding text and graphics unchanged), submit the same command but changing the last <control>a to <control>@.

Erase Block

Sending “<control>e (0x05)” followed by two sets of (x, y) coordinates defines opposite corners of the block to be erased. This is just like the draw box command, except the contents of the box are erased to the background color. As an example, to erase a rectangular block around the line from (0,10) to (50,60) send “0x7C 0x05 0x00 (x1) 0x0A (y1) 0x32 (x2) 0x3C (y2)”, or from a keyboard send “|”, <control>e, <control>@, <control>j, “2” and “<”.

Example 1 - FTDI Basic

Now that we know the commands used to control the LCD, why don’t you give it a shot. In this example, you will be using an FTDI Basic to communicate with and control your LCD.

What You Will Need

Hardware

The simplest and fastest way to connect and print to the LCD is to use an FTDI Basic or FTDI Cable. Using jumper wires, connect the FTDI to the LCD like so…

FTDIGraphic LCD
5VVin
GNDGND
TXORX

Once you have the the LCD wired up correctly, plug the FTDI device into your computer. Open a terminal window. Make sure you have the correct settings: Baud: 115200, 8-N-1-NONE. Once you are connected, begin typing. Everything you type should now show up on the LCD! Refer back to the ASCII Commands section to see which keys you need to press to perform specific commands such as clearing the screen, drawing a circle, or printing text to a specific x,y coordinate.

hello world

Talking to the LCD from the computer is fun and all, but the real fun begins when you can print information to the LCD from and embedded device. In the next example, we’ll use an Arduino to print information to the LCD.

Firmware Overview

Before we dive into hooking up the LCD to an Arduino, let’s discuss the firmware for a minute. The firmware is the code that resides on the backpack. It serves as a bridge, or translator, between the LCD and whichever microcontroller you use to communicate with it. On top of the firmware, we’ve written an Arduino library to make using the backpack even easier.

Backpack Firmware

We’ve revamped the firmware that ships with the backpack. It runs smoother than ever to give any project an awesome graphical display. Pending you don’t need anything too fancy, you should be able to use the default firmware for all your LCD needs. But that doesn’t mean that it’s not worth understanding. To see the firmware, head on over to the Serial Graphic LCD Backpack GitHub repository. You can either download the zip file, clone the repo to your computer, or just navigate with GitHub’s default editor.

Inside the Firmware folder you’ll see a lot of .c and .h files. These are the files that tell the backpack how to interact with the LCD based upon the input received. Since modifying the source code is beyond the scope of this tutorial, we’ll leave it here. Just know that if there is some internal functionality that you’d like to add, delete, or modify, this is the place to do it.

Do note that you’ll need a programmer to change the firmware on the backpack. It is not Arduino compatible, even though the IC on board is an ATmega328, the same IC found on many Arduino boards. Check out the Troubleshooting section for more info on how to reflash the firmware to your backpack.

Arduino Library

To make using the Serial Graphic LCD Backpack as easy as possible, we’ve written an Arduino library. The library can be found on the GitHub repository. This library basically creates function for each of the commands listed on the previous ASCII commands page. The example sketch that comes with the library demonstrates each function and shows you how to implement them for a full range of purposes on the LCD. If you need a refresher on installing an Arduino Library, please visit our Installing a Library tutorial.

Each function will be listed here and given a short description. However, these functions build upon the commands listed in the ASCII Commands section. For more details on each function, please refer to that section or read the comments provided in the library files.

Print Commands

  • printStr(char Str[78]) - Prints a string to the LCD. The buffer is set to 78 by default but can be changed in the header file.
  • printNum(int num) - Prints a single number to the LCD.
  • nextLine() - Acts as a newline for text.

These three function exist because the instance of the Software Serial library is declared within the library files to communicate with the backpack. Therefore, using the typical serial.print() commands won’t work to send text to the LCD while using this library.

LCD Functionality

  • clearScreen() - Clears the LCD of any and all pixels.
  • toggleReverseMode() - Toggles reverse mode – blue on white for the 160x128 display and green on black for the 128x64 display.
  • toggleSplash() - Turns the SparkFun splash screen on or off. Note that the one second delay on startup remains with or without the splash screen enabled.
  • setBacklight(byte duty) - Set the brightness of the backlight. Takes a single int as a parameter. The range is 0-100, where 0 is OFF and 100 is full brightness. Anything higher than 100 will still result in a max value of 100.
  • setBaud(byte baud) - Set the baud rate of the backpack. Takes a single int as a parameter with a range of 49-54.
  • restoreDefaultBaud() - Restores the LCD back to the default baud rate of 115200bps.

Cursor Positioning

  • setX() - Sets the x position of where text will appear on the screen.
  • setY() - Sets the y position of where text will appear on the screen.
  • setHome() - Sets poth x and y back to position 0,0.

Drawing

  • setPixel(byte x, byte y, byte set) - Set or reset (revert back to the background color) any pixel on the LCD.
  • drawLine(byte x1, byte y1, byte x2, byte y2, byte set) - Draws a line between two x,y coordinates.
  • drawBox(byte x1, byte y1, byte x2, byte y2, byte set) - Draws a box between two x,y coordinates.
  • drawCircle(byte x, byte y, byte rad, byte set) - Draws a circle with the center point starting at the given x,y coordinate and then extends out to the given radius.
  • eraseBlock(byte x1, byte y1, byte x2, byte y2) - Erases the block spanning from the two given x,y coordinates.
  • demo() - Initiates an internal demo built into the firwmare.

Example 2 - Arduino

We’ll first go over the quick and easy way to print to the LCD from an Arduino, then we’ll go over a more robust method that utilizes the special characters built into the LCD’s firmware.

What You Will Need

Serial Pass-through

This first example utilizes the built in UART on the Arduino. By doing this, we have to be careful when uploading code to the Arduino while the LCD is connected, since they’ll be sharing the same lines. We’re going to do things slightly backwards, and upload the code first, then connect the LCD.

With just a few lines of code, you can pass text through the Arduino to a terminal window. Copy this code to a new sketch, and upload it to the Arduino.

language:c
void setup() {
  Serial.begin(115200);
}
void loop() {
  if(Serial.available() > 0){
    Serial.write(Serial.read());
  }
}

This code takes whatever the Arduino receives on its RX line and sends it back out the TX line to the Serial Graphic LCD. You must use Serial.write() instead of Serial.print if you wish to see characters on the LCD and not ASCII numbers.

Hardware

Now, connect the LCD to the Arduino like so..

Make sure your connections are as follows:

ArduinoGraphic LCD
5VVin
GNDGND
TXRX

You don’t need to hook up to the LCD’s TX line because you’re only sending data to the LCD.

Now, open a terminal window (again at 115200), and begin typing. Again text should appear on the LCD. Backspace still works too!

Arduino Library Example

In this last example, we’re going to use the Serial Graphic LCD library to do all the work for us. One important feature of the library is that it uses the Software Serial library to create an alternative serial port for the Arduino to communicate to the LCD. The problem with the previous example is that we are using the internal UART and thus have to disconnect the LCD every time we want to upload code. This can be a pain in the butt when you are developing code and need to upload several times.

Hardware

We can use the previous examples setup for this example, you’ll just need to change one jumper wire. Move the jumper wire connected to the Arduino’s TX pin to Digital Pin 3 on the Arduino. This is the pin that the Serial Graphic LCD library uses when it initializes the Software Serial library.

Your connections should look like this now:

ArduinoGraphic LCD
5VVin
GNDGND
Pin 3RX

Or, for the visually inclined, here’s a picture of what your connections should look like.

LCD hooked up to RedBoard

Firmware

If you haven’t done so already, download and install the Arduino library, or clone it to your computer. Head back to the Firmware Details section for more info on installing the library. Once it’s installed, open up Arduino, and navigate to the library Example.

alt text

Select the proper serial port and board, and upload the example to your Arduino. Once uploading has finished, the library demo should begin. It will run through examples of using almost every function in the library. All that’s left is to sit back and enjoy the show!

Troubleshooting

Display Issues

  • If you don’t see any letters, make sure the contrast potentiometer on the backpack is adjusted accordingly. You’ll need a fine-tipped screwdriver to adjust it. Be careful when adjusting this trimpot as turning it too far or too hard can result in the trimpot breaking.
  • Make sure you are giving the backpack at least 5V. Any lower and you may have an issue with contrast. Some USB ports run around 4.7-4.8V and may not have enough voltage to fully power the LCD and backpack. We recommend powering the LCD with 6-7V.
  • If you can’t see any letters, even when the contrast is adjusted accordingly, then there may be a baud rate issue. If you changed the baud rate and forgot to what you changed it, you can use the restoreDefaultBaud() command in the Arduino library to restore the baud rate to its default of 115200bps. Simply create a sketch that imports the Graphic Serial LCD library and then call the restore function in Setup.

Copy and paste this code in to Arduino, make sure the LCD’s RX pin is connected to digital pin 3 on the Arduino, and then upload. You should see the screen print “Baud restored to 115200!”

language:c
#include <SerialGraphicLCD.h>//inculde the Serial Graphic LCD library
#include <SoftwareSerial.h>
LCD LCD;
void setup()
{
delay(1200);///wait for the one second splash screen
LCD.restoreDefaultBaud();
}
void loop()
{
//nothing in loop
}

Reflashing the Firmware

If you are experiencing odd behavior from your backpack, it may be the firmware. If this happens, we recommend updating the backpack with the latest firmware. We’ll briefly describe how to do this yourself if you have the proper tools.

The latest version of the firmware can be found on GitHub. Visit the link to the repository. Clone the repository, or download the zip file. Remember the location of this file.

alt text

You’re going to need some way to upload the firmware to the backpack. We recommend using an Atmel AVR MKII programmer. If you don’t have an MKII, you could use something similar such as the Pocket AVR Programmer. Plug your programmer into your computer. You can also use an Arduino board as a programmer. For more info on this and general reflashing firmware information, please see our Installing an Arduino Bootloader tutorial.

In this example, I’m going to use Atmel AVR Studio (v4.18) to upload the .hex file to the backpack. You can also use AVRDude to accomplish the same task in the command line. If you are running Mac or Linux, you’ll either need to look into uploading AVR code on your particular OS, or use a virtual machine such as Wine or VMWare to run AVR Studio in Windows.

Once you’ve figured out how to get AVR studio up and running, go ahead and start the program. You should be greeted with a prompt asking you to choose which programmer you’re using. Select AVR MKII, or whichever programmer you’re using.

alt text

Now, you’re going to want to select to which chip you plan to upload. Select ATmega168P.

alt text

Click on the Program tab. In the ‘Flash’ section, click the button with three dots on it to browse for the hex file you downloaded from GitHub.

alt text

Browse for the .hex file that come with the GitHub download.

alt text

Once you have pointed AVR Studio to the hex file, connect the programmer to the ISP header on the backpack, and click ‘Program.’

alt text

You should see a success message in the bottom of the program. If so, the new firmware should be on the backpack and ready to go!

Resources and Going Further

That about wraps it up. You should now have a good understanding of how the Serial Graphic LCD works and how you can use a variety of means to control the LCD. Now get out there and make some awesome projects with an nice user interface. For more info on the S-G-LCD backpack, check out the links below.


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Installing an Arduino Bootloader

0
0

Installing an Arduino Bootloader a learn.sparkfun.com tutorial

Overview

Do you have a bricked Arduino that won’t accept code anymore? Or, maybe you wrote your own firmware and would like to upload it to your Arduino? Or, maybe you just want to learn more about the inner-workings of Arduino, AVR, and microcontrollers in general. Well, you’re in luck! This tutorial will teach you what a bootloader is, why you would need to install/reinstall it, and go over the process of doing so.

Suggested Reading

You may want to check out these tutorials before continuing down the bootloader path.

What is a Bootloader?

Atmel AVRs are great little ICs, but they can be a bit tricky to program. You need a special programmer and some fancy .hex files, and its not very beginner friendly. The Arduino has largely done away with these issues. They’ve put a .hex file on their AVR chips that allows you to program the board over the serial port, meaning all you need to program your Arduino is a USB cable.

The bootloader is basically a .hex file that runs when you turn on the board. It is very similar to the BIOS that runs on your PC. It does two things. First, it looks around to see if the computer is trying to program it. If it is, it grabs the program from the computer and uploads it into the ICs memory (in a specific location so as not to overwrite the bootloader). That is why when you try to upload code, the Arduino IDE resets the chip. This basically turns the IC off and back on again so the bootloader can start running again. If the computer isn’t trying to upload code, it tells the chip to run the code that’s already stored in memory. Once it locates and runs your program, the Arduino continuously loops through the program and does so as long as the board has power.

Why Install a Bootloader

If you are building your own Arduino, or need to replace the IC, you will need to install the bootloader. You may also have a bad bootloader (although this is very rare) and need to reinstall the bootloader. There are also cases where you’ve put your board in a weird setting and reinstalling the bootloader and getting it back to factory settings is the easiest way to fix it. We’ve seen boards where people have turned off the serial port meaning that there is no way to upload code to the board, while there may be other ways to fix this, reinstalling the bootloader is probably the quickest and easiest. Like I said, having a bad bootloader is actually very very rare. If you have a new board that isn’t accepting code 99.9% of the time its not the bootloader, but for the 1% of the time it is, this guide will help you fix that problem.

Selecting a Programmer

We are going to talk about 2 different types of programmers you can use to install or reinstall bootloaders.

Option 1: Dedicated Programmers

For a quick easy programmer we recommend looking into the AVR Pocket Programmer (Windows only).

pocket programmer

Or, you can use the official Atmel AVR MKII programmer.

AVR MKII

The AVR Pocket Programmer or most cheaper options will work just fine for most applications, but they may have problems with some boards, specifically ones with lots of memory like the ATMega2560 based boards.

Option 2: Using the Arduino as a Programmer

The other option is grabbing an Arduino Uno (or Duemilanove). If you go into the Arduino IDE you will see an example sketch called ‘Arduino as ISP.’ If you upload this code to your Arduino, it will basically act as an AVR programmer. This isn’t really recommended for production of boards, or boards with lots of memory, but, in a pinch, it works pretty well. Also as of this writing the code only works on ATmega328 boards. Maybe one day it will work on the Leonardo or Due, but not yet.

Note: You can only use Arduinos that have a DIP IC and a socket like this Uno, not Arduinos that have SMD ATmegas on them, such as the RedBoard.

Connecting the Programmer

In-Circuit Serial Programming (ICSP)

It’s very uncommon to program ICs before they are soldered onto a PCB. Instead, most microcontrollers have what’s called an in-system programming (ISP) header. Particularly, some IC manufacturers, such as Atmel and Microchip, have a specialized ISP method for programming their ICs. This is referred to as in-circuit serial programming (ICSP) Most Arduino and Arduino compatible boards will have a 2x3 pin ICSP header on them. Some may even have more than one depending on how many ICs live on the PCB. It breaks out three of the SPI pins (MISO, MOSI, SCK), and power, ground, and reset. These are the pins you’ll need to connect your programmer to in order to reflash the firmware on your board.

UNO ISP

Here we have the Arduino Uno R3. It has two ICSP headers: one for the ATmega16U2 and one for the ATmega328. To reflash the bootloader on this board, you would use just the ICSP header for the ATmega328.

On some smaller boards you may not see this connector, but the pins should be broken out elsewhere. Whether you’re using an SMD IC or a DIP IC, the ISP pins should be accessible in one form or another. Some boards might only have test points for the ISP header. If this is the case, you may want to consider getting an ISP Pogo Adapter. This kit allows you to temporarily make a good connection with test test points in order to reprogram your IC.

alt text

ISP Pogo Adapter Kit Fully Assembled. You can connect any of the programmers we mentioned in the previous section to this board.

If you are having trouble finding the ICSP pins on your particular Arduino board, you can consult this website for detailed pinouts of most Arduino related ICs and then some.

Once you have located the six ICSP pins on your board, it’s time to hook up your programmer to the board. You can use a programming cable to connect the two, or, if you don’t have a cable, you can just use some male-to-female jumper wires.

If you are using a programmer such as the MKII or the Pocket Programmer, your setup should look something like this:

alt text

Click for larger image.

Or, if you’re using the Arduino as your programmer, it should look like this:

alt text

Click for larger image.

Here’s a table to help clarify which connections go where.

Arduino as ISPAVR ProgrammerISP HeaderATmega328ATmega32U4
Vcc/5V5VPin 2VccVcc
GNDGNDPin 6GNDGND
MOSI/D11MOSIPin 4D11D16
MISO/D12MISOPin 1D12D14
SCK/D13SCKPin 3D13D15
D10ResetPin 5ResetReset

Uploading Code - Easy Way

The easy way to upload the bootloader involves using the Arduino IDE. Open your IDE select the board you want to program. Then select the programmer (if you are using the Arduino as ISP you will also need to select the COM port that the Arduino as ISP is connected to). Then select BurnBootloader. This will take the board you selected and look up the associated bootloader in the board.txt file. Then, it will find the bootloader in the bootloader folder and install it. This only works if the board is installed correctly in the IDE and you have the correct bootloader.

If for some reason you want to use a bootloader that isn’t installed in the Arduino IDE, visit the nest section. However, it’s probably easier to just install the bootloader from the Arduino IDE. For those who are curious about settings such as fuse bits, have no fear. Arduino takes care of all the messy details for you when you burn bootloaders through it.

alt text

Uploading Code - Hard Way

The hard way is for those people who want to use the command line. This method may be more preferable if you are modifying and recompiling and don’t want to have to keep updating the IDE, but otherwise its pretty unnecessary. Again you will need to get the programmer, and hook everything up. In this example we are using avrdude on Windows.

There are two steps to this process. The first step involves setting the fusebits. Fusebits are the part of the AVR chip that determine things like whether you are using an external crystal or whether you want brown out detection. The commands listed below are for the Arduino Uno using an ATMega328, they will probably work on some other similar boards such as the Duemilanove, but make sure you know what you are doing before playing with fusebits (NOTE: these fusebits will not work on a 3.3V/8MHz board). All the required fuse bits are listed in the boards.txt file for different boards, but again, if you have a boards.txt file installed then just use the Easy Way.

Arduino as ISP: avrdude -P comport -b 19200 -c avrisp -p m328p -v -e -U efuse:w:0x05:m -U hfuse:w:0xD6:m -U lfuse:w:0xFF:m

AVR Pocket Programmer:avrdude -b 19200 -c usbtiny -p m328p -v -e -U efuse:w:0x05:m -U hfuse:w:0xD6:m -U lfuse:w:0xFF:m

The second step is actually uploading the program.

Arduino as ISP: avrdude -P comport -b 19200 -c avrisp -p m328p -v -e -U flash:w:hexfilename.hex -U lock:w:0x0F:m AVR Pocket Programmer: avrdude -b19200 -c usbtiny -p m328p -v -e -U flash:w:hexfilename.hex -U lock:w:0x0F:m

One last bit of info. As we stated earlier, a bootloader is essintially a .hex file. Thus, you can use this method to upload and code you wish to your ICs.

Resources and Going Further

For more info on AVRs, bootloaders, and flashing firmware to other boards, check out these other great tutorials.

You can also check out our Tiny AVR Programmer Hookup Guide to learn more about uploading code to AVR chips without using the Arduino IDE.


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

MPL3115A2 Pressure Sensor Hookup Guide

0
0

MPL3115A2 Pressure Sensor Hookup Guide a learn.sparkfun.com tutorial

MPL3115A2 Overview

The MPL3115A2 is a low-cost, low power, highly accurate barometric pressure sensor. Use this sensor to detect changes in barometric pressure (weather changes) or for altitude (UAV controllers and the like). The sensor is very sensitive and capable of detecting a change of only 0.05kPa which equates to a 0.3m change in altitude.

MPL3115A2 pressure sensor breakout board

MPL3115A2 Pressure sensor breakout board

Things you should know about this sensor:

  • Uses the I2C interface
  • Only one sensor can reside on the I2C bus
  • Uses the I2C repeated start condition. Arduino supports this, check if you’re using a different microcontroller.
  • Typical pressure accuracy of ±0.05kPa
  • Typical altitude accuracy of ±0.3m
  • Typical temperature accuracy of ±3C
  • 3.3V sensor - use inline logic level converters or 10k resistors to limit 5V signals
  • Here’s the datasheet
  • Here’s the schematic for the breakout board

This sensor is ideal for environmental sensing, a weather station, or datalogging. It is a worthy replacement for the BMP085 and is more sensitive than the MPL115A1.

Suggested Reading

Hooking It Up

Wiring up the MPL3115A2 pressure sensor is very easy!

alt text

Basic hook up with 10k in-line resistors

There are only four pins that need to be hooked up in order to start using this sensor in a project. One for VCC, one for GND, and two data lines for I2C communication.

Note: This breakout board has built in 1k pull up resistors for I2C communications. If you’re hooking up multiple I2C devices on the same bus, you may need to disable the other resistors on the bus.

Connections: Breakout board to Arduino

  • VCC → 3.3V
  • GND → GND
  • SDA → A4
  • SCL → A5

Note: You can also you the SDA and SCL lines on Arduino boards that have them broken out. Make sure you edit the code accordingly if you use those pins instead.

On an Arduino board connect the SDA pin on the breakout board to A4 and SCL to A5. If you’re using a 5V Arduino Uno we recommend putting 10k resistors in line to limit the 5V signal going into the sensor and prevent damage to the sensor.

MPL311A2 Library and Functions

We’ve written an Arduino library and some example code to make using the MPL3115A2 easy to get up and running. Grab the library here. Unzip and paste the folder “MPL3115A2_Pressure” into your Arduino libraries folder. Not sure how to install an Arduino library? Read here for more information.

Arduino Example Sub Menu

Load the Pressure example

Once the library is installed, open Arduino, and expand the examples menu. You should see the MPL3115A2_Pressure sub-menu. Load the “Pressure” example onto the Arduino. Open the serial terminal at 9600bps. You will see the current barometric pressure and temperature in the room!

Arduino terminal output

Pressure readings!

Explanation of Functions

The library and example code demonstrate the most popular functions supported by the MPL3115A2. Here is an explanation of all the available functions in the library:

  • myPressure.begin() gets sensor on the I2C bus.
  • myPressure.readAltitude() returns a float with meters above sea level. Ex: 1638.94
  • myPressure.readAltitudeFt() returns a float with feet above sea level. Ex: 5376.68
  • myPressure.readPressure() returns a float with barometric pressure in Pa. Ex: 83351.25
  • myPressure.readTemp() returns a float with current temperature in Celsius. Ex: 23.37
  • myPressure.readTempF() returns a float with current temperature in Fahrenheit. Ex: 73.96
  • myPressure.setModeBarometer() puts the sensor into Pascal measurement mode.
  • myPressure.setModeAltimeter() puts the sensor into altimetry mode.
  • myPressure.setModeStandy() puts the sensor into Standby mode. Required when changing CTRL1 register.
  • myPressure.setModeActive() starts taking measurements!
  • myPressure.setOversampleRate(byte) sets the # of samples from 1 to 128. See note below *
  • myPressure.enableEventFlags() sets the fundamental event flags. Required during setup.

Oversample settings table

Oversample settings

*setOversampleRate(byte) receives a value from 0 to 7. Check table 59 above. Allows the user to change sample rate from 1 to 128. Increasing the sample rate significantly decreases the noise of each reading but increases the amount of time to capture each reading. A oversample of 128 will decrease noise to 1.5Pa RMS but requires 512ms per reading. The datasheet recommends oversample of 128 for basic applications.

The MPL3115A2 has a large number of features. Checkout the datasheet for more info. This library covers the fundamentals. Help us out! Please add or suggesting more features on the MPL3115A2 github repo.

Pressure vs Altimeter Setting

If you grabbed a few pressure readings and became confused when you checked your local weather conditions, you’re not alone. The absolute pressure that the MPL3115A2 pressure sensor outputs is not the same as what weather stations refer to as pressure. Weather stations report pressure in lots of different units:

  • millimeters Mercury (mmHg)
  • inches Mercury (inHg)
  • millibars or hectopascals (hPa)
  • pounds per square inch
  • atmospheres (Atm)
  • kilogram per centimeter
  • inches of water

In barometer mode, the MPL3115A2 outputs pressure readings in Pascals. This is most closely related to millibars or hectopascals. But, why does the sensor not agree with the station around the corner? This is because many stations report pressure in a few different formats. Have a look at all these numbers for the Boulder/Denver area. The key is that your local weather station is probably reporting the Altimeter setting.

Thank you National Oceanic and Atmospheric Administration (NOAA)! Did you know they’re headquartered here in Boulder, CO?

  • Station pressure - This is the pressure that is observed at a specific elevation and is the true barometric pressure of a location.
  • Altimeter setting - This is the pressure reading most commonly heard in radio and television broadcasts. It is not the true barometric pressure at a station. Instead it is the pressure “reduced” to mean sea level using the temperature profile of the “standard” atmosphere, which is representative of average conditions over the United States at 40 degrees north latitude.
  • Mean sea level pressure - This is the pressure reading most commonly used by meteorologists to track weather systems at the surface. Like the altimeter setting, it is a “reduced” pressure, which uses observed conditions rather than “standard” conditions to remove the effects of elevation from pressure readings.

The calculation to get from Pascals to ‘Altimeter setting’ is a bit gnarly:

Alimeter setting formula

Formula to convert Pascal pressure to Altimeter setting

Grab the full formula here and give this great Altimeter setting calculator a try. This formula relies on two things: knowing the current pressure in milibars and knowing the height above sea level that the pressure was read. We recommend you capture altitude using a local survey point or a GPS receiver.

If you installed the MPL3115A2 library, you should also have the BarometricHgInch example sketch under the Examples->MPL3115A2_Pressure menu under the Arduino IDE. We didn’t build this calculation into the library because it could potentially chew up a lot of RAM and code space calculating all the floating point math. But, if you’re doing home weather station calculations, this should get you started.

Resources and Going Further

Now that you’ve got barometric pressure sensing under your belt, consider checking out the following projects and products:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado


Weather Shield Hookup Guide

0
0

Weather Shield Hookup Guide a learn.sparkfun.com tutorial

Weather Shield Overview

The Weather Shield is an easy to use Arduino shield that grants you access to barometric pressure, relative humidity, luminosity, and temperature. There are also connections to optional sensors such as wind speed/direction, rain gauge, and GPS for location and super accurate timing.

Weather Shield

The bare Weather Shield

Things you should know about this shield:

Suggested Reading

Hooking It Up

To get up and running with the Weather Shield you’ll need the following parts:

Weather shield with wind and rain meter

Shield on a RedBoard with optional weather meter (‘W'ind and 'R'ain cables) and GPS attached

Assembly

Solder the stackable headers onto the shield, and insert the shield into your Arduino. You are welcome to solder in the RJ11 connectors to the top of the board as well. If you have the GP-635T GPS module, don’t worry about attaching it at this time, we’ll get to GPS later.

Example Firmware

The Weather Shield example relies on the HTU21D and MPL3115A2 libraries. Download the libraries here then install them into your Documents/Arduino folder.

Grab the example sketch, and load it onto your Arduino. Open the serial monitor at 9600bps. You should see an output string every second containing the current weather information:

$,winddir=0,windspeedmph=0,windspdmph_avg2m=0.0,winddir_avg2m=0,windgustmph_10m=0.0,windgustdir_10m=0,humidity=31.7,tempf=76.3,rainin=0.00,dailyrainin=0.00,pressure=81525.25,batt_lvl=4.32,light_lvl=2.03,#

$,winddir=0,windspeedmph=0,windspdmph_avg2m=0.0,winddir_avg2m=0,windgustmph_10m=0.0,windgustdir_10m=0,humidity=31.7,tempf=76.3,rainin=0.00,dailyrainin=0.00,pressure=81520.75,batt_lvl=4.32,light_lvl=2.02,#

$,winddir=0,windspeedmph=0,windspdmph_avg2m=0.0,winddir_avg2m=0,windgustmph_10m=0.0,windgustdir_10m=0,humidity=31.7,tempf=76.3,rainin=0.00,dailyrainin=0.00,pressure=81517.50,batt_lvl=4.34,light_lvl=2.11,#

$,winddir=0,windspeedmph=0,windspdmph_avg2m=0.0,winddir_avg2m=0,windgustmph_10m=0.0,windgustdir_10m=0,humidity=31.7,tempf=76.3,rainin=0.00,dailyrainin=0.00,pressure=81509.25,batt_lvl=4.31,light_lvl=2.11,#

The $ and # are start and stop characters. These types of bytes are used to make it easy to parse out the data. For example, you could have an Electric Imp listen for a $ and record the data until you see a #. Once you have the string then split on the commas (also known as comma delimited), and start recording the next string.

Example with GPS

Weather Shield with GPS

Shield on a RedBoard with optional weather meter connectors and GPS attached

Attach the GP-635T GPS module using the short cable. To secure the module, there is space on the shield to attach the module using double-stick tape.

Picture of serial switch

Serial pins are connected to digital pins 4 and 5 when Serial is set to soft and are attached to the internal UART when set to hard.

There is a switch labeled Serial on the shield. This is to select which pins on the Arduino to connect the GPS to. In almost all cases the switch should be set to ‘Soft’. This will attach the GPS serial pins to digital pins 5 (TX from the GPS) and 4 (RX into the GPS).

Grab the GPS example sketch that demonstrates using the GP-635T with all the other sensors. Load it onto your Arduino, and open the serial monitor at 9600. You should see output similar to the following:

$,winddir=-1,windspeedmph=nan,humidity=28.2,tempf=76.1,rainin=0.00,dailyrainin=0.00,pressure=81355.00,batt_lvl=4.05,light_lvl=3.05,lat=40.018054,lat=-105.282577,altitude=1647.40,sats=10,date=11/16/2013,time=20:00:44,#

$,winddir=-1,windspeedmph=nan,humidity=28.2,tempf=76.1,rainin=0.00,dailyrainin=0.00,pressure=81358.00,batt_lvl=4.07,light_lvl=3.05,lat=40.018054,lat=-105.282577,altitude=1647.40,sats=10,date=11/16/2013,time=20:00:45,#

$,winddir=-1,windspeedmph=nan,humidity=28.2,tempf=76.1,rainin=0.00,dailyrainin=0.00,pressure=81358.25,batt_lvl=4.08,light_lvl=3.05,lat=40.018054,lat=-105.282585,altitude=1647.40,sats=10,date=11/16/2013,time=20:00:46,#

Note: The batt_lvl is indicating 4.08V. This is correct and is the actual voltage read from the Arduino powered over USB. The GPS module will add 50-80mA to the overall power consumption. If you are using a long or thin USB cable you may see significant voltage drop similar to this example. There is absolutely no harm in this! The Weather Shield runs at 3.3V and the Arduino will continue to run just fine down to about 3V. The reading is very helpful for monitoring your power source (USB, battery, solar, etc).

This example demonstrates how you can get location, altitude, and time from the GPS module. This would be helpful with weather stations that are moving such as balloon satellites, AVL, package tracking, and even static stations where you need to know precise altitude or timestamps.

Resources and Going Further

The Weather Shield example firmware outputs regular barometric pressure. This is very different from the pressure that weather stations report. For more information, see the definition of “altimeter setting pressure”. For an example of how to calculate altimeter setting type barometric pressure see the MPL3115A2 hook-up guide. Also checkout the MPL3115A2 library, specifically the BarometricHgInch example.

Datasheets

There’s a lot of technology on this shield. Here’s the datasheets in case you need to reference them:

Additional resources and projects to checkout:


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Constant Innovation in Qualty Control

0
0

Constant Innovation in Qualty Control a learn.sparkfun.com tutorial

Introduction

Here in Quality Control, we are constantly challenged to create fast, thorough, and reliable test procedures. We are never willing to sacrifice any of these three ingredients, and so, the only way to speed up a test is to hire more technicians or… innovate. In our true boot-strapping style, we have always done our best to do the latter.

In 2009, we began designing our testing equipment using pogopins.

alt text

You can read more about that here: PogoBeds: SparkFun Production and Testing

In 2011, we hacked together a multiple board programmer using our first ever waffle press.

alt text

You can read more about that here: Ganged Programming with AVR ISP MKIIs

Since then, we have made tons of advancements in our hardware, code, inspection processes, and board layout. In this article, we are going to share some of our best ideas from the past few years. We hope they will help you design better projects and maybe even think about your hardware design in new ways.

Cheers to making great electronics and how to test them!

Multi-board Programming

Our first approach to multi-board programming involved multiple programmers, a USB hub, a bunch of cables, and some tricky batch file action.

alt text

It sure did speed up our production runs. Nine at a time was a huge improvement from our previous single board programming methods. But, as with most of our testing equipment, it eventually became out-dated, and we wanted to upgrade it.

It became a bit of a hassle to setup – ensuring that everything was plugged in properly. And over the years, the ribbon cables began to wear out. In November of 2011, we posted a very thorough tutorial on how this ganged-programmer works. Click HERE to check that out. In addition to the hardware design ideas, it actually was a great exercise in using batch files.

About a year after the release of the above programmer, we started having a lot of our technicians computers freeze up mid programming. The famous blue screen of death was happening far too often. We replaced the USB hubs with better quality hubs, and this seemed to help the problem a bit. However, we knew another approach was needed.

We wanted to find a way to program multiple boards simultaneously using one single programmer. Our first thought was to use some sort of amplification or buffer on the programming lines.

To program an AVR using ISP, there are 6 connections that need to be made from the programmer to the target IC:

  • VCC
  • GND
  • RESET
  • SCK
  • MISO
  • MOSI

Experimenting with our logic level converter, we were able to get a few boards to program off one single programmer. Our initial hardware was as follows.

Physically bussing (as in metal connections on the same net) for the GND, VCC and RESET.

SCK and MOSI needed to be buffered, because these signals were being sent to multiple targets. It seemed that the MKII did not have enough output impedance to program multiple targets, so we sent them through the logic level converter. This way, the signal strength was relying on the HIGH logic pin of the converter and not the output of the MKII.

The MISO line was a little trickier. This line carries communication from the target back to the programmer. And if you have a few targets all trying to talk back to the programmer at the same time, the programmer would not understand the returning data. The solution we found was to have only one single target IC talk back to the programmer. This way, the programmer thought it was only talking with one IC and the remaining target ICs on the bus would simply listen along. We figured we could test the solder joint on the remaining ICs MISO lines with some sort of other testcode later.

alt text

Above is a picture of the first testing hardware to include a buffered programming circuit. It was used for the Arduino Pro Mini. It could program six boards at a time and lived a decent life on the production floor. If you look closely at the top left you can see the prototyping board and logic level converter used on the programing lines. Unfortunately, this is the best picture I could dig up. It has since been upgraded to a new version (that includes a hex converter buffer circuit). The original hardware pictured above must have been tossed into our electronics recycling.

We then incorporated the transistor buffer into the testbed PCB, as show below in the this section of the schematic:

alt text

The latest models in production incorporates a hex converter to amplify the SCK and MISO lines like so:

alt text

Below is a picture of the latest ganged programmer for the 9 Degrees of Freedom - Razor IMU. It programs six boards at a time and only uses one programmer.

alt text

It also has some other advancements including the waffle top, capsense buttons and more. The next few sections of this article are dedicated to some of these other improvements. Read on to learn more.

The Waffle Top

Holding a board in place (on top of pogopins) has always proven to be quite a challenge. We have eventually settled on two approaches: Nubbins and Waffle tops.

For our testbeds with minimal pogopins (usually a single board tester), we use a little device that we have termed, a “locking nubbin”. Basically, it is a small oval shaped piece of PCB with a drill hit in the center. These nubbins sit close the the edge of the frame layer. Below is a picture of a fairly new testbed design that tests our TXB014 Breakout.

alt text

This next picture shows the board under test in place. Notice how the nubbins turn and hold the board down on top of the pogopins.

alt text

The second approach is what we like to call, “the waffle top”. We use this solution for our larger testbeds that require more surface area and pressure to hold the board (or panel) in place.

It involves using a flat board of sorts (below shows an example made from acrylic). The waffle top is designed to sit on top of the board (or panel of boards) under test. It is connected to the edge of the testbed with hinges to keep it aligned. This hinged connection also makes it easy to lift away while moving the board-under-test in and out. It’s actually quite similar to how a waffle iron works, hence the name.

Below is a picture of the first waffle top. It was made from acrylic and used on the testbed for our Arduino Pro Mini 328 - 5V/16MHz.

alt text

We found that ordering two PCBs and glueing them together has proven to be a much easier method for us these days. Pictured below is our testbed for the Arduino FIOs.

alt text

Notice that it also has cut-out areas to allow space for the populated parts on the Fios. Again, it was a good transition to designing waffle tops as PCBs, because this kind of mill work is especially time consuming when making these from plexi glass. We also learned that it is important to very clearly let your fab house know about route out areas. We now add in large text. Here is what the board file looks like for the FIO waffle top:

alt text

We have also spent a lot of time designing around our gold hinges. It is important to get the spacing and height just right, so that the waffle top comes down nicely on top of the board without any binding. Here is a close up shot of the hinge area of our most recent IOIO testbed:

alt text

On this particular design (because it is rather large), we incorporated a few locking header footprints to help with alignment during gluing. We simply put a few header strips through each board and it really helps keep them perfectly aligned while the glue dries.

alt text

Shift Registers to control LEDs

Some of our larger testbeds need to indicated the status of 8-16 boards. The technician needs to see if all of the boards passed or failed. To expand the IO capabilities of our standard testbed micro (the trusty ATMega328), we have augmented our designs with shift registers.

alt text

Above, you can see that we have daisey-chained two shift registers together. This way we can use the same 5 pins off of our micro to control up to 16 LEDs.

We like this part (74HC595) for two reasons: (1) it’s already in our inventory and (2) the SOIC package is relatively easy to hand solder onto a testbed, and very unlikely to jumper.

One might ask, “Why not use a larger micro?” Well, we like to keep things simple, and so that means keeping our desings small, similar, and repeatable. And so we want to keep using the ATMega328 whenever possible. 99% of our testbeds use this micro.

Below is a picture of our multi-board testbed for the 9 Degrees of Freedom - Sensor Stick. Kade Jensen was the test developer on this project, and he appropriately named this the “144 DOF”.

alt text

Check out all those status LEDs:

alt text

All possible thanks to the innovating with a shift register - wahoo!

Cap-sense Buttons

alt text

Pictured above is our classic small momentary button. A simple mechanical switch is a great way for the tech to engage a test. We used this button on hundreds of testbeds. There are still hundreds on the production floor today. However, we found that after a few months on the floor (especially with our more popular products that may see 1000s of presses a day), the button would stop working 100% of the time. We found ourselves replacing quite a few buttons each week.

In order to solve this problem once and for all, we moved to a non-mechanical approach: capacitive touch. With this new approach, there is no mechanical connection to wear out, and we never see these fail on the floor. Below is a picture of our testbed for the OpenSegment Shield. You can see the two capsense buttons that engage the different portions of the test.

alt text

If you’re new to capacitive touch, check out this great tutorial on Arduino here . This is the same library and hardware technique that we use on all of our testbeds these days.

We have also created a special Eagle device that includes a few nice features in the package to speed up design work. It has a good sized metal pad to use as the sense area. It includes no tstop on the pad to protect from finger oils and oxidization. It also has a box of trestrict built into the package to keep the ground pour away. It has a dotted line on the silk to designate the touch area of the button. And lastly, the resistor is built into the package, so this makes it really easy to drop into a design.

alt text

At first, we thought that for the more simple testbeds it seemed a bit over-kill to include a micro just to engage a button. But we are finding now that 30 minutes invested in the design and assembly of a testbed is well worth the effort if it can ensure that the testbed will live on for years without the need for repairs. In most cases with QC related hardware, we invest our time and efforts to find the more permanent fix.

The High Side Switch

In order to more safely control the power to a board under test, we now use something called a high side switch. This improvement to our testbeds allows us to actively control the power we supply to a board.

Before this innovation, the pogopins on the testbed were always supplying power. We will sometimes call this a “hot” pogopin. Also, the act of swapping out boards on a testbed with this kind of hardware is called “hot swapping”. This method of supplying power to the board under test is usually okay for really low power products, and there are still a large number of testbeds on our production floor that have hot pins. However, when you are dealing with higher current devices, it can become rather dangerous.

The first product that received this upgrade was the Big Easy Driver. This board, like most stepper motor drivers, requires a substantial amount of current. The original testbed had hot pogopins and so would sometimes lead to damaging the board under test and/or the testbed itself.

Unfortunately, I was unable to dig up a decent picture of the original testing hardware. But I was able to get the most recent version:

alt text

Notice how there are cap-sense buttons for the technician to engage the test. When he or she presses this button, it will first turn on the high side switch (powering the board under test) and then engage the test. This ensures that the tech does not press a board down on hot pogopins.

Another issue that occurs with hot swapping is the possibility of momentary, accidental shorts. When a technician places a board down onto a testbed, sometimes they may accidentally slide the board horizontally. If VCC and GND are positioned next to each other on the board design (which often is the case), then this can cause a short between them for a small instance. This can cause large spikes in current and be damaging to the board and testbed. Using a high side switch helps avoid the possibility of these accidental shorts.

The circuit of a high side switch is actually quite similar to our MOSFET Power Control Kit. Below is a schematic view of our high side switch template:

alt text

Pre-testing for Jumpers

In July of 2013, we changed from testing the IOIO OTG with a raw input power of 9V up to 15V. This was to ensure that the board would work for our users at even larger input voltages.

This also lead to killing a lot of our testbeds. We eventually found that if there was a short to ground on any of the power rails (on the IOIO board under test), it would usually fry the testbed and the board. Our immediate fix was to have our technicians use a multimeter to check for shorts to ground on all of the power rails. Although this enabled us to continue building and testing IOIOs, it was not the most efficient way to pre-test. We knew there must be some way to automate this pre-test.

So, one afternoon, I told Pete Dokter about our troubles, and he helped us come up with the following test. It basically uses a voltage divider to measure a line and see if it has a jumper to GND.

alt text

It requires two pins from your micro: a control pin (digital) and a read pin (ADC). By manipulating the control pin HIGH and LOW, and watching the voltage on the read pin, we can know if the input pin (the power rail in the case of the IOIO) is jumpered to GND.

If the IN-1 net is grounded, then the READ net should sit at roughly ½ of CTRL-1 (logic level). Combined with the power control of a high side switch, this allows us to avoid powering up a board that has a jumper to GND, and ultimately saving the board-under-test and the testbed from potential damage.

Here is the function we use to test for jumpers on the latest IOIO testbed:

language:c
boolean jumper_test(int control_pin, int read_pin){

  digitalWrite(pre_testing_led, HIGH);

  pinMode(control_pin, OUTPUT);
  pinMode(read_pin, INPUT);

  digitalWrite(control_pin, HIGH);
  delay(200);
  int reading = analogRead(read_pin);

  if(debug){
  Serial.begin(9600);
  Serial.print("\t reading:");
  Serial.print(reading);
  Serial.end();
  }

  pinMode(control_pin, INPUT);

  int jumper_val = 486;

  digitalWrite(pre_testing_led, LOW);

  if((reading < (jumper_val*1.05)) && (reading > (jumper_val*0.95))) return true; // jumper detected!!
  else return false;

}

We have always put PTC resetable fuses on our testbeds to prevent damage when current spikes, but adding this pre-test is a great way to ensure that the current never surges in the first place. This issue had never come up on previous tests because most of our products require very little current. This means that when we test a board, we can limit our power supplies current (most of our tests call for 200mA). The IOIOs, on the other hand, require much higher current for testing the charge circuit. They actually draw up to 800 mA when charging our tablets.

Although it was kind of painful to see so many testbeds bite the dust, it was ultimately a good thing because it pushed us to make even better testbeds. We now have an extra tool to use for high current products!

Pad size, fillets, and AOI

As part of our constant quest to improve our testing thoroughness, in the spring of 2011 we purchased our first AOI machine (automated optical inspection). After watching it run a few panels of boards, we quickly named it “Disco Stu”. If you’ve ever seen an AOI machine run, than you probably remember a lot of flashing lights of various colors. It’s actually quite a spectacle to watch and usually has a pretty good “Ahhhhhh” effect on tours.

The AOI’s primary purpose is to look at boards and tell us if there are any manufacturing errors. It checks for 3 things:

  • Marks (to tell us if the part is in fact on the board and the polarity is correct)

  • Solders (to tell us if there is sufficient amounts of solder and how well it reflowed)

  • Lead banks and Toes (to tell us if any legs on an IC jumpered together and/or do not have sufficient solder on the toe of the leg)

As we programed more recipes (unique to each of our 500+ in house assemblies) we started to notice that the machine was having difficulty inspecting some of our components - particularly our 0603 solder joints. The reason was that the solder joint was forming underneath the component legs. This made it difficult for the top down camera to see. Also, the solder was not forming a fillet on it’s edge. In stead, it was basically forming a little bubble below.

There was a trend in our earlier designs to use 0402 sized packages on the PCBs and then populate an 0603 sized part. This was done in an effort to save space, while still using a component size that is moderately easy to handle with a set of tweezers.

We did this for years, and it didn’t seem to be that big of a problem. But now, with our new AOI machine, we wanted to fine tune our processes even more and narrow in on any manufacturing errors – no matter how small they may have been. We wanted to start catching the very rare cases where an 0.1uF capacitor would tomebstone and sneak through production to your workbench.

To understand how this problem was effecting the AOI, we need to look closer at how the machine does it’s testing. It actually looks at the same component in a variety of ways under three different colors:

  • White (all white LEDs pointing straight down on the board)

  • Red (this is primarily useful to see flat surfaces, because the red light is reflected to the side if the surface is anything but flat)

  • Red, Green and Blue (which are actually hitting the board from 3 unique angles)

The following graphic is combination of four different images. Each image was taken of the same row of components under a unique lighting. This particular design has 0402 pad sizes with 0603 parts populated.

alt text

On the right side, we are also seeing the binary bitmap image that the AOI can generate to help inspect for good solder reflow. The binary bitmap is created from the image taken under red light. The white pixels represent flat spots on the board, and the black pixels represent curved surfaces. In this way, a bare pad (without any solder on it) would reflect the red light and would show up as all white pixels. The software can count the white pixels of a designated area on the board and determine if there is sufficient solder present.

If you look at either side of the components, you can see that there is very little pad space to analyze. Most of it is covered up by the component and the solder. This makes it difficult for the AOI to test for sufficient solder.

The next image is a similar row of components, but this time they have the correct 0603 sized pads with 0603 parts populated.

alt text

Notice how there is more pad visible from this top down view. We can now compare the amount of white and black pixels and verify that there is sufficient solder.

This also helps us determine whether or not the part has slightly tombstoned. When you get a tombstone, the solder left on the pad will usually pillow and have a nice shiny flat spot on the top. The AOI can look for this flat spot under red light and see if the part did not reflow properly.

alt text

->On the left, a part has reflowed correctly. On the right, the part has tombstoned.<-

We have recently made a big push to revise a lot of our older designs to include true 0603 footprints. Each member of our QC team has made an effort to revise at least one design a month (sometimes two!).

Also, all future designs will have the correct pad size. In fact, the production QC team has become very involved whenever designing a new footprint for a new part. We want to ensure that the pad size and shape will promote the best possible solder reflow and that we can utilize our AOI to catch any possible errors.

In an effort to create the best footprint possible, we have recently developed a new technique using images of the bottom side of a component in Eagle. If you like, you can read more about that at our tutorial, Making Custom Footprints in Eagle.

Routing Away and Fake Traces

As mentioned in the previous section, we’re starting to do a lot more design revisions to help with reflow. One very recent development is the idea of “fake traces”. When you route away from an IC (especially small pitched QFN), the route job acctually effects the pad size/shape and ultimately the reflow and fillet formation. Due to the oversized tstop (aka mask cutout) on a PCB, the pad size is actually extended a tiny bit in the direction of the trace. Here is an example:

alt text

Pictured above is a bare pcb of the Pro Micro. You can see that some of the pads have been routed away from the IC, some have been routed underneath and some pads do not have any routing at all. This slight difference effects the way the solder flows.

alt text

Above is a picture of a populated board. Now let us look a little closer at the left side of the IC.

alt text

Notice how the size and shape of the fillet is different for each pad. The pads with the traces routed away look the best! Another added benefit is that the AOI now has almost twice the amount of solder to inspect.

In addition to ensuring that all traces route directly away from the IC, we are also approaching this problem from the library level. In Eagle 6, you can now create complex pad shapes. This means that we can add an extra bit of top copper (in the case below, it is a simple line drawn with the wire tool), and Eagle recognizes the extra copper as part of the pad. In this way, the wire is acting like a fake trace! In the example below, we have modified the pads on a QFN-44 package to include some extra fake traces.

alt text

  • One thing to keep in mind while doing this: the wire must start on exactly the same X-Y coordinates as the center point of the pad. This is important because it will ensure you do not run into a DRC (design rule check) errors for every pad.

The beauty of this approach is that even if one of the pads is not routed (i.e. its not needed in the design or its a no-connect), it will still have the same shape and padsize-to-paste ratio. The routing direction is now built into the part at the library level - wahoo!!

Resources and Going Further

These are just some of the examples of how we are constantly innovating not only our quality control but our entire board design process. In true open source fashion, we want to share with you every tip, trick, and technique we discover that helps us produce better products. If you have any questions or comments, feel free to hop on over to the discussion section and get a conversation started.

If you’re looking for more information on electronics assembly and design, check out these other tutorials.


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

RGB Panel Hookup Guide

0
0

RGB Panel Hookup Guide a learn.sparkfun.com tutorial

Introduction

Are you looking to add a lot of color to your project? These massive RGB LED panels are an awesome place to start. You can create animations, games, or all sorts of other fun displays with them.

LED Panels Lit Up

A 16x32 RGB LED panel to the left, and a 32x32 panel to the right.

These panels come in two varieties: a 3.75x7.5"16x32 pixel panel:

16x32 panel

And a 1024 pixel (3072 total LEDs!) 32x32 pixel panel measuring 7.5x7.5":

32x32 panel

In this tutorial we’ll show you just how, exactly, these panels operate. We’ll dig into the hardware hookup and examine how to best power them. Then we’ll work up a demo sketch and control them with Arduino.

Required Materials

On top of either size panel, you’ll also need:

  • At least an Arduino Uno (or comparable ATmega328-based Arduino). These panels really stretch the Arduino to its limits. If you have an Arduino Mega you may want to whip that out instead.
  • Male-to-male jumper wires. You’ll need around 16 to wire from the panel to your Arduino.
  • A 5V power supply. You’ll need something that can source a high amount of current. A simple 5V (1A) wall adapter does work, at least in the short run, but you may want to step up to a higher capacity supply, like these 12V/5V (2A) supplies.
  • You’ll also need some method to connect your power supply to the panel. The panel includes a 4-pin polarized connector and spade-terminated cable for its power supply. Check out the next page for help finding a power source and cable.

Suggested Reading

Before following along with this tutorial, we recommend reading through these tutorials first:

Powering the Panel

These panels require a regulated 3.3-5V supply for power. And that supply needs to be able to source a good amount of current – up to 2A in the worst case (all pixels bright, hot, white). A white, 4-pin (2 for VCC, 2 for GND), 0.15"-pitch polarized connector should be used to supply power to the panel.

Panel power connector

Included with the panel is a dedicated cable for power. It’s a 0.15" pitch 4-pin polarized connector. The included cable is terminated with both a female polarized connector, and a pair of spade terminals.

Panel power cable

Here are a few methods we’ve used to power the panel:

Longer-Term: Power Supply

This is our recommended method. Combine:

  1. A 12V/5V 2A Power Supply, which should be enough to keep the display running at maximum capacity. (Just don’t hook up the 12V output to it!)
  2. An IEC C13 Cable to connect AC power to the supply.
  3. A 4-pin Molex Connector w/ Pigtail to interface the supply to panel.

alt text

The ingredients for our power supply and cable.

To begin, we snipped the spade connectors off of the panel power supply cable. And then stripped the newly unterminated ends.

Then we spliced the Molex pigtail to the LED panel’s power cable by connecting the red wires together. Do the same for the black wires (make sure you use the black wire next to the red on the Molex pigtail). Make sure you are connecting to the 5V and GND pins and NOT the 12V pin.

Splice covered in heat shrink

Finally, cover the splice with heat shrink or electrical tape, and voila! That’s a beautiful power cable.

Finished power supply cable splice

Finished panel power supply cable.

This is a nice, sturdy interface between the panel and a solid power supply. If you’re looking for something easier, but less reliable check the below option.

Short-Term: Barrel Jack

A 5V 1A Wall Adapter or USB wall adapter (with USB barrel jack adapter) have both been tested to work with the panels as well. At least in the short term.

Wall adapter connected via barrel jack adapter

Use these in conjunction with a barrel jack adapter to get a quick and dirty connection between the spade and barrel jack.

Spade connected to barrel jack adapter

Or you can make a more permanent solution with a panel mount connector.


All of that said, don’t use the 5V supply from your Arduino. Those are only spec'ed to supply about 800mA, and the Arduino’s already eating into that capacity a bit.

Hardware Hookup

Before we can get into the code portion, there’s quite a bit of wiring to do. Both the 32x16 and 32x32 panels have a pair of 16-pin (2x8) IDC connectors, and we need to wire up to most of those pins.

Conveniently, both panels have the connector pins labeled (the unlabeled pins are ground). As we’re hooking up to the panel, make sure you use the connector labeled Input.

Connector labels on panel

Connector labels on a 32x32 panel. 16x32 has the same layout, except that D is a no connect (NC) instead.

Here are the pin connections between LED panel connector and Arduino:

Panel Pin LabelPanel Connector Pin #Arduino PinNotes
R012Red data (columns 1-16)
G023Green data (columns 1-16)
B034Blue data (columns 1-16)
GND4GNDGround
R155Red data (columns 17-32)
G167Green data (columns 17-32)
B178Blue data (columns 17-32)
GND8GNDGround
A9A0Demux input A0
B10A1Demux input A1
C11A2Demux input A2
D12A3Demux input E1, E3 (32x32 panels only)
CLK1311LED drivers' clock
STB1410LED drivers' latch
OE159LED drivers' output enable
GND16GNDGround

Panel connector pin numbering convention: Pin 1 is top left (R0), pin 2 is to the right of pin 1, pin 3 is below pin 1, pin 4 is to the right of pin 3, etc. Pin 16 is the bottom right.

For a more step-by-step approach, follow along below. We use male-to-male jumper wires to wire between the included ribbon cable and our Arduino.

Data Pins: R0, B0, G0, R1, G1, and B1

These LED driver (shift register) data pins are hard-coded in the Arduino library and can’t be moved. R0, G0, B0, R1, G1, and B1 go to Arduino pins 2 through 7 respectively.

R0 → 2
G0 → 3
B0 → 4
R1 → 5
G1 → 6
B1 → 7

When connecting into the ribbon cable connector, pay attention to the notch that signifies polarity. When looking at the cable with the notch facing up, R0 (pin 1) should be at the top left.

Red, green, and blue wires inserted into cable

Both red and blue wires should be on the notch side, the greens should be on the other.

(Arduino Mega Note: If you’re wiring the panel up to an Arduino Mega, these pins should be connected to pins 24-29 respectively.)

Clock Pin

This is the last pin that has some restriction on where it can go – it must be connected to one of Arduino’s port B pins. That means it must be either 8, 9, 10, 11, 12, or 13. The example code has it wired up to pin 11.

CLK → 11

A, B, C, (D for 32x32 users), OE, and STB

These five (or six if you’re using a 32x32 matrix) pins can be plugged in anywhere you may have space on your Arduino. Although, there’s probably not a lot of room left…

We chose to stick A, B, and C in pins A0, A1, and A2 respectively. OE connects to pin 9. STB to pin 10. And, if you’re using a 32x32 matrix, D goes to A3.

A → A0
B → A1
C → A2
D → A3
OE → 9
STB → 10

Feel free to swap those up if your application requires. Just make sure you switch it up in the example code too.

Ground(s)

Last, but certainly not least (well, maybe, if we’re talking about potential) is ground. There are three unlabeled pins on the connector which should all be tied to ground.

If you don’t have anything else plugged into them, there should be three ground pins available on your Arduino. If you’re struggling to find ground pins, though, you should be able to get away with only plugging one of the ground pins to your Arduino.

Cables connected from panel to Arduino

Woo color coded wires!

Example Sketch

Install Arduino Libraries

Our example code is going to make use of Adafruit’s most excellent RGBMatrixPanel library, which also requires their AdafruitGFXLibrary. You can grab both from their GitHub repositories (see our Using GitHub tutorial for help downloading). Or click here to download a zip file of both folders.

Install the libraries into a libraries folder within your Arduino sketchbook. For more help installing libraries, check out our Installing an Arduino Library tutorial.

The RGBMatrixPanel library includes a number of fun examples to help show how the library can be used. They’re awesome. Check them out under the File>Examples>RGBMatrixPanel menu in Arduino. (Definitely check out the Plasma_32x32 or Plasma_16x32 examples!)

Serial Paint Example

We wanted to write another fun sketch that provided an interactive way to explore with the panels and the Arduino library. What we came up with is a Serial-controlled Paint program. With this sketch, you can use the serial monitor (or, better yet, another terminal program) to control a cursor and draw on the matrix.

Check out the codebender.cc embed below. If that doesn’t load for you, you can click here to download the sketch.

Before uploading, make sure the sketch is set up to work with your panel. If you’re using a 16x32 panel, you’ll need to make a few changes. Comment out this line (83):

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false); // 32x32

And uncomment this line (85):

RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false); // 32x16

Also, 16x32 users should comment out the first bmp[] array in the bitmap.h file, and un-comment out the last.

Then upload! After upload, a single pixel should be blinking at the top left of the panel. It doesn’t look like much, but that’s a good sign.

Using the Sketch

To control the program, open up your serial terminal to 9600 bps. Try hitting sending l (lowercase ‘L’) through the serial monitor, which should load the demo bitmap. You can send E (uppercase) to erase the screen.

The idea of this sketch is: move the cursor around to draw pixels, shapes, or text. Here are the commands made available by the sketch (they are case-sensitive):

  • Movement: w, a, s, d (up, down, left, right)
  • Draw Pixel: Spacebar
  • Erase Pixel: e
  • Erase Screen: E
  • Fill screen with active color: f
  • Color Control:
    • Red value up: R (values between 0 [off] and 7 [most bright])
    • Red value down: r
    • Green up/down: G/g
    • Blue up/down: B/b
    • Copy color: z (copies a color under the cursor)
  • Shape Drawing:
    • Line: press v to place starting point. Then move cursor to endpoint and press vagain.
    • Rectangle: press x or X to place first corner. Then move your cursor to where you want the diagonal corner. Then press either x for an empty box, or X for a filled box.
    • Circle: press c or C to place the center of the circle. Then move your cursor to where you want the outside edge of your circle to be. Then press c for an empty circle or C for a filled circle.
  • Text: press t to go to text mode. Now any characters received will be displayed on the panel. It’ll wrap around from one line to the next, but not from bottom to top. Press ``` (above Tab / left of 1) to exit text mode.
  • Print: press p to print an array of your drawing to the serial terminal. You can copy this, and put it back in your sketch if you want to load it again.
  • Load: press l to load a pre-defined array from the sketch. The sketch includes a demo array, which was created from the print command. Follow this example to load your own drawings!

Give the paint sketch a try! See if you can make the next great Lite-Brite LED Panel picture. If you make something neat, share it with us! Here are our creations:

32x32 panel image

An example drawing on the 32x32 panel.

alt text

A drawing on the 16x32 panel.

Don’t laugh. I drew that SFE flame one pixel at a time!

Resources & Going Further

Now that you know how to make use of these beautiful RGB LED matrices, what nifty project are you going to create with them? Here are some more resources, if you need them:

Going Further

If you’re looking for some inspiration, or more stuff to learn, check out these tutorials:

  • Graphic LCD Hookup Guide– These little LCDs have a serious lack of color, but they’re very easy to control! And don’t require the crazy amounts of power our RGB matrices do.
  • Serial Graphic LCD Hookup Guide– These LCDs continue with the monochrome theme, but they’re super easy-to-control. Instead of the dozen-or-so wires required to control the LCD, you only need one!
  • LED Light Bar Hookup Guide– If super-bright LEDs are your thing, check out these LED light bars! If you just need a string of single color LEDs – whether you’re backlighting a project, or installing huge 7-segment LEDs – these make for an easy solution.
  • Light– This tutorial is a bit more esoteric…but if you’re interested in the physics behind light, check out this tutorial.

learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Motors and Selecting the Right One

0
0

Motors and Selecting the Right One a learn.sparkfun.com tutorial

Introduction

At any given moment, you are near at least one or two types of motors. From the vibration motor in your cell phone, to the fans and CD drive in your favorite gaming system, motors are all around us. Motors provide a way for our devices to interact with us and the environment. With a myriad of applications for motors, the design and operation of them can vary.

alt text

What You Will Learn

In this tutorial we’ll cover some of these basic motor types and uses:

  • DC Brush Motors
  • Brushless Motors
  • Stepper Motors
  • Linear Motors

Recommended Reading

What Makes A Motor Move?

The most vague and simple answer is magnetism! Ok, now let’s take this simple force and turn it into a super car!

alt text

To keep things simple, we will need to look at some concepts through the lens of the thought experiment. Some liberties will be taken, but if you want to get down and dirty with the details, you can consult Dr. Griffiths. For our thought experiment, we are going to state that a magnetic field is produced by a moving electron i.e. current. While this creates a classical model for us to use, things break down when we reach the atomic level. To understand the atomic level of magnetism more, Griffiths explains that in another book

Electromagnetism

To create a magnet or magnetic field, we are going to have to look at how they are generated. The relationship between current and magnetics field behave according to the right-hand rule. As current passes through a wire, a magnetic field forms around the wire in the direction of your fingers as they wrap around it. This is a simplification of Ampère’s force law as it acts on a current carrying wire. Now, if you place that same wire in a pre-existing magnetic field, you can generate a force. This force is referred to as the Lorentz force.

Right Hand Rule

The right-hand rule shows the direction of the magnetic field in relation to the current path.

(Credit: HyperPhysics)

If the current is increased, the strength of the magnetic field is strengthened. Though, to do something useful with the field, it would take incredible amounts of current. Furthermore, the wire delivering the current would be carrying the same magnetic strength, thus creating uncontrolled fields. By bending the wire into a loop, a directed and concentrated field can be created.

Loop of Wire Creates a Magnet

The field has not changed. By bending the wire into a loop, field directions are simply aligned.

(Credit: HyperPhysics)

Electromagnets

By looping wire and passing a current, an electromagnet is created. If one loop of wire can concentrate the field, what can you do with more? How about a few hundred more! The more loops you add to the circuit, the stronger the field becomes for a given current. If that’s the case, why don’t we see thousands , if not millions, of windings in motors and electromagnets? Well, the longer the wire the higher resistance it has. Ohm’s law (V = I*R) says to maintain the same current as resistance increases, voltage must increase. In some cases it makes sense to use higher voltages; in other cases some use larger wire with less resistance. Using larger wire is more costly and is generally more difficult to work with. These are factors that have to be weighed when designing a motor.

alt text

An energized electromagnet producing a magnetic field.

(Credit: HyperPhysics)

Experiment Time

To create your own electromagnet, simply find a bolt (or other round steel object), some magnet wire (30-22 gauge works fine), and a battery.

Note: Lithium Batteries are NOT recomended for this experiment.

alt text

Wrap between 75-100 turns of wire around the steel. Using a steel center further concentrates the magnetic field, increasing its effective strength. We will go over why this is happens in the next section.

alt text

alt text

A bit of heat shrink or tape can help keep the coils on the steel center.

Now, using sand paper, remove the insulation from the ends of the wires, and connect each wire to each terminal of the battery. Congratulations! You have built the first component of a motor! To test the strength of your electromagnet, try to pick up paper clips or other small steel objects.

alt text

It’s not magic, it’s SCIENCE!!!

Ferromagnetism

Looking back to the beginning of our thought experiment, magnetic fields may only be produced by a current. Taking the definition of current as a flow of electrons, electrons orbiting an atom should create a current and thus a magnetic field! If every atom has electrons is everything magnetic? YES! All matter, including frogs, can express magnetic properties when given enough energy. But not all magnetism is created equally. The reason I can pick up screws with a refriderator magnent and not a frog is the difference between ferromagnetism and paramagnetism. The way to differentiate the two (and a few more types) is through the study of quantum mechanics.

Ferromagnetism will be our focus, since it is the strongest phenomenon and is what we have the most experience with. Further, to relieve us from having to understanding this at the quantum level, we are going to accept that atoms of ferromagnetic materials tend to align their magnetic fields with their neighbors. Though they tend to align, inconsistencies in material and other factors like crystaline structure create magnetic domains.

alt text

When magnetic domains are aligned in a random order, neighboring fields cancel each other out resulting in a non-magnetized material. Once in the presence of an strong external field it is possible to re-align these domains. By aligning these domains, the overall field strengthens, creating a magnet!

alt text

(Credit: HyperPhysics)

This re-alignment can be permanent depending on the strength of the field. This is great because we’ll need these in the next section.

Permanent Magnets

Permanent magnets behave in the same way as electromagnets. The only difference is, well, they are permanent.

alt text

In all drawings, arrows will be pointing away from the north pole and towards the south pole. Another convention is to use the color red to represent north and blue to represent south. To identify a magnets polarity, you can use a compass. Since opposites attract, the needle will point north to the south pole of the magnet.

alt text

You can perform the same experiment with an electromagnet to determine polarity.

alt text

If you reverse the flow of current, you can see how an electromagnet can reverse its poles.

alt text

This is a key principle for building motors! Now, let’s look at some different motors and how they use magnets and electromagnets.

DC Brush Motors - The Classic

alt text

The DC brush motor is one of the simplest motors in use today. You can find these motors just about anywhere. They are in household appliances, toys, and automobiles. Being simple to construct and control, these motors are the go-to solution for professionals and hobbyists alike.

The Anatomy of a Brush Motor

To better understand how one works, let’s start by tearing down a simple hobby motor. As you can see, they are simple in construction, comprising of a few key components.

Disected Motor!

  • Brushes - Delivers power from the contacts to the armature through the commutator
  • Contacts - Brings power from the controller to the brushes
  • Commutator - Delivers power to the appropriate set of windings as the armature rotates
  • Coils - Converts electricity to a magnetic field that drives the axle
  • Stator - Increases the efficiency of the coils by focusing the magnetic field
  • Axle - Transfers the mechanical power of the motor to the user application
  • Magnets - Provide a magnetic field for the coils to attract and repel
  • Bushing - Minimizes friction for the axle
  • Can - Provides a mechanical casing for the motor

Theory of Operation

Go Speed Racer!

As the coils are energized, they attract to the magnets located around the motor. This rotates the motor until the brushes make contact with a new set of commutator contacts. This new contact energizes a new set of coils and starts the process again. To reverse the direction of the motor, simply reverse the polarity on the motor contacts. Sparks inside a brush motor are produced by the brush jumping to the next contact. Each wire of a coil is connected to the two closest commutator contacts.

Coils Shown

An odd number of coils is always used to prevent the motor from getting locked into a steady state. Larger motors also use more sets of coils to help eliminate “cogging,” thus providing smooth control at low revolutions per minute (RPMs). Cogging can be demonstrated by rotating the motor axle by hand. You will feel “bumps” in the motion where the magnets are closest to the exposed stator. Cogging can be eliminated with a few tricks in design, but the most prevalent is removing the stator all together. These types of motors are referred to as ironless or coreless motors.

Pros

  • Simple to control
  • Excellent torque at low RPM
  • Inexpensive and mass produced

Cons

  • Brushes can wear out over time
  • Brush arcing can generate electromagnetic noise
  • Usually limited in speed due to brush heating

Brushless Motors - MORE POWER!

alt text

Brushless motors are taking over! Ok, maybe that was an overstatement. However, brushless motors have begun to dominate the hobby markets between aircraft and ground vehicles. Controlling these motors had been a hurdle up until microcontrollers became cheap and powerful enough to handle the task. There is still work being done to develop faster and more efficient controllers to unlock their amazing potential. Without brushes to fail, these motors deliver more power and can do so silently. Most high-end appliances and vehicles are moving to brushless systems. One notable example is the Tesla Model S.

The Anatomy of a Brushless Motor

alt text

To better understand how one works, let’s start by tearing down a simple brushless motor. These are commonly found on remote control airplanes and helicopters.

alt text

  • Windings - Converts electricity to a magnetic field that drives the rotor
  • Contacts - Brings power from the controller to the brushes
  • Bearings - Minimizes friction for the axle
  • Stator - Increases the efficiency of the coils by focusing the magnetic field
  • Magnets - Provide a magnetic field for the coils to attract and repel
  • Axle - Transfers the mechanical power of the motor to the user application

Theory of Operation

alt text

The mechanics of a brushless motor are incredibly simple. The only moving part is the the rotor, which contains the magnets. Where things become complicated is orchestrating the sequence of energizing coils. The polarity of each coil is controlled by the direction of current flow. The animation demonstrates a simple pattern that controllers would follow. Alternating current changes the polarity, giving each coil a “push/pull” effect. The trick is keeping this pattern in sync with the speed of the rotor. There are two (widely used) ways this can be accomplished. Most hobby controllers measure the voltage produced (back EMI) on the un-energized coil. This method is very reliable in high velocity operation. As the motor rotates slower, the voltage produced becomes more difficult to measure and more errors are induced. Newer hobby controllers and many industrial controllers utilize Hall effect sensors to measure the magnets position directly. This is the primary method for controlling computer fans.

alt text

Pros

  • Reliable
  • High speed
  • Efficient
  • Mass produced and easy to find

Cons

  • Difficult to control without specialized controller
  • Requires low starting loads
  • Typically require specialized gearboxes in drive applications

Stepper Motors - Simply Precise

alt text

Stepper motors are great motors for position control. They can be found in desktop printers, plotters, 3d printers, CNC milling machines, and anything else requiring precise position control. Steppers are a special segment of brushless motors. They are purposely built for high-holding torque. This high-holding torque gives the user the ability to incrementally “step” to the next position. This results in a simple positioning system that doesn’t require an encoder. This makes stepper motor controllers very simple to build and use.

The Anatomy of a Stepper Motor

alt text

To better understand how one works, let’s start by tearing down a simple stepper motor. As you can see, these motors are built for direct drive loads containing a few key components.

alt text

  • Axle - Transfers the mechanical power of the motor to the user application
  • Bearings - Minimizes friction for the axle
  • Magnets - Provide a magnetic field for the coils to attract and repel
  • Poles - Increases the resolution of the step distance by focusing the magnetic field
  • Coils - Converts electricity to a magnetic field that drives the axle
  • Stator - Increases the efficiency of the coils by focusing the magnetic field
  • Contacts - Brings power from the controller to the brushes

Theory of Operation

alt text

(Credit: PCB heaven)

Stepper motors behave exactly the same as a brushless motor, only the step size is much smaller. The only moving part is the the rotor, which contains the magnets. Where things become complicated is orchestrating the sequence of energizing coils. The polarity of each coil is controlled by the direction of current flow. The animation demonstrates a simple pattern that controllers would follow. Alternating current changes the polarity, giving each coil a “push/pull” effect. A notable difference is how the magnet structure of a stepper is different. It is difficult to get an array of magnets to behave nicely on a small scale. It’s also very expensive. To get around this, most stepper motors utilize a stacked plate method to direct the magnetic poles into “teeth”.

alt text

In a brushless motor, back EMF is used to measure velocity. A stepper relies on the short throw of each winding to “guarantee” it reaches the desired point in time. In highspeed travel, this can lead to stalling where the rotor can’t keep up with the sequence. There are ways around this, but they rely on a higher understanding of the relationship between motor windings and inductance.

Pros

  • Excellent position accuracy
  • High holding torque
  • High reliability
  • Most steppers come in standard sizes

Cons

  • Small step distance limits top speed
  • It’s possible to “skip” steps with high loads
  • Draws maximum current constantly

Linear Motors - The Future!!!

alt text

The future is linear! In high-speed pick and place machines speed is everything. With speed comes friction, with friction comes maintanence, with maintanance comes downtime, with downtime comes lost productivity. By removing the components needed to transfer rotary to linear motion, the system becomes much lighter and more efficient. Linear motors are simple to maintain, and with only one moving part, are incredibly reliable. Did I mention they are incredibly fast?! This is the pick and place machine we are using in production, and it is incredibly fast! This machine also packs such a punch, there is a warning for pacemakers on it. There is an entire row of high power rare earth magnets.

alt text

The Anatomy of a Linear Motor

To better understand how one works, let’s look inside our pick and place machine downstairs.

  • Motion Module - Contains electromagnets and controller.
  • Magnets - Provide a magnetic field for the coils to attract and repel
  • Linear Bearning - Keeps the motor in alignment with magnets and is the only moving part.

alt text

Theory of Operation

alt text

The mechanics of a linear motor is nearly identical to a brushless motor. The only difference is take a brushless motor and unfold it into a straight line. The Motion Module is the only moving part. Where things become complicated is orchestrating the sequence of energizing coils. The polarity of each coil is controlled by the direction of current flow. The animation demonstrates a simple pattern that controllers would follow. Alternating current changes the polarity giving each coil a “push/pull” effect. In a linear motor, there is typically an encoder or some advanced positioning system to keep track of the location of the Motion Module. To reach a high position accuracy, the controllers are much more complicated than anything found on a conventional system. Microstepping is a method to “throttle” the magnets to provide smooth and precise motion. To achieve this though, linear motors require a highly specialized controller tuned for each motor. As controller technology improves, we are likely to see these motors decrease in price. Maybe someday our 3D printers will print in seconds and not hours!

Pros

  • Reliable
  • High speed
  • Efficient
  • No rotary to linear conversion required

Cons

  • Expensive
  • Require custom controllers
  • Purpose built for each system
  • Did I mention expensive?

Resources and Going Further

So we took a look at some different types of motors and how they might be used. Selecting a motor will require you to first determine the application requirements. With these requirements, you can look at the strengths and weaknesses of each motor type. But more importantly, look for the ratings on each motor. Each motor will have values for input power and output power. You can calulate the load requirements of a system but, sometimes it’s easy enough to just try it! To give yourself a headstart integrating motors, take a look as some of these pages:

And finally, here is a great place to learn just about everything physics related.


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Constant Innovation in Quality Control

0
0

Constant Innovation in Quality Control a learn.sparkfun.com tutorial

Introduction

Here in Quality Control, we are constantly challenged to create fast, thorough, and reliable test procedures. We are never willing to sacrifice any of these three ingredients, and so, the only way to speed up a test is to hire more technicians or… innovate. In our true boot-strapping style, we have always done our best to do the latter.

In 2009, we began designing our testing equipment using pogopins.

alt text

You can read more about that here: PogoBeds: SparkFun Production and Testing

In 2011, we hacked together a multiple board programmer using our first ever waffle press.

alt text

You can read more about that here: Ganged Programming with AVR ISP MKIIs

Since then, we have made tons of advancements in our hardware, code, inspection processes, and board layout. In this article, we are going to share some of our best ideas from the past few years. We hope they will help you design better projects and maybe even think about your hardware design in new ways.

Cheers to making great electronics and how to test them!

Multi-board Programming

Our first approach to multi-board programming involved multiple programmers, a USB hub, a bunch of cables, and some tricky batch file action.

alt text

It sure did speed up our production runs. Nine at a time was a huge improvement from our previous single board programming methods. But, as with most of our testing equipment, it eventually became out-dated, and we wanted to upgrade it.

It became a bit of a hassle to setup – ensuring that everything was plugged in properly. And over the years, the ribbon cables began to wear out. In November of 2011, we posted a very thorough tutorial on how this ganged-programmer works. Click HERE to check that out. In addition to the hardware design ideas, it actually was a great exercise in using batch files.

About a year after the release of the above programmer, we started having a lot of our technicians computers freeze up mid programming. The famous blue screen of death was happening far too often. We replaced the USB hubs with better quality hubs, and this seemed to help the problem a bit. However, we knew another approach was needed.

We wanted to find a way to program multiple boards simultaneously using one single programmer. Our first thought was to use some sort of amplification or buffer on the programming lines.

To program an AVR using ISP, there are 6 connections that need to be made from the programmer to the target IC:

  • VCC
  • GND
  • RESET
  • SCK
  • MISO
  • MOSI

Experimenting with our logic level converter, we were able to get a few boards to program off one single programmer. Our initial hardware was as follows.

Physically bussing (as in metal connections on the same net) for the GND, VCC and RESET.

SCK and MOSI needed to be buffered, because these signals were being sent to multiple targets. It seemed that the MKII did not have enough output impedance to program multiple targets, so we sent them through the logic level converter. This way, the signal strength was relying on the HIGH logic pin of the converter and not the output of the MKII.

The MISO line was a little trickier. This line carries communication from the target back to the programmer. And if you have a few targets all trying to talk back to the programmer at the same time, the programmer would not understand the returning data. The solution we found was to have only one single target IC talk back to the programmer. This way, the programmer thought it was only talking with one IC and the remaining target ICs on the bus would simply listen along. We figured we could test the solder joint on the remaining ICs MISO lines with some sort of other testcode later.

alt text

Above is a picture of the first testing hardware to include a buffered programming circuit. It was used for the Arduino Pro Mini. It could program six boards at a time and lived a decent life on the production floor. If you look closely at the top left you can see the prototyping board and logic level converter used on the programing lines. Unfortunately, this is the best picture I could dig up. It has since been upgraded to a new version (that includes a hex converter buffer circuit). The original hardware pictured above must have been tossed into our electronics recycling.

We then incorporated the transistor buffer into the testbed PCB, as show below in the this section of the schematic:

alt text

The latest models in production incorporates a hex converter to amplify the SCK and MISO lines like so:

alt text

Below is a picture of the latest ganged programmer for the 9 Degrees of Freedom - Razor IMU. It programs six boards at a time and only uses one programmer.

alt text

It also has some other advancements including the waffle top, capsense buttons and more. The next few sections of this article are dedicated to some of these other improvements. Read on to learn more.

The Waffle Top

Holding a board in place (on top of pogopins) has always proven to be quite a challenge. We have eventually settled on two approaches: Nubbins and Waffle tops.

For our testbeds with minimal pogopins (usually a single board tester), we use a little device that we have termed, a “locking nubbin”. Basically, it is a small oval shaped piece of PCB with a drill hit in the center. These nubbins sit close the the edge of the frame layer. Below is a picture of a fairly new testbed design that tests our TXB014 Breakout.

alt text

This next picture shows the board under test in place. Notice how the nubbins turn and hold the board down on top of the pogopins.

alt text

The second approach is what we like to call, “the waffle top”. We use this solution for our larger testbeds that require more surface area and pressure to hold the board (or panel) in place.

It involves using a flat board of sorts (below shows an example made from acrylic). The waffle top is designed to sit on top of the board (or panel of boards) under test. It is connected to the edge of the testbed with hinges to keep it aligned. This hinged connection also makes it easy to lift away while moving the board-under-test in and out. It’s actually quite similar to how a waffle iron works, hence the name.

Below is a picture of the first waffle top. It was made from acrylic and used on the testbed for our Arduino Pro Mini 328 - 5V/16MHz.

alt text

We found that ordering two PCBs and glueing them together has proven to be a much easier method for us these days. Pictured below is our testbed for the Arduino FIOs.

alt text

Notice that it also has cut-out areas to allow space for the populated parts on the Fios. Again, it was a good transition to designing waffle tops as PCBs, because this kind of mill work is especially time consuming when making these from plexi glass. We also learned that it is important to very clearly let your fab house know about route out areas. We now add in large text. Here is what the board file looks like for the FIO waffle top:

alt text

We have also spent a lot of time designing around our gold hinges. It is important to get the spacing and height just right, so that the waffle top comes down nicely on top of the board without any binding. Here is a close up shot of the hinge area of our most recent IOIO testbed:

alt text

On this particular design (because it is rather large), we incorporated a few locking header footprints to help with alignment during gluing. We simply put a few header strips through each board and it really helps keep them perfectly aligned while the glue dries.

alt text

Shift Registers to control LEDs

Some of our larger testbeds need to indicated the status of 8-16 boards. The technician needs to see if all of the boards passed or failed. To expand the IO capabilities of our standard testbed micro (the trusty ATMega328), we have augmented our designs with shift registers.

alt text

Above, you can see that we have daisey-chained two shift registers together. This way we can use the same 5 pins off of our micro to control up to 16 LEDs.

We like this part (74HC595) for two reasons: (1) it’s already in our inventory and (2) the SOIC package is relatively easy to hand solder onto a testbed, and very unlikely to jumper.

One might ask, “Why not use a larger micro?” Well, we like to keep things simple, and so that means keeping our desings small, similar, and repeatable. And so we want to keep using the ATMega328 whenever possible. 99% of our testbeds use this micro.

Below is a picture of our multi-board testbed for the 9 Degrees of Freedom - Sensor Stick. Kade Jensen was the test developer on this project, and he appropriately named this the “144 DOF”.

alt text

Check out all those status LEDs:

alt text

All possible thanks to the innovating with a shift register - wahoo!

Cap-sense Buttons

alt text

Pictured above is our classic small momentary button. A simple mechanical switch is a great way for the tech to engage a test. We used this button on hundreds of testbeds. There are still hundreds on the production floor today. However, we found that after a few months on the floor (especially with our more popular products that may see 1000s of presses a day), the button would stop working 100% of the time. We found ourselves replacing quite a few buttons each week.

In order to solve this problem once and for all, we moved to a non-mechanical approach: capacitive touch. With this new approach, there is no mechanical connection to wear out, and we never see these fail on the floor. Below is a picture of our testbed for the OpenSegment Shield. You can see the two capsense buttons that engage the different portions of the test.

alt text

If you’re new to capacitive touch, check out this great tutorial on Arduino here . This is the same library and hardware technique that we use on all of our testbeds these days.

We have also created a special Eagle device that includes a few nice features in the package to speed up design work. It has a good sized metal pad to use as the sense area. It includes no tstop on the pad to protect from finger oils and oxidization. It also has a box of trestrict built into the package to keep the ground pour away. It has a dotted line on the silk to designate the touch area of the button. And lastly, the resistor is built into the package, so this makes it really easy to drop into a design.

alt text

At first, we thought that for the more simple testbeds it seemed a bit over-kill to include a micro just to engage a button. But we are finding now that 30 minutes invested in the design and assembly of a testbed is well worth the effort if it can ensure that the testbed will live on for years without the need for repairs. In most cases with QC related hardware, we invest our time and efforts to find the more permanent fix.

The High Side Switch

In order to more safely control the power to a board under test, we now use something called a high side switch. This improvement to our testbeds allows us to actively control the power we supply to a board.

Before this innovation, the pogopins on the testbed were always supplying power. We will sometimes call this a “hot” pogopin. Also, the act of swapping out boards on a testbed with this kind of hardware is called “hot swapping”. This method of supplying power to the board under test is usually okay for really low power products, and there are still a large number of testbeds on our production floor that have hot pins. However, when you are dealing with higher current devices, it can become rather dangerous.

The first product that received this upgrade was the Big Easy Driver. This board, like most stepper motor drivers, requires a substantial amount of current. The original testbed had hot pogopins and so would sometimes lead to damaging the board under test and/or the testbed itself.

Unfortunately, I was unable to dig up a decent picture of the original testing hardware. But I was able to get the most recent version:

alt text

Notice how there are cap-sense buttons for the technician to engage the test. When he or she presses this button, it will first turn on the high side switch (powering the board under test) and then engage the test. This ensures that the tech does not press a board down on hot pogopins.

Another issue that occurs with hot swapping is the possibility of momentary, accidental shorts. When a technician places a board down onto a testbed, sometimes they may accidentally slide the board horizontally. If VCC and GND are positioned next to each other on the board design (which often is the case), then this can cause a short between them for a small instance. This can cause large spikes in current and be damaging to the board and testbed. Using a high side switch helps avoid the possibility of these accidental shorts.

The circuit of a high side switch is actually quite similar to our MOSFET Power Control Kit. Below is a schematic view of our high side switch template:

alt text

Pre-testing for Jumpers

In July of 2013, we changed from testing the IOIO OTG with a raw input power of 9V up to 15V. This was to ensure that the board would work for our users at even larger input voltages.

This also lead to killing a lot of our testbeds. We eventually found that if there was a short to ground on any of the power rails (on the IOIO board under test), it would usually fry the testbed and the board. Our immediate fix was to have our technicians use a multimeter to check for shorts to ground on all of the power rails. Although this enabled us to continue building and testing IOIOs, it was not the most efficient way to pre-test. We knew there must be some way to automate this pre-test.

So, one afternoon, I told Pete Dokter about our troubles, and he helped us come up with the following test. It basically uses a voltage divider to measure a line and see if it has a jumper to GND.

alt text

It requires two pins from your micro: a control pin (digital) and a read pin (ADC). By manipulating the control pin HIGH and LOW, and watching the voltage on the read pin, we can know if the input pin (the power rail in the case of the IOIO) is jumpered to GND.

If the IN-1 net is grounded, then the READ net should sit at roughly ½ of CTRL-1 (logic level). Combined with the power control of a high side switch, this allows us to avoid powering up a board that has a jumper to GND, and ultimately saving the board-under-test and the testbed from potential damage.

Here is the function we use to test for jumpers on the latest IOIO testbed:

language:c
boolean jumper_test(int control_pin, int read_pin){

  digitalWrite(pre_testing_led, HIGH);

  pinMode(control_pin, OUTPUT);
  pinMode(read_pin, INPUT);

  digitalWrite(control_pin, HIGH);
  delay(200);
  int reading = analogRead(read_pin);

  if(debug){
  Serial.begin(9600);
  Serial.print("\t reading:");
  Serial.print(reading);
  Serial.end();
  }

  pinMode(control_pin, INPUT);

  int jumper_val = 486;

  digitalWrite(pre_testing_led, LOW);

  if((reading < (jumper_val*1.05)) && (reading > (jumper_val*0.95))) return true; // jumper detected!!
  else return false;

}

We have always put PTC resetable fuses on our testbeds to prevent damage when current spikes, but adding this pre-test is a great way to ensure that the current never surges in the first place. This issue had never come up on previous tests because most of our products require very little current. This means that when we test a board, we can limit our power supplies current (most of our tests call for 200mA). The IOIOs, on the other hand, require much higher current for testing the charge circuit. They actually draw up to 800 mA when charging our tablets.

Although it was kind of painful to see so many testbeds bite the dust, it was ultimately a good thing because it pushed us to make even better testbeds. We now have an extra tool to use for high current products!

Pad size, fillets, and AOI

As part of our constant quest to improve our testing thoroughness, in the spring of 2011 we purchased our first AOI machine (automated optical inspection). After watching it run a few panels of boards, we quickly named it “Disco Stu”. If you’ve ever seen an AOI machine run, than you probably remember a lot of flashing lights of various colors. It’s actually quite a spectacle to watch and usually has a pretty good “Ahhhhhh” effect on tours.

The AOI’s primary purpose is to look at boards and tell us if there are any manufacturing errors. It checks for 3 things:

  • Marks (to tell us if the part is in fact on the board and the polarity is correct)

  • Solders (to tell us if there is sufficient amounts of solder and how well it reflowed)

  • Lead banks and Toes (to tell us if any legs on an IC jumpered together and/or do not have sufficient solder on the toe of the leg)

As we programed more recipes (unique to each of our 500+ in house assemblies) we started to notice that the machine was having difficulty inspecting some of our components - particularly our 0603 solder joints. The reason was that the solder joint was forming underneath the component legs. This made it difficult for the top down camera to see. Also, the solder was not forming a fillet on it’s edge. In stead, it was basically forming a little bubble below.

There was a trend in our earlier designs to use 0402 sized packages on the PCBs and then populate an 0603 sized part. This was done in an effort to save space, while still using a component size that is moderately easy to handle with a set of tweezers.

We did this for years, and it didn’t seem to be that big of a problem. But now, with our new AOI machine, we wanted to fine tune our processes even more and narrow in on any manufacturing errors – no matter how small they may have been. We wanted to start catching the very rare cases where an 0.1uF capacitor would tomebstone and sneak through production to your workbench.

To understand how this problem was effecting the AOI, we need to look closer at how the machine does it’s testing. It actually looks at the same component in a variety of ways under three different colors:

  • White (all white LEDs pointing straight down on the board)

  • Red (this is primarily useful to see flat surfaces, because the red light is reflected to the side if the surface is anything but flat)

  • Red, Green and Blue (which are actually hitting the board from 3 unique angles)

The following graphic is combination of four different images. Each image was taken of the same row of components under a unique lighting. This particular design has 0402 pad sizes with 0603 parts populated.

alt text

On the right side, we are also seeing the binary bitmap image that the AOI can generate to help inspect for good solder reflow. The binary bitmap is created from the image taken under red light. The white pixels represent flat spots on the board, and the black pixels represent curved surfaces. In this way, a bare pad (without any solder on it) would reflect the red light and would show up as all white pixels. The software can count the white pixels of a designated area on the board and determine if there is sufficient solder present.

If you look at either side of the components, you can see that there is very little pad space to analyze. Most of it is covered up by the component and the solder. This makes it difficult for the AOI to test for sufficient solder.

The next image is a similar row of components, but this time they have the correct 0603 sized pads with 0603 parts populated.

alt text

Notice how there is more pad visible from this top down view. We can now compare the amount of white and black pixels and verify that there is sufficient solder.

This also helps us determine whether or not the part has slightly tombstoned. When you get a tombstone, the solder left on the pad will usually pillow and have a nice shiny flat spot on the top. The AOI can look for this flat spot under red light and see if the part did not reflow properly.

alt text

->On the left, a part has reflowed correctly. On the right, the part has tombstoned.<-

We have recently made a big push to revise a lot of our older designs to include true 0603 footprints. Each member of our QC team has made an effort to revise at least one design a month (sometimes two!).

Also, all future designs will have the correct pad size. In fact, the production QC team has become very involved whenever designing a new footprint for a new part. We want to ensure that the pad size and shape will promote the best possible solder reflow and that we can utilize our AOI to catch any possible errors.

In an effort to create the best footprint possible, we have recently developed a new technique using images of the bottom side of a component in Eagle. If you like, you can read more about that at our tutorial, Making Custom Footprints in Eagle.

Routing Away and Fake Traces

As mentioned in the previous section, we’re starting to do a lot more design revisions to help with reflow. One very recent development is the idea of “fake traces”. When you route away from an IC (especially small pitched QFN), the route job acctually effects the pad size/shape and ultimately the reflow and fillet formation. Due to the oversized tstop (aka mask cutout) on a PCB, the pad size is actually extended a tiny bit in the direction of the trace. Here is an example:

alt text

Pictured above is a bare pcb of the Pro Micro. You can see that some of the pads have been routed away from the IC, some have been routed underneath and some pads do not have any routing at all. This slight difference effects the way the solder flows.

alt text

Above is a picture of a populated board. Now let us look a little closer at the left side of the IC.

alt text

Notice how the size and shape of the fillet is different for each pad. The pads with the traces routed away look the best! Another added benefit is that the AOI now has almost twice the amount of solder to inspect.

In addition to ensuring that all traces route directly away from the IC, we are also approaching this problem from the library level. In Eagle 6, you can now create complex pad shapes. This means that we can add an extra bit of top copper (in the case below, it is a simple line drawn with the wire tool), and Eagle recognizes the extra copper as part of the pad. In this way, the wire is acting like a fake trace! In the example below, we have modified the pads on a QFN-44 package to include some extra fake traces.

alt text

  • One thing to keep in mind while doing this: the wire must start on exactly the same X-Y coordinates as the center point of the pad. This is important because it will ensure you do not run into a DRC (design rule check) errors for every pad.

The beauty of this approach is that even if one of the pads is not routed (i.e. its not needed in the design or its a no-connect), it will still have the same shape and padsize-to-paste ratio. The routing direction is now built into the part at the library level - wahoo!!

Resources and Going Further

These are just some of the examples of how we are constantly innovating not only our quality control but our entire board design process. In true open source fashion, we want to share with you every tip, trick, and technique we discover that helps us produce better products. If you have any questions or comments, feel free to hop on over to the discussion section and get a conversation started.

If you’re looking for more information on electronics assembly and design, check out these other tutorials.


learn.sparkfun.com |CC BY-SA 3.0 | SparkFun Electronics | Boulder, Colorado

Viewing all 1114 articles
Browse latest View live




Latest Images