Using an Arduino to Program an ATtiny

October 15, 2012 2 comments

The ATtiny is in most ways a smaller version of the ATmega – the brain of an Arduino – and I will be attempting to program it using the Arduino for ISP. If you want to learn what ISP is you can briefly look at the wiki article or this finely detailed article which deals with programming ATMEL microcontrollers. But basically, ISP lets you program your chip when its already been placed into your circuit, which is why its known as In-System Programming (ISP).

Components

To guide me through this process I will be using this tutorial by MIT Media Labs(which is somewhat outdated) and this more easily digestible guide on Instructables. As described on both website, I will be needing:

  • Arduino Uno or Duemilanove (with an ATmega328)
  • ATtiny85 (but you can also use an ATtiny45, ATtiny44, or ATtiny84)
  • 10 uF Capacitor
  • a breadboard
  • jumper wires
  • an LED
  • a 220 Ohm resistor

Setup

First, we’ll need to install ATtiny support (also known as “cores”) into the Arduino IDE. I’m going to assume you already have the latest version of Arduino IDE (1.0.1 as of this posting), if not, you should go update it.

EDIT: While the above linked cores will work just fine with this tutorial, a much better version can be found here. The install process is much the same as below, simply copy and overwrite any files into the hardware folder.

  • Locate your main Arduino folder
  • In it should be a sub-folder called “hardware”
  • Copy the ATtiny folder from inside the .zip to the hardware folder. You should end up with a folder structure something like Documents > Arduino > hardware > ATtiny that contains the file boards.txt and another folder called variants.

  • Restart the Arduino development environment.
  • If done correctly, you should see multiple ATtiny entries in the Tools > Board menu.

Connections

Next, we need to connect the Arduino to the ATtiny. It may be a good idea to make sure that the Arduino isn’t running anything. You can do this by uploading the “BareMinimum” sketch found under File > Examples > Basics. Then, connect the ATtiny to the Arduino in this way:

Here’s how my setup looked:

(NOTE: In the picture I reversed the GND and 5V on the Arduino. Don’t do that.)

The pin connections are:

  • ATtiny Pin 2 to Arduino Pin 13 (or SCK of another programmer)
  • ATtiny Pin 1 to Arduino Pin 12 (or MISO of another programmer)
  • ATtiny Pin 0 to Arduino Pin 11 (or MOSI of another programmer)
  • ATtiny Reset Pin to Arduino Pin 10 (or RESET of another programmer)

NOTE: Dont confuse the output pins (0 – 4) above with the actual IC pins (1 – 8), refer to the Fritzing diagram above and the diagram below to connect everything correctly. You can use the dot in the corner of the ATtiny to orient it properly. Double check everything before powering up unless you want to chance frying your ATtiny.

Arduino ISP

Configuring the Arduino to act as a serial programmer to program other chips is simple;

  • Make sure the board being used is still the Arduino (you can see what board is being uploaded to at the bottom right of the Arduino IDE)
  • Open the “ArduinoISP” sketch from the File > Examples menu.
  • Upload the sketch to your Arduino.
  • The Arduino should now be ready to work as an ISP.

NOTE: At this point the capacitor should NOT be used to connect ground and reset as it may prevent the sketch from being uploaded successfully.

Configuring the ATtiny to run at 8 MHz

Before we program the ATtiny with our first sketch, its a good idea to configure it to run at 8 MHz to it so that we can have our sketches run at a normal speed and use the SoftwareSerial library. You will only need to do this once for each microcontroller.

  • Place the 10uF capacitor between ground and the Arduino reset pin. Be sure to connect the negative of the capacitor to ground.
  • Select which board you are programming by going to Tools > Board. In my case I will be programming a ATtiny85 and running it at 8 MHz.
  • Check to make sure the Arduino is serving as ISP by going to Tools > Programmer, and selecting “Arduino as ISP”.
  • Finally, run the “Burn Bootloader” command from the Tools menu.

Programming the ATtiny

Now that we’ve gotten through all the steps of setting everything up, programming the ATtiny is easy! I’ll be uploading the Blink sketch in this example.

  • Make sure that the ATtiny is still the board being uploaded to. (Check the bottom right corner of the Arduino IDE)
  • Open the basic blink sketch.
  • Remember to change the LED pin number from 13 to 0! (Check the ATtiny pin diagram above to see which pins you can use.)
  • Finally, upload it as you would any other sketch.

It should give the following error twice:

avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85

Simply ignore the error message and you should be good to go.

Testing

If all went well, you should be able to get an LED to blink by connecting it from ATtiny “Pin 0″ (pin 5 of the IC) to ground with a resistor in series. Here’s how my ATtiny85 looks running the sketch:

Note how I don’t need to have it connected to the Arduino any more! All I’m doing is giving the ATtiny a 5 volt supply via a voltage regulator. But really, the ATtiny85-10PU can run just fine with 1.8 – 5.5 volts (depending on the frequency you run it at). I should also note that the maximum current rating per I/O pin is 40 mA, so don’t plan on powering anything too big with this IC.

Final Note:

If you’re looking for somewhere to buy ATtinys check out Mouser. Here is a through hole ATtiny85-20PU for $1.29, but you can also get the ATtiny85-20SU* for $0.83, which is in a very solderable SOIC package if you are interested in saving some money and getting into surface mount soldering. I would go so far as to suggest buying at least 5 of them, because once you start using them you will think of all kinds of tiny projects that you could put them in.

*(20PU means that it runs at  maximum 20MHz, 2.7 – 5.5 volts. PU/SU is for package type.)

Bonus:

To make a dedicated ATtiny prototyping platform for the Arduino you can use a protoshield such as this and wire it up as shown here:

The space in the upper part of the mini-breadboard can be used for testing small circuits and debugging, though I would suggest using only Pin 3 and Pin 4 (left of the ATtiny in the image above) for this, as Pins 0 – 2 are used for programming. The bottom portion is used for programming status indicators, GREEN being all is well, YELLOW is programming in progress, and RED is error. Here is how it looks in real life:

My Purchase from Tayda Electronics

October 6, 2012 Leave a comment

So I decided that it may be a good idea to post the bill of materials on my recent purchase of components on here. For the reason that other people may see what items are good to stock up on, and so that I can keep an easy reference as to what components I have.

Before I go into the details of my previous purchase I would first like to give a shout out to Tayda Electronics. If you don’t know about them, you can check out their “About us” page here. Basically, they sell all sorts of electronic components and parts that you may need for your projects at INSANELY low prices.

Just to get an idea of how cheap they are, take a look at a comparison of this 16MHZ Crystal on SparkFun ($0.95 at a +/- 50ppm stability*) versus the same 16Mhz Crystal on Tayda ($0.07 at a +/- 20ppm stability*). Unreal! Makes you wonder why you anyone would ever buy basic components like that from anywhere else! On top of all that they frequently offer 15% discount codes if you keep an eye on their Facebook page.

*(Heres a link to understanding the 50ppm vs 20ppm stability if you don’t know what it is.)

My whole purchase of about ~170 components cost me a total of $53 and it shipped to me from Thailand in about a week. The packaging was also excellent, with each type of component was individually bagged and labeled. This is great because you can just leave the components in their bag and throw them in the storage.

Anyway, on to my bill of materials (BOM). There’s no easy way to list it here as there are about 34 different types of components, so I will link to a paste bin of it HERE.

The categories for the order linked above go like this top to bottom: Misc Components, Displays, Micro Controllers, ICs, Transistors, Voltage Regulators, Battery Connectors, Jacks & Plugs, Headers, IC Sockets, Buttons & Switches, Resistors, Capacitors, Diodes.

Still alive!

October 6, 2012 Leave a comment

Hey there! Just checking in to make sure that I haven’t abandoned this blog/journal/whatever on my progress into the world of electronics. I have been making great strides indeed, it’s just that documenting that work is quite laborious.

Anyway, there are numerous things that I’m working on simultaneously. I will be getting a fresh new batch of components and tools in the next few weeks (already got them! :) ) so I am looking forward to getting started on actual projects, instead of just tinkering around (although that has been greatly entertaining).

Some of the things that I will be working on are:

[Done!] A clock with a 7-segment led display whose time accuracy will be controlled by the real time clock (also known as a RTC) DS1307.

I already have the RTC DS1337 that I previously purchased, however it is quite different from what I expected. It doesn’t seem to have an easy battery backup like the DS1307, and there really isn’t much hacker community support for it in the way of libraries and tutorials.

Now I could buy a premade module for about $10-15 which would just “plug and play”, but the module is only made up a few passive components – besides the RTC -, and shouldnt be hard at all to make myself. (It wasn’t.)

[Done!] Controlling a 7-segment LED display with a display driver. More specifically, the MAX7219 display driver. I figure it would be a lot easier to get this thing up and running rathar then deal with the hastle of using multiple shift-registers and a whole lot of resistors just to control a 4 or so digit LED display. (And it was, honestly, this thing is like a god send for controlling 7-segment and matrix LED display.)

[Done!] Programming an ATtiny, to start with, and later an ATmega. This is so that I can get away from being dependent on the Arduino being hooked up to my projects all the time, and would reduce the size of my projects as all I would need is the ATmega/tiny, a crystal, a couple of capacitors and something to regulate voltage.

[Done!] Modifying a servo to rotate continuously. This is absolutely necessary for my main project, and there are more then a couple of guides/tutorials online that detail how to do it. (It was ridiculously easy to do this, took no more than 5 minutes start to finish.)

Update (6/Oct/2012): So I started writing this a while back, maybe a month or so, and have accomplished a lot of the things that I had planned. As such, I updated this post and am submitting it now. The detailed posts accompanying each project should be up soon – but knowing my post history I wouldn’t hold my breath waiting for them.

LM335 – Calibration

July 24, 2012 Leave a comment

After attempting to hook up an LCD to display the temperature and getting readings of above 90°F inside a well air conditioned room, I decided that attempts to determine the accuracy of the LM335A sensor were in order. (LM335A datasheet here .PDF) I will be attempting multiple calibrating procedures, but the easiest and most basic one should be the boiling point, which is most frequently used for calibrating kitchen thermometers.

I was going to check the accuracy of the sensor using the know temperature of freezing (32°F or 0°C) and boiling water (212°F or 100°C), but seeing as electricity and water don’t mix very well I needed some way to protect the sensor and the Arduino.

There was no way I was going to do these tests with the sensor on a breadboard so I had to hook it up to a cable. To prevent signal degradation due to noise caused by electromagnetic interference, which the datasheet specifically warns about, I decided to use the shortest cable I could find. The cable came from a disposable pulse-oximetry sensor, which happened to be well shielded (bonus!).

The Setup:

I stripped the cable and soldered it into the same configuration that was on the breadboard. One end of the cable was attached to the sensor, and the other to the breadboard via headers (whose plastic melted and loosened up the pins, rendering the header much less useful).

The sensor end of my cable required special consideration as it would be immersed in both boiling and freezing water. I needed a waterproof way to contain the sensor without decreasing thermal conductivity, using something that wouldn’t melt at 100°C. To do this I fit the sensor within a disposable thermometer probe cover whose tip I filled with thermal grease. An alternative would have been to use heat shrink tubing, as recommended in the datasheet.

Before going into the extremes I decided to compare readings against the outdoor temperature at my location. I pulled up the temperature from Weather.com and sat the sensor probe against the mesh of an open window. The results were rather surprising:

(Note: the Weather.com temperature was two hours old when this picture was taken, in which time the temperature had rose. The temperature was 4°F more three hours later.)

Could it be that the LM335A was already acceptably calibrated? It appeared to be within the +/- 1°C (+/- 1.8°F) uncalibrated temperature error at 25°C (77°F) specified in the datasheet. The only way to find out was to continue with the tests.

For the freezing temperature test the setup is seemingly simple; get a bunch of ice and put it in water. The problem is that the temperature will not be exactly accurate to freezing, and the elevation, and atmospheric pressure could alter our results, but for my purpose it was good enough:

Interesting, so it would appear that my sensor was giving me a reading that was too low for the expected temperature of freezing water. While expecting 0°C (32°F), we got -2°C (29°F), so we are low by about 2°C in this test.

Next test is boiling temperature, again the elevation plays a part, as does atmospheric pressure. (Fun Fact: In Denver, Colorado, which is at an elevation of about one mile, water boils at approximately 95 °C.) One important thing to know is that there are different stages of “boiling”, which I found out after performing this test. Unfortunately, it seems that I may have never reached the true boiling point of water. I was using a small sauce pan, and was unable to achieve a rolling boil of required, so these results may have been less useful:

Even though these results may be too low, and less useful, they were still relatively close to the expected value. While expecting 100°C (212°F), we got 97°C (206°F), so we are low by about 3°C in this test.

Interestingly, the most useful and entertaining result came from my attempting to obtain a sublingual temperature. Human body temperature, as it turns out, is a relatively stable and reliable source for temperature calibration; varying by only a few degrees from person to person and through the day.

The normal core body temperature of a healthy, resting adult human being is stated to be at 98.6 degrees fahrenheit or 37.0 degrees celsius. Though the body temperature measured on an individual can vary, a healthy human body can maintain a fairly consistent body temperature that is around the mark of 37.0 degrees celsius.

The normal range of human body temperature varies due to an individuals metabolism rate, the higher (faster) it is the higher the normal body temperature or the slower the metabolic rate the lower the normal body temperature. Other factors that might affect the body temperature of an individual may be the time of day or the part of the body in which the temperature is measured at. The body temperature is lower in the morning, due to the rest the body received, and higher at night after a day of muscular activity and after food intake.

Source

The typical oral temperature measurement is slightly cooler, at 36.8° +/- 0.4°C (98.2° +/- 0.7°F), which means the oral temperature results of 33°C (92°F) meant my sensor was still off by about 3.8°C (6.2°F), . Seeing as average body temperature varies by about a degree, I would say that this method would be sufficient for achieving around +/- 1°C (1.8°F) calibration in a pinch.

All in all, I can definitively say that this sensor is reading 1 – 2°C (1.8 – 3.6°F) low through the range of 0 – 100°C. While I did not calibrate the sensor yet (that will be in part two of this post, which will come eventually) I ended up learning a whole lot about taking measurements, comparing expected vs actual values, looking for variables that could modify my results unexpectedly and setting up tests.

Reference:

Allfoodbusiness: How To Calibrate Thermometers (This is an excellent guide for thermometer calibration that I will be using in my next post.)

Physics Fact Book: Temperature of a Healthy Human

Wiki: Shielded Cable

Understanding Cable Shielding (.PDF)

NHD-0216PZ – LDC Display

July 18, 2012 Leave a comment

I have been quite apprehensive towards working with LCDs. They take up nearly half of the digital pins available on my Arduino Uno and require quite a bit of work to set up and get going, or at least so I thought. Nevertheless, I did need some way to get feedback from the Arduino, and I couldn’t rely on the IDE serial monitor forever.

This is why I have purchased the New Haven NHD-0216PZ-FL-YBW-PC LCD display (link to datasheet .pdf).

Component:

The NHD-0216PZ-FL-YBW-PC is a character liquid crystal display module operating on a 5V supply. It is manufactured by Newhaven Display, features 2 rows of 16 characters each, is transflective and also has controllable yellow/green LED backlighting. One thing to note about this particular model is that the backlight pins 15 and 16 are reversed, and there is a 20 Ohm resistor already connected to the backlight.

Circuit:

The first order of business was to solder on some sort of connectors so that I can run jumper wires to the Arduino. I’ve seen many people attach pin headers to the bottom of the LCD so that they can connect the LCD directly into a breadboard, but I preferred to use single row 3M Boardmount Sockets. Ideally, I would have liked to have a 16-pin version of these stackable headers (and now that I think about it I could have just gotten two of them and attached them side by side) so that I could use them both on a breadboard and with jumper wires directly to them.

Note: Make SURE that you know which type of connector you want to use before you start soldering. I found this out the hard way as I neglected to consider the fact you needed a potentiometer and several connections to +5V and ground, it is much more difficult to have a standalone LCD as opposed to having a small breadboard devoted to an LCD. Boardmount sockets are ENORMOUSLY difficult to de-solder, and I nearly destroyed a trace on the PCB of the LCD trying to force it. I ended up having to break apart the socket into smaller sections so that I could de-solder the pins individually.

So, now that we have the LCD fully prepared  for use we can begin hooking it up to the Arduino. We will do that using the datasheet schematic and the pin wiring diagram below:

First thing well do is get the backlight working. Easy enough, connect ground to pin 15 and +5V to pin 16 (Note: my LCD has the+5V and GND pins reversed, and an onboard resistor. Most LCDs will be different, so check your datasheet!).

Next, we have to add a potentiometer so that we can adjust the contrast of the LCD. Connect one side of the pot to +5V and the other to GND. The middle pin of the pot should go to pin 3 of the LCD. We also want to connect power to the LCD itself which we do by connecting GND to pin 1 and +5V to pin 2. You should now be able to adjust the contrast by turning the pot.

The final part of wiring up the LCD is connecting the data lines.

Looking back at the data sheet pin diagram we can see that there are many pins that can connect to the MicroProcessor Unit, in this case, our Arduino. Fortunately, we will only be using six pins on our Arduino. Here is how everything connects:

  • RS Pin [4] – Used to let the LCD know if its being told to receive data or receive a command. – Connects to Pin 7 on the Arduino.
  • R/W Pin [5] – Read/Write select signal. – Wont be using this so connect to GND.
  • EN Pin [6] – Used to enable writing to the registers of the LCD. – Connects to Pin 8 on the Arduino.
  • DB4 Pin [11] – Data – Connect to Arduino Pin 9
  • DB5 Pin [12] – Data – Connect to Arduino Pin 10
  • DB6 Pin [13] – Data – Connect to Arduino Pin 11
  • DB7 Pin [14] – Data – Connect to Arduino Pin 12

Here’s how everything should now be wired up.

That’s it! The hardware part is complete, which was also the most difficult part. Provided you wired everything up correctly, you should now be able to control the LCD with the Arduino. Which brings us to the software side of things…

Arduino:

Lucky for us, most of the work on creating a sketch to control the LCD has been done. If you go to  File > Examples > LiquidCrystal in the Arduino IDE you will see several sketches that are already available, we’ll be using the HelloWorld sketch. Before we run the sketch though, we need to modify the part that determines what pins will be used for what. Doing so is very easy, the sketch uses a function to assign pins, here is the function and its parameters:

LiquidCrystal lcd(RS, EN, DB4, DB5, DB6, DB7);

And this is how we modify it to work with our setup:

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

Now when we run the sketch we should see something like this:

Excellent! Having made it this far we’re able to use an LCD to display any kind of information we like, completely independent of a computer. This capability empowers us to take on a whole new breadth of projects!

If you wish to download the completed sketch you can get it here.

Sources: [Adafruit, Arduino.cc]

Writing Functions

July 16, 2012 Leave a comment

This is a simple concept so I’m going to get through it quickly. A function is a block of code that has a name and a property and is designed to be easily reusable. When you create a function, you are essentially creating a machine that does a certain job, and you can call upon it at any time to do that job.

A simple function would be one that adds two numbers together:

int sum(int x, int y)
{
	int ans = 0;  //holds the answer
	ans = x + y;  //calculates the sum
	return ans  //returns the answer
}

The first part “int sum(int x, int y)” is the header, and has a name “sum()“, parameters that go in between the parentheses “int x, int y“, and the type of return value desired “int …“.

Within the body of the function (whats between the brackets) is what will be done when the function is called upon. So, say that I called for sum(3,2), looking at the body of the function I can tell that the result will be 5.

We can use this with the Arduino in quite the same way, for example, if we wanted to turn the blink sketch into a function that blinked LED 13 a certain number of times (n) it would look something like this:

int ledPin = 13;
 int blinkVal = 3;
void setup()
 {
 pinMode(ledPin, OUTPUT);
 blinkTimes(blinkVal); //here the function is run once
 }
void loop(){}
void blinkTimes(int n) //function definition
 {
  for (int i = 0; i < n; i++)
  {
  digitalWrite(ledPin,HIGH);
  delay(1000);
  digitalWrite(ledPin,LOW);
  delay(1000);
  }
 }

The function in use is colored blue, the number of blinks is red, the function definition is green, and the defined parameter within the function is bold and black.

Now that you have the function defined you can put it at the bottom of your sketch and forget about it, calling it when ever you need the defined task done. However, the true power of functions comes from the ability to use multiple parameters. Say I want to be able to adjust not only the number of times that it blinks, but also the delay in between. That is easy enough to do, all I need is to add another parameter and modify the body of the function to include it:

void blinkTimes(int n, int d) //function definition
 {
  for (int i = 0; i < n; i++)
  {
  digitalWrite(ledPin,HIGH);
  delay(d);
  digitalWrite(ledPin,LOW);
  delay(d);
  }

So if I call the function blinkTimes(10,500); now it will blink 10 times turning on and off for 500 milliseconds.

Sources: [C4Learn, C4LearnMYCPLUS]

OPL530 – Sensing Light (or so I thought)

July 14, 2012 Leave a comment

The OPL530 (click here for the datasheet (.PDF)) and the OPL5## series are “Photologic Sensors“. Unfortunately, I bought two of these when what I was actually looking for was a simple photodetector/photoresistor. Turns out that my datasheet comprehension is not as great as I thought, and this sensor is something entirely different. This sensor is actually a photodiode with an integrated circuit intended to be paired with a infrared LED with a wavelength of 935nm, and provides logic output, meaning; HIGH or LOW (1 or 0). I believe that the use of photologic sensors is intended for applications such as non-contact object sensing (think detecting rotating fan blades), end of travel sensing, and door position sensing.

As I understand it, the basic function of this sensor is; if it detects the light of an infrared LED, past a certain threshold, it will output the signal HIGH or 1, otherwise it will output LOW or 0. If this is true, and there is only two possible outputs, then this sensor most definitely cannot be used in a way similar to a photoresistor, which provides a variable analog output.

The projects that I had in mind required a sensor that would measure general lighting of the environment, something like a photoresistor. Perhaps this ambient light sensor (.PDF) was more in line of what I needed, or I can just go and buy a couple actual photoresitors off Digikey.

I do have a photoresistor … somewhere around here … and will follow up with a brief tutorial on its use as soon as I can find it.

Continue for more information about the sensor…

Read more…

Follow

Get every new post delivered to your Inbox.