КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Блок климатический (температура, влажность, освещенность), RS485 / Modbus - руководство по использованию

Общие сведения:

Блок климатических датчиков RS485 / Modbus - это устройство включающее в себя датчики HTL: влажности (Humidity), температуры (Temperature) и освещённости (Light).

Показания каждого датчика можно получать по протоколу Modbus шины RS485.

Блок HTL можно использовать для контроля климата гидропонной установки. Устройство легко подключается к блоку управления гидропонной установки, сетевым кабелем через разъемы RJ45.

Блок климатических датчиков HTL не обязательно использовать в гидропонных установках, это могут быть иные проекты где требуется контролировать климат используя для получения данных протокол Modbus широко применяемый в промышленности.

В соответствии с протоколом Modbus, к одной шине RS485 можно подключить до 247 блоков климатических датчиков. Адрес устройства (по умолчанию 0x03) назначается программно и хранится в его энергонезависимой памяти. Все устройства на шине должны иметь уникальный адрес.

Видео:

Редактируется...

Спецификация:

  • Напряжение питания: от 12 до 24 В постоянного тока (разъем RJ45).
  • Ток потребляемый модулем: до 10 мА.
  • Интерфейс: RS485 / Modbus.
  • Скорость шины: 4800 / 9600 / 19200 / 38400 / 57600 / 115200 бит/с.
  • Адрес на шине: устанавливается программно (по умолчанию 0x03).
  • Диапазон измерений температуры: от -40 до +125 °С (с шагом 0,1).
  • Диапазон измерений влажности воздуха: от 0 до 100 % (с шагом 0,1).
  • Диапазон измерений влажности воздуха: от 0 до 655,35 г/м3 (с шагом 0,01).
  • Диапазон измерений освещённости: от 0 до 65'535 лк (с шагом 1).
  • Рабочая температура: от -25 до +60 °С.
  • Габариты: 65 x 45 x 29 мм.
  • Вес: ? г.

Подключение:

Важно: Перед подключением устройства к шине RS485 нужно отключить питание.

Так называемое «горячее подключение» может повредить устройство!

Для подключения блока климатических датчиков к шине RS485 используется разъем RJ45.

Назначение выводов разъема RJ45:

  • 1: «A» - Линия данных (неинвертирующая).
  • 2: «B» - Линия данных (инвертирующая).
  • 3: «NC» - Не используется.
  • 4: «PWR» - Вывод питания от +12 до +24В.
  • 5: «PWR» - Вывод питания от +12 до +24В.
  • 6: «NC» - Не используется.
  • 7: «GND» - Общий вывод питания.
  • 8: «GND» - Общий вывод питания.
  • HL-1: «BLINK» - Индикатор включения (мигает если подано питание).
  • HL-2: «DATA» - Индикатор получения запроса и обнаружения устройства.

Назначение индикаторов разъёма RJ45:

  • HL-1 «BLINK» Индикатор включения:
    • Индикатор коротко мигает раз в две секунды -
      значит устройство работает, но не получило ни 1 запроса с подачи питания.
    • Индикатор медленно мигает раз в секунду -
      значит устройство работает, но последний запрос принят более 10 сек. назад.
    • Индикатор часто мигает пять раз в секунду -
      значит устройство работает и последний запрос принят менее 10 сек. назад.
  • HL-2 «DATA» Индикатор получения запроса и обнаружения устройства:
    • Индикатор включается при получении запросов, что позволяет визуально отследить их поступление.
    • Устройству можно отправить команду на постоянное свечение индикатора, что позволит визуально найти устройство с известным адресом среди одинаковых устройств на шине.

Питание:

Входное напряжение питания модуля от 12 до 24В постоянного тока подаётся через разъем PJ45. Модуль HTL сохраняет работоспособность при снижении питания до 5В. Не подавайте питание выше 24В.

Подробнее о блоке HTL:

Блок климатический (температура, влажность, освещённость) RS485 / Modbus построен на базе микроконтроллера STM32G030F4 и конвертера SN65HVD3082EDR с цепями защиты шины RS485 и встроенным терминатором, который можно отключать переключателем на плате. В устройстве присутствуют: импульсный DC-DC преобразователь, линейные преобразователи и датчики: SHT20 и LTR553. На корпусе блока есть фиксатор позволяющий устанавливать его на DIN-рейку.

Блок позволяет:

  • Менять свой адрес на шине.
  • Менять тип протокола Modbus (RTU/ASCII).
  • Менять скорость передачи данных.
  • Сохранять одно двухбайтное слово в энергонезависимую память и читать его.
  • Читать напряжение питания поступившее с разъема RJ45.
  • Управлять светодиодом обнаружения устройства на разъеме RJ45.
  • Читать показания датчиков:
    • Температура воздуха в °С.
    • Относительная влажность воздуха в %.
    • Абсолютная влажность воздуха в г/м3.
    • Освещённость в люксах.
  • Задавать и узнавать период обновления показаний датчиков.

Для работы с блоком климатических датчиков RS485 / Modbus предлагаем воспользоваться разработанными нами библиотеками iarduino_Modbus и iarduino_MB_HTL. Первая позволяет работать по протоколу Modbus на шине RS485, а вторая предназначена для работы с блоком климатических датчиков.

    Подробнее про установку библиотек читайте в нашей инструкции.

    Примеры:

      Предложенные библиотеки содержат больше примеров, доступных из меню Arduino IDE:
    • Файл / Примеры / iarduino Modbus (протокол) / ModbusClient / HardwareSerial.
    • Файл / Примеры / iarduino Modbus (протокол) / ModbusClient / SoftwareSerial.
    • Файл / Примеры / iarduino Modbus HTL (модуль климатических датчиков) / HardwareSerial.
    • Файл / Примеры / iarduino Modbus HTL (модуль климатических датчиков) / SoftwareSerial.

    Так как у большинства плат Arduino и ESP нет шины RS485, то библиотека iarduino_Modbus использует аппаратную или программную шину UART, сигналы которой преобразуются в сигналы шины RS485 при помощи конвертирующего модуля UART-RS485, например, на базе микросхемы MAX485. Конвертер подключается к выводам TX и RX шины UART, а так же назначается вывод разрешающий работу передатчика DE.

    Для более удобного подключения, можно воспользоваться Trema конвертером UART-RS485, как показано на картинке ниже. У этого конвертера имеется порт RJ-45, который позволяет подключать датчик при помощи стандартного 8-жильного кабеля витой пары патч-корд.

    Обратите внимание на то, что вывод TX конвертера подключается к выводу RX Arduino, вывод RX конвертера к выводу TX Arduino, вывод разрешения работы передатчика D (DE) подключается к любому выводу Arduino (назначается в скетче).

    В примерах ниже, для создания шины RS485, будет использована аппаратная шина UART1 (класс Serial1). Если у вашей платы Arduino нет свободных аппаратных шин UART, используйте программную шину UART при помощи входящей в состав Arduino IDE библиотеки SoftwareSerial.

    Смена адреса блока на шине:

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

    uint8_t nowAddress = 3;                     // Текущий адрес блока климатических датчиков ( 1 - 247 ).
    uint8_t newAddress = 10;                    // Новый адрес блока климатических датчиков ( 1 - 247 ).
    uint8_t pinDE      = 2;                     // Вывод DE конвертера UART-RS485.
                                                //
    #include <iarduino_Modbus.h>                // Подключаем библиотеку для работы по протоколу Modbus.
    #include <iarduino_MB_HTL.h>                // Подключаем библиотеку для работы с блоком климатических датчиков.
                                                //
    ModbusClient modbus(Serial1, pinDE);        // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE.
    iarduino_MB_HTL sensor(modbus);             // Создаём объект для работы с климатическими датчиками указав объект протокола Modbus.
                                                //
    void setup(){                               //
         int f;                                 //
         Serial.begin(9600); while(!Serial);    // Инициируем передачу данных в монитор последовательного порта, указав его скорость.
         Serial1.begin(9600); while(!Serial1);  // Инициируем работу с шиной UART подключённой к конвертеру UART-RS485.
         modbus.begin();                        // Инициируем работу по протоколу Modbus.
    //   modbus.setTimeout(10);                 // Указываем максимальное время ожидания ответа по протоколу Modbus.
    //   modbus.setDelay(4);                    // Указываем минимальный интервал между отправляемыми сообщениями по протоколу Modbus.
    //   modbus.setTypeMB( MODBUS_RTU );        // Указываем тип протокола Modbus: MODBUS_RTU (по умолчанию), или MODBUS_ASCII.
         Serial.print("Инициализация ");        //
         f =    sensor.begin(nowAddress);       // Инициируем работу с блоком климатических датчиков, указав его текущий адрес nowAddress.
         if(f){ Serial.println("OK");  }        // Если f=true значит инициализация пройдена успешно.
         else { Serial.println("ERR"); }        // Если f=false значит инициализация не пройдена.
         Serial.print("Смена адреса ");         //
         f =    sensor.changeID(newAddress);    // Меняем адрес блока климатических датчиков на новый newAddress.
         if(f){ Serial.println("OK");  }        // Если f=true значит адрес изменён.
         else { Serial.println("ERR"); }        // Если f=false значит адрес не изменён.
         Serial.print("Текущий адрес ");        //
         Serial.println(sensor.getID());        // Выводим текущий адрес блока климатических датчиков.
         Serial.print("Версия прошивки ");      //
         Serial.println(sensor.getVersion());   // Выводим версию прошивки блока климатических датчиков.
    }                                           //
                                                //
    void loop(){                                // Визуально показываем у какого устройства был изменён адрес.
         sensor.setIDLED(true ); delay(1000);   // Включаем светодиодом обнаружения устройства (на разъёме RJ45).
         sensor.setIDLED(false); delay(1000);   // Выключаем светодиодом обнаружения устройства (на разъёме RJ45).
    }                                           //
    

    Пример будет более коротким, если убрать вывод данных в монитор последовательного порта и обращаться к функциям sensor.begin(), sensor.changeID() без проверки f. Если при обращении к функции sensor.begin() не указывать текущий адрес блока nowAddress, то он будет найден автоматически, но это займёт некоторое время.

    Чтение показаний с датчиков блока:

    Пример выводит показания всех датчиков с проверкой корректности чтения.

    uint8_t pinDE = 2;                          // Вывод DE конвертера UART-RS485.
                                                //
    #include <iarduino_Modbus.h>                // Подключаем библиотеку для работы по протоколу Modbus.
    #include <iarduino_MB_HTL.h>                // Подключаем библиотеку для работы с блоком климатических датчиков.
                                                //
    ModbusClient modbus(Serial1, pinDE);        // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE.
    iarduino_MB_HTL sensor(modbus);             // Создаём объект для работы с климатическими датчиками указав объект протокола Modbus.
                                                //
    void setup(){                               //
         Serial.begin(9600); while(!Serial);    // Инициируем передачу данных в монитор последовательного порта, указав его скорость.
         Serial1.begin(9600); while(!Serial1);  // Инициируем работу с шиной UART подключённой к конвертеру UART-RS485.
         modbus.begin();                        // Инициируем работу по протоколу Modbus.
    //   modbus.setTimeout(10);                 // Указываем максимальное время ожидания ответа по протоколу Modbus.
    //   modbus.setDelay(4);                    // Указываем минимальный интервал между отправляемыми сообщениями по протоколу Modbus.
    //   modbus.setTypeMB( MODBUS_RTU );        // Указываем тип протокола Modbus: MODBUS_RTU (по умолчанию), или MODBUS_ASCII.
         int f = sensor.begin(3);               // Инициируем работу с блоком климатических датчиков, указав его адрес. Если адрес не указан sensor.begin(), то он будет найден, но это займёт некоторое время.
         if( !f ){                              // Если функция begin() вернула false, значит блок климатических датчиков с адресом 3 не найден.
             Serial.print("Блок не найден");    //
             while(1);                          // Запрещаем дальнейшее выполнение скетча.
         }                                      //
    //   sensor.setPeriod( SENSOR_SHT, 0.5f );  // Указываем модулю обновлять данные датчика влажности и температуры каждые 0.5 секунд.
    //   sensor.setPeriod( SENSOR_LTR, 1.0f );  // Указываем модулю обновлять данные датчика освещённости каждую секунду.
    }                                           //
                                                //
    void loop(){                                //
         float i;                               //
    //   Читаем температуру:                    //
         i=sensor.getTEM();                     //
                       Serial.print("TEM=" );   // Читаем данные.
         if( i< -40 ){ Serial.print("ERROR"); } // Сообщаем об ошибке чтения.
         else        { Serial.print( i , 1 ); } // Выводим данные с одном знаком после запятой.
                       Serial.print("°C, " );   // Выводим единицы измерения.
    //   Читаем относительную влажность:        //
         i=sensor.getHUM();                     //
                       Serial.print("HUM=" );   // Читаем данные.
         if( i< 0 )  { Serial.print("ERROR"); } // Сообщаем об ошибке чтения.
         else        { Serial.print( i , 1 ); } // Выводим данные с одном знаком после запятой.
                       Serial.print("%, "  );   // Выводим единицы измерения.
    //   Читаем абсолютную влажность:           //
         i=sensor.getHUMA();                    //
                       Serial.print("HUM=" );   // Читаем данные.
         if( i< 0 )  { Serial.print("ERROR"); } // Сообщаем об ошибке чтения.
         else        { Serial.print( i , 2 ); } // Выводим данные с двумя знаками после запятой.
                       Serial.print("г/м3, ");  // Выводим единицы измерения.
    //   Читаем освещённость:                   //
         i=sensor.getLUX();                     //
                       Serial.print("LUX=" );   // Читаем данные.
         if( i< 0 )  { Serial.print("ERROR"); } // Сообщаем об ошибке чтения.
         else        { Serial.print( i , 0 ); } // Выводим данные целочисленно.
                       Serial.println("лк.");   // Выводим единицы измерения.
    //   Задержка (не обязательно):             //
         delay(1000);                           //
    }                                           //
    

    Этот пример кажется большим, но если убрать все проверки и некоторые комментарии, то код будет более компактным.

    Пример без проверок:

    uint8_t pinDE = 2;                           // Вывод DE конвертера UART-RS485.
                                                 //
    #include <iarduino_Modbus.h>                 // Подключаем библиотеку для работы по протоколу Modbus.
    #include <iarduino_MB_HTL.h>                 // Подключаем библиотеку для работы с блоком климатических датчиков.
                                                 //
    ModbusClient modbus(Serial1, pinDE);         // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE.
    iarduino_MB_HTL sensor(modbus);              // Создаём объект для работы с климатическими датчиками указав объект протокола Modbus.
                                                 //
    void setup(){                                //
         Serial.begin(9600); while(!Serial);     // Инициируем передачу данных в монитор последовательного порта, указав его скорость.
         Serial1.begin(9600); while(!Serial1);   // Инициируем работу с шиной UART подключённой к конвертеру UART-RS485.
         modbus.begin();                         // Инициируем работу по протоколу Modbus.
         sensor.begin(3);                        // Инициируем работу с блоком климатических датчиков, указав его адрес. Если адрес не указан sensor.begin(), то он будет найден, но это займёт некоторое время.
    }                                            //
                                                 //
    void loop(){                                 //
         float i;                                //
         i=sensor.getTEM();                      // Читаем температуру.
         Serial.print((String)"TEM="+i+"°C, " ); //
         i=sensor.getHUM();                      // Читаем относительную влажность.
         Serial.print((String)"HUM="+i+"%, "  ); //
         i=sensor.getHUMA();                     // Читаем абсолютную влажность.
         Serial.print((String)"HUM="+i+"г/м3, ");//
         i=sensor.getLUX();                      // Читаем освещённость.
         Serial.println((String)"LUX="+i+"лк."); //
         delay(1000);                            //
    }                                            //
    

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

    Описание функций библиотеки:

    В данном разделе описаны функции библиотеки iarduino_MB_HTL для работы с блоком климатических датчиков RS485 / Modbus. Эта библиотека работает совместно с библиотекой iarduino_Modbus, описание функций которой доступно по ссылке Wiki - Работа с протоколом Modbus RTU/ASCI по шине RS485.

    Подключение библиотек:

    В примерах вход DE конвертера UART-RS485 подключён к выводу D2 Arduino. Вместо вывода D2 можно использовать любой выход Arduino, номер выхода указывается при создании объекта для работы по протоколу Modbus.

    • Если используется аппаратная шина UART:
    #include <iarduino_Modbus.h>          // Подключаем библиотеку для работы по протоколу Modbus.
    #include <iarduino_MB_HTL.h>          // Подключаем библиотеку для работы с блоком климатических датчиков.
                                          //
    ModbusClient modbus(Serial, 2);       // Создаём объект для работы по протоколу Modbus указав класс Serial и номер вывода DE конвертера UART-RS485.
    iarduino_MB_HTL sensor(modbus);       // Создаём объект для работы с блоком климатических датчиков, указав объект протокола Modbus.
                                          //
    void setup(){                         //
         ...                              //
         Serial.begin(9600);              // Указываем скорость шины RS485. Она равна скорости шины UART подключённой к конвертеру UART-RS485.
         while(!Serial);                  //
         sensor.begin(3);                 // Инициируем работу с блоком климатических датчиков, указав его адрес.
         ...                              // Если адрес блока не указан sensor.begin(), то он будет найден автоматически.
    }                                     //
    

    Если используется аппаратная шина UART-1, то вместо класса Serial указываем Serial1, для шины UART2 указываем Serial2 и т.д.

    • Если используется программная реализация шины UART:
    #include <SoftwareSerial.h>           // Подключаем библиотеку для работы с программной шиной UART.
    #include <iarduino_Modbus.h>          // Подключаем библиотеку для работы по протоколу Modbus.
    #include <iarduino_MB_HTL.h>          // Подключаем библиотеку для работы с блоком климатических датчиков.
                                          //
    SoftwareSerial rs485(8, 9);           // Создаём объект для работы с программной шиной UART указывая выводы RX, TX.
    ModbusClient modbus(rs485, 2);        // Создаём объект для работы по протоколу Modbus указав объект программной шины UART и номер вывода DE конвертера UART-RS485.
    iarduino_MB_HTL sensor(modbus);       // Создаём объект для работы с блоком климатических датчиков, указав объект протокола Modbus.
                                          //
    void setup(){                         //
         ...                              //
         rs485.begin(9600);               // Указываем скорость шины RS485. Она равна скорости программной шины UART подключённой к конвертеру UART-RS485.
         while(!rs485);                   //
         sensor.begin(3);                 // Инициируем работу с блоком климатических датчиков, указав его адрес.
         ...                              // Если адрес блока не указан sensor.begin(), то он будет найден автоматически.
    }                                     //
    

    Для программной реализации шины UART необходимо указать выводы которые будут использоваться как RX и TX, в примере указаны выводы 8, и 9 соответственно. При создании объекта modbus указывается не класс Serial, а объект для работы с программной шиной UART.

    Скорость передачи данных по шине Modbus равна скорости шины UART.

    Функция begin();

    • Назначение: Инициализация работы с блоком климатических датчиков.
    • Синтаксис: begin( [ АДРЕС_МОДУЛЯ ] );
    • Параметр: АДРЕС_МОДУЛЯ uint8_t - значение от 1 до 247.
    • Возвращаемое значение: bool - результат инициализации (true или false).
    • Примечание:
      • Если вызвать функцию без параметра, то адрес блока климатических датчиков будет найден автоматически. На это уйдёт некоторое время и на шине долен быть только один блок климатических датчиков.
      • Функцию достаточно вызвать 1 раз в коде Setup(), до обращения к остальным функциям библиотеки.
      • Блоки климатических датчиков поставляются с адресом 3 на шине, но этот адрес можно изменить.
    • Пример:
    sensor.begin(3); // Инициируем работу с блоком климатических датчиков, указав его адрес на шине.
    

    Функция reset();

    • Назначение: Программная перезагрузка блока климатических датчиков.
    • Синтаксис: reset();
    • Параметры: Нет.
    • Возвращаемое значение: bool - результат перезагрузки (true или false).
    • Пример:
    sensor.reset(); // Выполняем программную перезагрузку.
    

    Функция changeID();

    • Назначение: Установка нового адреса на шине.
    • Синтаксис: changeID( АДРЕС_МОДУЛЯ );
    • Параметр: АДРЕС_МОДУЛЯ uint8_t - значение от 1 до 247.
    • Возвращаемое значение: bool - результат изменения адреса (true или false).
    • Примечание:
      • Новый адрес сохраняется в энергонезависимую память, а значит остаётся после отключения питания.
      • Выполнение функции занимает более 120 миллисекунд.
    • Пример:
    sensor.changeID(10); // Изменить адрес модуля на значение 10.
    

    Функция setSpeedMB();

    • Назначение: Установка новой скорости передачи данных.
    • Синтаксис: setSpeedMB( СКОРОСТЬ );
    • Параметр: СКОРОСТЬ uint32_t - может принимать одно из значений:
      4800 / 9600 / 19200 / 38400 / 57600 / 115200.
    • Возвращаемое значение: bool - результат изменения скорости (true или false).
    • Примечание:
      • Новая скорость применяется на 2 секунды, в течении которых её нужно подтвердить.
      • Если скорость не подтвердить в течении 2 секунд, модуль вернёт прежнюю скорость.
      • Скорость подтверждается функцией ackSpeedMB() на новой скорости шины.

    Функция ackSpeedMB();

    • Назначение: Подтверждение смены скорости передачи данных.
    • Синтаксис: ackSpeedMB();
    • Параметры: Нет.
    • Возвращаемое значение: bool - результат подтверждения скорости (true или false).
    • Примечание:
      • Подтверждение скорости выполняется после установки новой скорости модуля функцией setSpeedMB() и установки той же скорости для шины UART-RS485.
      • Если скорость не подтвердить в течении 2 секунд, модуль вернёт прежнюю скорость.
      • Подтверждённая скорость сохраняется в энергонезависимую память, а значит остаётся после отключения питания.
      • Выполнение функции занимает более 50 миллисекунд.
    • Пример:
    sensor.setSpeedMB(9600); // Изменить скорость модуля на 9600 бит/сек.
    Serial.begin(9600);      // Изменить скорость шины UART-RS485 на 9600 бит/сек.
    sensor.ackSpeedMB();     // Подтвердить скорость модуля.
    

    Функция setTypeMB();

    • Назначение: Установка нового типа протокола Modbus.
    • Синтаксис: setTypeMB( ТИП );
    • Параметр: ТИП uint8_t - может принимать значение MODBUS_RTU или MODBUS_ASCII.
    • Возвращаемое значение: bool - результат изменения типа протокола (true или false).
    • Примечание:
      • Новый тип протокола применяется на 2 секунды, в течении которых его нужно подтвердить.
      • Если тип протокола не подтвердить в течении 2 секунд, модуль вернёт прежний тип.
      • Тип протокола подтверждается функцией ackTypeMB() по новому типу протокола на шине.

    Функция ackTypeMB();

    • Назначение: Подтверждение смены типа протокола Modbus.
    • Синтаксис: ackTypeMB();
    • Параметры: Нет.
    • Возвращаемое значение: bool - результат подтверждения типа протокола (true или false).
    • Примечание:
      • Подтверждение типа протокола Modbus выполняется после установки нового типа протокола модуля функцией setTypeMB() и установки того-же типа протокола для передачи данных по шине UART-RS485.
      • Если тип протокола не подтвердить в течении 2 секунд, модуль вернёт прежний тип.
      • Подтверждённый тип протокола Modbus сохраняется в энергонезависимую память, а значит остаётся после отключения питания.
      • Выполнение функции занимает более 50 миллисекунд.
    • Пример:
    sensor.setTypeMB(MODBUS_RTU); // Изменить тип протокола модуля на Modbus RTU.
    modbus.setTypeMB(MODBUS_RTU); // Изменить тип протокола шины UART-RS485 на Modbus RTU.
    sensor.ackTypeMB();           // Подтвердить тип протокола модуля.
    

    Функция writeFlash();

    • Назначение: Запись пользовательского значения в Flash память.
    • Синтаксис: writeFlash( ЧИСЛО );
    • Параметр: ЧИСЛО uint16_t - любое значение от 0 до 65535.
    • Возвращаемое значение: bool - результат записи (true или false).
    • Примечание:
      • Записываемое число сохраняется в энергонезависимую память, а значит остаётся после отключения питания.
      • Выполнение функции занимает более 50 миллисекунд.
      • Для чтения числа из Flash памяти воспользуйтесь функцией readFlash().
      • Число хранится в регистре "Holding Registers" [0x0120] «USER_DATA».
    • Пример:
    sensor.writeFlash(12345); // Записать число в энергонезависимую память.
    

    Функция readFlash();

    • Назначение: Чтение пользовательского значения из Flash памяти.
    • Синтаксис: readFlash();
    • Параметры: Нет.
    • Возвращаемое значение: int32_t - число из памяти (0...65535) , или -1 при провале чтения.
    • Примечание:
      • Для записи числа в Flash память воспользуйтесь функцией writeFlash().
      • Число хранится в регистре "Holding Registers" [0x0120] «USER_DATA».
    • Пример:
    i = sensor.readFlash();         // Читаем число из энергонезависимой памяти.
    if(i<0){ Serial.print("ERR"); } // Сообщаем о ошибке.
    else   { Serial.print(  i  ); } // Выводим прочитанное значение.
    

    Функция getID();

    • Назначение: Чтение адреса устройства на шине.
    • Синтаксис: getID();
    • Параметры: Нет.
    • Возвращаемое значение: uint8_t - адрес (1...247), или 0 если устройство не инициировано.
    • Примечание:
      • Данная функция может пригодиться если инициализация устройства выполнена функцией begin() без указания адреса (адрес найден автоматически).
    • Пример:
    i = sensor.getID();              // Читаем адрес устройства на шине.
    if(i==0){ Serial.print("ERR"); } // Сообщаем о ошибке.
    else    { Serial.print(  i  ); } // Выводим адрес устройства на шине.
    

    Функция getVersion();

    • Назначение: Чтение версии прошивки устройства.
    • Синтаксис: getVersion();
    • Параметры: Нет.
    • Возвращаемое значение: uint8_t - версия прошивки, или 0 если устройство не инициировано.
    • Пример:
    i = sensor.getVersion();         // Читаем версию прошивки устройства.
    if(i==0){ Serial.print("ERR"); } // Сообщаем о ошибке.
    else    { Serial.print(  i  ); } // Выводим версию прошивки устройства.
    

    Функция setIDLED();

    • Назначение: Управление индикатором обнаружения устройства.
    • Синтаксис: setIDLED( СОСТОЯНИЕ );
    • Параметр: СОСТОЯНИЕ bool - флаг включения индикатора (true или false).
    • Возвращаемое значение: bool - результат применения состояния индикатора (true или false).
    • Примечание:
      • Индикатор обнаружения устройства - это светодиод на разъеме RJ-45.
      • Если индикатор включён, то светодиод постоянно светится. Так можно визуально определить устройство, если на шине имеются несколько одинаковых устройств.
      • Если индикатор отключен, то светодиод информирует о получении запросов, адресованных этому устройству.
    • Пример:
    sensor.setIDLED(true ); // Включаем индикатор обнаружения устройства.
    sensor.setIDLED(false); // Отключаем индикатор обнаружения устройства.
    

    Функция getPWR();

    • Назначение: Чтение напряжения питания.
    • Синтаксис: getPWR();
    • Параметры: Нет.
    • Возвращаемое значение: float - напряжение (5,000...24,000 В), или -1 при провале чтения.
    • Примечание:
      • Данная функция позволяет узнать напряжение питания поступившее на разъем RJ45.
      • Функция позволяет возвращать значение за пределами указанного диапазона, но корректная работа устройства при таком питании не гарантируется.
    • Пример:
    i = sensor.getPWR();            // Читаем напряжение поступившее на разъем RJ45.
    if(i<0){ Serial.print("ERR"); } // Сообщаем о ошибке.
    else   { Serial.print(  i  ); } // Выводим напряжение питания в вольтах.
    

    Функция checkSensor();

    • Назначение: Проверка климатических датчиков.
    • Синтаксис: checkSensor( ДАТЧИК );
    • Параметр: ДАТЧИК uint8_t - может принимать одно из следующих значений:
      • SENSOR_SHT - Проверить только датчик влажности и температуры (SHT20).
      • SENSOR_LTR - Проверить только датчик освещённости (LTR-553ALS).
      • SENSOR_ALL - Проверить все датчики блока.
    • Возвращаемое значение: int8_t - результат проверки датчиков может принимать любую комбинацию из следующих значений:
      • ERROR_SHT_INIT - Ошибка инициализации датчика влажности и температуры.
      • ERROR_SHT_DATA - Ошибка чтения данных датчика влажности и температуры.
      • ERROR_LTR_INIT - Ошибка инициализации датчика освещённости.
      • ERROR_LTR_DATA - Ошибка чтения данных датчика освещённости.
      • 0 - Ошибки не выявлены.
      • -1 - Нет ответа от модуля.
    • Примечание:
      • Функция позволяет проверить один указанный датчик, или все датчики сразу.
      • Ошибки инициализации информируют о неисправности датчика. Инициализацию датчиков осуществляет блок сразу после подачи питания или после перезагрузки.
      • Ошибки чтения информируют, что с момента инициализации была хотя бы одна ошибка.
    • Пример:
    uint8_t err = sensor.checkSensor(SENSOR_ALL); // Проверяем все датчики модуля.
    if( err < 0              ){ Serial.println("Модуль не отвечает");       }
    if( err == 0             ){ Serial.println("Ошибки не выявлены");       }
    if( err & ERROR_SHT_INIT ){ Serial.println("Неисправен датчик SHT");    }
    if( err & ERROR_SHT_DATA ){ Serial.println("Ошибка чтения SHT");        }
    if( err & ERROR_LTR_INIT ){ Serial.println("Неисправен датчик LTR");    }
    if( err & ERROR_LTR_DATA ){ Serial.println("Ошибка чтения LTR");        }
    

    Функция getTEM();

    • Назначение: Чтение температуры в °С.
    • Синтаксис: getTEM();
    • Параметры: Нет.
    • Возвращаемое значение: float - температура от -40 до +125, или -100 при провале чтения.
    • Примечание: Температура возвращается с одним знаком после запятой.
    • Пример:
    i = sensor.getTEM();              // Читаем температуру в °С.
    if(i<-40){ Serial.print("ERR"); } // Ошибка чтения.
    else     { Serial.print( i,1 ); } // Выводим температуру с одним знаком после запятой.
    

    Функция getHUM();

    • Назначение: Чтение относительной влажности в %.
    • Синтаксис: getHUM();
    • Параметры: Нет.
    • Возвращаемое значение: float - влажность от 0 до 100%, или -1 при провале чтения.
    • Примечание: Влажность возвращается с одним знаком после запятой.
    • Пример:
    i = sensor.getHUMA();           // Читаем влажность в %.
    if(i<0){ Serial.print("ERR"); } // Ошибка чтения.
    else   { Serial.print( i,1 ); } // Выводим влажность с одним знаком после запятой.
    

    Функция getHUMA();

    • Назначение: Чтение абсолютной влажности в г/м3.
    • Синтаксис: getHUMA();
    • Параметры: Нет.
    • Возвращаемое значение: float - влажность от 0 до 655.35 г/м3, или -1 при провале чтения.
    • Примечание: Влажность возвращается с двумя знаками после запятой.
    • Пример:
    i = sensor.getHUMA();           // Читаем влажность в г/м3.
    if(i<0){ Serial.print("ERR"); } // Ошибка чтения.
    else   { Serial.print( i,2 ); } // Выводим влажность с двумя знаками после запятой.
    

    Функция getLUX();

    • Назначение: Чтение освещённости в лк.
    • Синтаксис: getLUX();
    • Параметры: Нет.
    • Возвращаемое значение: float - освещённость от 0 до 65535 лк, или -1 при провале чтения.
    • Примечание: Освещённость возвращается целочисленно.
    • Пример:
    i = sensor.getLUX();            // Читаем освещённость в лк.
    if(i<0){ Serial.print("ERR"); } // Ошибка чтения.
    else   { Serial.print( i,0 ); } // Выводим освещённость без знаков после запятой.
    

    Функция setPeriod();

    • Назначение: Установка периода опроса датчика внутри блока.
    • Синтаксис: setPeriod( ДАТЧИК, ВРЕМЯ );
    • Параметры:
      • uint8_t ДАТЧИК - может принимать одно из следующих значений:
        • SENSOR_SHT - Установить период для датчика влажности и температуры (SHT20).
        • SENSOR_LTR - Установить период для датчика освещённости (LTR-553ALS).
        • SENSOR_ALL - Установить период для всех датчиков блока.
      • float ВРЕМЯ - количество секунд с одним знаком после запятой (от 0,1 до 6'553,5 сек.).
    • Возвращаемое значение: bool - результат применения нового периода (true или false).
    • Примечание:
      • Блок постоянно опрашивает все датчики через определённые промежутки времени, сохраняя результаты в регистрах. Это позволяет читать значения по шине без задержек.
      • Данная функция позволяет задать временные промежутки опроса датчиков блоком.
      • Например, если установить период опроса датчика равным 5 секундам. А запрашивать данные из блока по шине RS485 каждую секунду, то мы будем получать по 5 одинаковых значений подряд. Значит период опроса датчика блоком, должен быть меньше периода с которым мы получаем данные из блока по шине RS485.
      • Функцию достаточно вызвать по одному разу для требуемых датчиков в коде setup().
      • Если в качестве первого параметра указать SENSOR_ALL, то указанный период опроса применится ко всем датчикам блока.
      • Узнать период опроса датчика можно функцией getPeriod().
    • Пример:
    sensor.setPeriod(SENSOR_SHT, 0.5); // Указываем период опроса датчика влажности и температуры.
    sensor.setPeriod(SENSOR_LTR, 1.0); // Указываем период опроса датчика освещённости.
    sensor.setPeriod(SENSOR_ALL, 1.2); // Указываем период опроса для всех датчиков блока.
    

    Функция getPeriod();

    • Назначение: Чтение установленного периода опроса датчика внутри блока.
    • Синтаксис: getPeriod( ДАТЧИК );
    • Параметр: ДАТЧИК uint8_t - может принимать одно из следующих значений:
      • SENSOR_SHT - Получить период опроса датчика влажности и температуры (SHT20).
      • SENSOR_LTR - Получить период опроса датчика освещённости (LTR-553ALS).
    • Возвращаемое значение: float - время в секундах (0,1...6'553,5), или -1 при провале чтения.
    • Примечание:
      • Блок постоянно опрашивает все датчики через определённые промежутки времени, сохраняя результаты в регистрах. Это позволяет читать значения по шине без задержек.
      • Функция возвращает время в секундах с одним знаком после запятой. Это время является периодом опроса датчика модулем.
    • Пример:
    i = sensor.getPeriod(SENSOR_SHT); // Читаем период опроса датчика влажности и температуры.
    if(i<0){ Serial.print("ERR"); }   // Ошибка чтения.
    else   { Serial.print( i,1 ); }   // Выводим время в секундах с одним знаком после запятой.
    

    Обработка ошибок:

    Рассмотренные выше функции библиотеки iarduino_MB_HTL возвращают не только результат чтения, но и ошибки при записи или чтении. Причину ошибок можно выяснить функцией lastError() библиотеки iarduino_Modbus.

    Функция lastError();

    • Назначение: Получение кода причины последней ошибки.
    • Синтаксис: lastError(); // Функция библиотеки iarduino_Modbus.
    • Параметры: Нет.
    • Возвращаемое значение: uint8_t - код причины последней ошибки.
      • ERROR_ILLEGAL_FUNCTION - Команда запроса не поддерживается модулем.
      • ERROR_ILLEGAL_ADDRESS - У модуля отсутствует регистр с указанным адресом.
      • ERROR_ILLEGAL_VALUE - Недопустимое значение в поле данных запроса.
      • ERROR_DEVICE_FAILURE - Любая невосстановимая ошибка кроме первых трёх.
      • ERROR_ACKNOWLEDGE - Модуль принял запрос, но на обработку требуется время.
      • ERROR_DEVICE_BUSY - Ведомый занят, запрос проигнорирован.
      • ERROR_MEMORY_PARITY - Ошибка чтения/записи файла.
      • ERROR_GATEWAY_UNAVAILABLE - Шина перегружена данными или не настроена.
      • ERROR_GATEWAY_NO_DEVICE - Ведомого устройства нет или от него нет ответа.
      • ERROR_SYNTAX - Ошибка синтаксиса.
      • ERROR_ADR_IARDUINO - Ошибка назначения или сортировки адресов устройств iarduino.
      • ERROR_ADR_RESPONSE - Несовпадение адреса регистра в ответе.
      • ERROR_VAL_RESPONSE - Несовпадение данных в ответе.
      • ERROR_CRC_RESPONSE - Несовпадение CRC в принятом ответе.
      • ERROR_LEN_REQUEST - Размер отправляемого запроса превышает размер буфера.
      • ERROR_LEN_RESPONSE - Размер полученного ответа превышает размер буфера.
    • Пример:
    float i = sensor.getLUX();           // Читаем освещённость в лк.
    if(i>=0){                            // Если чтение выполнено без ошибок...
        Serial.print( i,0 );             // Выводим значение освещённости без знаков после запятой.
    }else{                               // Если чтение не выполнено...
        switch( modbus.lastError() ){    // Получаем код последней ошибки.
            case ERROR_ILLEGAL_FUNCTION:    Serial.println( F("Модуль не поддерживает команду или функцию запроса")           ); break;
            case ERROR_ILLEGAL_ADDRESS:     Serial.println( F("Запрос содержит недопустимый адрес регистра")                  ); break;
            case ERROR_ILLEGAL_VALUE:       Serial.println( F("Запрос содержит недопустимое значение в поле данных")          ); break;
            case ERROR_DEVICE_FAILURE:      Serial.println( F("Ошибка запроса не связана с командой, адресом или данными")    ); break;
            case ERROR_ACKNOWLEDGE:         Serial.println( F("Модуль сообщает что занят и обработает запрос позже")          ); break;
            case ERROR_DEVICE_BUSY:         Serial.println( F("Модуль сообщает что занят и не будет обрабатывать запрос")     ); break;
            case ERROR_MEMORY_PARITY:       Serial.println( F("Модуль сообщает что произошла ошибка чтения/записи файла")     ); break;
            case ERROR_GATEWAY_UNAVAILABLE: Serial.println( F("Шлюз неправильно настроен или перегружен запросами")           ); break;
            case ERROR_GATEWAY_NO_DEVICE:   Serial.println( F("Модуль которому адресован запрос не отвечает")                 ); break;
            case ERROR_SYNTAX:              Serial.println( F("Ошибка синтаксиса")                                            ); break;
            case ERROR_ADR_IARDUINO:        Serial.println( F("Ошибка назначения или сортировки адресов устройств iarduino")  ); break;
            case ERROR_ADR_RESPONSE:        Serial.println( F("Ответ от модуля содержит недопустимый адрес регистра")         ); break;
            case ERROR_VAL_RESPONSE:        Serial.println( F("Ответ от модуля содержит недопустимое значение в поле данных") ); break;
            case ERROR_CRC_RESPONSE:        Serial.println( F("Несовпадение CRC в ответе модуля")                             ); break;
            case ERROR_LEN_REQUEST:         Serial.println( F("Размер запроса к модулю превышает буфер обмена или ADU")       ); break;
            case ERROR_LEN_RESPONSE:        Serial.println( F("Размер ответа от модуля превышает буфер обмена")               ); break;
            default:                        Serial.println( F("Неизвестная ошибка")                                           ); break;
        }
    }
      Зная причину ошибки, можно принять меры к её устранению:
    • ERROR_GATEWAY_NO_DEVICE - нет ответа от модуля, означает что устройство отсутствует на шине. Причиной данной ошибки может быть, как физическое отключение устройства, так и плохой контакт, или недостаточное питание.
    • ERROR_SYNTAX - ошибка синтаксиса, означает наличие ошибки в коде, например функция вызвавшая данную ошибку была вызвана с некорректными параметрами, или вызвана до инициализации модуля.

    Ссылки:




    Обсуждение

    Гарантии и возврат Используя сайт Вы соглашаетесь с условями