Грэг Дункан

Сегодняшнее пятничное аппаратное сообщение посвящено работающему примеру использования Visual Basic в проекте с Nenduino.

Мониторинг температуры с помощью VB.Net, Microframework и Netduino

...

Это произошло в тот момент, когда я увидел небольшое устройство, называемое Netduino, которое работало под управлением чего-то, называемого .Net Microframework. Это было именно то, что я искал. Микроконтроллер, который можно соединить с готовыми электронными блоками, продающимися в магазине, и написать .NET код на языке, который я выбрал (VB) для реализации основной функциональности.

Так что следующим вопросом стало, чему бы посвятить первый классный проект?

Моя жена учится на сомелье, а это означает, что у нас в доме всегда есть несколько бутылок вина. Иногда мы открываем одну, и оказывается, что оно испортилось. Есть множество причин, почему вино может испортиться, и неправильное хранение лишь одна из них. Вино крайне темпераментно и лучше всего его хранить в прохладном темном месте с постоянными условиями, которые не меняются в зависимости от сезона, вот почему погреба или пещеры так подходят для хранения, но, к сожалению, в современных домах пещеры или винные погреба не предусмотрены. Поэтому мы используем кладовую для хранения вина.

Имея это в виду, я захотел узнать, действительно ли условия кладовой существенно меняются. Итак, я получил проект, но с чего начать? Простой прибор для контроля винного погреба (или кладовой!!!) и выдающий предупреждения при слишком высокой или низкой температуре

...

Приложение должно выполнять ряд задач

  • Считывать информацию с датчиков
  • Записывать данные на SD-карту
  • Определять условия предупреждения по температуре
  • Обеспечивать наглядную индикацию работы и выдачи предупреждений
  • Обеспечивать возможность перезагрузки

Мой подход состоял в том, чтобы взять каждую задачу и создать изменяющуюся систему. Так что первым делом было подсоединить датчики и светодиоды. Использование макетной платы делает эту задачу действительно простой и сводящейся к созданию соединений с помощью проводов.

Конструкция следующая. Она выглядит слегка безумной в прототипе, но я приведу ее в порядок перед тем, как помещу в кладовую и получу обеспокоенную жену, которая придет рассказать мне о загадочном устройстве с проводами, появившемся в кладовке.

...

clip_image002

...

Чтение с датчиков

Код приложения – это простое консольное приложение, работающее в бесконечном цикле. Как только я подключу законченное устройство к 9-вольтовой батарее, я хочу, чтобы работа считалась завершенной, но также хочу быть уверен, что батареи хватит надолго. Поэтому я буду считывать данные каждые 10 мин, а это означает, что большую часть времени устройство спит.

Существуют аналоговые и цифровые температурные датчики. Мой датчик – простой термистор (резистор, чье сопротивление зависит от температуры). Используя аналоговые порты Netduino вместе с ним, можно измерять температуру. Существует две версии Netduino (Rev A и Rev B). Главным различием между ними является наличие опорного сигнала и необходимость дополнительного провода между выводом 3,3 В и выводом Aref0 – без него значения, прочитанные из аналогового порта будут неверными. К счастью, подавляющее большинство плат на рынке относятся к Rev B, в которой уже существует внутреннее соединение на плате, и об этом можно забыть.

Формула для вычисления температуры следующая…

Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
Imports SecretLabs.NETMF.Hardware.Netduino

Public Module Module1
Dim PollingDelay As Integer = 2
Dim tempSensor As New AnalogInput(Pins.GPIO_PIN_A5)
Dim CurrentTemperature As Double = 0

Public Sub Main()
Dim Temperature As Double = 0

'//Setup Event Handlers
PollingTemperatureMethod()

'//Get the initial temperature
CurrentTemperature = GetAverageTemperatureReading()
While True
Thread.Sleep(Timeout.Infinite)
End While
End Sub

Function GetCurrentTemperature() As Double
''Read the raw sensor value
Return tempSensor.Read()
End Function

'Get the average temperature of 101 readings over a second
Function GetAverageTemperatureReading() As Double
Dim totalTemp As Double
Dim averagetemp As Double = 0

For i = 0 To 99
totalTemp += GetCurrentTemperature()
Thread.Sleep(10)
Next
averagetemp = totalTemp / 100

Dim Kelvin As Double = (((averagetemp / 1023) * 3.3) * 100)
Dim Celsius As Double = (Kelvin - 273) - 17.8
Dim Fahrenheit = (Celsius) * (9 / 5) + 32

Debug.Print(WarningStatus.ToString & " " & averagetemp.ToString() & " " & Fahrenheit.ToString & " / " & Celsius.ToString & " ")

Return Celsius
End Function


Private PollingTimer As Timer

Private Sub PollingTemperatureMethod()
Dim PollingDelegate As New TimerCallback(AddressOf PollForTemperature)
PollingTimer = New Timer(PollingDelegate, Nothing, 1000, PollingDelay * 1000)
End Sub

Public Sub PollForTemperature(stateInfo As Object)
Module1.CurrentTemperature = GetAverageTemperatureReading()
End Sub

End Module

Определение условий генерации предупреждения

Мне бы хотелось, чтобы определялись условия возникновения предупреждений о слишком высокой и слишком низкой температуре, поскольку они обе могут вызывать проблемы при хранении вина. Во время разработки я хотел установить узкий интервал температур, который можно было бы легко переключать, но затем выбрал чтение этих параметров в приложение из файла на SD-карте, чтобы сделать процесс более гибким. Такое решение позволяет изменять настройки без необходимости перезагрузки приложения в контроллер. Задав эти максимальное и минимальное значения, я могу использовать их для определения того, выходят ли считанные датчиком значения из определенного диапазона, и если да, то включить один из светодиодных индикаторов, показывающих, что произошло событие выхода температуры за установленные пределы.

Dim HiWarningLED As New OutputPort(Pins.GPIO_PIN_D9, False)
Dim LowWarningLED As New OutputPort(Pins.GPIO_PIN_D11, False)

Public Enum LevelCheck
LowTemp
HiTemp
End Enum

Dim LowWarningStatus As Boolean = False
Dim WarningStatus As Boolean = False
Dim MinTemp As Single = 20
Dim MaxTemp As Single = 26

Function CheckTemperatureForWarning(Temp As Double, Optional Level As LevelCheck = LevelCheck.HiTemp) As Boolean
Dim WarnStateOccured As Boolean = False
If Level = LevelCheck.LowTemp Then
'Is Temperature Exceeding MaxTemp
If Temp <= MinTemp Then
Debug.Print("Low Warning Triggered")
Debug.Print("Temp: " & Temp.ToString)
Debug.Print("maxTemp: " & MaxTemp.ToString)
Debug.Print("minTemp: " & MinTemp.ToString)
WarnStateOccured = True
End If
ElseIf Level = LevelCheck.HiTemp Then
'Is Temperature Exceeding MaxTemp
If Temp >= MaxTemp Then
Debug.Print("Hi Warning Triggered")
Debug.Print("Temp: " & Temp.ToString)
Debug.Print("maxTemp: " & MaxTemp.ToString)
Debug.Print("minTemp: " & MinTemp.ToString)
WarnStateOccured = True
End If
End If
Return WarnStateOccured
End Function

Sub WarningStatusLight(State As Boolean, Optional Level As LevelCheck = LevelCheck.HiTemp)
'Code to turn on/off LED
If Level = LevelCheck.LowTemp Then LowWarningLED.Write(State)
If Level = LevelCheck.HiTemp Then HiWarningLED.Write(State)
End Sub

Public Sub PollForTemperature(stateInfo As Object)
Module1.CurrentTemperature = GetAverageTemperatureReading()

'If the warning status light is off and a warning temperature occurs then
'set Warning Light State to True and don't bother checking any more as the
'alarm condition has been met
If LowWarningStatus = False AndAlso CheckTemperatureForWarning(CurrentTemperature, LevelCheck.LowTemp) = True Then
LowWarningStatus = True
WarningStatusLight(LowWarningStatus, LevelCheck.LowTemp)
End If

If WarningStatus = False AndAlso CheckTemperatureForWarning(CurrentTemperature, LevelCheck.HiTemp) = True Then
WarningStatus = True
WarningStatusLight(WarningStatus, LevelCheck.HiTemp)
End If
End Sub

Заключение

Теперь у меня есть датчик с основной функциональностью, который можно использовать для определения температуры в моем винном погребке и который даст мне наглядное представление возникновение условий повреждения вина. Я описал создание схемы, чтение данных датчика, использование таймеров для опроса датчиков, включение/выключение светодиодов для индикации, взаимодействие с устройством с помощью кнопки и запись данных на карту MicroSD. Это основные функции, которые могут быть использованы снова во многих различных приложениях.

Основная идея заключается в том, что не так сложно начать работать с Netduino и если вы знаете C# или VB, .Net Micro Framework говорит на вашем языке.

Вот несколько ссылок, которые могут оказаться интересными: