U-BLOX NINA W106 SENDO PROGRAMADO .NET nanoFramework - modo LOW ENERGY
Testado no VISUAL STUDIO 2015 e 2019
O objetivo deste BLOG (BETA) é demonstrar como é possível utilizar o .NET nanoFramework para programar o módulo U-BLOX NINA W106 o qual é baseado no Core ESP32. Foi utilizado o EVK-NINA-W1 para o teste e exemplo consiste em colocar o u-BLOX no modo LOW ENERGY para que tenha um baixo consumo de Bateria.
Tradução do Blog de Laurent Ellerbach e portabilidade para u-BLOX NINA W106.
Hoje, gostaria de mostrar como o DOTNET pode executar seu próprio aplicativo .NET em uma unidade de microcontrolador (MCU) em uma bateria simples por vários anos. Construirei um aplicativo que fará a leitura de temperatura e pressão em um sensor BMP280 conectado a um u-BLOX W106. A ideia central é ser executado em um pequeno painel solar carregando uma bateria LiPo.
Eu sou Laurent Ellerbach. Sou Gerente de Engenheiro de Software Principal da Microsoft trabalhando para a equipe de Engenharia de Software Comercial. Minha equipe e eu estamos fazendo co-engenharia com nossos maiores clientes, ajudando-os em sua transformação digital e focando no Azure. Estou mais focado na indústria de manufatura e estou envolvido em IoT há muito tempo. Tenho contribuído para o .NET IoT e rapidamente me tornei um dos principais contribuidores, o que me levou a trabalhar muito de perto com a equipe do .NET. Como fã de C# desde o primeiro dia, estou sempre procurando maneiras divertidas e inovadoras de usá-lo o máximo que posso. Eu estava animado para descobrir o .NET nanoFramework e estou trabalhando na ponte entre o .NET IoT e o .NET nanoFramework para tornar mais fácil para um desenvolvedor C# usar um ou outro e reutilizar o máximo de código possível.
PS: testado no u-BLOX NINA W106
MCU, CPU, qual é a diferença?
Uma unidade de microcontrolador (MCU) é um processador pequeno, geralmente sinônimo de baixo consumo de energia e tamanho pequeno. Os modernos são baseados em ARM Cortex M, incorporando algumas centenas de kilobytes de RAM, flash pequeno e algumas centenas de milhões de cadência de clock de hertz. Em processadores pequenos como esses, você executa um sistema operacional muito simples chamado Real Time OS (RTOS) como o Azure RTOS . Esses RTOS fornecem encadeamento, mensagens e sincronização entre encadeamentos, capacidade de rede mínima e você precisa construir seus aplicativos em cima, tradicionalmente usando C/C++. Existe uma implementação especial do .NET para esses MCUs, chamada .NET nanoFramework .
Uma Unidade Central de Processamento (CPU) é um processador maior, nesta categoria, você encontrará todos os tradicionais x86, x64, mas também outros processadores ARM como o usado no Raspberry Pi. Essas são as famílias que executam sistemas operacionais “reais”, como Windows, Linux ou macOS. Nesse tipo de processador, você pode executar o .NET 5.0, por exemplo.
Uma das principais diferenças entre eles é o poder de computação que se traduz em consumo de energia. E, claro, no custo do chip; uma CPU é muito mais cara que um MCU. Os custos típicos do MCU variam de alguns centavos a alguns dólares. O custo da CPU é um fator de escala de pelo menos 10 ou 100.
Além disso, mesmo que você sinta que sua máquina baseada em CPU é rápida e seu sistema operacional preferido também, você pode não estar pensando em cenários como inicializar ou voltar do modo de suspensão, medir algo, enviar essas medições por uma rede e voltar ao modo de suspensão . Isso não é fácil com uma máquina baseada em CPU. Em um MCU, entrar em um estado de suspensão é fácil e, como o RTOS é muito leve, seu aplicativo pode ser instalado e executado muito, muito rapidamente. Em um MCU, você pode habilitar um modo de suspensão que colocará o processador em um estado que usa muito baixo consumo de energia. Imagine um animal como um ouriço durante o inverno, é quase a mesma coisa. Tudo será colocado em um modo de baixo consumo, onde todos os elementos não vitais serão totalmente desligados. O consumo cairá para alguns mili- ou micro-Amperes (µA).
Em uma CPU, isso não é totalmente possível. Você pode, na arquitetura moderna, ajustar a frequência da CPU, e também existem modos de suspensão, que são apenas sono leve. Portanto, uma CPU sempre estará ativa ou em modo de economia de energia, onde ainda consumirá bastante energia. Essa é a razão pela qual, em todos os hardwares ou fornecedores, baseados em CPU, depois de algum tempo em um sono leve, o sistema entra em hibernação, que é basicamente descartar os estados e a memória do disco rígido e interromper a CPU. Você experimentou o tempo para acordar de ambos os modos, mesmo quando sente que é rápido, ainda está demorando uma quantidade significativa de tempo, pelo menos vários segundos.
No mundo MCU, existe a possibilidade de apenas dormir ou ir para um modo de suspensão profunda (deep sleept), reduzindo ainda mais o consumo de energia. Você pode se perguntar: o que pode acordar o MCU? Depende do MCU. Uma das situações mais comuns é baseada em um temporizador. Tecnicamente falando, tudo será desligado, exceto um pequeno cristal de relógio e um cronômetro. Esses elementos consomem apenas alguns micro-Amperes, o que significa que a unidade pode funcionar com uma bateria por anos ou décadas. Quando o tempo de despertar é alcançado, o MCU desperta, executa a seqüência de inicialização e começa a executar seu programa.
Existem outras maneiras de despertá-lo, assim como na vida real! O balde de água fria ou alguém sacudindo você também é possível. Este é chamado de interrupção. No mundo MCU, isso significará uma mudança de estado em um pino de entrada/saída de uso geral (GPIO). Resumindo, algo aconteceu. Você pressionou um botão ou tocou em uma tela alterando o estado do GPIO. Este modo consome um pouco mais de energia do que o anterior, ainda assim, o processador está profundamente adormecido e, novamente, apenas alguns micro-Amperes são consumidos.
O .NET nanoFramework aborda o mundo do MCU e oferece suporte a esse mecanismo de suspensão para todas as arquiteturas suportadas. Isso permite que os cenários tenham código .NET rodando por anos com uma única bateria, como explicarei mais adiante,
O que mais nos interessa neste mundo de IoT é medir um elemento de tempos em tempos, enviar esses dados pelo ar ou por cabo e esperar o próximo período para medi-los novamente. Este é o cenário mais comum no mundo da IoT. Você quer consumir o mínimo possível; você deseja trocar as baterias com a menor frequência possível e ainda deseja que o dispositivo diga que está ativo de tempos em tempos.
Experimente você mesmo: usando um painel solar e uma bateria LiPo
Para experimentar esse comportamento, você precisará usar um dos MCUs com suporte para .NET nanoFramework. Aqui, vou usar apenas um ESP32 barato e popular. Eu tenho este código implantado em um jardim. Ele está se conectando ao meu Wi-Fi, conectando-se ao Hub IoT do Azure, obtendo configurações, publicando seu estado, medindo temperatura e pressão, postando esses dados no Hub IoT do Azure e voltando a dormir. Para completar esta sequência de operações requer apenas alguns segundos. O código está disponível no repositório GitHub de amostra nanoFramework . O esquema é o seguinte:
O .NET nanoFramework tem uma Extensão do Visual Studio que você precisa instalar. Você também precisa fazer o flash do seu dispositivo . Então você pode depurar seu código C# como você faz com qualquer aplicativo .NET! Você também pode se conectar a uma rede Wi-Fi ou com fio. Os auxiliares facilitam sua vida e tudo o que você precisa está em um pacote nanoFramework NuGet. A primeira parte do código se conecta ao Wi-Fi, solicita ou renova um endereço IP:
// As we are using TLS, we need a valid date & time
// We will wait maximum 1 minute to get connected and have a valid date
CancellationTokenSource cs = new(sleepTimeMinutes);
var success = NetworkHelper.ConnectWifiDhcp(Ssid, Password, setDateTime: true, token: cs.Token);
if (!success)
{
Trace($"Can't connect to wifi: {NetworkHelper.ConnectionError.Error}");
if (NetworkHelper.ConnectionError.Exception != null)
{
Trace($"NetworkHelper.ConnectionError.Exception");
}
GoToSleep();
}
Com o código anterior, estamos armazenando o SSID e a senha no código, o que você pode argumentar que não é seguro. Também é possível armazená-lo diretamente no dispositivo e apenas chamar um auxiliar que irá conectar sem especificar nada no código.
A segunda parte do código é a conexão com o Azure IoT. Não vou me aprofundar nos detalhes. Estamos usando o MQTT para se conectar ao Azure IoT, com uma chave simétrica.
const string DeviceID = "nanoDeepSleep";
const string IotBrokerAddress = "yourIoTHub.azure-devices.net";
const string SasKey = "alongsastoken";
// nanoFramework socket implementation requires a valid root CA to authenticate with.
// This can be supplied to the caller (as it's doing on the code bellow) or the Root CA has to be stored in the certificate store
// Root CA for Azure from here: https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/certs.c
// We are storing this certificate as an application resource
X509Certificate azureRootCACert = new X509Certificate(Resources.GetBytes(Resources.BinaryResources.AzureCAcertificate));
// Creates MQTT Client with default port 8883 using TLS protocol
MqttClient mqttc = new MqttClient(
IotBrokerAddress,
8883,
true,
azureRootCACert,
null,
MqttSslProtocols.TLSv1_2);
// Handler for received messages on the subscribed topics
mqttc.MqttMsgPublishReceived += ClientMqttMsgReceived;
// Handler for publisher
mqttc.MqttMsgPublished += ClientMqttMsgPublished;
// Now connect the device
byte code = mqttc.Connect(
DeviceID,
$"{IotBrokerAddress}/{DeviceID}/api-version=2020-09-30",
GetSharedAccessSignature(null, SasKey, $"{IotBrokerAddress}/devices/{DeviceID}", new TimeSpan(24, 0, 0)),
false,
MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE,
false, "$iothub/twin/GET/?$rid=999",
"Disconnected",
false,
60
);
//If we are connected, we can move forward
if (mqttc.IsConnected)
{
mqttc.Subscribe(
new[] {
$"devices/{DeviceID}/messages/devicebound/#",
"$iothub/twin/res/#"
},
new[] {
MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE,
MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE
}
);
//Rest of the code here
}
A primeira coisa que você notará é que o .NET nanoFramework fornece tudo o que é necessário para se conectar a qualquer agente MQTT, incluindo o Hub IoT do Azure. Assim como para o restante dos elementos, a biblioteca MQTT é instalada com um pacote NuGet . Esta biblioteca MQTT é uma porta de M2Mqtt em .NET nanoFramework.
O certificado raiz do Azure é necessário para validar a identidade do ponto de extremidade ao qual estamos nos conectando. Ele é armazenado nos recursos de código. O .NET nanoFramework também oferece um conceito de recursos de aplicativos.
Estamos registrando eventos. Aqui, estaremos interessados nas mensagens que podemos receber e na confirmação de que essas mensagens foram recebidas pelo Azure IoT. Há mais eventos nos quais você pode se inscrever. Isso é feito em duas etapas, a primeira com a classe MQTT e a segunda com o protocolo.
Para conectar o próprio dispositivo, é necessária uma assinatura de acesso compartilhado. Este cálculo é feito com o ajudante de classe que permite criar usando um cálculo HMACSHA256. A maioria dos parâmetros é específica do protocolo MQTT e documentada na documentação do Hub IoT do Azure .
No futuro, estamos solicitando o DEVICE TWIN para este dispositivo. Um gêmeo é um conceito que está criando propriedades desejadas e propriedades relatadas. Veja isso como uma configuração desejada e relatada para o dispositivo. Cabe a você definir o que deseja configurar.
Vamos solicitá-los e esperar para recebê-los. Como sempre, estamos usando um padrão com um tempo limite para garantir que, mesmo que não o recebamos, ele não impeça o código por muito tempo e continuemos com as próximas etapas.
mqttc.Publish($"{TwinDesiredPropertiesTopic}?$rid={Guid.NewGuid()}", Encoding.UTF8.GetBytes(""), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false);
CancellationTokenSource cstwins = new(10000);
CancellationToken tokentwins = cstwins.Token;
while (!twinReceived && !tokentwins.IsCancellationRequested)
{
tokentwins.WaitHandle.WaitOne(200, true);
}
À medida que nos inscrevemos no evento de mensagem, assim que o Twin for enviado, o evento será acionado e poderemos processá-lo:
void ClientMqttMsgReceived(object sender, MqttMsgPublishEventArgs e)
{
string message = Encoding.UTF8.GetString(e.Message, 0, e.Message.Length);
if (e.Topic.StartsWith("$iothub/twin/"))
{
if (message.Length > 0)
{
// skip if already received in this session
if (!twinReceived)
{
try
{
TwinProperties twin = (TwinProperties)JsonConvert.DeserializeObject(message, typeof(TwinProperties));
minutesToGoToSleep = twin.desired.TimeToSleep != 0 ? twin.desired.TimeToSleep : minutesToGoToSleep;
twinReceived = true;
}
catch
{
// We will ignore
}
}
}
}
}
}
O twin é codificado como uma mensagem de texto Json:
{"desired":{"TimeToSleep":5,"$version":2},"reported":{"Firmware":"nanoFramework","TimeToSleep":2,"$version":94}}
Um serializador e desserializador Json está disponível como um NuGet para .NET nanoFramework . Estou usando uma classe para desserializar o objeto. A TimeToSleep
propriedade descreve quantos minutos peço ao dispositivo para dormir. 5 neste caso representará 5 minutos. Isso me permite ajustar o comportamento do meu código sem precisar reimplantar meu código. Esse mecanismo é muito importante oferecido pelo Hub IoT do Azure.
Assim que os detalhes do gêmeo forem recebidos e processados ou, caso contrário, um tempo limite expirará, eu republico o gêmeo:
mqttc.Publish($"{TwinReportedPropertiesTopic}?$rid={Guid.NewGuid()}", Encoding.UTF8.GetBytes($"{{"Firmware":"nanoFramework","TimeToSleep":{minutesToGoToSleep}}}"), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false);
E não espero nenhuma confirmação neste caso, vou direto para a próxima etapa. Meu próximo passo é medir a temperatura e a pressão atmosférica usando um sensor BMP280. Este sensor é um sensor I2C, muito popular barato e fácil de encontrar.
Este sensor foi implementado em .NET IoT e portado para .NET nanoFramework . O .NET nanoFramework oferece uma grande biblioteca de sensores, baseada na mesma base de código . Como o .NET nanoFramework tem restrições, cada ligação foi dividida em cada NuGet. O código para essas associações pode ser encontrado no repositório nanoFramework.IoT.Device . O código teve que ser transformado para suportar o tipo de projeto específico do .NET nanoFramework e outras especificidades como transformar lista genérica ou span em não genéricos. Por causa das restrições de tamanho, por exemplo, os Enums têm uma implementação simplificada. IsDefined
ou GetValues
não estão disponíveis porque a descrição dos itens Enum foi removida para economizar armazenamento flash no MCU.
O código para ler o sensor é o seguinte:
// I2C bus 1 is using GPIO 18 and GPIO 19 on the ESP32
const int busId = 1;
I2cConnectionSettings i2cSettings = new(busId, Bmp280.DefaultI2cAddress);
I2cDevice i2cDevice = I2cDevice.Create(i2cSettings);
var i2CBmp280 = new Bmp280(i2cDevice);
// set higher sampling
i2CBmp280.TemperatureSampling = Sampling.LowPower;
i2CBmp280.PressureSampling = Sampling.UltraHighResolution;
var readResult = i2CBmp280.Read();
E seria exatamente o mesmo código em um Raspberry Pi executando o .NET 5.0 usando o pacote NuGet de vinculação de dispositivo .NET IoT .
Além disso, muito trabalho e esforços foram feitos para permitir um simples, consistente e direto para todas as ligações suportadas. Isso permite desenvolver soluções em .NET que são fáceis de reutilizar a partir da perspectiva de código e suporte em uma CPU e em um MCU.
Uma vez que a medida é feita, podemos publicar o resultado no Azure IoT:
//Publish telemetry data using AT LEAST ONCE QOS Level
messageID = mqttc.Publish(telemetryTopic, Encoding.UTF8.GetBytes($"{{"Temperature":{readResult.Temperature.DegreesCelsius},"Pressure":{readResult.Pressure.Hectopascals}}}"), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
// Wait for the message or cancel if waiting for too long
CancellationToken token = new CancellationTokenSource(5000).Token;
while (!messageReceived && !token.IsCancellationRequested)
{
token.WaitHandle.WaitOne(200, true);
}
GoToSleep();
Vamos esperar um pouco para receber a confirmação dos resultados publicados. Isso está acontecendo por meio de um dos eventos que assinamos.
void ClientMqttMsgPublished(object sender, MqttMsgPublishedEventArgs e)
{
if (e.MessageId == messageID)
{
messageReceived = true;
}
}
Como sempre, se não recebermos a confirmação em uma janela de tempo específica, continuaremos e dormiremos, não importa o quê. Não receber a confirmação não significa necessariamente que ela não foi publicada e que não chegou. Em uma rede lenta, obter a confirmação pode demorar um pouco. Além disso, alguns eventos podem ser ignorados. E sem entrar em detalhes, é por isso que o protocolo MQTT possui um mecanismo de entrega adaptado a essas situações.
O método _GoToSleep_
começa configurando o mecanismo de ativação. MCUs têm muitos deles. Aqui, usaremos o temporizador:
void GoToSleep()
{
Sleep.EnableWakeupByTimer(new TimeSpan(0, 0, minutesToGoToSleep, 0));
Sleep.StartDeepSleep();
}
Observe que o tempo que o MCU permanecerá no modo de suspensão (em minutos) é determinado pela propriedade gêmea recebida do Hub IoT do Azure.
A classe Sleep
é específica para .NET nanoFramework e foi especialmente projetada para gerenciar os modos de suspensão em cada dispositivo. Apesar de ter uma API comum, a implementação de baixo nível é específica para cada MCU suportado. Alguns oferecem mais recursos do que outros. API estão alinhadas e se um modo, como o temporizador, estiver disponível em todos os MCUs, a API será exatamente a mesma.
Em cerca de 100 linhas de código .NET e poucas horas de esforço, você pode se conectar a uma rede Wi-Fi, conectar-se ao Hub IoT do Azure, obter as propriedades gêmeas, relatá-las, medir um sensor, relatar a medição ao Hub IoT do Azure e, em seguida, entre no modo de suspensão profunda, diminuindo o consumo de energia de um MCU! O .NET nanoFramework NuGet e os auxiliares de código existentes facilitam isso.
Duração da execução do código
Agora vamos ver mais dados durante a execução do código.
O código de exemplo usa Microsoft.Extensions.Logging
para log. O .NET nanoFrameworks segue os padrões de log usados no .NET 5.0 framework e é compatível com a implementação no .NET IoT. Vamos usá-lo aqui para poder rastrear o que está acontecendo quando o código está em execução.
O código .NET nanoFramework pode ser depurado usando o depurador do Visual Studio. Portanto, quando você estiver na fase de desenvolvimento, poderá, é claro, iniciar uma sessão de depuração e fazer o que está acostumado a fazer ao depurar qualquer aplicativo .NET C#. Agora, quando o dispositivo vai dormir, ele perde o contexto de depuração e quando ele vai acordar, você não poderá voltar a ele.
Assim, para esta fase e para medir como tudo está funcionando, um mecanismo de log externo pode ser usado. Usaremos uma porta serial, plugada na máquina. Uma ferramenta como Putty ou qualquer outro leitor serial funcionará perfeitamente para capturar os dados.
O código para colocar isso em prática é o seguinte:
// Use Trace to show messages in serial COM2 as debug won't work when the device will wake up from deep sleep
// Set the GPIO 16 and 17 for the serial port COM2
Configuration.SetPinFunction(16, DeviceFunction.COM2_RX);
Configuration.SetPinFunction(17, DeviceFunction.COM2_TX);
SerialPort serial = new("COM2");
serial.BaudRate = 115200;
logger = new SerialLogger(ref serial, "My logger");
logger.MinLogLevel = LogLevel.Debug;
Trace("Program Started, connecting to WiFi.");
void Trace(string message)
{
logger?.LogDebug(message);
}
Coloquei chamadas de rastreamento abundantes em todo o código, então o resultado é bastante detalhado. E aqui está um exemplo do rastreamento que vejo:
Program Started, connecting to WiFi.
Date and time is now 06/09/2021 12:45:33
subscribing to topics
Getting twin properties
Response from publish with message id: 2
Message received on topic: $iothub/twin/res/200/?$rid=be27fc48-85bb-455e-3585-6ff363d09002
and message length: 115
and was in the success queue.
New sleep time to sleep received: 30
Sending twin properties
Message received on topic: $iothub/twin/res/200/?$rid=be27fc48-85bb-455e-3585-6ff363d09002
and message length: 115
and was in the success queue.
Temperature: 22.86265857°C
Pressure: 991.79647718hPa
Message received on topic: $iothub/twin/res/200/?$rid=be27fc48-85bb-455e-3585-6ff363d09002
and message length: 115
and was in the success queue.
Message ID for telemetry: 4
Response from publish with message id: 3
Message received on topic: $iothub/twin/res/204/?$rid=54f8f9a7-d190-48db-ba88-9ed4a47bc50b&$version=263
and message length: 0
and received confirmation for desired properties.
Response from publish with message id: 4
Full operation took: 00:00:07.3871120
Set wakeup by timer for 30 minutes to retry.
Deep sleep now
Primeiro, a operação completa levou apenas um pouco mais de 7 segundos, pois o tempo de inicialização de cerca de 1 segundo não está incluído no código gerenciado. Segundo, esses 7 segundos incluem obter os gêmeos do Azure, ajustá-los, relatá-los, medir o sensor, relatar a medição e receber a confirmação!
Terceiro, você pode ter dificuldade em seguir a lógica desses traços. E isso é esperado. O .NET nanoFramework funciona com vários threads. Quando eventos são gerados, como receber os gêmeos ou obter a confirmação de uma mensagem sendo postada, todos os outros threads continuam a ser executados.
Algo para refletir é que a execução da minha própria medição leva entre 3 e 10 segundos, com média em torno de 6 segundos.
O tempo total de execução pode ser melhorado removendo completamente o código de rastreamento que sai para a porta serial.
No lado do Azure, usando por exemplo o Azure IoT Explorer , você pode verificar se o dispositivo enviou a telemetria corretamente e se você recebeu tudo:
Consumo medido
O que realmente nos interessa aqui é a possibilidade de colocar o MCU em modo de hibernação profunda e medir seu consumo para comparar com o modo de execução normal.
Para isso, teremos que usar um amperímetro no fio da fonte de alimentação. Vamos medir quando o MCU está funcionando e quando está dormindo.
Ao rodar na inicialização, posso ver um pico de aproximadamente 250 mA que rapidamente desce para cerca de 140 mA.
Uma vez em sono profundo, são consumidos menos de 2 mA porque ainda tenho um pequeno led conectado que deve ser removido. As especificações indicam entre 10 e 150 µA neste modo. Portanto, mais do que um fator de 1000!
Se você pegar uma bateria de 2000 mAh e fazer contas simples com um consumo de sono profundo de 50 µA, poderá ficar com essa bateria por 40.000 horas, o que representa mais de 4 anos e meio. Leia a seção sobre os cenários de casos reais para entender que este é um cenário real e válido.
Agora supondo que eu vou rodar o tempo todo meu código conectando ao WiFi, ao Azure IoT, medindo, postando os dados, meu consumo será sempre em média cerca de 140 mA, você pode esperar trabalhar em bateria por mais de 14 horas sem descontinuidade . Isso representaria mais de 5.000 ciclos.
Considerando que a saúde da bateria é boa, e supondo que a temperatura seja constante junto com alguns outros elementos relacionados, eu seria capaz de executar minha medição 2 vezes por dia e ainda seria capaz de permanecer na mesma bateria por 2 anos e meio sem nenhum problema.
Para o meu próprio cenário, no meu jardim, usarei um painel solar simples, um carregador LiPo e uma bateria LiPo. Eles serão conectados a um ESP32. Este ESP32 terá uma temperatura BMP280 e sensor barométrico conectado. Meu ESP32 está localizado no jardim ainda ao alcance do Wi-Fi, mas longe de qualquer tomada elétrica. Posso generosamente fazer várias medições por hora, mesmo que o tempo não esteja particularmente ensolarado por vários dias, a bateria será grande o suficiente.
Microsoft .NET
“O Microsoft .NET é uma das melhores plataformas para construir ótimos aplicativos, e o .NET nanoFramework nos ofereceu os mesmos benefícios para o microcontrolador e todo o nosso hardware. O .NET nanoFramework e a equipe por trás dele criaram a mesma rica experiência de desenvolvimento que o irmão mais velho .NET Framework. Tê-lo também como open source, com uma grande comunidade, nos faz sentir confortáveis que nosso investimento tem futuro e não temos que depender de uma tecnologia proprietária, licenciamento e assim por diante.
Conclusão
O consumo de energia é um problema global. Como desenvolvedores, temos uma responsabilidade. A tecnologia que escolhemos tem um impacto e, na IoT, é ainda mais importante escolher uma tecnologia que consuma o mínimo de energia possível e ainda permita toda a produtividade que adoramos com o .NET.
Essa é a realidade executando código .NET em um MCU com consumo de energia extremamente baixo, mesmo em um cenário em que você precisa enviar dados para o Azure. A criação desses dispositivos, incluindo as placas de hardware, agora é uma questão de semanas ou meses em comparação com o uso de tecnologias tradicionais.
Como começo com o .NET nanoFramework?
Para começar com o .NET nanoFramework, o primeiro passo é obter um dos dispositivos suportados, como um ESP32, no caso o u-BLOX NINA W106, com 4Mb de Flash. Em seguida, você deve seguir o guia passo a passo para instalar a extensão do Visual Studio 2019, atualizar seu dispositivo, criar seu primeiro projeto e executá-lo.
Ter seu próprio código C# .NET em execução em um desses dispositivos incorporados é uma questão de minutos e muito simples.
Você precisa de sensores como o BMP280 para reproduzir o que tenho feito. Há um suporte muito grande em .NET IoT e .NET nanoFramework . Você pode usá-los da mesma maneira da CPU ou MCU!
Se alguma ajuda for necessária, a comunidade .NET nanoFramework é muito ativa e está usando os canais do Discord . Contribuições para melhorar o .NET nanoFramework em C nativo, C# e documentação são mais que bem-vindas. A página principal do .NET nanoFramework fornecerá todos os links necessários.
Referências:
Mais detalhes em www.smartcore.com.br
Nenhum comentário:
Postar um comentário