Глава 3. Разработка общих для всех локальных контроллеров аппаратной и программной частей.

Умный дом

Все локальные контроллеры подключаются к информационной сети системы “Умный дом”.

Предыдущая глава     Список статей     Следующая глава

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

 

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

 

Функциональная схема.

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

У меня получилось так.

Функциональная схема

Прежде всего, необходимо управлять драйвером интерфейса RS-485. Это сигналы RX, TX и DE. Последний разрешает работу передатчика драйвера. Рядом с сигналами показан активный уровень. Например, для сигнала DE это высокий уровень. Передатчик будет работать при логической 1 на выводе 2 платы Ардуино.

Этот же вывод будем использовать для управления светодиодом ОБМЕН. Светодиод должен помигивать в момент передачи ответных данных от устройства. Это будет означать, что центральный контроллер обратился именно к нашему контроллеру.

Для работы с сетью необходимы какие-то параметры. Как минимум сетевой адрес. Параметры будут храниться в EEPROM микроконтроллера, и сопровождаться контрольным кодом. Значит, данные могут быть неправильными. Неплохо бы индицировать, что устройство не способно работать или функционирует в ограниченном режиме. Добавим для этого светодиод ОШИБКА, подключим к выводу 3, определим, что он будет светиться при высоком уровне.

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

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

 

Принципиальная схема.

Драйвер MAX485, светодиоды, кнопки мы уже подключали к плате Ардуино. Функциональная схема легко трансформируется в принципиальную.

Принципиальная схема

Отмечу, что на предыдущих схемах вывод RE микросхемы MAX485 был подключен к земле. В новом варианте при передаче данных (сигнал DE высокого уровня), запрещается работа приемника, и микроконтроллер не принимает ненужные данные. Хотя, все будет работать и при подключенном к земле выводе RE.

Мы используем выводы аппаратного UART микроконтроллера RX и TX. Но эти выводы применяются для загрузки резидентной программы из Arduino IDE. Для того чтобы не происходил конфликт в разрыв  сигнала RX я поставил переключатель.

Разрыв цепи RX

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

Для проверки контроллера и отладки программы я подключил макет к конвертеру UART – RS-485 из предыдущей статьи. Просто соединил между устройствами соответствующие сигналы (A и B). Каждый контроллер подключил к компьютеру штатными USB-кабелями. Питание устройства получают от компьютера.

Макет системы Умный дом

 

Общий алгоритм программного обеспечения.

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

Я выбрал такой формат общих данных. Напомню, что минимальная единица данных в сети с протоколом ModBus это 16ти разрядное слово или регистр хранения (2 байта).

Регистр 0. Идентификационная информация.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
2 1 0 4 3 2 1 0 7 6 5 4 3 2 1 0
Резерв Версия ПО Тип  контроллера

Регистр 1. Идентификационная информация.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Заводской номер

Регистр 2. Идентификационная информация.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
3 2 1 0 3 2 1 0 3 2 1 0 3 2 1 0
десятки единицы десятки единицы
Год Месяц
Дата  выпуска устройства

Регистр 3. Состояние локального контроллера.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Состояние контроллера (пока неопределенно)

Регистр 4. Доступ к EEPROM

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
Данное 1 Данное 0

Регистр 5. Доступ к EEPROM.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
признаки 11 10 9 8 7 6 5 4 3 2 1 0
- слово запись чтение Адрес EEPROM

В регистре с адресом 0 хранится самая главная идентификационная информация – тип локального контроллера. В зависимости от типа устройства меняются форматы данных, алгоритм управления и т.п. Центральный контроллер должен знать, к какому устройству он обращается.

В регистрах с адресами 1 и 2 содержатся заводской номер и дата выпуска устройства. Можно обойтись без этой информации, но иногда она бывает полезной.

Регистр 3 содержит слово состояния контроллера. Это всевозможные ошибки, этапы алгоритмов, состояние датчиков. В регистре есть общая часть для всех контроллеров и индивидуальные для каждого типа устройства признаки. Определим его формат позже, по мере необходимости.

Регистры 4 и 5 используются для доступа к EEPROM. О них я напишу ниже.

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

 

Программа обмена данными по сети RS-485.

Для реализации протокола ModBus будем использовать мою библиотеку Tiny_ModBusRTU_Slave (урок 57).

Я ее немного подправил. Добавил метод setAdress(), позволяющий оперативно устанавливать адрес сетевого устройства. Если у вас старая версия, то загрузите библиотеку по этой ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

или ссылке из урока 57. Новая версия появилась 31 марта 2018 года. Новые файлы запишите поверх старых.

Реализуем обмен данными по сети. Используем программу из урока 57.

// локальный контроллер
// обмен по RS-485

#include <Tiny_ModBusRTU_Slave.h>
#include <TimerOne.h>

unsigned int regHoldTable[20];
Tiny_ModBusRTU_Slave slaveRS485(254, 8, regHoldTable, 20, 2); // создаем объект, адрес 1, таймаут 4 мс, массив regHoldTable, размер 10, вывод DE 2

void setup() {
Timer1.initialize(500); // таймера 1, 500 мкс
Timer1.attachInterrupt(timerInterrupt500, 500); // обработчик прерываний
Serial.begin(9600);
}

void loop() {
}

// обработчик прерывания
void timerInterrupt500() {
slaveRS485.update();
}

Загрузить скетч можно по ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

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

Мы собираемся разрабатывать еще много локальных контроллеров. Отлаживать их будем через регистры хранения. Поэтому я написал программу верхнего уровня для доступа к регистрам.

Загрузить программу можно по ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

В программе единственное окно.

HoldingReg

Позволяет считывать данные из контроллера, записывать в контроллер. В полях ”Считанные данные” и ”Данные для записи” используется шестнадцатеричная система исчисления, в остальных – десятичная.

Я проверил работу первого скетча. Данные правильно записываются и считываются.

 

Доступ к EEPROM.

Мы собираемся хранить в EEPROM самые разные параметры. Необходимо создать инструмент для записи и чтения данных в этот тип памяти.

Для доступа к EEPROM используются 2 регистра.

Регистр 4. Доступ к EEPROM

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
Данное 1 Данное 0

Регистр 5. Доступ к EEPROM.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
признаки 11 10 9 8 7 6 5 4 3 2 1 0
- слово запись чтение Адрес EEPROM

Алгоритм операций следующий. Для чтения:

  • В регистр 5 записать код, содержащий:
    • адрес чтения EEPROM;
    • признак “чтение” (бит 12) должен быть установлен.
  • Считать данные из регистра 4.

Информация в EEPROM хранится в байтах. Поэтому при чтении считываются 2 соседних байта. Если будут использоваться оба байта, то адрес должен быть четным.

Для записи:

  • В регистр 4 записать данные для записи.
  • В регистр 5 записать код, содержащий:
    • адрес записи EEPROM;
    • признак “запись” (бит 13) должен быть установлен;
    • если необходимо записать 2 байта, то должен быть установлен признак ”слово”.
  • После этого произойдет загрузка данных в EEPROM.

Запись в EEPROM длительная операция, поэтому она “подвешивает”  микроконтроллер и нарушает ответ сети ModBus. В программах может индицироваться ошибка обмена. Я решил с этим не бороться, поскольку запись в EEPROM редкая операция, необходима только при смене параметров. Да и всегда можно проверить, что записалось.

После чтения или записи одноименные биты в регистре 5 (биты 13 и 12) сбрасываются автоматически после выполнения операции.

Для реализации этого  алгоритма я добавил к предыдущему скетчу блок ”доступ к EEPROM”.

Новый скетч можно загрузить по ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

Проверим его работу программой HoldingReg. Это потребует определенного терпения.

Я проверял так:

  • регистр 4 <- 0x5a (данное для записи);
  • регистр 5 <- 0x2000 (адрес 0, признак записи);
  • можно (но необязательно) прочитать регистр 5 и убедиться, что признак записи сбросился;
  • регистр 5 <- 0x1000 (адрес 0, признак чтения);
  • регистр 4 -> считанное данное.

Для записи двух байтов последовательность будет такая:

  • 4 <- 0x1234;
  • 5 <- 0x6008;
  • 5 -> 0x4008;
  • 5 <- 0x5008;
  • 4 -> данное.

HoldingReg

 

Формат адресов EEPROM.

Раз у нас появился доступ к EEPROM, надо решить, что и как мы будем там хранить. Т.е. определить формат общих данных.

Некоторые данные явно недопустимо менять в рабочем режиме контроллера. Например, если мы от центрального контроллера будем записывать адрес локального устройства или его код типа, то наступит хаос. У контроллеров будут “плясать” адреса, меняться функциональные типы. Система разрушится.

Значит, часть данных необходимо защитить, разрешить запись только в отладочном режиме, например, когда нажата кнопка ”Установка адреса”. Поэтому в адресном пространстве EEPROM определим две зоны: защищенная область и адреса общего назначения.

Я назначил такие адреса и форматы.

Адрес EEPROM Назначение Защита
0 Защищенная
область
32 байта
1
2 Адрес контроллера
3 Адрес контроллера  ^ e5
4 Заводской номер, младший байт
5 Заводской номер, старший байт
6 Заводской номер, младший байт ^ 0xe5
7 Заводской номер, старший байт ^ 0xa3
8 Дата выпуска, младший байт
9 Дата выпуска, старший байт
10 Дата выпуска, младший байт ^ 0xe5
11 Дата выпуска, старший байт ^ 0xa3
. . .
31
32 Общего
назначения
224 байта
. . .
255

В защищенной области пока хранятся:

  • сетевой адрес устройства;
  • заводской номер;
  • дата выпуска.

Все данные для защиты целостности сопровождаются контрольными кодами.

Для работы с EEPROM я написал программу верхнего уровня. Вот ссылка для загрузки:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

Программа позволяет считывать и записывать 1 или 2 байта в память EEPROM.

Доступ к EEPROM

При операциях с 2 байтами адрес EEPROM должен быть четным.

 

Идентификационная информация.

Следующим этапом добавим в программу контроллера идентификационные данные  и обработку адреса устройства.

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

А вот если ”залетит” сетевой адрес контроллера, то могут быть неприятности. В лучшем случае контроллер перестанет отвечать на запросы. А может помешать работе других сетевых устройств.

Сделаем так. Если контрольный код сетевого адреса контроллера показывает, что параметр неверен, то мы вычисляем его по формуле:

сетевой адрес = 192 + (код типа контроллера) & 0x3f

Т.е. мы отводим область адресов 192 … 253 для ”залетевших” контроллеров. А адрес в этой области равен коду типа устройства. Если у нас испортятся адреса у контроллеров разных типов, то система будет работать. Центральный контроллер знает, где искать их. Если в системе ни один тип контроллера не используется дважды, то адреса из этой области могут быть базовыми, они никогда не пересекутся.

Подкорректируем слово состояния контроллера, назначим два признака.

Регистр 3. Состояние локального контроллера.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
F E
Состояние контроллера
  • F – фатальная ошибка (контроллер работать не может);
  • E – ошибка защищенной области EEPROM.

Признак F (фатальная ошибка) означает, что устройство не может работать нормально. Например, оторвался датчик или в EEPROM испортился важный параметр. Признак показывает, что человеку нужно вмешаться, переустановить параметры, проверить датчик и т.п.

Признак E говорит, что какой-то параметр в защищенной области EEPROM испорчен.

Очередной скетч можно загрузить по ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

В нем добавлена функция reloadIdent(). Она загружает данные для идентификации в первые 3 регистра хранения. При ошибке данных, функция загружает нули, а адрес вычисляет по описанному выше алгоритму.

Программой HoldingReg проверяем, что контроллер стал отвечать на адрес 193 (резервный адрес). В регистрах идентификации правильные данные только в первом: код – 1, версия ПО – 1. Для остальных данных в EEPROM  контрольные коды неправильные, программа подставила нули.

HoldingReg

Запишем в EEPROM правильный адрес и контрольный код к нему. Используем программу верхнего уровня EEPROM.

адрес EEPROM 2 <- 0x32 <-0xd7

0x32 это шестнадцатеричное представление числа 50, а 0xd7 – правильный контрольный код к нему.

Перезапускаем, и видим, что контроллер стал отвечать на адрес 50.

Аналогичным способом запишем в EEPROM правильные данные идентификации:

  • Заводской номер  3458:
    • E 4 < 0x82 < 0xd;
    • E 6 < 0x67 < 0xae;
  • Дату выпуска 03.18:
    • E 8 < 0x03 < 0x18;
    • E 10 < 0xe6 < 0xbb.

Перезапускаем и видим.

HoldingReg

В первых 3х регистрах правильная информация.

 

Циклическая перезагрузка регистров идентификации, светодиод, кнопка.

После изменения данных идентификации мы перезагружали контроллер. Это было необходимо потому, что функцию reloadIdent() разместили в блоке начальных установок setup().

  • Сейчас сделаем так, чтобы перезагрузка происходила циклически раз в секунду.
  • Неизвестно, что “придет в голову “ центральному контроллеру, не запишет ли он что-нибудь в регистры идентификации. Локальный контроллер вернет правильные данные.
  • Обработаем состояние кнопки УСТАНОВКА, используя цифровую фильтрацию. Если кнопка нажата, то активен будет признак buttonPress.
  • Реализуем индикацию состояния контроллера с помощью светодиода ОШИБКА:
    • светодиод мигает с высокой частотой (5 раз в секунду), если нажата кнопка УСТАНОВКА;
    • светодиод редко подмигивает (с периодом секунда горит 0.1 секунду), если ошибка данных защищенной области  EEPROM;
    • светодиод мигает раз в секунду (скважность 0,5) при фатальной ошибке.

Все вышеописанное реализует скетч:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

При желании, можете проверить.

 

Защита области EEPROM.

Осталось реализовать защиту от записи первых 32 байтов EEPROM и добавить сторожевой таймер.

Алгоритм защиты понятен. Операции записи в EEPROM с адресом меньше 32 разрешаются только в случае, если нажата кнопка УСТАНОВКА.

Установка адреса контроллера происходит загрузкой данных в EEPROM. Но для того, чтобы загрузить данные надо знать адрес устройства. А он может быть неизвестен. Проблема решается так. При нажатии на кнопку УСТАНОВКА сетевой адрес контроллера становится равным 254. Таким образом, все операции с защищенной областью EEPROM производятся по адресу 254.

Все это реализовано в последнем скетче этого урока:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

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

  • Нажать кнопку контроллера УСТАНОВКА. Устройство прейдет на работу с адресом 254.
  • По нажатию кнопки (стрелочка вниз) программа загружает адрес с контрольным кодом в устройство с сетевым адресом 254.

SetAdress

Программу можно загрузить по ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

 

 

Окончательная проверка.

Мы разработали своеобразный скелет для локальных контроллеров. В принципе это можно назвать даже операционной системой. Для каждого устройства будем добавлять свои функции.

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

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

Сейчас в основной отладочной программе один тип устройства. Это типовой контроллер с общими функциями.

Тестирование Умного дома SmartHouseTest

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

Программу можно загрузить по ссылке:

Зарегистрируйтесь и оплатитеВсего 60 руб. в месяц за доступ ко всем ресурсам сайта!

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

 

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

 

Предыдущая глава     Список статей     Следующая глава

0

Автор публикации

не в сети 1 день

Эдуард

280
Комментарии: 1936Публикации: 197Регистрация: 13-12-2015

44 комментария на «Глава 3. Разработка общих для всех локальных контроллеров аппаратной и программной частей.»

  1. Здравствуйте. Шикарные уроки, доходчиво, особенно для таких как я тугодумов. Есть желание создать что то вроде умного дома только функций по меньше заявленных в данном проекте. Скажите каким материалом запасаться, пока изучаю ваш проект, подойдут из Китая (ограничение в финансировании) комплектующие. Почему ваш проект? Потому что все проекты либо на ИК, Блютузе и.т.д. не внушают доверия. Жду с нетерпением следующих уроков-практиков. Удачи Вам и терпения, а главное здоровья!

    0
    • Здравствуйте! Спасибо за приятные слова.
      Не только я определяю функциональность и элементную базу устройства. Я не знаю, какие датчики планирует использовать Михаил.
      В качестве локальных контроллеров используются платы Arduino Nano. Можно заменить на вариант дешевле — Arduino Pro Mini, но к ним надо добавить хотя бы один конвертер USB-UART, например, CH340. Необходимы модули или микросхемы MAX-485. В качестве центрального контроллера планируется использовать MEGA 2560.

      0
      • С контролерами разобрался. В уроке у Вас написано про витую пару, это спец провода с определенным сопротивлением или любые? Кабель с роутера на ПК идет такой же?

        0
        • В зависимости от расстояния, от уровня помех. Я думаю, в доме достаточно простой витой пары. Свивать провода обязательно. Но можно применить кабель для сети Ethernet.

          0
  2. сейчас появились контроллеры esp с встроенным WI FI, я думаю они отлично подадут для умного дома

    0
  3. Не судите строго, я не волшебник, а только учусь… Вопрос: Если я правильно понял смысл интерфейса 485 соединять датчики, контролеры и.т.д. между собой с минимальными искажениям? Если так, то к примеру датчик температуры вывешиваю на улицу, а соединяю его с контролером витой парой через МАХ485, расстояние примерно 2 метра, или 2 метра можно соединить обычными проводами? В интернете примеры все в тестовом режиме ( рукой нагрели во работает!), а на практике нет примеров. Как быть с реальным подключением датчиков?

    0
    • Здравствуйте!
      Интерфейс RS-485 предназначен для создания цифровых сетей. Обычно им объединяют в сеть микроконтроллеры, хотя бывают и датчики с таким интерфейсом. Думаю, что 2 м можно подключить простыми проводами, но почему бы их не свить.
      RS-485 подробно расписан у уроке 60, а в следующем уроке есть пример его использования.

      0
  4. Добрый день!
    К сожалению очень поздно обнаружил Ваш сайт. Но он тем не менее не стал от этого менее интересным. Спасибо за Ваши уроки, хотя я уже не новичок. Вот только один вопрос возник у меня в связи с этим проектом. Почему Вы решили привязаться к проводам? почему бы не использовать nRF24L01+, ведь это полноценный сетевой адаптер и к тому же без проводной.

    0
    • Здравствуйте!
      Только что отвечал на этот вопрос в комментариях к главе 1. Повторю.
      Такой вариант имеет право на жизнь. Возможно я его реализую.
      Но, вариант с проводной связью:
      — дешевле;
      — надежнее;
      — решаются проблемы с питанием, с резервным питанием, с электробезопасностью;
      — возможность использовать недорогие контроллеры без опасения, что они зависнут. Всегда центральный контроллер может отключить питание локальных контроллеров и подать его снова.
      Очень много плюсов.

      0
  5. Позвольте с Вами не согласится по всем пунктам.
    1. цена на модули полностью сопоставима.
    2. Надежность передачи тоже реализована на равнозначном уровне.
    3. проблемы с питанием решаются проще если нет необходимости тянуть провода (да и не всегда есть возможность тянуть провода.
    4. полностью соответствует беспроводному решению.
    В данном случае я сам пользуюсь этими модулями уже довольно длительное время (уже пару лет) и проблем со связью не наблюдалось. У меня сеть из трех ардуин-нано, разнесенных на расстояние около 8-10 м. по разным этажам.

    0
  6. Добрый день, Эдуард.

    Еще раз БОЛЬШОЕ СПАСИБО за понятные уроки. Но тем не менее, хотелось бы уточнить по поводу программ верхнего уровня: коммуникация с локальным контроллером через адаптер USB-RS485 — это отправка в COM порт и чтение из него последовательности байт? Извиняюсь за глупый вопрос.

    0
    • Здравствуйте!
      Со стороны RS-485 стандартный протокол ModBus. Вместо компьютера можно подключить любое ведущее ModBus устройство.
      Со стороны компьютера мой нестандартный протокол. Дело в том, что RS-485 это шинный интерфейс. К одной шине подключено несколько устройств. Необходимо вовремя разрешать работу передатчиков сетевых устройств на шину. Это же касается и передатчика конвертера. Кроме RxD и TxD необходим еще один сигнал для выбора передатчика. Но главное, что этот сигнал должна вырабатывать программа на компьютере. Сигнал должен отключать передатчик конвертера после передачи последнего бита последнего байта пакета. Выявить этот момент на компьютере, загруженным работой операционки, других программ достаточно проблематично. Поэтому я передал эту функцию на микроконтроллер конвертера. Ну а для обмена конвертера с компьютером получился другой протокол. Конвертер — это не просто преобразователей интерфейсов, но и преобразователь протоколов.

      0
      • Эдуард, я правильно понял, что готовый модуль компактного USB-RS485 преобразователя http://roboshop.spb.ru/USB-RS485-converter
        использовать для связи с компьютером нельзя?

        0
  7. Эдуард, здравствуйте!
    С заводским номером понятно, может быть несколько однотипных контроллеров с одинаковой версией ПО.
    Но зачем в EEPROM хранить версию ПО и тип контроллера, если эта информация явно определена прошивкой? Почему не оставить их в константах?

    0
  8. скетчи Glava_3_1 — Glava_3_5 загружаются в какую плату ? — в которой нужно изменить адрес в сети (по интерфейсу RS485) ?

    0
  9. Добрый день, спасибо за статьи. Очень поучительно и досконально. Тут уже звучал комментарий про готовые системы OpenHub. Как раз я пробовал это дело, неплохо. Протокол я также брал mosquitto — m2m. Почитайте, может с ним будет удобней?

    0
    • Забыл дописать. Там используется смысл подписки. Если вы подписаны на тему, вы будете получать сообщения.

      0
  10. Приветствую. Я не понял как в каждый контроллер записать параметры: Тип контроллера, Заводской номер, Дата выпуска. Пытаюсь программой HoldingReg ( что, куда, в разные регистры ? — не пойму.). У меня в сети будет сразу 3 платы + потом ещё планируется добавлять. Сетевые адреса каждой плате присваивать получается. Спасибо.

    0
    • Здравствуйте!
      Тип контроллера задан в программе.
      #define DEVICE_SORT 1 // код типа контроллера
      #define PROG_VER 1 // версия программного обеспечения

      Заводской номер и дата выпуска хранятся в EEPROM. Значит записывать надо программой EEPROM. Смотрите таблицу формат EEPRM. Заводской номер расположен по адресам 4 и 5, младший и старший байт соответственно. По адресам 6 и 7 заводской номер, над которым совершили операцию исключающее ИЛИ с кодом 0xa3e5.
      Например, заводской номер 836. С помощью стандартного калькулятора Windows переводите его в HEX вид: 344. Делаете исключающее ИЛИ с 0xa3e5, получается A0A1. Загружаете в EEPROM начиная с 4 адреса: 44, 03, A1, A0.
      Надеюсь, я ничего не перепутал.

      0
      • 1.Понятно (с типом и версией ПО).

        2. Ваш пример загружаю. В 4 адрес — 44, 5 адрес — 03 и т.д. Записанные значения считываются в виде: 44 считывается как ff cd, 03- как cd cc, A1 — как сс cd, A0 — как cd 34.
        В итоге зав. номер — 0 и дата выпуска — 00.00
        Что-то делаю не так ?

        0
          • Я записывал программой HoldingReg. Делаю программой EEPROM — тоже самое.

            0
          • Тут же записываю (44) и считываю с этого же регистра (ff cd) — ерунда. ?

            0
          • Я перечитал урок, при записи должна быть нажать кнопка Установка адреса. И адрес платы нужно указывать 254, а то который присвоил я (192) с помощью программы SetAdress. Теперь всё получилось. Так ?

            0
          • Да, конечно. Запись в защищенную область EEPROM происходит с аппаратной защитой.

            0
          • С заводским номеров потренировался — получается разные номера записывать.
            Теперь не пойму как преобразовать в код дату выпуска контроллера и не понял как в уроке это преобразовано. Я делаю преобразования как таким же методом как и зав. номером — в итоге программа DiagnWater_5_1 отображает совсем другую дату. Загружаю в EEPROM начиная с 8 по 11 адрес. Что не так делаю ? Помогите пожалуйста, с примером, как с зав. номером. Спс

            0
          • Здравствуйте!
            Дата задается в шестнадцатеричном коде. Например, июль 2018 года будет выглядеть 0x0718. А дальше все также. 0x0718 ^ 0xa3e5.

            0
          • Да, все работает. «Поехали дальше». Спасибо.

            0
  11. Здравствуйте, Эдуард. Спасибо за подробные уроки. У меня вопрос по аппаратной части. Зачем нужен подтягивающий резистор 2к на входах с кнопками? Ведь к этим входам программно подключены внутренние резисторы микроконтроллера. В уроках по кнопкам Вы обещали подробно рассказать про номиналы этих резисторов, но я что-то не нашел этой информации. Может плохо искал )

    0
    • Здравствуйте!
      Внутренние резисторы высокоомные 50 кОм. Для повышения помехозащищенности лучше уменьшить сопротивление. Тогда наводке потребуется больший ток, чтобы снизить напряжение на входе для ложного срабатывания.

      0
  12. Здравствуйте, Эдуард! Я только начал изучать протокол ModBus. Расскажите пожалуйста более подробно про блок:
    //—————————————- доступ к EEPROM
    if((regHoldTable[5] & 4096) != 0) {
    // команда чтение
    noInterrupts();
    * ((byte *) regHoldTable + 8) = EEPROM.read((byte)regHoldTable[5]);
    * ((byte *) regHoldTable + 9) = EEPROM.read((byte)regHoldTable[5] + 1);
    interrupts();
    regHoldTable[5] &= 0xefff;
    }
    else if((regHoldTable[5] & 8192) != 0) {
    // команда запись
    if( buttonPress == true || (byte)regHoldTable[5] > 31 ) {
    noInterrupts();
    EEPROM.write((byte)regHoldTable[5], (byte)regHoldTable[4]);
    if((regHoldTable[5] & 16384) != 0) {
    // второй байт
    if((byte)regHoldTable[5] != 255) {
    EEPROM.write((byte)regHoldTable[5] + 1, * ((byte *)regHoldTable + 9));
    }
    }
    interrupts();
    }
    regHoldTable[5] &= 0xdfff;
    }
    1. Почему здесь написано * ((byte *) regHoldTable + 8), а не * ((byte *) regHoldTable[4] и
    * ((byte *) regHoldTable + 9), а не * ((byte *) regHoldTable[4] + 1?
    Есть разница между записями типа regHoldTable + 1 и regHoldTable[0] + 1?

    2. Что означает (byte)regHoldTable[5] > 31 ) при команде запись? Я так понял это связано с защищенной областью

    EEPROM? Но ведь она 31 ) и regHoldTable[1] = 0, regHoldTable[2] = 0 в функции reloadIdent().

    0
    • Здравствуйте!
      Я уже забыл этот проект. Но, попробую ответить.
      1. Регистры хранения ModBus (regHoldTable) 16ти разрядные. К EEPROM доступ происходит только байтами. Поэтому необходимо преобразование форматов данных. Здесь это происходит с помощью операций через указатели. Посмотрите урок 15 Ардуино.
      * ((byte *) regHoldTable + 8) = EEPROM.read((byte)regHoldTable[5]);
      Например, эта строка означает:
      — указатель на массив регистров хранения (а имя массива является указателем на него) regHoldTable преобразуется к указателю типа байт.
      — делаем операцию с младшим байтом регистра regHoldTable[4]. Если считать в байтах, то это будет 8й. Прибавляем к указателю 8.
      — записываем в него данное из EEPROM.
      Разница между regHoldTable + 1 и regHoldTable[0] + 1, конечно есть. В первом случае мы прибавляем 1 к указателю на массив, а во втором к его данному.

      2. Не понял вопроса по (byte)regHoldTable[5] > 31. Запись в эту область происходит только при определенных условиях.

      3. Да. QModBus должно работать. Что-то с адресами напутали. А с моими программами работает? Может что-то с кнопкой?

      0
      • EEPROM.read((byte)regHoldTable[5] + 1);
        Что означает эта запись? Чтение 2го байта из пятой ячейки массива regHoldTable? Здесь ведь не прибавляется единица к данному ячейки 5?

        2. Я не понял каким образом происходит защита записи в eeprom с адресами 31 в условии. То что должна быть нажата кнопка понятно.

        3. При нажатой кнопке и обращению к контроллеру с адресом 254 QModBus выдаёт ошибку. С Вашими программами и с Вашим конвертером всё работает. Я пробую использовать готовый конвертер usb-rs485 c АлиЭкспресс.

        0
        • Что то у Вас сайтом. Часть слов почемуто теряется из середины предложений при отправке коментария.

          2. Я не понял каким образом происходит защита записи в eeprom с адресами 31 в условии. То что должна быть нажата кнопка понятно.

          0
          • 2. Я не понял каким образом происходит защита записи в eeprom с адресами меньше 32. Не понял именно запись (byte)regHoldTable[5] > 31 в условии. То что должна быть нажата кнопка понятно.

            0
          • Добрый день!
            EEPROM.read((byte)regHoldTable[5] + 1);
            Это чтение из EEPROM по адресу = содержимое 5й ячейки массива + 1.
            Да, QModBus не обращается к регистрам, адрес которых больше 247.

            0
          • Спасибо за ответ, Эдуард, и за статьи!
            С записью (byte)regHoldTable[5] > 31 разобрался. Запись происходит если в первом байте регистра 5 записан адрес больше 31 (не защищенная область).

            С записью в защищенную область eeprom с помощью QModBus пока не разобрался. Попробую перезагрузить QModBus с уже зажатой кнопкой установки.

            0
  13. 2. Что означает (byte)regHoldTable[5] > 31 ) при команде запись? Я так понял это связано с защищенной областью

    EEPROM? Но ведь она 31 ) и regHoldTable[1] = 0, regHoldTable[2] = 0 в функции reloadIdent().

    0
  14. 2. Что означает (byte)regHoldTable[5] > 31 ) при команде запись? Я так понял это связано с защищенной областью

    EEPROM? Но ведь она < 32 и regHoldTable[5] это ведь один регистр под номером 5 — регистр доступа к EEPROM?

    0
  15. 3. Можно как то, кроме Ваших резидентных программ, (например с помощью программы QModBus) изменить данные в EEPROM?
    Как я понял, блок «доступ к EEPROM» как раз записывает данные по адресам EEPROM. Но, с помощью QModBus, у меня
    получилось изменить заводской номер и дату выпуска только закомментировав if( buttonPress == true || (byte)regHoldTable[5] > 31 ) и regHoldTable[1] = 0, regHoldTable[2] = 0 в функции reloadIdent().

    0

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".