neděle 7. července 2013

Lekce 5. Co je přerušení a jak funguje - infračervené čidlo pohybu

 Jak již název článku napovídá, v této lekci se budeme věnovat přerušení. A aby to bylo trošku zajímavější, tak namísto nudného tlačítka použijeme infračervené pohybové čidlo.
Pohybové čidlo je snadné zapojit. Má totiž jen dva kontakty od tlačítka Tamper (pokud otevřete kryt čidla tak se rozepne). Další dva kontakty jsou od spínacího relé čidla (pokud čidlo zaznamená pohyb tak je rozepne). No a nakonec jsou dva napájecí kontakty pro +12V.


 
Zapojení:
Do nepájivého pole si zapojíme adapter s +12V pro napájení čidla. Kontakty relé a tlačítka Tamper připojíme přes Pull-Up rezistory na vstupní porty D3 a D5. Dále si zapojíme dvě diody na porty D7 a D9.

Detail zapojení svorek pohybového čidla
Detail zapojení svorek čidla
Pohled na celé pohybové čidlo
Pohled na celé pohybové čidlo
 
Přerušení je příjemnou abstrakcí nad digitálními vstupy. Při změně jejich hodnoty je automaticky vygenerována událost na kterou můžeme reagovat.
Při deklaraci máme na výběr z několika způsobů detekování přerušení:

  • InterruptNone
  • InterruptEdgeLow
  • InterruptEdgeHigh
  • InterruptEdgeBoth
  • InterruptEdgeLevelHigh
  • InterruptEdgeLevelLow

Pokud použijete při deklaraci hodnotu InterruptNone tak při přidávání reakce na událost OnInterrupt obdržíte výjímku An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll. Nejčastěji použijete asi hodnotu InterruptEdgeBoth, která vyvolá přerušení při změně stavu z LOG1 na LOG0 a zpět. Další dvojice InterruptEdgeLow a InterruptEdgeHigh reaguje pouze na náběžnou, nebo sestupnou hranu.
To jak funguje poslední dvojice se mi nepodařilo rozklíčovat. Při použití těchto hodnot se mi podařilo přerušení vyvolat pouze jedenkrát. Potom už na stisknutí tlačítka nereagovalo.

Reakci na přerušení připojíme stejně jako reakci na běžnou událost.
Tamper.OnInterrupt += new NativeEventHandler(Tamper_OnInterrupt);

Metoda reagující na přerušení má potom tři parametry.
data1 obsahuje číslo pinu na kterém došlo k přerušení. data2 obsahuje hodnotu 0 nebo 1 odpovídající úrovni vstupu. Poslední parametr time pak obsahuje čas vzniku přerušení.
static void Tamper_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            GreenLed.Write(data2 == 1);
        }

Video:

Zdrojový kód:
namespace Lekce05
{
    using System;
    using System.Threading;
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoPlus;

    public class Program
    {
        public static readonly OutputPort AlarmLed = new OutputPort(Pins.GPIO_PIN_D7, false);
        
        public static readonly OutputPort TemperLed = new OutputPort(Pins.GPIO_PIN_D9, false);

        public static readonly InterruptPort Temper = new InterruptPort(Pins.GPIO_PIN_D3, false, ResistorModes.Disabled, Port.InterruptMode.InterruptEdgeBoth);
        
        public static readonly InterruptPort Alarm = new InterruptPort(Pins.GPIO_PIN_D5, false, ResistorModes.Disabled, Port.InterruptMode.InterruptEdgeBoth);

        public static void Main()
        {
            Temper.OnInterrupt += new NativeEventHandler(Temper_OnInterrupt);

            Alarm.OnInterrupt += new NativeEventHandler(Alarm_OnInterrupt);

            Thread.Sleep(Timeout.Infinite);
        }

        static void Temper_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            TemperLed.Write(data2 == 1);
        }

        static void Alarm_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            AlarmLed.Write(data2 == 1);
        }
    }
}


Pokud tlačítko zapojíte mezi nulu a vstupní pin tak vhodná konfigurace portu vypadá něka takto:
public static readonly InterruptPort d = new InterruptPort(Pins.GPIO_PIN_D5, false, ResistorModes.PullUp, Port.InterruptMode.InterruptEdgeBoth);


PullUp rezistor zajistí filtrování kolísavého napětí pokud u tlačítka nezapojíte rezistor. Jinak se Vám bude přerušení generovat stále dokola podle toho kterou hodnotu se v rušení podaří detekovat.

V dalším díle se podíváme jak zjistit stav tlačítka
Zdrojové kódy ze všech lekcí jsou dostupné na https://csharpduino.codeplex.com/
Budu rád za každý komentář a konstruktivní kritiku.

pátek 5. července 2013

Lekce 4. Jak zjistit stav tlačítka?

V této lekci Vám ukážu, jak jednoduše zjistit stav tlačítka a reagovat jeho stisknutí. NetDuino Plus má na své desce jedno tlačítko, které můžeme pro tuto lekci využít. Ve výchozím nastavení toto tlačítko slouží jako Reset. Pokud ale v programu deklarujeme vstupní port pro pin s názvem Pins.ONBOARD_SW1, přestane tlačítko restartovat NetDuino a začne nám vracet jeho stav. Stav tlačítka zjistíme pomocí metody Read().


Inicializace vstupního portu:
Při inicializaci zadáme jako první parametr číslo pinu tlačítka, které je přímo na desce NetDuino Plus s názvem Pins.ONBOARD_SW1.
Jako další parametr je takzvaný GlitchFilter. K jeho vysvětlení se dostaneme v některé z dalších lekcí. Prozatím budeme používat hodnotu false. No a jako poslední je parametr ResistorMode. U tohoto parametru se trošku zastavím protože při jeho použití se můžete trošku zamotat jako já.
Tento parametr je totiž možné nastavovat hodnotami ze dvou namespace a to:
using Microsoft.SPOT.Hardware;
a nebo
using SecretLabs.NETMF.Hardware.NetduinoPlus;

Pokud totiž použijete výčtový typ z namespace Microsoftu, tak budete mít k dispozici enumerátor Port.ResistorMode který má tři možnosti:
  1. Disable
  2. PullUp
  3. PullDown
Naopak enumerátor ResistorModes.PullUp  z namespace NetduinoPlus má pouze dvě hodnoty.
  1. Disable
  2. PullUp
private static readonly InputPort Btn = new InputPort(Pins.ONBOARD_SW1, false, ResistorModes.Disabled);

Pokud se pokusíte deklarovat port v modu PullDown tak při spouštění programu dostanete výjimku System.ArgumentException.
Pull-Up - znamená, že vstupní pin je přes rezistor připojen na Log1 a stisknutím tlačítka se dostává do Log0. Protože je to naopak něž bychom očekávali (při stisku tlačítka je na vstupu LOG1) je toto nastavení invertující.
Pull-Down - je opačná varianta k Pull-Up. Vstupní pin je přes rezistor stažen na Log0 a stisknutím tlačítka se dostává do Log1. Toto nastavení je tedy neinvertující

MikroProcesor má nejspíše natvrdo zapojen odpor ke kladnému napětí a druhá varianta (PullDown) není tedy možná. Toto zapojení se používá k omezení šumu na vstupu kdy hodnota není ani v LOG1 ani v LOG0 a celý obvod se tak může chovat nepředvídatelně.

Podrobnější vysvětlení naleznete v tomto videu http://www.youtube.com/watch?v=BxA7qwmY9mg [EN]

Video:

Zdrojový kód:
namespace Lekce04
{
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoPlus;

    public class Program
    {
        private static readonly InputPort Btn = new InputPort(Pins.ONBOARD_SW1, false, ResistorModes.Disabled);

        private static readonly OutputPort Led = new OutputPort(Pins.ONBOARD_LED, false);

        public static void Main()
        {
            while (true)
            {
                Led.Write(Btn.Read());
            }
        }
    }
}
V dalším díle se podíváme jak fungují přerušení.
Zdrojové kódy ze všech lekcí jsou dostupné na https://csharpduino.codeplex.com/
Budu rád za každý komentář a konstruktivní kritiku.

neděle 23. června 2013

Lekce 3. Světelný had neboli běžící světlo


Dneska si ukážeme jak pomocí LED diod vytvořit běžící světlo. Pro začátek vytvoříme pole výstupních portů LedBar, nad kterými budeme provádět v cyklu změny hodnot a tím zhasínat a rozsvěcet jednotlivé ledky. Toto pole inicializujeme v metodě Init a do každé jeho buňky vytvoříme novou instanci výstupního portu. Jako parametr použijeme jednu z hodnot pole PinList, která obsahuje názvy jednotlivých pinů, ke kterým jsme ledky připojily. Na ukázku zde uvádím dvě metody WormMove a KnightRider.

WormMove posouvá rozsvícenou Led diodu zleva doprava a jakmile narazí na konec, tak začne od začátku. Metoda KnightRider na konci řady ledek otočí směr a posouvá světlo na druhou stranu. Zpoždění mezi jednotlivými změnami je možné nastavit konstantou Speed.

Zapojení:
Do nepájivého pole zapojíme osm super svítivých LED diod, tak aby jejich katoda byla zapojena do minusové lišty. Anody propojíme s NetDuinem a každou zapojíme do jednoho digitálního výstupu od D6 po D13. Nakonec propojíme zem s minusovou napájecí lištou nepájivého pole.
Sestavení tohoto zapojení Vám nezabere více než tři minuty.

Video:

Zdrojový kód:
namespace Lekce03
{
    using System;
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoPlus;

    public class Program
    {
        private const int Speed = 100;

        private static readonly Cpu.Pin[] PinList = new Cpu.Pin[]
            {
                Pins.GPIO_PIN_D13,
                Pins.GPIO_PIN_D12,
                Pins.GPIO_PIN_D11,
                Pins.GPIO_PIN_D10,

                Pins.GPIO_PIN_D9,
                Pins.GPIO_PIN_D8,
                Pins.GPIO_PIN_D7,
                Pins.GPIO_PIN_D6
            };

        private static readonly OutputPort[] LedBar = new OutputPort[8];

        private static DateTime nextStep;

        private static int idx = 0;

        private static bool direction = true;

        public static void Main()
        {
            Init();

            while (true)
            {
                WormMove();
                // KnightRider();
            }
        }

        private static void Init()
        {
            for (int n = 0; n < LedBar.Length; n++)
            {
                LedBar[n] = new OutputPort(PinList[n], false);
            }
            nextStep = DateTime.Now;
        }

        private static void KnightRider()
        {
            if (nextStep < DateTime.Now)
            {
                if (direction)
                {
                    LedBar[idx].Write(false);
                    idx++;
                    LedBar[idx].Write(true);
                }
                else
                {
                    LedBar[idx].Write(false);
                    idx--;
                    LedBar[idx].Write(true);
                }

                idx = idx % LedBar.Length;
                if (idx == 0 || idx == LedBar.Length - 1)
                {
                    direction = !direction;
                }

                nextStep = DateTime.Now.AddMilliseconds(Speed);
            }
        }

        private static void WormMove()
        {
            if (nextStep < DateTime.Now)
            {
                LedBar[idx].Write(false);
                idx++;
                idx = idx % LedBar.Length;
                LedBar[idx].Write(true);
                nextStep = DateTime.Now.AddMilliseconds(Speed);
            }
        }
    }
}
V dalším díle se podíváme jak zjistit stav tlačítka.
Zdrojové kódy ze všech lekcí jsou dostupné na https://csharpduino.codeplex.com/
Budu rád za každý komentář a konstruktivní kritiku.

pátek 14. června 2013

Lekce 2. Zapojení LED diody mimo desku a tři druhy zpoždění

V minulé lekci jsme si ukázali jak rozblikat LED diodu, která je na desce NetDuina. Jak připojit a rozblikat diodu, kterou připojíme k NetDuinu? To bude náplní této lekce.

Zapojení LED diod
NetDuino má 14 digitálních pinů na které můžeme zapisovat logické hodnoty, nebo číst jejich stav.
Můžeme jim tedy přiřazovat hodnotu Log 0 (0V), nebo Log 1 (3,3V).
V této ukázce budeme používat piny Pins.GPIO_PIN_D4 a Pins.GPIO_PIN_D5. LED diod je spousta druhů a typů. Mají různé velikosti a tvary. Mimo to ještě různé napětí a proud, které je rozsvítí. Dneska Vám představím dvě varianty jak diodu k NetDuinu připojit.
První z nich je obyčejná červená LED dioda, která k rozsvícení potřebuje napětí 2V. Pokud bychom ji připojili na výstupní port, který má napětí 3,3V, dioda by to přežila, ale nedělalo by jí to dobře. Proto se do série k ní zapojuje předřadný odpor, který zajistí aby se dioda cítila pohodlně. Velikost tohoto odporu spočítáme podle Ohmova zákonu a parametrů, které zjistíme v katalogu k naší diodě.
Druhý způsob je vhodný pro tak zvané "super svítivé diody", ty mají napájecí napětí 3,2V jako např. tato modrá. Ta tedy nepotřebuje žádný předřadný odpor a je možné ji připojit na výstup přímo.
Důležitou informací při zapojování je polarita. Jelikož ledka není jen malá žárovka, ale polovodičová dioda, záleží na který vývod připojíme kladné napětí a kam záporné. Aby se to nepletlo a dobře pamatovalo, tak na Katodu nepřipojíme Kladné, ale Záporné napětí a na Anodu připojíme Kladné.

Zpoždění
No a teď bych chtěl ještě probrat několik variant jak zpozdit změnu stavu a tím způsobit blikání. Ve zdrojovém kódu ukazuji tři možnosti.
1. možnosti je nejpohodlnější a to je uspaní vlákna ve kterém se program vykonává na požadovanou dobu. Tato varianta má tu nevýhodu, že během čekání se nevykonává ani nic jiného. Což nám může vadit.
2. možností je nepoužít uspání vlákna, ale for cyklus. Ale výsledek je pořád stejný. Zatím co program běží v prázdném for cyklu, ostatní kód se neprovádí.
3. varianta je podle mě nejlepší. Změna stavu se provede pouze pokud je splněna podmínka že již uběhl čas kdy se má změna provést. To nám umožní v nekonečné smyčce provádět další smysluplný kód a ne jen čekat na zahřmění.

Podívejte se na výsledek této lekce v následujícím videu

Zdorjový kód
namespace Lekce02
{
    using System;
    using System.Threading;
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoPlus;

    public class Program
    {
        private static readonly OutputPort Led4 = new OutputPort(Pins.GPIO_PIN_D4,false);
        private static readonly OutputPort Led5 = new OutputPort(Pins.GPIO_PIN_D5, false);

        private static DateTime t = DateTime.Now;
        private static DateTime next = t.AddMilliseconds(500);

        public static void Main()
        {
            while (true)
            {
                // Blikej1();

                // Blikej2();

                Blikej3();
            }
        }

        private static void Blikej2()
        {
            SwapState();
            for (int i = 0; i < 20000; i++)
            {
            }
        }

        private static void Blikej1()
        {
            SwapState();
            Thread.Sleep(500);
        }

        private static void Blikej3()
        {
            if (DateTime.Now > next)
            {
                SwapState();
                next = DateTime.Now.AddMilliseconds(500);
            }
        }

        private static void SwapState()
        {
            Led4.Write(!Led4.Read());
            Led5.Write(!Led5.Read());
        }
    }
}


V dalším díle se podíváme jak rozblikat několik LED diod a ukážeme si pár efektů.

Zdrojové kódy ze všech lekcí jsou dostupné na https://csharpduino.codeplex.com/
Budu rád za každý komentář a konstruktivní kritiku.

Zdroje:
http://www.casemodding.wu.cz/view.php?cisloclanku=2007020002
http://zajimavebastleni.sweb.cz/ledky.html

čtvrtek 13. června 2013

Lekce 1. Blikání LEDkou na desce [NetDuino Plus]

NedDuino Plus má na svojí desce několik LED diod. Jedna slouží jako kontrolka napájení, další tři ukazují stav ethernetového portu a poslední je dostupná pro vlastní použití.
Aby bylo možné s LEDkou pracovat nejprve si pro ni musíme inicializovat výstupní port. To uděláme pomocí třídy OutputPort, které předáme název pinu a výchozí hodnotu. V našem případě to bude OnBoard_Led a výchozí stav bude false - nesvítí.
Aby se nám LEDka rozblikala je potřeba na výstupní port posílat střídavě Log0 a Log1 v nekonečné smyčce. Toho nejjednodušeji dosáhneme tak, že budeme její hodnotu invertovat. Protože má ale procesor kmitočet 48MHz, tak musíme přidáme do smyčky ještě zpoždění, aby bylo blikání vůbec vidět. Hodnota zpoždění je v milisekundách a proto jedné vteřině pak odpovídá hodnota 1000 ms.

Na výsledek se můžete podívat na tomto videu:


Zdrojový kód:
namespace Lekce01
{
    using System.Threading;
    using Microsoft.SPOT.Hardware;
    using SecretLabs.NETMF.Hardware.NetduinoPlus;

    public class Program
    {
        private static readonly OutputPort LedPin = new OutputPort(Pins.ONBOARD_LED, false);

        public static void Main()
        {
            while (true)
            {
                LedPin.Write(!LedPin.Read());
                Thread.Sleep(1000);     
            }
        }
    }
}

V dalším díle se podíváme na zapojení Ledky mimo desku a na několik způsobů zpoždění blikání.

Zdrojové kódy ze všech lekcí jsou dostupné na https://csharpduino.codeplex.com/
Budu rád za každý komentář a konstruktivní kritiku. S psaním blogu a točením videí teprve začínám, tak to asi hned od začátku na Oskara nebude.

Co je to NetDuino Plus vlastně zač?

S čím si vlastně si budeme hrát? Na začátek je potřeba trošku popsat co nám vlastně leží na stole. Netduino  Plus je vybaveno 32-bitovým  ARM7 procesorem od firmy Atmel o výkonu 48MHz. Pro uložení zdrojového kódu je k dispozici 64KB a pro data 42KB. Pokud nepotřebujete komunikovat po síti, tak čísla vzrostou na 128KB pro kód a 60KB pro data.
Můj první počítač byl 486SX o výkonu 25MHz. Myslím, že měl 4MB operační paměti a 250MB HDD. První co jsem na něm naprogramoval myslím byla ještě v Q-Basicu, pomocí příkazu Play, písnička "Skákal pes".

NetDuino Plus

Napájení: 7,5-12V
Kmitočet: 48MHz

Konektory, piny a ostatní věcičky na desce
1x Konektor napájení
1x Micro USB
1x RJ-45
5x LED
14x Digitální vstup/výstupní piny
6x Analogové vstup výstupní piny
4x PWM (Pluzně šířková modulace) jsou započítány do digitálních
2x Sériová linka - podobně jako PWM nám překrývá digitální piny
1x Micro SD
1x Tlačítko Reset

Rozšiřitelnost pomocí Shieldů
Pomocí tzv. shieldů se dá NetDuino rozšířit o další periferie mezi které patří např. Robot Shield, shield pro ovládání servomotorů atd. NetDuino je svým rozmístěním pinů kompatibilní s Arduinem. Proto je možné používat stejné shieldy.
Rozdíl meti NetDuinem a Arduinem je hlavně v tom že NetDuino má již v základu na sobě konektor pro připojení do počítačové sítě. K Arduinu by jste si museli dokoupit NetworkShield.


pátek 7. června 2013

Začínáme ...

V prosinci roku 2011 jsem navštívil kurz Roboti na zavolanou od Microsoftu a Hobby robot. Dostal se mi zde do rukou kus hardwaru NetDuino Plus. Na internetu je možné najít spoustu videí, ukázek zdrojového kódu, ale velká část videí je v angličtině a zdrojový kód v programovacím jazyce arduina http://www.arduino.cc/en/Reference/HomePage. Abych měl kde si dělat poznámky, založit jsem si tento blog. Postupně tady budou přibývat články o tom jak jsem začal programovat v .NET C# Micro Frameworku. V plánu mám napsat přes 30 článků, které by měli postupně vést k vytvoření komplexního projektu.

Všechny zdrojové kódy naleznete na CodePlexu C# Duino

Zdroje: