You are on page 1of 18

Distributed Real-Time Control

Systems
Module 5
Digital and Analog I/O

1
Bibliography
• ATMEGA 328 Datasheets and application notes.

http://www.microchip.com/wwwproducts/en/ATmega328

• arduino.cc

• Book:
– “Arduino Cookbook”, 2nd Ed.
– Michael Margolis
– O’Reilly, 2012

2
Interfaces
• I/O
– Digital I/O, PWM
– Analog Input
• Serial (USART)
• SPI
• TWI

3
Digital I/O
• Port function (input/output) is programmable by enabling and disabling
some switches.

4
Output Modes
• Output High • Output Low

5
Input Modes
• Input floating (high • Input with Internal Pull
impedance) Up

6
Digital Output - Driving LED’s
const int led1 = 7; // LED1 connected to digital pin 7
• Caution! const int led2 = 8;
const int rate = 500;
// LED2 connected to digital pin 8
// Delay in ms to commute leds
– Source/Sink limits int counter = 0; // loop counter

– 40mA at 5Vcc void setup()


{
// enable output on the led1 pin
pinMode(led1, OUTPUT);
// enable output on the led2 pin
pinMode(led2, OUTPUT);
// initialize serial comms to host
Serial.begin(9600);
}

void loop()
{
Serial.println(++counter); // print rate to serial monitor
digitalWrite(led1, HIGH); // set the LED1 on
• How much current passes digitalWrite(led2, HIGH); // set the LED2 off
delay(rate); // wait duration
through the LED’s ? digitalWrite(led1, LOW); // set the LED1 off
digitalWrite(led2, LOW); // set the LED2 on
delay(rate);
• Set the power specification of }

the resistors.
7
Analog Output (PWM)
• Analog Output is emulated via
Pulse Width Modulation (PWM).

• Arduino function
analogWrite(pin, value)
generates a PWM signal with
frequency ~500Hz and duty cycle
proportional to value.

• 0 <= value <= 255

• pin = 5,6 (TIMER0)


• pin = 9, 10 (TIMER1)
• pin = 3, 11 (TIMER2)

8
Modulate LED Brightness
const int firstLed = 3;

• Fade LED brightness in const int secondLed = 5;


const int thirdLed = 6;

and out. int brightness = 0;


int increment = 1;

void setup() { // pins driven by analogWrite do not need to be


declared as outputs
}

void loop() {
if(brightness > 255) {
increment = -1; // count down after reaching 255
}
else if(brightness < 1) {
increment = 1; // count up after dropping back down to 0
}
brightness = brightness + increment;
// write the brightness value to the LEDs
analogWrite(firstLed, brightness);
analogWrite(secondLed, brightness);
analogWrite(thirdLed, brightness );
delay(10); // mean 2.55 secs to fade up or down
}

9
Driving High Power Devices
• Arduino PINs can
source/sink 40 mA at
most.

• To drive more than 40mA:

– Use amplification
(transistors, opamps, etc).
Check datasheets.

– Use multiple pins (limited


to 400mA if USB power).

10
Drive a DC Motor in a Single Direction
• When the motor does not need to reverse
direction, a simple PWM drive is as follows:

11
Drive a DC motor in both directions
• To drive a DC motor in both
directions we need what is
typically called a H-Bridge.

• Solutions:

– make a H-bridge with


discrete components.

– Buy an IC with H-bridges.

– Buy a motor shield for


arduino.

12
Drive a DC motor in both directions
const int enPin = 5; // H-Bridge enable pin

• Example with the L239 const int in1Pin = 7; // H-Bridge input pins
const int in2Pin = 4;
void setup() {
H-Bridge. Serial.begin(9600);
pinMode(in1Pin, OUTPUT); pinMode(in2Pin, OUTPUT);
Serial.println("Speed (0-9) or + - to set direction");
}
void loop() {
if ( Serial.available()) {
char ch = Serial.read();
if(isDigit(ch)) // is ch a number? {
int speed = map(ch, '0', '9', 0, 255);
analogWrite(enPin, speed);
}
else if (ch == '+') { //Rotate CW
digitalWrite(in1Pin,LOW); digitalWrite(in2Pin,HIGH);
}
else if (ch == '-') { //Rotate CCW
digitalWrite(in1Pin,HIGH); digitalWrite(in2Pin,LOW);
}
else {
Serial.print("Unexpected character "); Serial.println(ch);
}
}
}

13
Digital Input – Reading Switches
int inputPins[] = {2,3,4,5}; // create an array of switch inputs
• Must use pull-ups. int ledPins[] = {10,11,12,13}; // create array of output LEDs

void setup() {
for(int index = 0; index < 4; index++) {
pinMode(ledPins[index], OUTPUT); // LED as output
pinMode(inputPins[index], INPUT); // pushbutton as input
digitalWrite(inputPins[index],HIGH); // enable pull-ups
}
}

void loop() {
for(int index = 0; index < 4; index++) {
int val = digitalRead(inputPins[index]); // read input value
// check if the switch is pressed
if (val == LOW) {
// turn LED on if switch is pressed
digitalWrite(ledPins[index], HIGH);
}
else {
// turn LED off
digitalWrite(ledPins[index], LOW);
}
}
}

14
Switch Debouncing
// debounce returns true if the switch in the given pin
// is closed and stable

boolean debounce(int pin)


{
boolean state;
boolean previousState;
// store switch state
previousState = digitalRead(pin);
for(int counter=0; counter < debounceDelay; counter++) {
// wait for 1 millisecond
delay(1);
// read the pin
state = digitalRead(pin);
if( state != previousState) {
// reset the counter if the state changes
counter = 0;
// and save the current state
previousState = state;
}
}
// here when the switch state has been stable
// longer than the debounce period
return state;
}

15
Analog Input
• ARDUINO UNO ATMEL 328 ADC
Characteristics • Free Running or Single Conversion Mode

– 10-bit Resolution (0x000 – 0x3FF) • Interrupt on ADC Conversion Complete

– 0.5 LSB Integral Non-linearity • Sleep Mode Noise Canceler

– ± 2 LSB Absolute Accuracy • The ADC is optimized for analog signals with an
output impedance of approximately 10 kΩ or
– 13 - 260 μs Conversion Time less.

– Up to 76.9 kSPS (Up to 15 kSPS at


Maximum Resolution)

– 6 Multiplexed Single Ended Input Channels

– Temperature Sensor Input Channel

– 0 - VCC ADC Input Voltage Range

– Selectable 1.1V ADC Reference Voltage

– Voltage Range Externally Selectable

16
Analog Input Example
const int ledPin = 13; // LED connected to digital pin 13
• Light dependent LED const int sensorPin = 0; // connect sensor to analog input 0

blinking. // the next two lines set the min and max delay between blinks
const int minDuration = 100; // minimum wait between blinks
• Analog Read returns const int maxDuration = 1000; // maximum wait between blinks

values between 0 (min) void setup()


{
and 1024 (max). pinMode(ledPin, OUTPUT); // enable output on the led pin
Serial.begin(9600); // initialize Serial
}

void loop()
{
int rate = analogRead(sensorPin); // read the analog input
//scales the blink rate between the min and max values
rate = map(rate, 200, 800, minDuration, maxDuration);
rate = constrain(rate, minDuration,maxDuration); // saturate
Serial.println(rate); // print rate to serial monitor
digitalWrite(ledPin, HIGH); // set the LED on
delay(rate); // wait duration dependent on light level
digitalWrite(ledPin, LOW); // set the LED off
delay(rate);
}

17
Measuring Voltages
• If voltages are in the
range [0 … 5]V, they can
be measured directly.

• Otherwise we need
voltage dividers.

• Question: How to
measure negative
voltages ?

18

You might also like