Bruk av interrupt og Timer i Arduino-program.

Like dokumenter
Bruk av interrupt og Timer i Arduino-program.

Prototyping med Arduino del 2

ARDUINO STUDIELABEN PROGRAMMERING DIGITALE/ANALOGE INNDATA/UTDATA LYSDIODER FRITZING. Roger Antonsen INF januar 2012

Høgskoleni østfold EKSAMEN. Oppgavesettet består av 8 sider inklusiv denne forsiden og vedlegg.

Prototyping med Arduino del 3

EKSAMEN (Del 2, våren 2015) Løsningsforslag

WORKSHOP BRUK AV SENSORTEKNOLOGI

Analyseøving 8 - løsningsforslag

7-Segment Display Nybegynner Arduino Lærerveiledning

Eksamensoppgaven: Hele oppgavesettet består av 8 oppgaver. Hver oppgave har en %-angivelse som angir hvor mye den teller ved sensurering.

Ultralydsensor. Introduksjon. Litt om ultralydsensorer. Arduino. Skrevet av: Martin Ertsås & Morten Minde Neergaard

7-Segment Display. Introduksjon. Steg 1: Finn frem utstyr. Til denne oppgaven trenger du. Skrevet av: Martin Ertsås & Morten Minde Neergaard

består av 7 sider inklusiv denne forsiden og vedlegg. Kontroller at oppgaven er komplett før du begynner å besvare spørsmålene.

EKSAMEN. Informasjon om eksamen. Emnekode og -navn: ITD13012 Datateknikk. Dato og tid: timer. Fagansvarlig: Robert Roppestad

Blinkende lysdiode Introduksjon Arduino Lærerveiledning

Litt mer om Arduino. Roger Antonsen Sten Solli INF januar 2011

Steg 1: Installere programvaren

Emnenavn: Datateknikk. Eksamenstid: 3 timer. Faglærere: Robert Roppestad. Hele oppgavesettet består av 8 oppgaver, samt 1 vedlegg.

SUPER DISCLAIMER. Vi endrer opplegget litt fra år til år, og vi hører på dere!

E K S A M E N FAKULTET FOR TEKNOLGI OG REALFAG. Emnekode: ELE217 Emnenavn: Mikrokontrollere og styresystemer.

INF1510: Bruksorientert design

Fag ITD Datateknikk. Laboppgave 7. Programmering av Arduino med Ethernet shield. Kort løsningsforslag.

INF1510: Bruksorientert design

FORDYPNINGSEMNE 2012

DM6814/DM5814 User s Manual

1: { 2: Display functions 3: ============================================================= 4: Instruction DB5 DB4 DB3 DB2 DB1 DB0 5:

Dynamic Programming Longest Common Subsequence. Class 27

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

IN1060: Bruksorientert design

INF1510: Bruksorientert design

Erik Grindheim - fagprøve Kildekode til mikrokontroller << led_ctrl.asm >> side 1/6.

Rapport Øving 2 TDT4258 Mikrokontroller Systemdesign

Arduino med Atmel studio 6.x (6.1)

Du må håndtere disse hendelsene ved å implementere funksjonene init(), changeh(), changev() og escape(), som beskrevet nedenfor.

LabVIEW seriekommunikasjon med mikrokontroller

Exercise 1: Phase Splitter DC Operation

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

Øvingsforelesning 5 Python (TDT4110)

IN2010: Algoritmer og Datastrukturer Series 2

Tittel: Design av FSK-demodulator. Forfattere: Torstein Mellingen Langan. Versjon: 1.0 Dato: Innledning 1

KYBERNETIKKLABORATORIET. FAG: Industriell IT DATO: OPPG.NR.: LV4. LabVIEW Temperaturmålinger BNC-2120

1. Arduino Bluetooth 2 HC-05 modul

Del 1 En oversikt over C-programmering

Øvingsforelesning 5 Python (TDT4110)

Oppgave 1a Definer følgende begreper: Nøkkel, supernøkkel og funksjonell avhengighet.

Bruksanvisning - hovedpunkter Floalarm K 4

Vi skal se på lambda-uttrykk. Følgende er definerte og vil bli brukt gjennom oppgaven

Løsningsforslag til slutteksamen i SESM3401 Styring av mekatroniske systemer

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

HØGSKOLEN I SØR-TRØNDELAG

I oppgave 1 skal det prøves ut en binærteller i en integrert krets (IC). Telleren som skal brukes er SN74HC393N, hvor

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Del 4 Noen spesielle C-elementer

Flowcharts and State-Machines. IEC Ladder Logic Statement Lists Function Block Diagrams. G. Hovland /10

TDT4100 Objektorientert programmering

En to-timers oppskrift for å bygge og programmere en Arduino-drevet strikk-

Test av USB IO-enhet. Regulering og HMI.

Kapittel 1 En oversikt over C-språket

1. Arduino Bluetooth 4.0 Low Energy (BLE)

Tips! OMRON ELECTRONICS NORWAY AS

Løsning av temperatur- regulering med USB Lager et C#-program for å teste. Se prosjekt NI_DAQ_Control_1

HONSEL process monitoring

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Antall vedlegg O Tillatte hjelpemidler:

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

GUI («Graphical User Interface») del 2

Dagens tema: Sjekking

Vedlegg 2 Dokumentasjon fra TVM leverandør

Scheduling og prosesshåndtering

Elektronisk termostat med spareprogram. Lysende LCD display øverst på ovnen for enkel betjening.

INF2270. Input / Output (I/O)

<?php. count tar en array som argument, og returnerer et tall som uttrykker antallet innførsler i arrayen.

Tilstandsmaskiner med UML og Java

Programmeringsspråket C Del 2. Hans Petter Taugbøl Kragset

Neural Network. Sensors Sorter

Oversikt over SMS kommandoer for Holars 2020G

Marine Propulsion Control Systems 9000 Series Processor Feilsøking

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

Emneevaluering GEOV272 V17

static int skrivetidsfrist = 0; // antall overskredet tid når skrive

1 Innledning. 2 Virkemåte for kortet. Bli kjent med USB I/O kort K8055. NB! Ta med multimeter og lite skrujern!

TDT4110 IT Grunnkurs Høst 2015

Elektronisk innlevering/electronic solution for submission:

Zelio Soft grunnkurs. Zelio Logic reléerstatter programmering

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

Slope-Intercept Formula

Tilstandsmaskiner (FSM) Kapittel 5

Python: Input og output

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Dagens tema Kapittel 8: Objekter og klasser

A-NO ER OVERSETTELSE AV INSTRUKSJONSBOKEN

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

Transkript:

1 Bruk av interrupt og Timer i Arduino-program. Når vi skal utføre handlinger som kan inntreffe tilfeldig (ikke forutsigbare hendelser), slik som å håndtere alarmer, at IO ønsker service etc kan vi benytte Polling som et prinsipp eller vi kan mer effektivt benytte Interrupt. Hva er Polling? Polling betyr at CPU en sjekker ved jevne mellomrom om noen trenger å bli betjent. CPU en bruker følgelig masse tid på å spørre enhetene om de trenger oppmerksomhet. Noe som de normalt ikke trenger. Bortkastet tid. Polling er enkelt å programmere, da det kun består i å «spørre» enheter om de trenger å bli betjent. Hvis svaret er «ja» kjøres en rutine som betjener enheten. Kan for eksempel gjøre dette med digitalread() i loop()-funksjonen. Interrupt (avbrudd). Betyr at CPU en sjekker ved jevne mellomrom om noen trenger å bli betjent. CPU en sjekker om et avbruddssignal er signalert etter utførelsen av hver instruksjon. Det betyr at det vil gå svært liten tid fra avbrudd er signalert til det blir oppdaget av CPU en. Avbrudd er mer effektiv metode enn polling. CPU en utfører sine oppgaver som normalt, og vil kun avbrytes hvis det kommer et avbruddsignal (interrupt) som varsler en «unormal» hendelse. Ved interrupt vil normalt kjørende program bli avbrutt for at en avbruddsrutine (ISR Interrupt Service Routine) skal kjøres for å betjene enheten som har signalert avbrudd. Etter at avbruddet er betjent fortsetter CPU en med oppgaven den utførte før avbruddet inntraff. CPU er har en egen avbruddslinje (fysisk linje) som brukes for å varsle interrupt (INTR) fra eksterne enheter.

2 Figur som viser at kjørende program blir avbrutt ved interrupt. Tilgjengelige Interrupt på Atmega 328 i prioritert orden. 1 Reset 2 External Interrupt Request 0 (pin D2) (INT0_vect) 3 External Interrupt Request 1 (pin D3) (INT1_vect) 4 Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect) 5 Pin Change Interrupt Request 1 (pins A0 to A5) (PCINT1_vect) 6 Pin Change Interrupt Request 2 (pins D0 to D7) (PCINT2_vect) 7 Watchdog Time-out Interrupt (WDT_vect) 8 Timer/Counter2 Compare Match A (TIMER2_COMPA_vect) 9 Timer/Counter2 Compare Match B (TIMER2_COMPB_vect) 10 Timer/Counter2 Overflow (TIMER2_OVF_vect) 11 Timer/Counter1 Capture Event (TIMER1_CAPT_vect) 12 Timer/Counter1 Compare Match A (TIMER1_COMPA_vect) 13 Timer/Counter1 Compare Match B (TIMER1_COMPB_vect) 14 Timer/Counter1 Overflow (TIMER1_OVF_vect) 15 Timer/Counter0 Compare Match A (TIMER0_COMPA_vect) 16 Timer/Counter0 Compare Match B (TIMER0_COMPB_vect) 17 Timer/Counter0 Overflow (TIMER0_OVF_vect) 18 SPI Serial Transfer Complete (SPI_STC_vect) 19 USART Rx Complete (USART_RX_vect) 20 USART, Data Register Empty (USART_UDRE_vect) 21 USART, Tx Complete (USART_TX_vect) 22 ADC Conversion Complete (ADC_vect) 23 EEPROM Ready (EE_READY_vect) 24 Analog Comparator (ANALOG_COMP_vect) 25 2-wire Serial Interface (I2C) (TWI_vect) 26 Store Program Memory Ready (SPM_READY_vect) Arduino Uno gir oss mulighet til å benytte pinne 2 og 3 til egne Interrupt.

3 Hvordan sette opp Interrupt på Arduino Uno.? Vi benytter funksjonen: attachinterrupt(). Den kobler et fysisk avbrudd på digital IO-pinne 2 eller 3 til en avbruddsrutine. attachinterrupt() har 3 parametre som vist i følgende kode. attachinterrupt (BUTTON_INT, navn på avbruddsrutine, type avbruddspuls ); BUTTON_INT skal være enten 0 eller 1 med Arduino Uno. Dette angir henholdsvis at digital inngang pinne 2 eller 3 skal detektere interrupt. ( Kun 2 innganger til interrupt på Uno.) Avbruddsrutine navn på funksjonen som utgjør avbruddsrutina Avbruddsrutine er en funksjon som ikke skal ha paramtere og heller ikke noen returverdi. Type avbruddspuls. Må være en av følgende 4 valg. RISING angir at interrupt skal detekteres på en puls som går fra lav til høy (stigende flanke). FALLING. - Puls som går fra Høy til Lav. Fallende flanke. CHANGE Interrupt når signalet endrer seg fra lav/høy eller motsatt. LOW Intterupt hvis signaler er lavt. Eksempel 1. const int BUTTON_INT=0; // Interrupt 0 (pin 2 på Arduino Uno) // Interrupt 1 (pin 3 på Arduino Uno) // Set up interrupt attachinterrupt(button_int, tempalarm, RISING); void tempalarm() // Interrupt function... Kode som håndterer interrupt-kilden Kan ikke inneholde delay() Bør være hurtig, og lite kode....

4 Eksempel 2. const int ledpin = 13; const int interruptpin = 2; // Interrupt kobles til Dig.IO pin 2 volatile int state = LOW; void setup() pinmode(ledpin, OUTPUT); pinmode(interruptpin, INPUT_PULLUP); attachinterrupt(digitalpintointerrupt(interruptpin), blink, CHANGE); void loop() digitalwrite(ledpin, state); void blink() // Interrupt-rutina state =!state; digitalpintointerrupt(interruptpin)- er en funksjon som kobler interruptpin til riktig Interrupt på mikrokontrolleren. - Pinne 2 er Interrupt 0. - Pinne 3 er Interrupt 1.

5 Timer. En Timer benyttes for å tidsstyre kjøring av rutiner. Vi kan sette en Timer-tid fra mikrosekunder opp til minutter/timer. For eksempel kan vi sette opp en rutine til å kjøre periodisk hvert 100 msek. Vi kan dermed enkelt lage rutiner som går periodisk, for eksempel styring, måling, regulering, sampling. Hvordan sette opp en Timer? Atmega 328 mikrokontroller har 3 timere innebygd. De kan være forholdsvis knotete å sette opp fra bunn av. En enkel måte å sette opp timere på er å benytte et bibliotek som noen har utviklet. Et enkelt bibliotek er: TimerOne Søk etter TimerOne. Last ned zip-fila og pakk ut innholdet. zip-fila ligger også på hjemmesiden under tidsplan. Pakk ut zip-fila. Og du skal se følgende filer: Innholdet i zip-fila.

6 Kopier disse filene til en katalog du kaller TimerOne som må ligge under Libraries under Arduino katalogene som vist på figuren under. Vi kan benytte Timer-funksjonen på følgende vis: #include <TimerOne.h> // Må være med // Initiere og sette opp en timer Timer1.initialize(500000); // 500000 mikrosek = 0.5 sekund Timer1.attachInterrupt(changePitch); // Kjører "changepitch" hvert 0.5 sek ----------------- Timer1.initialize(tid) Timer1.attachInterrupt(timer_rutine) angir periodetiden i mikrosekunder angir navnet på funksjonen som skal kjøres periodisk

7 Eksempel med timer. /* Enkel test av Timer. Lar timer-rutina styre Led 11. Tid oppgis i mikrosekunder. loop() styrer en frekvens som benyttes av tone() RR mars 2018 Fil: timer1.io */ #include <TimerOne.h> const int LED=11; const int tonepin = 8; int frekvens = 50; void setup() Serial.begin(9600); pinmode(led, OUTPUT); Timer1.initialize(2000000); // periodetid for timer 2 sekunder Timer1.attachInterrupt(blinkLed); // blinkled er timerfunksjonen som blir utført void loop() tone(tonepin, frekvens,400); frekvens += 50; // Generer frekvens på tonepin if (frekvens >= 4000) frekvens = 100; Serial.print("Frekvensen er: "); Serial.println(frekvens); delay(500);

8 //Timer funksjonen void blinkled() static bool ledonoff = 0; ledonoff =!ledonoff; digitalwrite(led, ledonoff); Serial.print("Led er: "); Serial.println(ledOnOff); // Toggle LED State Eksempel som benytter både interrupt og timer. /* Enkel test av Timer og Interrupt. Lar timer-rutina styre Blå Led pinne 11. Interrupt-rutina slår rødt lys på pinne 12 av/på. loop() styrer en frekvens på lyden mellom 100 og 4000 Hz. RR mars 2018 Fil: test_timer_interrupt_enekel_ver_mars2018 */ //Using Timer Interrupts with the Arduino #include <TimerOne.h> const int blueled=11; const int redled=12; const int tonepin = 8; int frekvens = 50; const int INT_BUTTON = 0; // Interrupt0 er koblet til pinne 2 på Uno. void setup() Serial.begin(9600); pinmode(blueled, OUTPUT); pinmode(redled, OUTPUT); Timer1.initialize(1500000); // set a timer of length 1500000 microseconds (1.5 second) Timer1.attachInterrupt(blinkLed); //Runs "blinkled" on each timer interrupt // Setter opp interrupt-rutina, // Benytter IO-pinne 2 som utgjør Int 0. Rising angir puls fra lav til høy. attachinterrupt(int_button, intrutine, RISING );

9 void loop() tone(tonepin, frekvens,800); frekvens += 50; if (frekvens >= 3000) frekvens = 100; Serial.print("Frekvensen er: "); Serial.println(frekvens); delay(800); //Timer interrupt function void blinkled() static boolean ledonoff = 0; ledonoff =!ledonoff; digitalwrite(blueled, ledonoff); //Toggle blueled On/Off Serial.println(""); Serial.println("Timer-rutine blir utfoert."); Serial.print("blueLed er: "); Serial.println(ledOnOff); // Interrupt-rutine som switcher Rød Led på pinne 12 av/på void intrutine(void) static boolean ledonoff = 0; ledonoff =!ledonoff; Serial.println(""); Serial.println("int_routine blir utfoert."); Serial.print("RedLed er: "); Serial.println(ledOnOff); digitalwrite(redled, ledonoff); //Toggle redled State

10 Sjekker monitoren.

11 Program som skal hinder prelling når en bryter trykkes /* Test av prelling, og styring av Led med PWM. RR mars 2018. Fil: bounce_test_1.io */ const int BLUELED = 9; const int BUTTON = 12; int ledverdi = 0; boolean lastbuttonstate = false; boolean ledon = false; void setup() pinmode(blueled, OUTPUT); pinmode(button, INPUT); void loop() bool currentbutton = buttononoff(); if ( lastbuttonstate == LOW && currentbutton == HIGH) ledon =!ledon; lastbuttonstate = currentbutton; // Bruke PWM på led bruker analogwrite() // BLUELED kjøres fra 0 -> Max lys. // Hvis bryter er trykket starter den fra 0 igjen. if ( ledon == true) analogwrite(blueled, ledverdi); ledverdi++; if (ledverdi == 255) ledverdi = 0; else ledverdi = 0; analogwrite(blueled, ledverdi); delay(10);

12 // Sjekker tilstand på bryter. Leser 2 ganger. Unngår prelling. boolean buttononoff(void) boolean current = digitalread(button); if ( current!= lastbuttonstate) delay(5); // delay for å unngå prelling på bryter current = digitalread(button); // Leser 1 gang til for å være sikker på verdien return current; Eksempel 2. Hindre prelling. Venter x antall msek etter endring. /* Hindre prelling p bryter Fil: test_prelling_15mars2018.ino */ int inpin = 2; int outpin = 11; // the number of the input pin // the number of the output pin int counter = 0; int reading; int current_state = LOW; // how many times we have seen new value // the current value read from the input pin // the debounced input value // the following variable is a long because the time, measured in milliseconds, // will quickly become a bigger number than can be stored in an int. long time = 0; // the last time the output pin was sampled int debounce_count = 10; // number of millis/samples to consider before declaring a debounced input

void setup() Serial.begin(9600); pinmode(inpin, INPUT); pinmode(outpin, OUTPUT); digitalwrite(outpin, current_state); // setup the Output LED for initial state 13 void loop() // If we have gone on to the next millisecond if(millis()!= time) reading = digitalread(inpin); if(reading == current_state && counter > 0) // Skal sikre at det går 10 msek etter siste prelling. Serial.println(" counter-- "); counter--; if(reading!= current_state) // Teller opp, fordi det er en endring i tilstand Serial.println(" counter++ "); counter++; // If the Input has shown the same value for long enough let's switch it if(counter >= debounce_count) counter = 0; current_state = reading; digitalwrite(outpin, current_state); Serial.println(" counter > 10 "); time = millis(); // Leser av tiden for å sikre at det går 1 ms mellom hver sjekk

14 Sjekker monitoren.