Опрос


Что для Вас Умный Дом?


Результаты

Beckhoff. ADS-программирование

07/09/2011 12:23:01

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

Достичь этого не так сложно. Достаточно в программе завести свою логическую переменную для каждой лампочки, и написать программу в контроллере так, что если переменная = TRUE. то лампочка включена, а если FALSE - то выключена. Таким образом, если извне мы имеем возможность посмотреть, какое значение сейчас у конкретной переменной, то мы можем знать какие лампочки у нас включены, а если сможем извне поменять ее значение, то соотвественно можем включать - выключать лампочку.

Для общения с контроллером у BECKHOFF разработан специальный протокол обмена данными ADS на базе TCP/IP. Протокол открытый. Инструментарий для работы с этим протоколом предоставляется бесплатно в виде файлов библиотек и поддерживает DLL, OCX, VB Script, J Script, .NET, Java для Windows, а также есть open source проект для реализации этого протокола под Linux.

Для своего проекта я использую Visual Basic 2010 для программ и ASP для web страниц. Соотвественно использую компоненту для .NET для VB2100 и VBScript для ASP. Я буду приводить примеры на ASP и VBScript так как это более упрощенно и наглядно.

Набор базовых функций для общения с контроллером очень простой - они просто дают возможность читать и писать в память контроллера значения... Главное знать, за что каждый байт памяти отвечает.

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

Для этих задач у языка программирования контроллера МЭК есть возможность фиксированной адресации переменных. Работает в контроллере BC9000 это так - есть фиксированная область в памяти размером 4 кб. И при объявлении переменной мы можем четко указать, где именно в этой области будет хранится значение этой переменной. Выглядит это так:

    VAR_GLOBAL
       MyInt :INT; (* Обычная целочисленная переменная, разместиться хрен знает где *)
       MyBool :BOOL; (*Обычная булева пременная, разместиться там же*)

       MySuperInt   AT %MW0: INT; (* Целое число разместили в первых 2 байтах памяти *)
       MySuperBool    AT %MX2.0:    BOOL := FALSE; (* Булева переменная в 3-м байте в первом бите*)
       MySuperBool2    AT %MX2.1:    BOOL := FALSE; (* Булева переменная в 3-м байте во втором бите*)
    END_VAR

Как мы видим, при объявлении переменной появляется конструкция "AT %M", которая говорит, что переменную размещаем в специальную фиксированную область памяти. Следующая буква обозначает префикс размера, например W-выделение слова, то есть два байта, ну и следующее число означает где именно в памяти мы будем хранить переменную. Также видно, что для экономии места мы можем размещать булеву переменную не в байте а в конкретном бите байта. Более подробно можно почитать в описании стандарта МЭК. Также надо очень аккуратно размещать данные, так как принципиально компилятор разрешает пересечение переменных.

Теперь на VBScript пишем простенькую програмку. Для этого используем COM объект TCSCRIPT.TcScriptSync, который устанавливается при установке TwinCat.

    Dim TcClient, VarBool, VarInt16
    Set TcClient = CreateObject("TCSCRIPT.TcScriptSync")   ' загружаем COM объект
    Call TcClient.ConnectTo("192.168.208.188.1.1", 800)  ' подключаемся к контроллеру на 800 порт
    VarInt16 = TcClient.ReadInt16(&H4020, 0) ' читаем целое двухбайтовое число из памяти
    VarBool = TcClient.ReadBool(&H4021, 9) ' читаем значение переменной MySuperBool
    Call TcClient.WriteBool(&H4021, 9, NOT VarBool) ' меняем значение булевой переменной на противоположное 
    Call TcClient.WriteInt16(&H4020, 0, VarInt16 + 1) ' увеличиваем значение целого на единицу 

Сначала мы по IP адресу обращаемся к контроллеру (обратите внимание что немцы уже давно в контроллер встроили IPv6, два последних числа по умолчанию .1.1). Чтение и запись по адресу #4020 отсылает нас как раз в начало фиксированной памяти контроллера и нужно только указать правильное смещение в байтах. Если же обратиться к контроллеру по адресу #4021, то он нас отсылает в ту же самую память, но только позволяет читать из нее побитово, то есть смещение - это смещение в битах. Очень иногда удобно при программировании, так как избавляет нас от вычленения значения каждого бита в байте.

Ну и собственно "Вот и все что было, ты как хочешь это назови", как пел известный грузинский певец... Таким образом мы можем доставать из контроллера любые данные, а также менять значение переменных, управляя ходом исполнения программы внутри контроллера. Можно циклично опрашивать переменные в контроллере и ловить события типа "лампочка включилась" и по этому событию исполнять какую либо операцию на компьютере. А сделать web-интерфейс для удаленного включения лампочки вообще превращается в простейшую задачу. Вообщем, имея возможность коммуникации с контроллером он превращается в полнофункциональный модуль в единой системе "УМНЫЙ ДОМ"

Автор: Али
Любое использование материалов сайта возможно только с разрешения автора и с обязательным указанием источника.



Добавить комментарий:



Сортировка комментариев: Последние сверху | Первые сверху

2013-10-31 09:28:10 | AAsad
С IPv6 ошибочка вышла, это AmsNetId, у IPv6 каждое число представлено не одним, а двумя байтами. пример IPv6: 2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d


2012-11-13 14:06:34 | Али
Денис, я думаю, что это может быть познавательно не только вам, но и другим посетителям сайта. Поэтому приглашаю вас зарегистрироваться на нашем форуме и задать вопрос в моей ветке "Умный дом на Beckhoff". Я там с огромным удовольствием отвечаю на все вопросы коллег по этой тематике


2012-11-13 11:04:32 | Денис
Али, добрый день! Все, что Вы в этой статье написали очень интересно и увлекательно, приятно осознавать, что есть еще такие люди на земле готовые делиться своим опытом с другими и передавать им свои знания! У меня к Вам следующий вопрос, а не могли бы Вы более подробно рассмотреть данную статью, так как для меня немного не понятно где и что Вы делаете. У меня есть опыт программирования, но до этого я еще не доходил, в основном занимался написанием программ для контроллеров управляющих системами локально, будь то это технологический процесс либо система автоматизации и диспетчеризации инженерных систем здания. Как например Вы связали ПК и ПЛК? понятно, что это Ethernet TCP/IP, а какой протокол, что за программа связывается с ПЛК? Она постоянно должна быть запущена на ПК? Вопросы все такого рода. Если Вас не затруднит напишите мне на почту, буду очень Вам благодарен! (stefanenkov.denis@yandex.ru)