Archive

Archive for the ‘Programming’ Category

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:

Advertisements

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]

LM335 – Measuring Temperature

July 12, 2012 Leave a comment

I recently ordered a whole bunch of components, sensors and parts off of Mouser, one of which was the LM335A temperature sensor.

The LM335A is part of the LM135 series, which are precision, easily-calibrated, integrated circuit temperature sensors. It operates as a 2-terminal zener, and has a breakdown voltage directly proportional to absolute temperature at +10 mV/°K. With less than 1 Ohm dynamic impedance the device operates over a current range of 400 mA to 5 mA with virtually no change in performance. When calibrated at 25°C the LM135 has typically less than 1°C error over a 100°C temperature range. Unlike other sensors the LM135 has a linear output.

All this and more information about the sensor can be acquired in the datasheet here.

The important parts to know are that it works like a zener diode with a breakdown voltage that is proportional to the temperature. A 10 mV increase correlated to a 1°K increase in temperature. Calibration of the sensor can be done via a potentiometer connecting output to ground. At this time I will be using the sensor uncalibrated, which will give a temperature error of +/- 1 – 3°C, I may attempt to calibrate it at a later date using the known temperatures of boiling/freezing water.

 

Circuit:

Components:

  • 2.2k Ohm resistor
  • LM335A

To use the sensor I set up this circuit on my protoshield:

5V is supplied to the (+) pin of the sensor through a 2.2k resistor, and GND is connected to the (-) pin. Analog 0 of the Arduino is also connected to the (+) pin.  This forms a circuit known as a voltage divider, and is a linear circuit that produces an output voltage that is a fraction of the input voltage. In my case, the voltage out changes as the break down voltage changes in the sensor, and is representative of the temperature.

Note: To calculate the resistor used in this circuit you would have to take into consideration the voltage drop of the sensor, which I don’t quite understand at this point so I will be saving this comment from SparkFun user “superbrad” for later use:

I believe the issue that most of you are having is that you are neglecting to take into account the ~3V drop of the LM335 into account. It is a diode, which needs to be included in the resistor calculation.
Ohm’s law: V = IR. But if you’re running on 5V, don’t use V = 5V! The diode blocks ~3V, so V = (5V – 3V) = 2V.
Solving for R where V = 2V and I = 1mA (R = V/I = 2V/.001A), you should find that a 2Kohm resistor at 5V is appropriate.
Best of luck.

Another thing to keep in mind is that since we are working with such a low voltage signal, it is important to keep the sensor close to the Arduino or the signal will be degraded and inaccurate. So I wouldn’t advise stringing up the sensor on a 20″ wire cable unless you use some kind of shielding or filtering/amplification like that which is demonstrated in the datasheet.

Arduino:

To get the sensor to start giving us data we tell the Arduino to do this:

int sensePin = 14; // Pin A0
float sensorValue = 0; //Set the sensor value as a floating number
void setup()
{
 Serial.begin(9600);
 pinMode(sensePin, INPUT);
}
void loop() 
{
 int sensorValue = analogRead(sensePin); //reads voltage on Pin A0
 Serial.println(sensorValue); //returns voltage on a 0 - 1023 scale (0 - 5 Volts)
 delay(1000);
}

And we get a response in the serial logger of something like this:

Now, this isn’t quite useful to us as it isn’t in the °C or °F temperature format we are used to so we have to convert what the sensor is spitting out to a human readable number. First thing we can do is convert the number to Kelvin, as we know that every 10 mV change in the output is equivalent to 1°K

float kelvinValue = (((sensorValue / 1023.0) * 5.0) * 100.0); // convert sensorValue to Kelvin

This is better, but we aren’t doing any science (yet) so we don’t want Kelvin, we want Celsius or Fahrenheit.

float celsiusValue = kelvinValue - 273.0; // convert Kelvin to Celsius
float fahrenheitValue = (celsiusValue) * (9.0/5.0) + 32.0; // convert Celsius to Fahrenheit

Now we can finally have the Arduino return the temperature of its environment in Celsius or Fahrenheit! Wooohoo! Here are the results with a little added formatting flair:

Click here to go to the completed sketch with formatting on pastebin. (updated Jul-14-2012)

Now that we have the ability to roughly (since our sensor is still uncalibrated) sense the temperature of the environment we can make all kinds of things! Computer fan controllers, green house temperature monitoring, self-regulating homebrewing fridges are projects that we are ready to take on.

And if you don’t know, now you know.

January 18, 2012 Leave a comment

I’ve got to put my projects on the back-burner as school starts up again, but I’ll be trying to keep in touch with electronics and the Arduino as best as I can. I’ll probably get sucked into mini projects every now and then anyway since I constantly bombard myself with sources of intriguing information relating to electronics.

So that’s what this post will be about, spilling the beans on my current sources of stories and general info on electronics and the Arduino. I’ll try to organize this list by what I frequent the most.

reddit.com/r/Arduino+Electronics+AskElectronics+Ece+Engineeringstudents

Reddit’s electronics related subreddits combined into one link. All of those constantly provide me with new ideas and interesting articles to read, and I see people submit questions that I have all the time. /r/Breadboard and /r/Letslearnelectronics also merit a look.

EEVblog – eevblog.com

“An off-the-cuff video blog for electronics engineers, hobbyists, hackers and makers.” This guy puts out some really entertaining and educational videos, some of the topics may be a bit advanced for the beginner but it gets you thinking in that electronics mindset.

Ladyada / Adafruit Industries Tutorials

Some great tutorials by Ladyada on the Arduino, electronic components, projects, and programming.

Arduino.cc Tutorials and Arduino.cc Reference

Nothing better than having your source of info be right from the creators of the Arduino.

bildr – bildr.org

“Documented methods for doing one thing, and offering them for as many microcontrollers as possible.” Puts out beautifully done tutorials.

falstad Electronic Circuit Simulator

Simple circuit simulator. You can add wires and various components to try out some basic ideas before you build them.

kpsec The Electronics Club

Very nice site for easy to digest explanations of basic electronic principles, various components and parts, and sample projects and prototyping.

Others worth mentioning:

jeremyblum.com

electronics-tutorials.ws

tronixstuff.wordpress.com

conductiveresistance.com

for Loop

January 11, 2012 Leave a comment

I’m going to do a quick run though the “for” loop, using a part of this guide as a foundation.

Using the Arduino.cc explanation here you can get a basic understanding of how it works.

The for statement is used to repeat a block of statements enclosed in curly braces. An increment counter is usually used to increment and terminate the loop. The for statement is useful for any repetitive operation, and is often used in combination with arrays to operate on collections of data/pins.

There are three parts to the for loop header:

for (initialization; condition; increment) {
    //statement(s);
}
The initialization happens first and exactly once. Each time through the loop, the condition is tested; if it’s true, the statement block, and the increment is executed, then the condition is tested again. When the condition becomes false, the loop ends.

So now that you have a basic understanding of the for loop, lets see how we can apply it…

I will use my own version of the original example sketch from tronixstuff to illustrate how the for loop functions.

Click here for Pastebin with syntax highlighting for the following code.

void setup(){
    pinMode(9, OUTPUT);
}
void loop(){
    for (int x = 1; x <= 5; x++){
        digitalWrite(9, HIGH);
        delay(1000);
        digitalWrite(9, LOW);
        delay(1000);
    }
    delay(10000);
}

Here’s whats actually happening in the for loop in human language:

    for (set x equal to 1; is x less than or equal to 5?; increase x by 1){
        set pin 9 high;
        wait one second;
        set pin 9 low;
        wait one second;
    }
    wait 10 seconds;

The steps taken in our loop are;

  1. a variable “x” is set to equal to 1, this is done once
  2. a test is done to check if x is equal to or less than 5
  3. if the test is passed, the statements inside the braces are acted upon
  4. x is set to equal x + 1
  5. steps 2 through 4 are done until the test fails, in which case the loop is terminated

The physical result of the sketch – if you have an LED hooked up to pin 9 of the Arduino – will be that the LED will blink 5 times, wait 10 seconds, blink 5 times… and so on, for infinity.

That’s pretty much it. You can do more complicated things with the for loop, but the fundamentals can be summarized to: initialize, test, incrament/decrement.

if Test

January 9, 2012 Leave a comment

The “if” is a test you give to the Arduino. In this test you make the questions and you determine what happens when it passes or fails. If the test that you made is passed, as in something happens that you wanted to happen, then you want the Arduino to do a certain action. Optionally, if the test is failed or something unexpected happens and the test is failed, you can tell the Arduino to take a different action.

If you wanted to make a test on the Arduino that would turn on a light for 5 seconds every time someone walked through a door it would look something like this:

if (PersonWalkingThroughDoor == 1) {
 digitalWrite(LIGHT, HIGH);
 delay(5000);
 digitalWrite(LIGHT, LOW);
 }

And a translated human readable version to understand whats going on:

if (a person walks through the door) {
 turn on the light;
 wait 5 seconds;
 turn off the light;
 }

Now, let’s try to understand the Arduino version of the test and see why it works…

A person can only be walking through the door or not, we can represent this as 1 or 0, respectively. Then, we can assign this state to a certain variable – which can be thought of as a digital box that can hold thing – we’ll call this variable “PersonWalkingThroughDoor”.

If a person is walking though a door our variable PersonWalkingThroughDoor would equal 1, otherwise it would be 0. Given this basic setup we can run a test, and that is exactly what this part of our code does:

if (PersonWalkingThroughDoor == 1) {

If our variable PersonWalkingThroughDoor is equal to 1, then it would pass our test and go into the action phase, where it would preform a certain task.

digitalWrite(LIGHT, HIGH);
delay(5000);
digitalWrite(LIGHT, LOW);
}

What happens in our “action phase” are just some basic commands, first we use digitalWrite() to set the pin attached to the LIGHT variable to HIGH (turning on the light), then we wait 5000 milliseconds, then we turn the light off.
Finally, if you want to expand the function of the test then you can include an “else” clause which would look something like this:


 if (PersonWalkingThroughDoor == 1) {
 digitalWrite(LIGHT, HIGH);
 delay(5000);
 digitalWrite(LIGHT, LOW);
 }
 else {digitalWrite(LIGHT, LOW);}

In that case, if the initial test is failed you can tell the Arduino to take a different action. In our case it would simply keep the light off if there is nobody walking through the door, and it truly inessential as the light is turned off by default after 5 seconds.

So that’s it, that’s the basic overview of an if function. You might know it, but the best way to understand it is to try it out yourself.