Вы находитесь на странице: 1из 18

Arduino Interrupt:

Interrupts stop the current work of Arduino such that some other work can be done.

Suppose you are sitting at home, chatting with someone. Suddenly the telephone rings. You stop
chatting, and pick up the telephone to speak to the caller. When you have finished your telephonic
conversation, you go back to chatting with the person before the telephone rang.

Similarly, you can think of the main routine as chatting to someone, the telephone ringing causes you to
stop chatting. The interrupt service routine is the process of talking on the telephone. When the
telephone conversation ends, you then go back to your main routine of chatting. This example explains
exactly how an interrupt causes a processor to act.

The main program is running and performing some function in a circuit. However, when an interrupt
occurs the main program halts while another routine is carried out. When this routine finishes, the
processor goes back to the main routine again.

Interrupt

Important features

Here are some important features about interrupts −

Interrupts can come from various sources. In this case, we are using a hardware interrupt that is
triggered by a state change on one of the digital pins.

Most Arduino designs have two hardware interrupts (referred to as "interrupt0" and "interrupt1")
hard-wired to digital I/O pins 2 and 3, respectively.

The Arduino Mega has six hardware interrupts including the additional interrupts ("interrupt2"
through "interrupt5") on pins 21, 20, 19, and 18.
You can define a routine using a special function called as “Interrupt Service Routine” (usually known
as ISR).

You can define the routine and specify conditions at the rising edge, falling edge or both. At these
specific conditions, the interrupt would be serviced.

It is possible to have that function executed automatically, each time an event happens on an input
pin.

Types of Interrupts

There are two types of interrupts −

Hardware Interrupts − They occur in response to an external event, such as an external interrupt pin
going high or low.

Software Interrupts − They occur in response to an instruction sent in software. The only type of
interrupt that the “Arduino language” supports is the attachInterrupt() function.

Using Interrupts in Arduino

Interrupts are very useful in Arduino programs as it helps in solving timing problems. A good application
of an interrupt is reading a rotary encoder or observing a user input. Generally, an ISR should be as short
and fast as possible. If your sketch uses multiple ISRs, only one can run at a time. Other interrupts will be
executed after the current one finishes in an order that depends on the priority they have.

Typically, global variables are used to pass data between an ISR and the main program. To make sure
variables share
The following three constants are predefined as valid values −

LOW to trigger the interrupt whenever the pin is low.

CHANGE to trigger the interrupt whenever the pin changes value.

FALLING whenever the pin goes from high to low.

Example:

int pin = 2; //define interrupt pin to 2

volatile int state = LOW; // To make sure variables shared between an ISR

//the main program are updated correctly,declare them as volatile.

void setup() {

pinMode(13, OUTPUT); //set pin 13 as output

attachInterrupt(digitalPinToInterrupt(pin), blink, CHANGE);

//interrupt at pin 2 blink ISR when pin to change the value

void loop() {

digitalWrite(13, state); //pin 13 equal the state value

void blink() {

//ISR function

state = !state; //toggle the state when the interrupt occurs


}

Millis:

Traditional Programming

Before I begin the Arduino Millis Tutorial, let me show a simple example circuit and code that you might
be following till now.

Assume, Arduino UNO board and in that board, a user LED is connected to Digital IO pin 13. The
following code is a simple Blink Code that Blinks the LED connected to Pin 13 of Arduino UNO.

Example:

const int ledPin = 13;

void setup()

pinMode(ledPin, OUTPUT);

void loop()

digitalWrite(ledPin, HIGH);

delay(1000);

digitalWrite(ledPin, LOW);

delay(1000);

}
In this code, the Arduino UNO is configured to make the Digital IO pin 13 HIGH for a second and LOW for
a second and this process repeats in a loop.

Delay is the culprit:

You might be familiar with the delay() function in the Arduino environment. From the day go with
Arduino, delay is one of the first function you come across. It is a simple function that is associated with
timing.

Using the delay function is simple and straightforward: mention the amount of time in milliseconds in
the delay function and your microcontroller holds its operations for that period of time.

There seems no problem with this approach but if you observe or understand closely how delay works
internally, you will get to know the disadvantage of delay.

When the delay function with a value is called, Arduino enters into a busy state and suspends all activity
until that time is finished. During this state i.e. during the execution of the delay function, Arduino
cannot perform any other tasks, like reading a button for example.

The following is a possible code for delay that keeps the processor busy.

Example:

void delay (int d)

unsigned char i=0;

for(;d>0;d--)

for(i=250;i>0;i--);

for(i=248;i>0;i--);
}

NOTE: This is in fact the main delay code I use in my 8051 Microcontroller projects. The combination of
250 and 248 in the for loops take approximately 1millisecond of the controller’s execution time. If I run
this loop for 1000 times, I get a delay of approximately 1000ms or 1 second.

How Arduino benefits by avoiding Delay?

Arduino is a microcontroller based system that performs simple tasks based on a single program. There
is no operating system involved with Arduino and hence you cannot run multiple programs on Arduino.

Does this mean we are struck with just one program that runs over and over? The simple answer is yes.
But this doesn’t mean that we cannot program Arduino to handle multiple tasks.

In order to program Arduino to manage many tasks (many tasks in a single program), functions like
delay, which engage the processor is a busy state, must be avoided. So, get ready to ditch the delay.

Meet Millis the Delay Killer:

Now that we have understood that using delay function in our Arduino programs must be avoided, how
can we achieve the same functionality without actually using the delay?

In order to achieve the functionality of timing, the simple process is to keep track of a clock at regular
intervals. If you regularly check a clock, you can easily know when is the time to act on something.

This is possible in Arduino with the help of millis function.


Before actually talking about the mechanism responsible for this, let me show you the code for blinking
an LED without using the delay function.

Blinking an LED without using Delay

The following is a simple for blinking an LED connected to Pin 13 of Arduino to blink without using the
delay function.

Example:

const int ledPin = 13;

int ledState = LOW;

unsigned long previousMillis = 0;

const long interval = 1000;

void setup()

pinMode(ledPin, OUTPUT);

void loop()

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval)

previousMillis = currentMillis;

if (ledState == LOW)

{
ledState = HIGH;

else

ledState = LOW;

digitalWrite(ledPin, ledState);

Arduino Millis Tutorial

If you try the above mentioned code for blinking the LED, it will work flawlessly. But in order to
understand more, you need to get to know the Arduino Millis function.

According to the literature provided by Arduino, millis is an Arduino function that returns the present
time in milliseconds from the moment the Arduino board is powered on or reset.

The return value of millis is number of milliseconds through an unsigned long variable since the program
in Arduino started. The reason I mentioned the return type as unsigned long is because if you use this
return types, you can keep track of the time for almost 50 days, after which the value resets to 0.

If you try to use any other return type like int or signed long, you may get logical errors or less duration.

Arduino Millis Example

The following code shows the usage of millis function in Arduino.


int period = 1000;

unsigned long time_now = 0;

void setup() {

Serial.begin(9600);

void loop() {

if(millis() > time_now + period)

time_now = millis();

Serial.print("Time: ");

Serial.print(time_now/1000);

Serial.print("s - ");

Serial.println("Hello");

//Run other code

Arduino Millis Applications:

Using millis in Arduino allows you to be more creative than before. Consider an application where you
want to print MESSAGE1 for every 5 seconds, MESSAGE2 for every 7 seconds and a MESSAGE3 for every
9 seconds.

You can implement this type of functionality in Arduino with the help of millis function but it is not
possible delay.

#define INTERVAL1 5000


#define INTERVAL2 7000

#define INTERVAL3 9000

unsigned long millis_1 = 0;

unsigned long millis_2 = 0;

unsigned long millis_3 = 0;

void displayTime(unsigned long);

void setup()

Serial.begin(9600);

void loop()

if(millis() > millis_1 + INTERVAL1)

millis_1 = millis();

displayTime(millis_1);

Serial.println("1");

if(millis() > millis_2 + INTERVAL2)

millis_2 = millis();

displayTime(millis_2);

Serial.println("2");
}

if(millis() > millis_3 + INTERVAL3)

millis_3 = millis();

displayTime(millis_3);

Serial.println("3");

void displayTime(unsigned long time_millis)

Serial.print("Time: ");

Serial.print(time_millis/1000);

Serial.print("s - ");

Multitasking:

Blinking Two LEDs at different Rates without using delay:

In the Arduino Millis Tutorial, I have shown you a simple program which can be used to blink and LED
but without using the delay function.

This is possible with the millis function. If you are using delay function for blinking two LEDs, you cannot
achieve different ON and OFF times for the LEDs and make then blink simultaneously at different rates.

But you can implement this with the help of millis in Arduino. Before seeing an example on Arduino
Multitasking, let me show you an example of how to achieve the above mentioned functionality.
const int blinkLEDPin1 = 8;

const int blinkLEDPin2 = 9;

int blinkLEDState1 = LOW;

int blinkLEDState2 = LOW;

unsigned long previousMillis1 = 0;

unsigned long previousMillis2 = 0;

long OnTime1 = 400;

long OnTime2 = 750;

long OffTime1 = 400;

long OffTime2 = 750;

void setup()

pinMode(blinkLEDPin1, OUTPUT);

pinMode(blinkLEDPin2, OUTPUT);

void loop()

{
unsigned long currentMillis = millis();

if((blinkLEDState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1))

blinkLEDState1 = LOW;

previousMillis1 = currentMillis;

digitalWrite(blinkLEDPin1, blinkLEDState1);

else if ((blinkLEDState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1))

blinkLEDState1 = HIGH;

previousMillis1 = currentMillis;

digitalWrite(blinkLEDPin1, blinkLEDState1);

if((blinkLEDState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2))

blinkLEDState2 = LOW;

previousMillis2 = currentMillis;

digitalWrite(blinkLEDPin2, blinkLEDState2);

else if ((blinkLEDState2 == LOW) && (currentMillis - previousMillis2 >= OffTime2))

blinkLEDState2 = HIGH;

previousMillis2 = currentMillis;
digitalWrite(blinkLEDPin2, blinkLEDState2);

Arduino Multitasking Example

Let me now show a simple Arduino Multitasking code. For this, let us take the above example as a
reference i.e. I will use the above code and extend it a little bit to achieve multitasking in Arduino.

In the above example, I am blinking two LEDs at different rates simultaneously. Continuing the same
task, I will add a new task where an LED connected to a different pin must be toggled every time I press
a button. This should happen instantaneously as soon as I press the button with any delay.

Circuit Diagram for Arduino Multitasking Example

Circuit Design
This is a simple demonstration of multitasking in Arduino and doesn’t involve a complex circuit.
Three LEDs (preferably of three different colors) are connected to Pins 8, 9 and 10 of Arduino
through respective current limiting resistors.

A push button is connected to Pin 2 of Arduino (important to connect it to this pin).

const int toggleLEDPin = 10;


const int buttonPin = 2;

const int blinkLEDPin1 = 8;


const int blinkLEDPin2 = 9;

int blinkLEDState1 = LOW;


int blinkLEDState2 = LOW;

unsigned long previousMillis1 = 0;


unsigned long previousMillis2 = 0;

long OnTime1 = 400;


long OnTime2 = 750;
long OffTime1 = 400;
long OffTime2 = 750;

int buttonDebounce = 20;


int ledToggle = LOW;
volatile int buttonFlag=0;
int previousState = HIGH;
unsigned int previousPress;

void setup()
{
pinMode(blinkLEDPin1, OUTPUT);
pinMode(blinkLEDPin2, OUTPUT);
pinMode(toggleLEDPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), button_ISR, CHANGE);
}
void button_ISR()
{
buttonFlag = 1;
}
void loop()
{
unsigned long currentMillis = millis();

if((blinkLEDState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1))


{
blinkLEDState1 = LOW;
previousMillis1 = currentMillis;
digitalWrite(blinkLEDPin1, blinkLEDState1);
}
else if ((blinkLEDState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1))
{
blinkLEDState1 = HIGH;
previousMillis1 = currentMillis;
digitalWrite(blinkLEDPin1, blinkLEDState1);
}

if((blinkLEDState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2))


{
blinkLEDState2 = LOW;
previousMillis2 = currentMillis;
digitalWrite(blinkLEDPin2, blinkLEDState2);
}
else if ((blinkLEDState2 == LOW) && (currentMillis - previousMillis2 >= OffTime2))
{
blinkLEDState2 = HIGH;
previousMillis2 = currentMillis;
digitalWrite(blinkLEDPin2, blinkLEDState2);
}

if(buttonFlag==1)
{
if((millis() - previousPress) > buttonDebounce && buttonFlag)
{
previousPress = millis();
if(digitalRead(buttonPin) == LOW && previousState == HIGH)
{
ledToggle =! ledToggle;
digitalWrite(toggleLEDPin, ledToggle);
previousState = LOW;
}
else if(digitalRead(buttonPin) == HIGH && previousState == LOW)
{
previousState = HIGH;
}
buttonFlag = 0;
}
}
}

Working

When the Arduino starts running the program (after uploading it), it will just blink the LEDs
connected to Pins 8 and 9 as per the mentioned ON and OFF Times.

As the button is connected to the external interrupt pin Digital IO Pin 2, whenever it is pressed,
an interrupt is generated and the status of the buttonflag is updated. Based on this flag, the
Arduino will then toggle the LED connected to Pin 10.

Вам также может понравиться