Arduino & Modbus

 Arduino  Комментарии к записи Arduino & Modbus отключены
Июл 172019
 

Arduino & Modbus

В предыдущей статье мы соединили открытую платформу домашней автоматизации OpenHAB с контроллером Arduino использовав очень простой, текстовый протокол. Но это решение поставит нас в тупик, если мы захотим подключить наш контроллер к другой системе, что же делать?

Modbus — самый известный и распространенный стандарт в промышленной автоматизации, его поддерживают миллионы устройств по всему миру, эти устройства легко интегрируется в единую сеть и стыкуются с огромным количеством готового программного обеспечения. Попробуем использовать его в нашем проекте?

Что нам необходимо знать об этом стандарте?
Протокол Modbus использует последовательные линии связи (например, RS232, RS485), а протокол Modbus TCP рассчитан на передачу данных по сетям TCP/IP.
Протокол Modbus имеет два режима передачи RTU и ASCII, в режиме ASCII каждый байт передается как два ASCII символа его шестнадцатеричного представления.
В сети Modbus есть только один ведущий, который с заданным интервалом опрашивает несколько ведомых устройств, каждое из которых имеет свой уникальный адрес от 1 до 254, адрес 0 широковещательный и на него отвечают все устройства, так как ведущий в сети один у него нет своего адреса.
В спецификации Modbus определено два типа данных, один бит и 16 битное слово. Данные организованны в четыре таблицы с 16 битной адресацией ячеек, адресация в таблицах начинается с 0. Для доступа к данным из разных таблиц предназначены отдельные команды.

Discrete Inputs 1 бит только чтение
Coils 1 бит чтение и запись
Input Registers 16 бит только чтение
Holding Registers 16 бит чтение и запись

Как нам подключить Modbus устройство к OpenHAB? За это отвечает модуль Modbus Tcp Binding, этот модуль работает в режиме ведущего и обеспечивает подключение нескольких ведомых устройств через последовательный порт или TCP/IP сеть.
Для того чтобы связать с ним Arduino нам необходимо реализовать в контроллере ведомое Modbus устройство, воспользуемся для этого библиотекой Modbus-Master-Slave-for-Arduino.

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

Рассмотрим на примере нашего скетча основные шаги необходимые для работы с этой библиотекой.

Все функции библиотеки реализованы в одном файле ModbusRtu.h.
Для взаимодействия с ней, в программе нужно создать объект, задав в его конструкторе Modbus адрес, номер последовательного порта, номер выхода, управляющего передачей (для RS485)

Modbus slave(ID, 0, 0); 

Затем определить массив регистров Modbus

uint16_t au16data[11]; 

После этого, при старте программы настроить последовательный порт ведомого

slave.begin(9600); 

В основном цикле программы необходимо вызывать функцию обработки Modbus сообщений

state = slave.poll(au16data, 11); 

И после этого можно обработать полученные данные и сохранить необходимые переменные в регистрах Modbus.

#include "ModbusRtu.h" #define ID 1 // адрес ведомого #define btnPin 2 // номер входа, подключенный к кнопке #define stlPin 13 // номер выхода индикатора работы // расположен на плате Arduino #define ledPin 12 // номер выхода светодиода //Задаём ведомому адрес, последовательный порт, выход управления TX Modbus slave(ID, 0, 0); boolean led; int8_t state = 0; unsigned long tempus; // массив данных modbus uint16_t au16data[11]; void setup() { // настраиваем входы и выходы io_setup(); // настраиваем последовательный порт ведомого slave.begin( 9600 ); // зажигаем светодиод на 100 мс tempus = millis() + 100; digitalWrite(stlPin, HIGH ); } void io_setup() { digitalWrite(stlPin, HIGH ); digitalWrite(ledPin, LOW ); pinMode(stlPin, OUTPUT); pinMode(ledPin, OUTPUT); pinMode(btnPin, INPUT); } void loop() { // обработка сообщений state = slave.poll( au16data, 11); // если получили пакет без ошибок - зажигаем светодиод на 50 мс if (state > 4) { tempus = millis() + 50; digitalWrite(stlPin, HIGH); } if (millis() > tempus) digitalWrite(stlPin, LOW ); //обновляем данные в регистрах Modbus и в пользовательской программе io_poll(); } void io_poll() { //Копируем Coil[1] в Discrete[0] au16data[0] = au16data[1]; //Выводим значение регистра 1.3 на светодиод digitalWrite( ledPin, bitRead( au16data[1], 3 )); //Сохраняем состояние кнопки в регистр 0.3 bitWrite( au16data[0], 3, digitalRead( btnPin )); //Копируем Holding[5,6,7] в Input[2,3,4] au16data[2] = au16data[5]; au16data[3] = au16data[6]; au16data[4] = au16data[7]; //Сохраняем в регистры отладочную информацию au16data[8] = slave.getInCnt(); au16data[9] = slave.getOutCnt(); au16data[10] = slave.getErrCnt(); } 

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

40f0a878912f4bf4930ded14fe21e707.JPG

Для демонстрации работы с разными регистрами, в процессе работы программы данные из регистра с типом coil будут скопированы в регистр с типом discrete, а из регистров с типом holding в регистры с типом input. Кроме этого состояние кнопки будет сохранено в третий бит регистра au16data[0] (discrete), а значение третьего бита регистра au16data[1] (coil) выведено на светодиод.

Доработаем макет контроллера, который был собран для предыдущих экспериментов, переключим светодиод с 13 на 12 вывод. Обычно на плате самого Arduino уже есть светодиод, подключенный к 13 выводу, в нашей программе он станет индикатором статуса работы. Теперь подключим USB кабель к компьютеру, скомпилируем и загрузим программу в контроллер.

6ff226483d9448a5b787af24c94286c2.JPG

Пора приступать к испытаниям. Значительно облегчает работу на этом этапе эмулятор Modbus мастер-устройства, в сети есть несколько хороших, при этом бесплатных программ, вот некоторые из них:
www.focus-sw.com/fieldtalk/modpoll.html
qmodbus.sourceforge.net
www.mikont.com/products/EAT-Console.html

Среди них можно отметить утилиту EAT-Console которая позволяет не только управлять и опрашивать Modbus устройства, но и отображает данные в графическом виде, что очень удобно при отладке работы с различными датчиками, например датчиками влажности, давления и температуры. Перед началом работы с программой и её конфигуратором рекомендую ознакомиться с документацией.

8184e77240054ca3a681087d35db8388.JPG

Для установки эмулятора нужно скачать архив и распаковать его в папку C:\arduino\EATConsole, затем открыть страницу загрузки Eclipse, скачать Eclipse IDE for Java Developers и распаковать его в папку C:\arduino\eclipse, после этого скопировать файлы из папки C:\arduino\EATConsole\eclipse\plugins в папку C:\arduino\eclipse\plugins.

Для создания конфигурации необходимо запустить C:\arduino\eclipse\eclipse.exe, создать пустой проект, скопировать в него пустой файл C:\arduino\EATConsole\menu.ptmenu и добавить в редакторе пункты в соответствии со следующей таблицей. Если же вы скачали проект из репозитория, то в нём, в папке EATConsole уже есть подготовленный файл menu.ptmenu.

Type Address Bit Name Point Slave
Display Boolean 0 0 DT0 1
Display Boolean 0 1 DT1 1
Display Boolean 0 2 DT2 1
Display Boolean 0 3 BTN 1
Input Boolean 1 0 CL16 1
Input Boolean 1 1 CL17 1
Input Boolean 1 2 CL18 1
Input Boolean 1 3 LED 1
Display Integer 2 INPT3 0 1
Display Integer 3 INPT4 0 1
Display Integer 4 INPT5 0 1
Display Integer 5 HOLD6 0 1
Display Integer 6 HOLD7 0 1
Display Integer 7 HOLD8 0 1

Type — тип элемента меню EATConsole.
Address — адрес регистра данных.
Bit – номер бита в регистре.
Name – название элемента меню.
Point – количество десятичных знаков после точки.
Slave – Modbus адрес контроллера.

add9437d0a2f4e13a987d841bc8c993e.JPG

Теперь сохраним и скопируем файл menu.ptmenu в каталог C:\arduino\EATConsole, для этого можно щёлкнуть правой кнопкой мыши на файле прямо в Eclipse, выбрать в контекстном меню пункт “Copy”, а затем вставить в проводнике в папку C:\arduino\EATConsole.

После этого запустим C:\arduino\EATConsole\EATConsole.exe, настроим последовательное соединение, выбрав пункт меню Файл\Настройки, в диалоговом окне укажем номер порта, скорость 9600, 8 бит данных, 1 стоповый бит.

351170a62856416da0b7a5f82885e5c7.JPG

*Программа работает с портами с 1 по 8 и если USB переходник Arduino встал на порт с большим номером, придётся открыть диспетчер устройств Windows и изменить номер порта для него.

Когда все настройки будут введены, нажмите кнопку “Установить”, сразу после этого программа начнёт опрос устройства и если что-то пошло не так появится сообщение – НЕТ СВЯЗИ. Если же всё было сделано правильно и связь есть в чём можно убедиться по миганию индикатора статуса (светодиод на выводе 13), то пора приступить к испытаниям нашего контроллера.

Попробуем поменять значение в регистрах HLD0…HLD2 и СL0…СL2, при этом должно поменяться значение в соответствующем регистре IN0..IN2 и DT0..DT2, затем нажмём на кнопку макета, при этом должно поменяться значение в поле BTN, щёлкнем по полю LED, при этом должен загореться или потухнуть светодиод.

e458a8cc65be4a059abd2734578c4336.JPG

Что мы получили в результате нашей работы:

1 познакомились с азами протокола Modbus;
2 создали скетч, который превращает Arduino в Modbus slave устройство и позволяет читать и записывать несколько Modbus регистров с разными типами данных;
3 протестировали обмен с контроллером при помощи эмулятора функций Modbus master устройства, для которого создали конфигурацию соответствующую структуре регистров контроллера.

Выводы
Библиотека Modbus-Master-Slave-for-Arduino проста в использовании, позволяет создать ведомое Modbus устройство, которое корректно работает с программным эмулятором. Скомпилированный пример занимает немногим более 5кб памяти программ, так что в контроллере остаётся достаточно места для добавления необходимого функционала.

Стандарт Modbus открыт и популярен, но в нём есть ряд недостатков — в стандарте определено только два типа данных,
протокол требует постоянного обмена между ведущим и ведомыми устройствами, конфигурировать систему приходится вручную.

Имея некоторые недостатки, протокол вполне пригоден для использования в контроллере систем домашней автоматизации, особенно если необходима стыковка с различным программным обеспечением.

В следующий раз займёмся подключением контроллера к платформе OpenHAB.

Как подружить OpenHAB и Arduino

 Arduino  Комментарии к записи Как подружить OpenHAB и Arduino отключены
Июл 172019
 

Как подружить OpenHAB и Arduino

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

Arduino — простой электронный конструктор, который пользуется заслуженным уважением у любителей, говорят, что его недолюбливают профессионалы, хотя тайком используют в своих жутких экспериментах. В чём секрет его популярности, как воспользоваться ей для решения нашей задачи?

Arduino подходит для локального контроля и управления в доме, в сети есть масса проектов для этого — отлично, но недостаточно, ведь нужно мыслить глобально! Нам нужен выход в сеть и мобильный интерфейс!

Хорошо, что благодаря этой статье мы уже знакомы с OpenHAB — платформой с открытым исходным кодом, объединяющей большое количество устройства с разными протоколами в единую сеть. OpenHAB реализован на Java, поэтому работает в различных ОС, его можно запустить на одноплатном компьютере и даже роутере, в нём есть мобильный и Web интерфейс. Звучит как хороший набор заклинаний против наших, надоевших уже граблей, проверим?

Вначале установим OpenHAB, откроем страницу загрузки, скачаем Runtime core и Demo setup, распакуем их в C:\openhab. При распаковке Demo setup разрешим замену файла README.txt. Если на компьютере отсутствует Java (проверим командой java –version), то инсталлируем ее в соответствии с инструкцией.

Теперь запустим OpenHAB, выполнив C:\openhab\start.bat, подождём немного и откроем Web интерфейсlocalhost:8080/openhab.app?sitemap=demo
(если нам потребуется остановить OpenHAB — нажмём Ctl+C или закроем консоль программы)

image

Работает! Продолжим. Наша цель поиск простого решения, поэтому начнём с экспериментов. В одном из комментариев к статье предлагалось подключить контроллер к OpenHub через последовательный порт использовав Serial-Binding. Вполне интересное решение, попробуем его реализовать.

Для установки дополнения открываем страницу загрузки, качаем Addons, распаковываем org.openhab.binding.serial-1.6.1.jar (версия плагина может отличаться) в папку C:\openhab\addons. При желании читаем документацию.

Так как отладка взаимодействия с реальным устройством обычно доставляет немало хлопот, попробуем сначала отправить команды через терминал, соединив его с OpenHAB через эмулятор нуль-модемного кабеля.

Качаем и устанавливаем эмулятор com0com, запускаем утилиту image Setup из меню программы и видим, что при установке уже создана виртуальная пара последовательных портов — у меня это COM35 + COM36. Будем использовать их в нашей работе.

image

В качестве терминала я использовал Hercules SETUP utility, это бесплатная программа позволяющая выбрать порты с большими номерами и ввести несколько команд, отправляя их нажатием соответствующей кнопки. Скачиваем её, запускаем hercules_3-2-8.exe, переходим на вкладку “Serial”, выбираем второй порт виртуальной пары (у меня это COM36) и вводим следующие настройки – скорость 9600, 8 бит, 1 стоповый бит, нет контроля четности. Открываем порт.

45e089736561407590c4e72a3a1b8345.JPG

Теперь нужно сконфигурировать openHAB, для этого воспользуемся его дизайнером. Откроем страницу загрузки, скачаем openHAB Designer и распакуем его в папку C:\openhab\designer, запустим C:\openhab\designer\openHAB-Designer.exe и укажем папку, в которой лежит конфигурация — C:\openhab\configurations.

d75109973e294e7d8f0d3228fd21944c.JPG

Сначала создадим элемент (item) и свяжем его с первым в виртуальной паре последовательным портом (у меня это COM35). Для этого добавим следующий код в конец файла demo.items, после чего щёлкнем правой кнопкой мыши в окне редактора и скомандуем “Save”, вместо этого можно просто нажать ctl+S.

String Serial_string "Текст [%s]" { serial="COM35" } 

55844677eb6348e58daa3c751821998f.JPG

Для тестирования пропишем правило, которое каждую минуту будет отправлять команду созданному элементу. Для этого добавим следующий код в конец файла demo.rules после чего сохраним его.

rule "Test serial string" when System started or Time cron "0 * * * * ?" then Serial_string.sendCommand("Test") end 

3c2e558e31da4803ab1acb084b8405c0.JPG

Если OpenHAB запущен, мы почти сразу начнём принимать текст команды в терминальной программе, а в консоли увидим отчёт о её прохождении:

1d840e45d8d24c8dad6b90be8b78529e.JPG

Попробуем теперь отправить команды в OpenHAB. Введём в терминале, в первое поле панели “Send” текст “ON_1”, а во второе “OFF_1”. Нажмём первую кнопку “Send”, затем вторую. В результате этого в консоли появляются следующие сообщения:

ef1720dbf7764275acbf7125049a4057.JPG

Для того, чтобы наши усилия не пропали даром, создадим правило которое будет обрабатывать наши команды, Для этого добавим следующий код в конец файла demo.rules и сохраним его.

rule "Serial control" when Item Serial_string received update then if(Serial_string.state=="ON_1") sendCommand(Light_FF_Corridor_Ceiling, ON) if(Serial_string.state=="OFF_1") sendCommand(Light_FF_Corridor_Ceiling, OFF) if(Serial_string.state=="ON_2") sendCommand(Light_GF_Kitchen_Ceiling, ON) if(Serial_string.state=="OFF_2") sendCommand(Light_GF_Kitchen_Ceiling, OFF) end 

Откроем WEB интерфейс, щёлкнем по пункту “First Floor” затем по пункту “Corridor” или скопируем в браузер ссылку: localhost:8080/openhab.app?sitemap=demo#_FF_Corridor, отправим текст “ON_1”, а потом OFF_1” из терминала. Проконтролируем выключатель в WEB приложении, его состояние должно изменяться.

c76ab6d5c0714466af9ae0759c6eddec.JPG

Теперь нажмём “Home”, выберем пункт “Ground Floor” затем пункт “Kitchen” или скопируем в браузер ссылку: localhost:8080/openhab.app?sitemap=demo#_GF_Kitchen, отправим текст “ON_2”, а затем “OFF_2” из терминала. Проконтролируем выключатель в WEB приложении, его состояние также должно изменяться.

a1406434fb484363a0771592a4592952.JPG

Результат нашего эксперимента можно наблюдать в консоли приложения, в которой появятся следующие сообщения:

e780a15d9096473f8b77e7dc81830063.JPG

На компьютере всё работает, пора подключаться к реальному миру!

В большинство плат Arduino уже встроен переходник с COM порта на USB, поэтому у нас не возникнет вопросов с присоединением к компьютеру или ноутбуку. Из подручных средств соберём макет, для этого нам понадобится контроллер Arduino, макетная плата, провода, кнопка, светодиод, резисторы 10кОм и 1кОм.

43d3ff91a9f140aeb677cf2ec27a132c.JPG

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

Откроем редактор, добавим в него следующий код и сохраним скетч в файле btn.ino.

// задаем константы const int buttonPin = 2; // номер входа, подключенный к кнопке const int ledPin = 13; // номер выхода светодиода // переменные int buttonState = 3; // переменная для хранения состояния кнопки int buttonCnt = 0; // переменная для защиты от дребезга кнопки void setup() { // инициализируем пин, подключенный к светодиоду, как выход pinMode(ledPin, OUTPUT); // инициализируем пин, подключенный к кнопке, как вход pinMode(buttonPin, INPUT); // настраиваем последовательный порт Serial.begin(9600); } void loop(){ // обработка дребезга кнопки delay(1); if (buttonState != digitalRead(buttonPin)) buttonCnt++; else buttonCnt = 0; if (buttonCnt > 100) { // считываем значения с входа кнопки buttonState = digitalRead(buttonPin); buttonCnt = 0; // проверяем нажата ли кнопка // если нажата, то buttonState будет LOW: if (buttonState == LOW) { // включаем светодиод digitalWrite(ledPin, HIGH); // отправляем команду Serial.print("ON_1"); } else { // выключаем светодиод digitalWrite(ledPin, LOW); // отправляем команду Serial.print("OFF_1"); } } } 

c37e5c7d6e6f4701b713ea12f9813023.JPG

Компилируем и загружаем скетч в Arduino, открываем монитор порта, выбираем скорость 9600 и пробуем нажать кнопку на плате. В результате мы можем наблюдать получение команд:

2969056c698445fa92846315c407a974.JPG

Теперь закроем монитор порта и настроим связь OpenHAB с контроллером, для этого отредактируем настройки нашего элемента (в моём случае нужно поменять значение на COM18 так как USB переходник Arduino встал на этот порт).

String Serial_string "Текст [%s]" { serial="COM18" } 

В завершении проконтролируем прохождение команд при помощи консоли и WEB интерфейса.

Что мы получили в результате нашей работы:

1 установили, настроили OpenHAB, научились добавлять элементы (item) и автоматизировать обработку при помощи правил (rule);
2 научились тестировать обмен при помощи программных средств. Эти инструменты помогут в дальнейшем при поиске неисправностей и в постановке собственных экспериментов;
3 сделали простейший скетч для Arduino, подключили его к OpenHAB, создали правило обрабатывающее текстовые команды, протестировали возможность управления через последовательный порт.

Выводы:

Отправка команд в текстовом виде обычное дело в практике Arduino, обработку таких команд можно реализовать в OpenHAB поэтому такой способ взаимодействия заслуживает внимания и обсуждения.

Недостатком полученного решения является то, что команды ничем не разделены между собой кроме паузы, это может приводить к их “слипанию” и ненадёжной обработке. Для решения этой проблемы необходимо доработать скетч и правило обработки команд либо внести изменения в модуль Serial-Binding.

Многие назовут такой вариант взаимодействия с OpenHAB любительским, поэтому прежде чем продолжать работу над ним попробуем связать OpenHAB и Arduino через протокол Modbus.

Об этом в следующих публикациях:
Arduino & Modbus habrahabr.ru/post/249043
Arduino & OpenHAB habrahabr.ru/post/252555
Открытый контроллер умного дома на базе Arduino vk.com/myremoter

RGB панели

 Arduino  Комментарии к записи RGB панели отключены
Июл 072019
 

Test Example Code

by Phillip Burgess

We have example code ready to go for these displays. It’s compatible with the Arduino Uno or Mega…but not other boards like the Leonardo, nor “Arduino-like” boards such as Netduino…programming gurus might be able to port it to other microcontrollers by adapting the C++ source, but as written it does some pretty low-level, non-portable things.

Continue reading »

Операция «пучеглазка». (RGB LED Matrix Panels Test)

 Arduino  Комментарии к записи Операция «пучеглазка». (RGB LED Matrix Panels Test) отключены
Июл 022019
 

В данной заметке речь пойдёт о светодиодных панелях, используемых в рекламных вывесках и архитектурных ТВ экранах.
Вот примерно таких:
bea69c.jpg

Continue reading »

si4463 описание

 Arduino  Комментарии к записи si4463 описание отключены
Мар 292019
 

Описание АТ команд модулей:

Для настройки модуля необходимо перевести его в командный режим, для этого необходимо притянуть контакт «SET» к массе и подождать ~40ms. Контакт «SET» имеет подтягивающий резистор на 10к. В командном режиме последовательный порт сконфигурирован на 9600bps. Если параметры модуля были изменены, после выхода из командного режима, они будут применены через ~80ms.

Continue reading »

DIY Professional Double Sided PCB

 Arduino  Комментарии к записи DIY Professional Double Sided PCB отключены
Мар 232019
 

Nowadays, PCBs can be bought extremely cheap from China. But let’s say you need one within 24 hours, making your own is then the only option. Furthermore, it’s way more challenging and fun!

Continue reading »