INPUT vstupy - tlačidlo, potenciometer



Tlačidlo - digitalRead()

Akékoľvek tlačidlo, spínač, kontaktný nárazník a pod. je pripojené na digitálny vstupný pin. Môže nadobúdať iba dve hodnoty, buď je stlačené alebo stlačené nie je. Počet digitálnych pinov závisí od dosky Arduina.

Digitálny pin nastavíme ako vstupný príkazom pinMode(cislo_pinu, INPUT); (v prípade, že používame externý pull up alebo pull down rezistor), prípadne príkazom pinMode(cislo_pinu, INPUT_PULLUP); (ak nepoužívame externý pull up rezistor a chceme, aby po stlačení tlačidla bola na pine hodnota LOW (0V, GND)) na začiatku programu, najčastejšie vo funkcii void setup(). Aj analógové vstupné piny sa dajú použiť ako digitálne, viď. nižšie.

Pri stlačení tlačida (a tiež pri jeho uvoľnení) vznikajú vo veľmi krátkom čase viacnásobné zopnutia a rozopnutia, zákmity tlačidla (bounce). Odstránenie tohto javu (debouncing) je možné buď softvérovo (viacnásobné čítanie vstupu) alebo hardvérovo (RC obvod, klopný obvod). Čiastočne pomôže aj samostatný kondenzátor pripojený paralelne k tlačidlu.

Pri návrhu zapojenia tlačidla sa treba rozhodnúť, akú hodnotu (HIGH/LOW) chceme mať na vstupnom pine po stlačení tlačidla. Podľa toho volíme jednu z nasledujúcich schém (a prípadne tiež aj zapneme interný pull up rezistor, ak nepoužijeme externý pull up rezistor a chceme aby po stlačení tlačidla bola na pine hodnota LOW (0V, GND)).

Digital INPUT

V nasledujúcich príkladoch použijeme druhú schému s externým pull down rezistorom. Po stlačení tlačidla bude na pine č. 2 hodnota HIGH (+5V, 1).

Tlačidlo - schéma

Ak je tlačidlo stlačené, svieti LED integrovaná na doske Arduino (pin č. 13). Ak tlačidlo nie je stlačené, LED nesvieti.

/*
  Digitalny vstup - tlacillo na pine c. 2 (cez PULL-DOWN rezistor na GND)
  LED na pine c. 13
  Ak je tlacidlo stlacene, LED svieti
*/

int led_pin = 13;               // premenna led ma hodnotu 13
int tlacidlo_pin = 2;           // premenna tlacidlo ma hodnotu 2

void setup() {                
  pinMode(tlacidlo_pin, INPUT); // pin tlacidlo je VSTUP 
  pinMode(led_pin, OUTPUT);     // pin led je VYSTUP 
}

void loop() {
  if (digitalRead(tlacidlo_pin) == HIGH) digitalWrite(led_pin, HIGH);
  if (digitalRead(tlacidlo_pin) == LOW) digitalWrite(led_pin, LOW); 
}

Alebo druhá možnosť so zaznamenaním hodnoty do premennej.

/*
  Digitalny vstup - tlacillo na pine c. 2 (cez PULL-DOWN rezistor na GND)
  LED na pine c. 13
  Ak je tlacidlo stlacene, LED svieti
*/

int led_pin = 13;              // premenna led ma hodnotu 13
int tlacidlo_pin = 2;          // premenna tlacidlo ma hodnotu 2
int hodnota_tlacidla;          // nova premenna, kde bude bud 0-LOW alebo 1-HIGH

void setup() {                
  pinMode(tlacidlo_pin, INPUT);// pin tlacidlo je VSTUP 
  pinMode(led_pin, OUTPUT);    // pin led je VYSTUP 
}

void loop() {
  hodnota_tlacidla = digitalRead(tlacidlo_pin); 
  digitalWrite(led_pin, hodnota_tlacidla);
}

A do tretice to isté s použitím iba jedného zloženého príkazu.

/*
  Digitalny vstup - tlacillo na pine c. 2 (cez PULL-DOWN rezistor na GND)
  LED na pine c. 13
  Ak ja tlacidlo stlacene, LED svieti
*/

int led_pin = 13;              // premenna led ma hodnotu 13
int tlacidlo_pin = 2;          // premenna tlacidlo ma hodnotu 2

void setup() {                
  pinMode(tlacidlo_pin, INPUT);// pin tlacidlo je VSTUP 
  pinMode(led_pin, OUTPUT);    // pin led je VYSTUP 
}

void loop() {
  digitalWrite(led_pin, digitalRead(tlacidlo_pin)); 
}

Tlačidlo, 2xLED

Tlačidlo a LED - schéma

LED1 svieti a LED2 nesvieti. Ak je tlačidlo stlačené, svetlá sa vymenia. Program čaká na stlačenie a uvoľnenie tlačidla (while).

/*
  Digitalny vstup - tlacillo na pine c. 2 (cez PULL-DOWN rezistor na GND)
  2xLED na pine c. 9 a 10
  Pocas drzania tlacidla su svetla LED vymenene
*/

int tlacidlo_pin = 2;            // premenna tlacidlo ma hodnotu 2
int led1_pin = 9;                // premenna led1 ma hodnotu 9
int led2_pin = 10;               // premenna led2 ma hodnotu 10

void setup() {                
  pinMode(tlacidlo_pin, INPUT);  // pin tlacidlo je VSTUP 
  pinMode(led1_pin, OUTPUT);     // pin led1 je VYSTUP 
  pinMode(led2_pin, OUTPUT);     // pin led2 je VYSTUP 
}

void loop() {
  digitalWrite(led1_pin, HIGH);  // led1 svieti a led2 nie
  digitalWrite(led2_pin, LOW);  
  while(digitalRead(tlacidlo_pin) == LOW); // caka kym nebude tlacidlo stlacene
  
  digitalWrite(led1_pin, LOW);   // led2 svieti a led1 nie
  digitalWrite(led2_pin, HIGH);  
  while(digitalRead(tlacidlo_pin) == HIGH); // caka kym nebude tlacidlo pustene 
}

Alebo druhá možnosť, bez čaakania na stlačenie a uvoľnenie tlačidla (if).

/*
  Digitalny vstup - tlacillo na pine c. 2 (cez PULL-DOWN rezistor na GND)
  2xLED na pine c. 9 a 10
  Pocas drzania tlacidla su svetla LED vymenene
*/

int tlacidlo_pin = 2;            // premenna tlacidlo ma hodnotu 2
int led1_pin = 9;                // premenna led1 ma hodnotu 9
int led2_pin = 10;               // premenna led2 ma hodnotu 10

void setup() {                
  pinMode(tlacidlo_pin, INPUT);  // pin tlacidlo je VSTUP 
  pinMode(led1_pin, OUTPUT);     // pin led1 je VYSTUP 
  pinMode(led2_pin, OUTPUT);     // pin led2 je VYSTUP 
}

void loop() {
  if (digitalRead(tlacidlo_pin) == LOW) {
    digitalWrite(led1_pin, HIGH);  // led1 svieti a led2 nie
    digitalWrite(led2_pin, LOW);
  }
  else {
    digitalWrite(led1_pin, LOW);   // led2 svieti a led1 nie
    digitalWrite(led2_pin, HIGH);   
  }  
}

Hore hájom chodník

Potenciometer - analogRead()

Snímače, ktoré na základe zmeny snímanej veličiny menia veľkosť elektrického napätia (zväčša od 0V do 5V) pripájame na analógové vstupné piny. Počet analógových vstupných pinov závisí od dosky Arduina. V nasledujúcom nahradíme takýto snímač potenciometrom (trimrom), kde veľkosť elektrického napätia bude závisieť od uhla otočenia v rozsahu od 0V do 5V. V prípade nižšieho maximálneho vstupného elektrického napätia viď príkaz analogReference(). Analógové vstupné piny nemusíme nastavovať na začiatku programu (ak sa však chcú použiť ako digitálne piny, je úvodné nastavenie potrebné). Analógový vstupný pin môže nadobúdať hodnoty od 0 do 1023 v závislosti od pripojeného elektrického napätia na pine.

Analog INPUT

Potenciometer - schéma

LED budú svietiť v závislosti od otočenia potenciometra. Čím viac sa potenciometer otočí vľavo, tým silnejšie bude svietiť LED1 (a LED2 slabšie) a naopak, pri pootočení smerom vpravo sa viac rozsvieti LED2 (a jas LED2 zoslabne). V príklade je novinkou príkaz map(), ktorý preškáluje jeden číselný rozsah na druhý. V našom prípade potrebujeme vstupnú hodnotu z rozsahu 0-1023 (analog input) preškálovať na hodnotu z rozsahu 0-255 (PWM output). Ostatné príkazy by už mali byť zrejmé, boli už použité v predchádzajúcich príkladoch.

/*
  Analogovy vstup - potenciometer na pine A0
  2xLED na pine c. 9 a 10
  LED svietia v zavislosti od otocenia potenciometra
*/

int led1_pin = 9;              // premenna led1 ma hodnotu 9
int led2_pin = 10;             // premenna led2 ma hodnotu 10
int pot_pin = A0;              // potenciometer na analogovom pine A0
int analog_hodnota;            // 0-1023 analog vstup
int pwm_hondota;               // 0-255 PWM digital vystup

void setup() {                
  pinMode(led1_pin, OUTPUT);   // pin1 led je VYSTUP 
  pinMode(led2_pin, OUTPUT);   // pin1 led je VYSTUP 
}

void loop() {
  analog_hodnota = analogRead(pot_pin); // nacitanie hodnoty z potenciometra (0-1023)
  pwm_hondota = map(analog_hodnota, 0, 1023, 0, 255); // preskalovanie na 0-255 pre PWM
  analogWrite(led1_pin, pwm_hondota);
  analogWrite(led2_pin, 255-pwm_hondota);  
}

Ďalej doplníme náš príklad o sériovú komunikáciu s PC a z Arduino dosky urobíme jednoduchý voltmeter. Pre určenie hodnoty elektrického napätia vo voltoch opäť použijeme príkaz map(). Vstupnú hodnotu 0-1023 potrebujeme preškálovať na elektrické napätie 0V-5V. V príklade použijeme reálnu premennú float pre uloženie desatinného čísla. Pretože príkaz map() pracuje s celými číslami, najprv vstupnú hodnotu preškálujeme na hodnotu z rozsahu 0-500 (v desatinách volta) a následne už v premannej typu float podelíme číslom 100. (Dalo by sa to aj v jednom riadku podeliť 100.0, prípadne priamo pretypovať na float, ale tako je to názornejšie.)

/*
  Analogovy vstup - potenciometer na pine A0
  2xLED na pine c. 9 a 10
  LED svietia v zavislosti od otocenia potenciometra
  Serial Monitor vypisuje hodnotu elektrickeho napatia na pine A0
*/

int led1_pin = 9;              // premenna led1 ma hodnotu 9
int led2_pin = 10;             // premenna led2 ma hodnotu 10
int pot_pin = A0;              // potenciometer na analogovom pine A0
int analog_hodnota;            // 0-1023 analog vstup
int pwm_hondota;               // 0-255 PWM digital vystup
float voltmeter;               // desatinne cislo od 0V do 5V

void setup() {                
  pinMode(led1_pin, OUTPUT);   // pin led1 je VYSTUP 
  pinMode(led2_pin, OUTPUT);   // pin led2 je VYSTUP
  Serial.begin(9600);          // nastavenie seriovej komunikacie
}

void loop() {
  analog_hodnota = analogRead(pot_pin);               // nacitanie hodnoty z potenciometra (0-1023)
  pwm_hondota = map(analog_hodnota, 0, 1023, 0, 255); // preskalovanie na 0-255 pre PWM
  analogWrite(led1_pin, pwm_hondota);
  analogWrite(led2_pin, 255-pwm_hondota);
  voltmeter = map(analog_hodnota, 0, 1023, 0, 500);   // preskalovanie na 0-500 (v desatinach V)
  voltmeter /= 100;                                   // staci na dve desatiny
  Serial.print("El. napatie na pine A0 je ");
  Serial.println(voltmeter);
}

No a na záver zabezpečíme, aby sa výpočty a výpis uskutočnili iba pri zmene vstupu (o hodnotu väčšiu ako premenná prah) a do výpisu zahrnieme všetky hodnoty.

/*
  Analogovy vstup - potenciometer na pine A0
  2xLED na pine c. 9 a 10
  LED svietia v zavislosti od otocenia potenciometra
  Serial Monitor vypisuje hodnoty:
    analogoveho vstupu na pine A0 (0-1023)
    digitalneho vstupu na pine A0 (0/1)
    elektrickeho napatia vstupu na pine A0 (0.00V-5.00V)
    PWM vystupu LED1 na pine 9 (0-255)
    PWM vystupu LED2 na pine 10 (0-255)   
*/

int led1_pin = 9;              // premenna led1 ma hodnotu 9
int led2_pin = 10;             // premenna led2 ma hodnotu 10
int pot_pin = A0;              // potenciometer na analogovom pine A0
int analog_hodnota;            // 0-1023 analog vstup
int digital_hodnota;           // 0/1 digital vstup
int pwm_hondota;               // 0-255 PWM digital vystup
float voltmeter;               // desatinne cislo od 0.00V do 5.00V
int minula_analog_hodnota=0;   // aby vypisoval na Serial Monitor iba pri zmene, tak nech
                               // si pamata hodnotu predchadzajuceho merania
int prah=9;                    // citlivost na zmenu vstupu A0 (nech tolko nevypisuje)

void setup() {                
  pinMode(led1_pin, OUTPUT);   // pin led1 je VYSTUP 
  pinMode(led2_pin, OUTPUT);   // pin led2 je VYSTUP
  Serial.begin(9600);          // nastavenie seriovej komunikacie
}

void loop() {
  analog_hodnota = analogRead(pot_pin);                  // nacitanie hodnoty z potenciometra (0-1023)
  
  if ((analog_hodnota < minula_analog_hodnota-prah) ||
      (analog_hodnota > minula_analog_hodnota+prah)) {   // bola zmena hodnoty, ideme pocitat a vypisovat

    digital_hodnota = digitalRead(pot_pin);              // nacitanie hodnoty z potenciometra (0/1)
 
    pwm_hondota = map(analog_hodnota, 0, 1023, 0, 255);  // preskalovanie na 0-255 pre PWM
    voltmeter = map(analog_hodnota, 0, 1023, 0, 500);    // preskalovanie na 0-500
    voltmeter /= 100;                                    // na dve desatiny 
   
    analogWrite(led1_pin, pwm_hondota);                  // rozsvietenie lavej LED1 
    analogWrite(led2_pin, 255-pwm_hondota);              // rozsvietenie pravej LED2 
    
    Serial.print("analog: ");                            // vypis na Serial Monitor 
    Serial.print(analog_hodnota);
    Serial.print("    digital: ");           
    Serial.print(digital_hodnota);
    Serial.print("    napatie: ");           
    Serial.print(voltmeter);
    Serial.print("V    PWM1: ");           
    Serial.print(pwm_hondota);
    Serial.print("    PWM2: ");           
    Serial.println(255-pwm_hondota);                     // a ukoncenie riadku 
 
    minula_analog_hodnota = analog_hodnota;              // zapamatanie si hodnoty merania  
  }
  
}

Na výpise je pekne vidieť vzťah medzi analógovým a digitálnym vstupom pri danej hodnote elektrického napätia na vstupnom pine, rovnako ako aj vzťah medzi hodnotou PWM digitálneho PWM výstupu a jasom LED.

Serial Monitor

Schémy zapojení boli vytvorené v programe Eagle 6.1.0. Obrázky schematického znázornenia obvodov na kontaktnom poli boli vytvorené v programe Fritzing 0.9.0. Html kód príkladov je generovaný pomocou http://tohtml.com/cpp/.

Hore hájom chodník

PaedDr. Karol Pauchly, ZŠ s MŠ Chlebnice, november 2014