Sunteți pe pagina 1din 7

MAE 3780 M ECHATRONICS

FALL 2013
LAB 6: INTRODUCTION TO ATMEL AND ARDUINO
PRELAB

The use of microcontrollers (often abbreviated C or simply uC) is ubiquitous in many


fields such as machine design (often referred to as an embedded controller), robotics and data
acquisition. Basic environmental interaction with a microcontroller is necessary for most common
applications to be practical.
The purpose of this laboratory is to get familiar with programming the Atmega328
microprocessor, working with the Arduino Uno board, and creating circuits connecting sensors and
actuators to the microcontroller. In this lab students will learn how to open a uC project using Atmel
Studio 6.1, program and execute code on a uC, and look at two types of interfaces: an indicator light
(Output) and a tactile switch (Input). In terms of programming, the concepts covered are basic C
programming, working with registers, polling and interrupts.

In this lab you will be modifying the provided TouchSensor.c program:


/*
*TouchSensor.c
*
*Created:9/11/20131:14:23PM
*Author:dah322
*/

//ThisincludestheClibraryforI/Odevices
#include<avr/io.h>

#defineF_CPU16000000UL
//ThissetstheclocktothecrystalontheUNO

#include<util/delay.h> //ThisincludestheClibraryforthe_ms_delay()method
#include<avr/interrupt.h>//ThisincludestheClibraryforinterrupts

//Youneedtoinsertyoursourcecodehere(oraftermain)
intmain(void)
{

//Andhere

while(1)

//Andhere
//Thisisthe"infinitewhileloop"

}
}

Recall: The microcontroller must never exit its main() function, or it will assume an unknown state
and will not operate as you would expect. Therefore we always include an infinite loop at the end of
main(). Any code that needs to be executed once in the beginning of your program (initialization
code) will go before the loop. Code that needs to be executed continuously will go in the loop.

MA
AE 3780 M E CHATRONIC
CS
FALL 201 3

Figuure 1. Touch ssensor circuit

MAE 3780 M ECHATRONICS


FALL 2013
M&AE 3780: Mechatronics Laboratory 6
PRELAB

Solution by A. McNicoll
Name: ______________________________________

In all of the following, lines are provided for your convenience they do not imply anything
about the length of your code.
Make sure to add comments to the code you write.
Before starting to work understanding power on the Arduino
1. Read the power section (it is not long read ALL of it) on the Arduino Uno webpage:
http://arduino.cc/en/Main/ArduinoBoardUno
The 5V pin.
2. Which pin will you use for Vcc in the touch sensor circuit? _________________
9V battery or other power jack
3. What will you connect (in the future) to Vin (if anything)? __________________

Part 1 -- Blinking the onboard LED:


1. Knowing that the onboard LED is connected to pin 13 on the Arduino board, if we want to
PB5
change the status of the LED, we need to write to pin ______
of the microcontroller. This can
be found on the Arduino Uno pinout diagram. Also OK: Pin 19 on ATMEGA328
2. Write code that will cause the LED to constantly be on. Do not forget to first make sure the
pin from part 1 is an output pin (hint: use the appropriate DDR register). There are many
ways to program this but keep in mind this can be done in as little as 2 lines of code.
DDRB |= 0b00100000; or DDRB = 0b00100000 or DDRB |= 1 << PB5 or ...
_______________________________________________________________________
PORTB |= 0b00100000; or PORTB |= (1 << PB5) or ....
_______________________________________________________________________

_______________________________________________________________________
_______________________________________________________________________

* There are MANY ways of doing the same thing - keep this in mind while checking.
From now on I'll only write one way (full binary mask); you can check equivalence.
The solution is NOT the best/most effective way of writing the code, but the most "basic".
Note, while direct assignment (=) works in many cases for this lab, it is ALWAYS better
practice to use |= or &=. You should always use these; it will make your code more flexible.

MAE 3780 M ECHATRONICS


FALL 2013
3. Write code that will cause the LED to blink on and off. Do not forget to first make sure the
pin from part 1 is an output pin. This will require alternatively writing 0 and 1 to the pin
from part 1. Make sure to put a delay between turning the LED on and off; this can be easily
done using the built in _delay_ms() function. Again, there are many ways to program this.
Indicate which part of the code should be in the initialization and which in the while loop.
int main(void)
{ ____________________________________________________________________
DDRB |= 0b00100000;
_______________________________________________________________________

_______________________________________________________________________
_______________________________________________________________________
_______________________________________________________________________
while(1)
Another way:
{ One
________________________________________________________________
way:
PORTB ^= 0b00100000;
________________________________________________________________
PORTB
&= 0b11011111;
_delay_ms(500);
________________________________________________________________
_delay_ms(500);
PORTB
|= 0b00100000;
________________________________________________________________

________________________________________________________________
_delay_ms(500);
________________________________________________________________
________________________________________________________________
________________________________________________________________
}
}

Part 2 Touch sensor:


4. What is the maximal DC current allowed on an Atmega328 I/O pin? (this can be found on the
Atmega328 datasheet, in the Absolute Maximal Rating listing)
40.0 mA

5. Given the maximum current from part 4, what is the minimal value the resistor R in the touch
sensor circuit should be? Explain.
Worst case scenario is pin configured as output low and sinks current from VCC
In that case, current I = 5/R = .04, so Rmin = 125 ohms.
Pull up/down resistors in this application are typically 1K - 10K.

MAE 3780 M ECHATRONICS


FALL 2013
6. Polling the input:
a. Choose an input pin that the touch sensor circuit will connect to. The pin number on
8
the Arduino board is ________
and the corresponding pin of the Atmega328 is
PB0
(Pin
14)
_______
b. Write an expression for checking whether the input pin of part 6a is high
PINB & 0b00000001
Important part is to AND PIN register with pin's mask
____________________________________________________________
c. Write a program that will turn the onboard LED on whenever the touch sensor closes
the circuit

int main(void)
{ ____________________________________________________________________
_______________________________________________________________________
DDRB
|= 0b00100000; Set PB5 to output. Below, set PB0 to input.
DDRB &= 0b11111110;
There is no need for this line, though, since pins default to INPUT (low).
_______________________________________________________________________

_______________________________________________________________________
while(1)
{
________________________________________________________________
Pin is high, so switch is open
if (PINB & 0b00000001) {
Turn off the LED
PORTB &= 0b11011111;
________________________________________________________________
Otherwise, switch must be closed
} else {
________________________________________________________________
PORTB |= 0b0010000;
________________________________________________________________
Turn on the LED
}
________________________________________________________________

________________________________________________________________
% This repeats forever in the infinite while loop... polling until eternity...
________________________________________________________________
}
}

MAE 3780 M ECHATRONICS


FALL 2013
7. Interrupts:
Write a program that will turn the onboard LED on whenever the touch sensor closes the circuit,
but this time write it using interrupts; that is, a change in the pin value should trigger the
appropriate behavior. This can be done with a PCINT or INT interrupt - not the same thing!
If time allows I will write a brief memo on the differences. Here, I use INT0.
Hints:
You may need to change the input pin take a look at the external interrupt
documentation in the Atmel data sheet. (We suggest you choose one of the external
interrupt pins INT0 or INT1)
Do not forget to enable global interrupts
Do not forget to enable the specific interrupt. If using the external input pins, take a look
at the EIMSK and EICRA registers. The description can be found in the data sheet.
When writing the ISR function, the argument should be the interrupt identifier. For INT0
the interrupt identifier is INT0_vect and for INT1 the identifier is INT1_vect
ISR(INT0_vect) {
_______________________________________________________________________

if (PIND & 0b00000100) {


_______________________________________________________________________
PORTB &= 0b11011111;
Sorry about poor spacing.
_______________________________________________________________________
} else {
PORTB |= 0b0010000;
_______________________________________________________________________
}

}
_______________________________________________________________________

int main(void)
|= 0b00100000; Set PB5 to output. Below, set PD2 to input.
{ DDRB
____________________________________________________________________
DDRB &= 0b11111011;

INT0 is located on pin PD2. Again, no real need for this line.

_______________________________________________________________________
EICRA |= 0b00000001; Set the ISC00 bit: "Any logical change on INT0 generates... interrupt..."
_______________________________________________________________________
EIMSK |= 0b00000001; Set the INT0 bit: "External Interrupt Request 0 Enable"
sei(); Allow interrupts to happen (global interrupt enable)
_______________________________________________________________________

while(1)
{
________________________________________________________________
________________________________________________________________
________________________________________________________________
% No need to do anything at all - interrupt is taking care of it.
________________________________________________________________

________________________________________________________________
________________________________________________________________
________________________________________________________________
}
}
_______________________________________________________________________

MAE 3780 M ECHATRONICS


FALL 2013
_______________________________________________________________________
_______________________________________________________________________

8. Explain, briefly, what the difference is between polling and interrupt when reading sensor
information. Specifically, what happens to the execution, how fast does the microcontroller
react to the input and what can go wrong with each.

Polling's advantage:
- Straightforward to implement - no need to dig around datasheet
- Some things, like analog, need to be polled because there is no interrupt
Polling's disadvantages:
- Slow - only reacts when it checks, which is not necessarily often
- Ties up CPU; can't do anything else while you're checking pins

Interrupt advantages:
- Reacts immediately to interrupt conditions
- Can assign interrupts to all sorts of things; every pin has a PCINT
- Does not clog up main code - run another program if you want
Interrupt disadvantages:
- If not careful about using sei() and cli(), can run code in the middle of
doing something else you didn't want interrupted.
- Subtle variable/access issues - could potentially be trying to change a variable
that was in the middle of getting changed somewhere else, etc.

S-ar putea să vă placă și