Общие сведения:
Датчик эквивалента углекислого газа eCO2 RS485 / Modbus - является устройством измерения количества эквивалента углекислого газа eСО2 и количества летучих органических соединений в окружающем воздухе, позволяющее получать указанные значения по протоколу Modbus шины RS485.
Датчик построен на базе чипа SGP30 который измеряет содержание H2, паров этанола и иных газов в воздухе, обрабатывает полученные значение и вычисляет количество эквивалента eC02 и TVOC. Стоит учесть что эквивалент eCO2 это не CO2. Так при снижении концентрации CO2 ниже 350 ppm и снижении концентрации H2 или увеличении концентрации паров этанола, алгоритм чипа определит резкое увеличение эквивалента eCO2. Лучшие результаты датчик показывает при содержании CO2 выше 400 ppm.
Датчик можно использовать для контроля климата гидропонной установки. Устройство легко подключается к блоку управления гидропонной установки, сетевым кабелем через разъемы RJ45.
Датчик не обязательно использовать в гидропонных установках, это могут быть иные проекты где требуется контролировать климат используя для получения данных протокол Modbus широко применяемый в промышленности.
В соответствии с протоколом Modbus, к одной шине RS485 можно подключить до 247 датчиков. Адрес устройства (по умолчанию 0x03) назначается программно и хранится в энергонезависимой памяти. Все устройства на шине должны иметь уникальный адрес.
Видео:
Редактируется...
Спецификация:
- Напряжение питания: от 12 до 24 В постоянного тока (разъем RJ45).
- Ток потребляемый модулем: до 50 мА (при включённом нагревательном элементе).
- Интерфейс: RS485 / Modbus.
- Скорость шины: 4800 / 9600 / 19200 / 38400 / 57600 / 115200 бит/с.
- Адрес на шине: устанавливается программно (по умолчанию 0x03).
- Диапазон обнаружения эквивалента СО2: от 400 до 60'000 ppm (с шагом 1).
- Диапазон обнаружения летучих органических соединений: от 0 до 60'000 ppm (с шагом 1).
- Рабочая температура: от -25 до +80 °С.
- Габариты: 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. Модуль сохраняет работоспособность при снижении питания до 5В. Не подавайте питание выше 24В.
Подробнее о датчике:
Датчик эквивалента углекислого газа eCO2 RS485 / Modbus построен на базе микроконтроллера STM32G030F4 и конвертера SN65HVD3082EDR с цепями защиты шины RS485 и встроенным терминатором, который можно отключать переключателем на плате. В устройстве присутствуют: импульсный DC-DC преобразователь, линейные преобразователи и чип SGP30 с встроенным нагревательным элементом. На корпусе блока есть фиксатор позволяющий устанавливать его на DIN-рейку.
Датчик позволяет:
- Менять свой адрес на шине.
- Менять тип протокола Modbus (RTU/ASCII).
- Менять скорость передачи данных.
- Сохранять одно двухбайтное слово в энергонезависимую память и читать его.
- Читать напряжение питания поступившее с разъема RJ45.
- Управлять светодиодом обнаружения устройства на разъеме RJ45.
- Читать показания:
- Эквивалент СО2, в частях на миллион (ppm).
- Количество летучих органических соединений, в частях на миллиард (ppm).
- Эквивалент СО2, в частях на миллион (ppm).
- Задавать и узнавать период обновления показаний чипа SGP30.
Для работы с датчиком эквивалента углекислого газа eCO2 RS485 / Modbus предлагаем воспользоваться разработанными нами библиотеками iarduino_Modbus и iarduino_MB_eCO2. Первая позволяет работать по протоколу Modbus на шине RS485, а вторая предназначена для работы с датчиком эквивалента углекислого газа.
Подробнее про установку библиотек читайте в нашей инструкции.
Примеры:
- Предложенные библиотеки содержат больше примеров, доступных из меню Arduino IDE:
- Файл / Примеры / iarduino Modbus (протокол) / ModbusClient / HardwareSerial.
- Файл / Примеры / iarduino Modbus (протокол) / ModbusClient / SoftwareSerial.
- Файл / Примеры / iarduino Modbus eCO2 (датчик CO2) / HardwareSerial.
- Файл / Примеры / iarduino Modbus eCO2 (датчик CO2) / 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_eCO2.h> // Подключаем библиотеку для работы с датчиком эквивалента углекислого газа. // ModbusClient modbus(Serial1, pinDE); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_eCO2 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_eCO2.h> // Подключаем библиотеку для работы с датчиком эквивалента углекислого газа. // ModbusClient modbus(Serial1, pinDE); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_eCO2 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( 1.0f ); // Указываем модулю обновлять данные каждую секунду. } // // void loop(){ // float i; // // Читаем количество эквивалента СО2: // i=sensor.getCO2(); // Serial.print("CO2=" ); // Читаем данные. if( i< 0 ) { Serial.print("ERROR"); } // Сообщаем об ошибке чтения. else { Serial.print( i , 0 ); } // Выводим данные целочисленно. Serial.print("ppm, "); // Выводим единицы измерения. // Количество органических соединений: // i=sensor.getTVOC(); // Serial.print("TVOC="); // Читаем данные. if( i< 0 ) { Serial.print("ERROR"); } // Сообщаем об ошибке чтения. else { Serial.print( i , 0 ); } // Выводим данные целочисленно. Serial.println("ppb"); // Выводим единицы измерения. // Задержка (не обязательно): // delay(1000); // } //
Этот пример кажется большим, но если убрать все проверки и некоторые комментарии, то код будет более компактным.
Пример без проверок:
uint8_t pinDE = 2; // Вывод DE конвертера UART-RS485. // #include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus. #include <iarduino_MB_eCO2.h> // Подключаем библиотеку для работы с датчиком эквивалента углекислого газа. // ModbusClient modbus(Serial1, pinDE); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_eCO2 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.getCO2(); // Читаем количество эквивалента СО2. Serial.print((String)"eCO2="+i+"ppm, ");// i=sensor.getTVOC(); // Читаем количество летучих органических соединений. Serial.println((String)"TVOC="+i+"ppb");// delay(1000); // } //
Несмотря на то, что код без проверок кажется более понятным, рекомендуется выполнять проверки, так как это помогает отслеживать ошибки в процессе работы устройства.
Описание функций библиотеки:
В данном разделе описаны функции библиотеки iarduino_MB_eCO2 для работы с датчиком эквивалента углекислого газа 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_eCO2.h> // Подключаем библиотеку для работы с датчиком эквивалента углекислого газа. // ModbusClient modbus(Serial, 2); // Создаём объект для работы по протоколу Modbus указав класс Serial и номер вывода DE конвертера UART-RS485. iarduino_MB_eCO2 sensor(modbus); // Создаём объект для работы с датчиком эквивалента углекислого газа, указав объект протокола Modbus. // void setup(){ // ... // Serial.begin(9600); // Указываем скорость шины RS485. Она равна скорости шины UART подключённой к конвертеру UART-RS485. while(!Serial); // sensor.begin(6); // Инициируем работу с датчиком эквивалента углекислого газа, указав его адрес. ... // Если адрес блока не указан sensor.begin(), то он будет найден автоматически. } //
Если используется аппаратная шина UART-1, то вместо класса Serial указываем Serial1, для шины UART2 указываем Serial2 и т.д.
- Если используется программная реализация шины UART:
#include <SoftwareSerial.h> // Подключаем библиотеку для работы с программной шиной UART. #include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus. #include <iarduino_MB_eCO2.h> // Подключаем библиотеку для работы с датчиком эквивалента углекислого газа. // SoftwareSerial rs485(8, 9); // Создаём объект для работы с программной шиной UART указывая выводы RX, TX. ModbusClient modbus(rs485, 2); // Создаём объект для работы по протоколу Modbus указав объект программной шины UART и номер вывода DE конвертера UART-RS485. iarduino_MB_eCO2 sensor(modbus); // Создаём объект для работы с датчиком эквивалента углекислого газа, указав объект протокола Modbus. // void setup(){ // ... // rs485.begin(9600); // Указываем скорость шины RS485. Она равна скорости программной шины UART подключённой к конвертеру UART-RS485. while(!rs485); // sensor.begin(6); // Инициируем работу с датчиком эквивалента углекислого газа, указав его адрес. ... // Если адрес блока не указан sensor.begin(), то он будет найден автоматически. } //
Для программной реализации шины UART необходимо указать выводы которые будут использоваться как RX и TX, в примере указаны выводы 8, и 9 соответственно. При создании объекта modbus указывается не класс Serial, а объект для работы с программной шиной UART.
Скорость передачи данных по шине Modbus равна скорости шины UART.
Функция begin();
- Назначение: Инициализация работы с датчиком эквивалента углекислого газа.
- Синтаксис: begin( [ АДРЕС_МОДУЛЯ ] );
- Параметр: АДРЕС_МОДУЛЯ uint8_t - значение от 1 до 247.
- Возвращаемое значение: bool - результат инициализации (true или false).
- Примечание:
- Если вызвать функцию без параметра, то адрес датчика эквивалента углекислого газа будет найден автоматически. На это уйдёт некоторое время и на шине долен быть только один датчик эквивалента углекислого газа.
- Функцию достаточно вызвать 1 раз в коде Setup(), до обращения к остальным функциям библиотеки.
- Датчики эквивалента углекислого газа поставляются с адресом 6 на шине, но этот адрес можно менять.
- Пример:
sensor.begin(6); // Инициируем работу с датчиком эквивалента углекислого газа, указав его адрес на шине.
Функция reset();
- Назначение: Программная перезагрузка датчика эквивалента углекислого газа.
- Синтаксис: reset();
- Параметры: Нет.
- Возвращаемое значение: bool - результат перезагрузки (true или false).
- Примечание:
- Выполняется сброс счётчиков журнала событий modbus и временных переменных.
- Выполняется сброс ошибок регистра диагностики возвращаемых функцией checkSensor().
- Выполняется перезагрузка и самодиагностика датчика.
- Нагревательный элемент чипа SGP30 отключается и включается через 100 мс.
- Чип SGP30 в течении 15 секунд после включения нагревательного элемента будет возвращать eCO2=400ppm, TVOC=0ppb.
- Пример:
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();
- Параметры: Нет.
- Возвращаемое значение: int8_t - результат проверки датчика может принимать любую комбинацию из следующих значений:
- ERROR_SGP_INIT - Ошибка инициализации чипа SGP30.
- ERROR_SGP_DATA - Ошибка чтения данных из чипа SGP30.
- 0 - Ошибки не выявлены.
- -1 - Нет ответа от модуля.
- Примечание:
- Функция позволяет проверить работу датчика с чипом SGP30.
- Инициализацию чипа SGP30 осуществляет датчик сразу после подачи питания или после перезагрузки.
- Ошибки чтения информируют, что с момента инициализации была хотя бы одна ошибка.
- Для сброса ошибок нужно перезагрузить датчик функцией reset().
- Пример:
uint8_t err = sensor.checkSensor(); // Проверяем работу чипа в датчике эквивалента углекислого газа. if( err < 0 ){ Serial.println("Модуль не отвечает"); } if( err == 0 ){ Serial.println("Ошибки не выявлены"); } if( err & ERROR_SGP_INIT ){ Serial.println("Неисправен чип SGP"); } if( err & ERROR_SGP_DATA ){ Serial.println("Ошибка чтения SGP" ); }
Функция setHeating();
- Назначение: Управление нагревательным элементом чипа SGP30 в датчике.
- Синтаксис: setHeating( ФЛАГ );
- Параметр: bool - ФЛАГ разрешения работы нагревательного элемента (true или false).
- Возвращаемое значение: bool - результат применения флага (true или false).
- Примечание:
- В чип SGP30 интегрирован нагревательный элемент, который необходим для количественного определения эквивалента СО2 и летучих органический соединений.
- Отключение нагревательного элемента в разы уменьшает потребляемую мощность.
- Если нагревательный элемент отключён, или с момента его включения прошло меньше 15 секунд, то датчик будет возвращать значения: eCO2=400ppm, TVOC=0ppb.
- Узнать реальное состояние нагревательного элемента можно функцией getHeating().
- По умолчанию, нагревательный элемент включается при подаче питания на датчик.
- Пример:
sensor.setHeating(true); // Включить нагревательный элемент чипа SGP30.
Функция getHeating();
- Назначение: Чтение состояния нагревательного элемента чипа SGP30.
- Синтаксис: getHeating();
- Параметры: Нет.
- Возвращаемое значение: int8_t - флаг состояния (true / false), или -1 при провале чтения.
- Примечание:
- Для работы датчика, нагревательный элемент чипа SGP30 должен быть включён.
- Если нагревательный элемент отключён, или с момента его включения прошло меньше 15 секунд, то датчик будет возвращать значения: eCO2=400ppm, TVOC=0ppb.
- Если функция вернула 1 (true), значит нагревательный элемент включён.
- Если функция вернула 0 (false), значит нагревательный элемент отключён.
- Если функция вернула -1, значит датчик не ответил на запрос.
- Пример:
i = sensor.getHeating(); // Читаем состояние нагревательного элемента чипа. if(i<0){ Serial.print("ERR" ); } // Ошибка чтения. else { Serial.print(i?"ON":"OFF"); } // Выводим состояние нагревательного элемента.
Функция getCO2();
- Назначение: Чтение количества эквивалента СО2 в частях на миллион.
- Синтаксис: getCO2();
- Параметры: Нет.
- Возвращаемое значение: float - количество от 400 до 60'000 ppm, или -1 при провале чтения.
- Примечание: Количество эквивалента СО2 возвращается целочисленно.
- Пример:
i = sensor.getCO2(); // Читаем количество эквивалента СО2 в ppm. if(i<0){ Serial.print("ERR"); } // Ошибка чтения. else { Serial.print( i,0 ); } // Выводим количество эквивалента СО2 без знаков после запятой.
Функция getTVOC();
- Назначение: Чтение количества летучих органический соединений в частях на миллиард.
- Синтаксис: getTVOC();
- Параметры: Нет.
- Возвращаемое значение: float - количество от 0 до 60'000 ppb, или -1 при провале чтения.
- Примечание: Количество летучих органический соединений возвращается целочисленно.
- Пример:
i = sensor.getTVOC(); // Читаем количество летучих органический соединений в ppb. if(i<0){ Serial.print("ERR"); } // Ошибка чтения. else { Serial.print( i,0 ); } // Выводим количество летучих органический соединений без знаков после запятой.
Функция setPeriod();
- Назначение: Установка периода опроса чипа SGP30 внутри датчика.
- Синтаксис: setPeriod( ВРЕМЯ );
- Параметр:
- float ВРЕМЯ - количество секунд с одним знаком после запятой (от 0,1 до 6'553,5 сек.).
- Возвращаемое значение: bool - результат применения нового периода (true или false).
- Примечание:
- Датчик постоянно опрашивает чип SGP30 через определённые промежутки времени, сохраняя результаты в регистрах. Это позволяет читать значения по шине без задержек.
- Данная функция позволяет задать временные промежутки опроса чипа датчиком.
- Например, если установить период опроса чипа равным 5 секундам. А запрашивать данные из датчика по шине RS485 каждую секунду, то мы будем получать по 5 одинаковых значений подряд. Значит период опроса чипа датчиком, должен быть меньше периода с которым мы получаем данные из датчика по шине RS485.
- Функцию достаточно вызвать один раз в коде setup().
- Узнать период опроса чипа можно функцией getPeriod().
- Период опроса по умолчанию равен 1 секунде.
- Пример:
sensor.setPeriod(1.0); // Указываем период опроса чипа равный 1 секунде.
Функция getPeriod();
- Назначение: Чтение установленного периода опроса чипа SGP30 внутри датчика.
- Синтаксис: getPeriod();
- Параметры: Нет.
- Возвращаемое значение: float - время в секундах (0,1...6'553,5), или -1 при провале чтения.
- Примечание:
- Датчик постоянно опрашивает чип SGP30 через определённые промежутки времени, сохраняя результаты в регистрах. Это позволяет читать значения по шине без задержек.
- Функция возвращает время в секундах с одним знаком после запятой. Это время является периодом опроса чипа датчиком.
- Пример:
i = sensor.getPeriod(); // Читаем период опроса чипа. if(i<0){ Serial.print("ERR"); } // Ошибка чтения. else { Serial.print( i,1 ); } // Выводим время в секундах с одним знаком после запятой.
Обработка ошибок:
Рассмотренные выше функции библиотеки iarduino_MB_eCO2 возвращают не только результат чтения, но и ошибки при записи или чтении. Причину ошибок можно выяснить функцией 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.getCO2(); // Читаем количества эквивалента СО2 в частях на миллион. 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 - ошибка синтаксиса, означает наличие ошибки в коде, например функция вызвавшая данную ошибку была вызвана с некорректными параметрами, или вызвана до инициализации модуля.
Ссылки:
- Датчик эквивалента углекислого газа eCO2 RS485 / Modbus.
- Trema конвертер UART-RS485.
- Wiki - Блоки климатические (eCO2,TVOC, t°C, RH%, lux) RS485 / Modbus - Datasheet.
- Wiki - Работа с протоколом Modbus RTU/ASCI по шине RS485.
- Библиотека iarduino_Modbus.
- Библиотека iarduino_MB_eCO2.
- Wiki - Установка библиотек в Arduino IDE.
Обсуждение