IoT Para Desenvolvedores C# com dotnet/iot

Este post faz parte da série Novidades do .NET Core 3

O .NET Core 3 foi lançado no dia 23/09/2019, com novidades para o mundo dos sistemas Embarcados e IoT. Como vimos no artigo anterior agora temos suporte a ARMv8 64 bits, onde demonstramos o deploy de um “Hello World” utilizando .NET Core e C# em uma placa com processador i.MX8QXP.

Nesse artigo vamos demonstrar a segunda novidade deste lançamento, as interfaces para acesso a GPIO do .NET Core 3, que eu tive o prazer de contribuir para o projeto open source do GitHub da .NET Foundation (fico devendo um artigo sobre os aspectos técnicos destas contribuições aqui no Embarcados).

Bibliotecas .NET Core IoT

O .NET Core pode ser usado para criar aplicativos para dispositivos IoT Linux Embarcado. É normal que aplicativos de IoT interajam com sensores, monitores e dispositivos de entrada que exigem o uso de GPIO (General Purpose Input Output), portas seriais ou hardware semelhante.

Para facilitar acesso e padronizar uma API a essas interfaces, utilizando .NET Core, que foi criado o projeto dotnet/iot, dentro do grupo da .NET Foundation que dá suporte ao projeto open source do .NET Core. Esse projeto implementa a System.Device.Gpio library que tem as interfaces para acesso a GPIO, PWM, I2C e SPI. 

A comunidade do projeto dotnet/iot ainda foi além e desenvolveu também a biblioteca IoT.Device.Bindings, que utiliza a API do System.Device.Gpio para fornecer abstrações, drivers, e classes prontas para controle de sensores e dispositivos populares.

Hardware para Demonstrações – Apalis iMX8QM

No artigo anterior eu utilizei um Toradex Colibri iMX8QXP ARMv8 64 bits quad core 4x Cortex-A35. Neste artigo eu estou com um monstro mais poderoso ainda: o Apalis iMX8QM, que foi lançado oficialmente pela Toradex nesta última terça feira 08/10/2019. Um ARMv8 64 bits HEXA core com 2x Cortex-A75, 4x Cortex-A53, 4 GB de RAM (SIM eu falei 4 GB RAM) e 16 GB eMMC.

 A Toradex foi uma das seletas parceiras da NXP com acesso antecipado ao i.MX8QM para desenvolvimento do System on Module Apalis iMX8QM e do ecossistema de software, junto a seus parceiros e clientes. Estou com um monstro desses em mãos, para testes, e foi ele que utilizei nas demonstrações deste artigo.

System.Device.Gpio – Demonstração

Qual a melhor forma de exemplificar a utilização de uma API de GPIO? Ahh, o bom e velho LED blink, o Hello World dos sistemas embarcados.

Vamos primeiramente criar, em um computador de desenvolvimento, nosso projeto com o comando:

dotnet new console

Lembrando que estamos utilizando o novo .NET Core 3. No comando acima o .NET SDK vai criar nosso projeto com o nome da pasta de onde executamos o comando. No meu caso minha pasta tem o nome demo2, logo meu projeto vai ser configurado com o nome demo2.

Para utilizar a biblioteca System.Device.Gpio temos que adicionar seu pacote NuGet ao projeto. Execute o seguinte comando para adicionar o pacote NuGet do dotnet/iot:

dotnet add package System.Device.Gpio --version 1.0.0
dotnet restore

Agora podemos, enfim, escrever o código C# do Blink:

using System;
using System.Threading;
using System.Device.Gpio;

namespace demo2
{
    class Program
    {
        static void Main(string[] args)
        {
            // GpioController set bank 0 as default
            GpioController controller = new GpioController();
            // GPIO bank 0 line 12
            int GPIO0_IO12 = 12;

            // say hello
            Console.WriteLine("Blinking on Apalis iMX8QM with .NET Core 3");

            // set pin mode to output
            controller.OpenPin(GPIO0_IO12, PinMode.Output);

            // blink forever
            while(true)
            {
                Console.WriteLine("Blink");
                controller.Write(GPIO0_IO12, PinValue.High);
                Thread.Sleep(500);
                controller.Write(GPIO0_IO12, PinValue.Low);
                Thread.Sleep(500);
            }
        }
    }
}

Note a linha 14, onde estamos construindo um objeto GpioController que terá os comandos de interface para controlar nossos pinos de entrada e saída. Na linha 20 usamos o método OpenPin para configurar nosso pino, onde teremos conectado um LED, para output, esse método é muito importante pois todos os outros métodos do controller só serão executados em um pino anteriormente configurado. E por fim nas linhas 25 e 27, dentro da nossa estrutura de repetição, utilizamos o método Write que vai setar o nível lógico do pino que foi configurado como output.

Para realizar o deploy para a arquitetura do nosso sistema embarcado vou utilizar o mesmo comando do artigo passado, mas com um adendo:

dotnet publish -r linux-arm64 --self-contained true /p:PublishSingleFile=true

Outra novidade do .NET Core 3 é que agora temos a opção de publicar um projeto como sendo um único arquivo executável, que é a função desse último argumento /p:PublishSingleFile=true. Agora ao invés de ser gerada uma pasta /publish com todas as dependências, vários .dll e .so, teremos apenas dois arquivos:

Assim, copiando apenas esse executável gerado, já teremos todo nosso projeto pronto para ser executado no nosso sistema embarcado:

scp bin/Debug/netcoreapp3.0/linux-arm64/publish/demo2 torizon@10.42.0.22:/home/torizon

Acessando o bash da placa, via ssh, podemos então executar o programa .NET Core 3 IoT:

Lembrando que no caso de acesso ao hardware, GPIO nesse caso, precisamos executar com privilégios de super usuário. Nesse momento, se tudo deu certo, teremos um LED piscando conectado à porta GPIO0_IO12 do nosso Apalis iMX8QM.

IoT.Device.Bindings – Demonstração

Para demonstração das bibliotecas do IoT.Devices.Bindings vou utilizar um sensor de temperatura muito popular: o onipresente DHT11.

Para utilizar o IoT.Devices.Bindings em nosso projeto temos que primeiramente adicionar o pacote NuGet:

dotnet add package Iot.Device.Bindings --version 1.0.0

O DHT11 já tem uma implementação pronta para uso, então podemos utilizar o sensor facilmente:

using System;
using System.Threading;
using Iot.Device.DHTxx;
using Iot.Units;

namespace demo3
{
    class Program
    {
        static void Main(string[] args)
        {
            // GPIO bank 0 line 12
            int GPIO0_IO12 = 12;
            
            // say hello
            Console.WriteLine("DHT11 on Apalis iMX8QM with .NET Core 3");

            // use the Dht11 class
            using (Dht11 sensor = new Dht11(GPIO0_IO12))
            {
                while (true)
                {
                    // easy device controll
                    Temperature temp = sensor.Temperature;
                    double humidity = sensor.Humidity;

                    if (sensor.IsLastReadSuccessful)
                    {
                        Console.WriteLine($"Temperature :: {temp.Celsius}");
                        Console.WriteLine($"Humidity :: {humidity}");
                        Console.WriteLine("----------------------------------");
                    }

                    // wait 1 second to the next read
                    Thread.Sleep(1000);
                }
            }
        }
    }
}

Note como simplesmente instanciamos um objeto do tipo Dht11, linha 19, referenciando o pino de dados conectado à placa e ao sensor e pronto. Podemos então requisitar a temperatura, linha 24, e a umidade do sensor, linha 25. O objeto vai realizar as chamadas e controles necessários, por debaixo dos panos utilizando as APIs do System.Device.Gpio, para entregar esses dados de forma fácil.

Deploy – DHT11

Executando os mesmos comandos do deploy da demonstração do LED Blink dentro da pasta do projeto:

dotnet publish -r linux-arm64 --self-contained true /p:PublishSingleFile=true

Copiando o executável único gerado via ssh:

scp bin/Debug/netcoreapp3.0/linux-arm64/publish/demo3 torizon@10.42.0.22:/home/torizon

E pronto, teremos as leituras do DHT11 sendo apresentadas no bash da placa:

Confira o vídeo onde demonstro a utilização e programação descritas nesse artigo na prática:

Conclusões

Legal como o System.Device.Gpio tem uma API bem simples, algo bem parecido com as chamadas do Arduino por exemplo, para você programar dispositivos com linguagem C# e o .NET Core 3.0. 

As implementações do IoT.Device.Bindings facilitam e agilizam muito o desenvolvimento de aplicações IoT, com uma extensa lista de dispositivos e sensores disponíveis. Você pode acompanhar todos dispositivos no Github do projeto: https://github.com/dotnet/iot/tree/master/src/devices

Lembrando que o .NET Core e o .NET IoT são projetos da Microsoft totalmente open source. Ou seja, como eu contribuí, você também pode contribuir! A comunidade é um grande adjuvante na inclusão e suporte de vários dispositivos para o projeto. 

Novidades do .NET Core 3

Novidades do .NET Core 3 para IoT e Sistemas Embarcados
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Linux Embarcado » IoT Para Desenvolvedores C# com dotnet/iot

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: