Netduino и VB – это круто… как показано в проекте мониторинга температуры

Грэг Дункан

Сегодняшнее пятничное аппаратное сообщение посвящено работающему примеру использования 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 говорит на вашем языке.

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