Arduino IDE,
setup/loop, LEDky

NSWI170, 2026, Labs 02

Jáchym Bártík

Feedback

  • Žádost o revizi
  • Dekompozice (a další pravidla)
    • Červené vs. bílé připomínky
  • Mattermost
  • Funkce abs
    
    if (temperature < 0) {
        printChars(' ', indentation - abs(temperature));
        ...
    }
                

Pravidlo #2 - konstanty

  • Najděte 4 rozdíly:
    
    for (int i = 0; i < 4; i++)
        digitalWrite(13 - i, LOW);
                    
    
    for (int i = 0; i < LEDS_SIZE; i++)
        digitalWrite(LEDS[i], ON);
                    
  • Setup:
    
    // funshield.h
    constexpr int ON = LOW;
    constexpr int LED1_PIN = 13;
    
    // solution.ino
    #include <funshield.h>
    constexpr int[] LEDS = { LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN };
    constexpr int LEDS_SIZE = sizeof(LEDS) / sizeof(LEDS[0]);
                
  • Výhody:
    • Pojmenovávají konstantní hodnoty - self-documentation
    • Definice na jednom místě - snadnější změny, DRY
    • Jména jsou unikátní, hodnoty ne

Pravidlo #2 - konstanty

  • Upřesnění:
    • Jmenná konvence (zpravidla UPPER_CASE)
    • Lze použít i pro složitější objekty, nejen literály
    • Odvozené konstanty
    • Preferujte constexpr před const
    
    constexpr int[] LEDS = { LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN };
    constexpr int LEDS_SIZE = sizeof(LEDS) / sizeof(LEDS[0]);
                
  • Čemu se vyhnout:
    • Nemají žádný speciální význam - 0, 1, true, false, "", ...
    • Lokální matematické hodnoty, které se nemění

Arduino

  • Open-source hardwarový a softwarový projekt
  • Základová deska
    • V tomto případě Arduino UNO
  • Možnost přidávat další shieldy
    • V tomto případě FunShield (je s ním spousta srandy)
  • Existuje mnoho neoficiálních klonů
  • Software - Arduino IDE

Arduino UNO

  • CPU ATmega328P
  • 14 digitálních I/O pinů
    • 6 z nich lze použít jako Pulse With Modulation výstupy
  • 6 analogových vstupních pinů
  • Frekvence 16 MHz
  • FLASH paměť 32 KB
  • SRAM (Static RAM) 2KB
  • EEPROM (další paměť) 1 KB
  • USB-B
  • DC napájení
  • Tlačítko pro reset

FunShield

  • 3 tlačítka
  • 4 LEDky
  • 4 číselný sedmisegmentový display
  • 1 bzučák (bohužel nebudeme používat na cvičeních)
    • Viz ukázka #1 (později)
  • 1 potenciometr (také nevyužijme)
  • Nějaké další vstupy a výstupy
  • Tlačítko pro reset

Arduino IDE

  • Deska se připojí přes USB
    • Pokud ji IDE nedetekuje automaticky, je nutné ji vybrat manuálně
  • Sketch - program
    • Verify - kompilace
    • Upload - nahrání kódu na desku
  • Po nahrání se deska resetuje a začne rovnou vykonávat nový program
    • Ukázka #1
  • Knihovny - Sketch > Include Library
    • Add .ZIP library... (jednou)
    • funshield (u každého projektu)

Základy

  • Dvě hlavní funkce
    • setup - volá se právě jednou na začátku programu
    • loop - volá se stále dokola (řádově 1000 krát za sekundu)
  • Veškerou logiku týkající se přímo hardwaru je nutné volat až z těchto dvou funkcí.

Cvičení #1

  • Rozsviťte diodu

#include <funshield.h>

void setup() {
    pinMode(LED1_PIN, OUTPUT);  // Declare given pin as output
    
    digitalWrite(LED1_PIN, ON); // Set voltage on the pin
}

void loop() {
    
}
    
  • Všechny konstanty jsou v uvedené knihovně
    • ON a OFF mohou být prohozeny, kdyžtak si to opravte

Cvičení #2

  • Rozblikejte diodu
    • Funkce delay(int milliseconds) umožňuje aktivní (blokující) čekání

constexpr int PERIOD = 100; // In milliseconds

void loop() {
    // Do something
    
    delay(PERIOD);          // Wait
    
    // Do something else ...
}
    

Cvičení #3

  • Rozblikejte diodu bez delay
    • Vždy je lepší vyhnout se blokujícímu čekání
    • Funkce unsigned long millis() vrací počet milisekund od něčeho (zapnutí napájení? restart?)
    • Přeteče za ~50 dní

unsigned long lastTime;
unsigned long timer;

void setup() {
    lastTime = millis();
    timer = 0;
}

void loop() {
    unsigned long currentTime = millis();               // Time since start
    unsigned long deltaTime = currentTime - lastTime;   // Time since last loop
    
    lastTime = currentTime;
    timer += deltaTime;                                 // Resetable timer
}
    

Ukázka #2

  • Více nezávislých časovačů s různými periodami
    • Pomocí delay by to prakticky nebylo možné
  • Většinu logiky schováme do OOP

Odevzdávání do ReCodExu

  • Moccarduino - emulátor Arduina a FunShieldu
    • Funguje na úrovni API funkcí, neemuluje fyzickou desku
    • V některých detailech se může lišit
  • Některé testy jsou tricky
    • Důsledně dodržujte specifikaci
      • Pozor na rozdíly v řádu milisekund, na fyzické desce nejsou vidět, ale testy je odhalí
    • Pokud si přesto myslíte, že chyba není na vaší straně, kontaktujte nás co nejdříve

Domácí úkol #2

  • Zobrazte složitější vzor
    • Jeden krok trvá 300 ms
    • V každém kroku svítí právě jedna dioda
    • Vzor je: 1, 2, 3, 4, 3, 2, 1, 2, ...

Cvičení #4 (bonus)

  • Zobrazte libovolný vzor
    • Nemusí být nijak pravidelný
    • Vymyslete vhodné kódování pro uložení fází
    • Periodicky přepínejte z jedné fáze do druhé

Cvičení #5 (bonus)

  • PWM (Pulse With Modulation)
    • Dioda má dvě možné intenzity - 0 a 1
    • Rychlým střídáním těchto stavů můžeme docílit libovolné průměrné intenzity
  • Bonus: Zařiďte, aby se průměrná intenzita limitně blížila dané hodnotě, i když délky loopů nebudou náhodné
    • Např. chceme poloviční intenzitu, ale loopy trvají 1 ms, 9 ms, 1 ms, 9 ms, ...
    • Přesný přístup - numericky integrujeme skutečnou intenzitu
    • Náhodný přístup - porovnáváme cílovou intenzitu s RNG