Общие сведения:
Датчик кислотности жидкости (pH-метр) RS485 / Modbus с дисплеем и без дисплея - является устройством для измерения водородного показателя жидкости (показателя pH), характеризующего её кислотность, в диапазоне от 0 pH до 14 pH. Рассчитанную кислотность можно получать по протоколу Modbus шины RS485.
Датчик обеспечивает гальваническую развязку разъема щупа и разъема шины с питанием, что гарантирует отсутствие влияния и реакции щупа на другие устройства измерения жидкости.
Устройство можно использовать для анализа жидкостей используемых в аквариумах, системах водоснабжения, гидропонных установках и т.д. Датчик легко подключается сетевым кабелем через разъем RJ45.
В соответствии с протоколом Modbus, широко применяемому в промышленности, к одной шине RS485 можно подключить до 247 pH-метров. Адрес устройства (по умолчанию 0x04) назначается программно и хранится в его энергонезависимой памяти. Все устройства на шине должны иметь уникальный адрес.
Видео:
Спецификация:
- Напряжение питания: от 12 до 24 В постоянного тока (разъем RJ45).
- Ток потребляемый датчиком: до 100 мА (при свечении всех сегментов дисплея).
- Интерфейс: RS485 / Modbus.
- Скорость шины: 2400 / 4800 / 9600 / 19200 / 38400 / 57600 / 115200 бит/с.
- Адрес на шине: устанавливается программно (по умолчанию 0x04).
- Диапазон измерений водородного показателя: от 0 до 14 pH
- Рабочая температура: от 0 до +60 °С.
- Габариты: 100 x 70 x 40 мм.
- Вес: ? г.
Подключение:
Важно: Перед подключением устройства к шине RS485 нужно отключить питание.
Так называемое «горячее подключение» может повредить устройство!
На корпусе датчика pH-метра имеется 2 разъёма: RJ45 и BNC:
- Разъем RJ45 - для подключения датчика к контроллеру по шине RS485.
- Разъем BNC - для подключения измерительного щупа.
Назначение выводов разъема 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» Индикатор получения запроса и обнаружения устройства:
- Индикатор включается при получении запросов, что позволяет визуально отследить их поступление.
- Устройству можно отправить команду на постоянное свечение индикатора, что позволит визуально найти устройство с известным адресом среди одинаковых устройств на шине.
Назначение выводов разъёма BNC:
- 1: «IN» - Вывод щупа на котором датчик устанавливает потенциал 1/2 Vcc = 1,65 В
- 2: «OUT» - Вывод щупа с которого сигнал поступает на вход микросхемы АЦП.
- Потенциалы разъема BNC гальванически развязаны с потенциалами разъема RJ45.
Если к разъёму BNC подключить щуп и погрузить его в нейтральную жидкость 7.0 pH, то между выводами 1 и 2 не будет разности потенциалов, что подано на вывод 1, то и придёт с вывода 2.
Щуп поставляемый с датчиком имеет чувствительность 59,16 мВ/pH. Это значит, что изменение кислотности на 1pH приводит к изменению разности потенциалов между выводами на 59,16 мВ. Но входное сопротивление микросхемы АЦП частично шунтирует напряжение щупа и снижает его чувствительность до 30 мВ/pH.
Значит при погружении щупа в жидкость 6.0 pH, на выводе 2 будет потенциал 1,65+0,03=1,68В, а при погружении щупа в жидкость 8.0 pH, на выводе 2 будет потенциал 1,65-0,03 = 1,62В.
Стоит учесть, что измерительный щуп является расходным материалом. Его характеристики со временем ухудшаются, уменьшается чувствительность и сдвигается потенциал нейтральной кислотности. Калибровка позволяет датчику определить текущие характеристики щупа, сохранить их в энергонезависимую память и использовать в дальнейших расчётах.
Питание:
Входное напряжение питания датчика от 12 до 24В постоянного тока подаётся через разъем PJ45. Датчик сохраняет работоспособность при снижении питания до 5В. Не подавайте питание выше 24В.
Подробнее о датчике:
Датчик кислотности жидкости (pH-метр) RS485 / Modbus построен на базе микроконтроллера STM32G030F4, микросхемы АЦП CS1237 и конвертера SN65HVD3082EDR с цепями защиты шины RS485 и встроенным терминатором, который можно отключать переключателем на плате. В устройстве используется несколько DC-DC преобразователей и стабилизаторы питания. Наличие гальванической развязки по линиям питания и линиям данных гарантирует, что измерительный щуп pH-метра не будет реагировать на другие устройства измерения жидкости подключённые к той же шине RS485.
Датчик с дисплеем оснащен четырёхразрядным LED дисплеем для отображается кислотности в режиме реального времени.
Датчик без дисплея оснащен зуммером для подачи сигналов о ошибках и стадиях калибровки.
Датчики способны работать с различными измерительными щупами, подключаемыми к разъему BNC, калибровка которых осуществляется всего одним нажатием на кнопку.
Принцип действия pH-метра основан на измерении величины ЭДС электродной системы, значение которой пропорционально водородному показателю pH = -Lg[H+]. Устройство считывает разницу потенциалов между выводами щупа, преобразуя полученные данные в отклонение водородного показателя жидкости от нейтрального значения 7,0 pH.
Датчик позволяет:
- Менять свой адрес на шине.
- Менять тип протокола Modbus (RTU/ASCII).
- Менять скорость передачи данных.
- Сохранять одно двухбайтное слово в энергонезависимую память и читать его.
- Читать гальванически развязанные напряжения с разных узлов схемы.
- Управлять светодиодом обнаружения устройства на разъеме RJ45.
- Запускать и контролировать процесс калибровки измерительного щупа.
- Получать результаты калибровки и менять их вручную.
- Задавать кислотности жидкостей используемых для калибровки.
- Получать водородный показатель исследуемой жидкости.
Для работы с датчиком кислотности жидкости (pH-метр) RS485 / Modbus с дисплеем и без дисплея, предлагаем воспользоваться разработанными нами библиотеками iarduino_Modbus и iarduino_MB_pH. Первая позволяет работать по протоколу Modbus на шине RS485, а вторая предназначена для работы с датчиком pH-метра.
Подробнее про установку библиотек читайте в нашей инструкции.
Примеры:
- Предложенные библиотеки содержат больше примеров, доступных из меню Arduino IDE:
- Файл / Примеры / iarduino Modbus (протокол) / ModbusClient / HardwareSerial.
- Файл / Примеры / iarduino Modbus (протокол) / ModbusClient / SoftwareSerial.
- Файл / Примеры / iarduino Modbus pH (pH-метр) / HardwareSerial.
- Файл / Примеры / iarduino Modbus pH (pH-метр) / 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 (назначается в скетче).
Trema конвертер UART-RS485 позволяет использовать датчик с дисплеем, без подключения к контроллеру (Arduino). Нужно подать питание на колодку Vin конвертера, а выводы TX, RX, G, V, D оставить без подключения. Получается схема визуального контроля за кислотностью жидкости.
В примерах ниже, для создания шины RS485, будет использована аппаратная шина UART1 (класс Serial1). Если у вашей платы Arduino нет свободных аппаратных шин UART, используйте программную шину UART при помощи входящей в состав Arduino IDE библиотеки SoftwareSerial.
Смена адреса датчика на шине:
Пример меняет текущий адрес датчика (nowAddress) на новый (newAddress) и сохраняет его в энергонезависимую память датчика, значит адрес сохранится и после отключения питания.
uint8_t nowAddress = 4; // Текущий адрес pH-метра ( 1 - 247 ). uint8_t newAddress = 10; // Новый адрес pH-метра ( 1 - 247 ). uint8_t pinDE = 2; // Вывод DE конвертера UART-RS485. // #include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus. #include <iarduino_MB_pH.h> // Подключаем библиотеку для работы с датчиком pH-метра. // ModbusClient modbus(Serial1, pinDE); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_pH sensor(modbus); // Создаём объект для работы с pH-метром указав объект протокола 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); // Инициируем работу с датчиком pH-метра, указав его текущий адрес nowAddress. if(f){ Serial.println("OK"); } // Если f=true значит инициализация пройдена успешно. else { Serial.println("ERR"); } // Если f=false значит инициализация не пройдена. Serial.print("Смена адреса "); // f = sensor.changeID(newAddress); // Меняем адрес датчика pH-метра на новый newAddress. if(f){ Serial.println("OK"); } // Если f=true значит адрес изменён. else { Serial.println("ERR"); } // Если f=false значит адрес не изменён. Serial.print("Текущий адрес "); // Serial.println(sensor.getID()); // Выводим текущий адрес датчика pH-метра. Serial.print("Версия прошивки "); // Serial.println(sensor.getVersion()); // Выводим версию прошивки датчика pH-метра. } // // 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_pH.h> // Подключаем библиотеку для работы с датчиком pH-метра. // ModbusClient modbus(Serial1, pinDE); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_pH sensor(modbus); // Создаём объект для работы с pH-метром указав объект протокола Modbus. // void setup(){ // Serial.begin(9600); while(!Serial); // Инициируем передачу данных в монитор последовательного порта, указав его скорость. Serial1.begin(9600); while(!Serial1); // Инициируем работу с шиной UART-RS485 указав её скорость. modbus.begin(); // Инициируем работу по протоколу Modbus. // modbus.setTimeout(10); // Указываем максимальное время ожидания ответа по протоколу Modbus. // modbus.setDelay(4); // Указываем минимальный интервал между отправляемыми сообщениями по протоколу Modbus. // modbus.setTypeMB( MODBUS_RTU ); // Указываем тип протокола Modbus: MODBUS_RTU (по умолчанию), или MODBUS_ASCII. bool f = sensor.begin(4); // Инициируем работу с датчиком pH-метра, указав его адрес. if( !f ){ // Если функция begin() вернула false, значит датчик pH-метра с адресом 4 не найден. Serial.print("pH-метр не найден"); // while(1); // Запрещаем дальнейшее выполнение скетча. } // } // // void loop(){ // delay(1000); // // Получаем кислотность жидкости: // float pH = sensor.getPH(); // Получаем кислотность жидкости. // Выводим результат: // if( pH<0 ){ Serial.println("Err"); } // Сообщаем о ошибке чтения. else { Serial.println(pH, 1); } // Выводим полученный водородный показатель жидкости с одним знаком после запятой. } //
Этот пример кажется большим, но если убрать все проверки и некоторые комментарии, то код будет более компактным.
Пример выводит показания кислотности без проверок инициализации и чтения:
#include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus. #include <iarduino_MB_pH.h> // Подключаем библиотеку для работы с датчиком pH-метра. // ModbusClient modbus(Serial1, 2); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_pH sensor(modbus); // Создаём объект для работы с pH-метром указав объект протокола Modbus. // void setup(){ // Serial.begin(9600); while(!Serial); // Инициируем передачу данных в монитор последовательного порта, указав его скорость. Serial1.begin(9600); while(!Serial1); // Инициируем работу с шиной UART-RS485 указав её скорость. modbus.begin(); // Инициируем работу по протоколу Modbus. sensor.begin(4); // Инициируем работу с pH-метром, указав его адрес. } // Если адрес не указан sensor.begin(), то он будет найден, но это займёт некоторое время. // void loop(){ // delay(1000); // Serial.println(sensor.getPH(), 1); // Выводим полученный водородный показатель жидкости с одним знаком после запятой. } //
Несмотря на то, что код без проверок кажется более понятным, рекомендуется выполнять проверки, так как это помогает отслеживать ошибки в процессе работы устройства.
Чтение кислотности жидкости с проверкой на наличие ошибок:
Пример позволяет не только прочитать кислотность жидкости, но и проверить её корректность.
uint8_t pinDE = 2; // Вывод DE конвертера UART-RS485. // #include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus. #include <iarduino_MB_pH.h> // Подключаем библиотеку для работы с датчиком pH-метра. // ModbusClient modbus(Serial1, pinDE); // Создаём объект для работы по протоколу Modbus указав шину UART-RS485 и вывод DE. iarduino_MB_pH sensor(modbus); // Создаём объект для работы с pH-метром указав объект протокола Modbus. // void setup(){ // Serial.begin(9600); while(!Serial); // Инициируем передачу данных в монитор последовательного порта, указав его скорость. Serial1.begin(9600); while(!Serial1); // Инициируем работу с шиной UART-RS485 указав её скорость. modbus.begin(); // Инициируем работу по протоколу Modbus. // modbus.setTimeout(10); // Указываем максимальное время ожидания ответа по протоколу Modbus. // modbus.setDelay(4); // Указываем минимальный интервал между отправляемыми сообщениями по протоколу Modbus. // modbus.setTypeMB( MODBUS_RTU ); // Указываем тип протокола Modbus: MODBUS_RTU (по умолчанию), или MODBUS_ASCII. bool f = sensor.begin(4); // Инициируем работу с датчиком pH-метра, указав его адрес. if( !f ){ // Если функция begin() вернула false, значит датчик pH-метра с адресом 4 не найден. Serial.print("pH-метр не найден"); // while(1); // Запрещаем дальнейшее выполнение скетча. } // } // // void loop(){ // delay(1000); // // Получаем данные от датчика: // float pH = sensor.getPH(); // Получаем кислотность жидкости. int32_t err = sensor.getErr(); // Получаем ошибки диагностики (датчик постоянно проводит самодиагностику). int8_t stab = sensor.getStability(); // Получаем флаг нормализации показаний кислотности (указывает что pH не меняется). // Информируем о отсутствии ответа: // if( pH<0 || err<0 || stab<0 ){ // Serial.println( "Нет ответа." ); // Сообщаем о ошибке чтения. return; // Переходим к следующему проходу цикла loop. } // // Информируем о наличии ошибок: // if( err ){ Serial.print( F("Показания не точны! " ) ); } // Если есть ошибки. if( err & ERR_MB_pH_Power ){ Serial.print( F("Стабилизация после подачи питания. " ) ); } // Прибору требуется время для стабилизации показаний после подачи питания. if( err & ERR_MB_pH_Data ){ Serial.print( F("Ошибка чтения данных из АЦП. " ) ); } // Чип АЦП на плате датчика не отвечает. if( err & ERR_MB_pH_Jumps ){ Serial.print( F("Значение pH 'скачет'. " ) ); } // Возможно плохой контакт на разъёме щупа или прибор не откалиброван. if( err & ERR_MB_pH_Vin ){ Serial.print( F("Некорректное напряжение на щупе. " ) ); } // Напряжение подаваемое на щуп вышло за допустимый диапазон. if( err & ERR_MB_pH_Vout ){ Serial.print( F("Некорректное напряжение от щупа. " ) ); } // Напряжение снимаемое с щупа вышло за допустимый диапазон. if( err & ERR_MB_pH_5V ){ Serial.print( F("Низкое напряжение питания 5В. " ) ); } // Стабилизированное напряжение питания 5В < 4В. Стабильная работа не гарантируется. if( err & ERR_MB_pH_Init ){ Serial.print( F("Ошибка инициализации АЦП. " ) ); } // Настройка АЦП на плате датчика не выполнена. // Выводим результат: // Serial.print( "Кислотность "); // Serial.print( pH, 1 ); // Выводим полученный водородный показатель жидкости, с одним знаком после запятой. Serial.print( " pH" ); // // Выводим анализ стабильности: // if( stab ){ // Serial.println( ", стабильна." ); // Информируем о стабильности показаний (pH не меняется). }else{ // Serial.println( " и меняется." ); // Информируем о не стабильности показаний (pH меняется). } // } //
Этот пример, как и два предыдущих, получает кислотность жидкости sensor.getPH()
, но еще проверяет наличие ошибок sensor.getErr()
и выводит флаг стабильности кислотности жидкости sensor.getStability()
.
Датчик проводит самодиагностику в режиме реального времени и при обнаружении ошибок, выводит соответствующие сообщения на дисплей.
Дисплей:
Данный раздел относится только с датчику с дисплеем.
Четырёхразрядный LED дисплей выводит кислотность жидкости и информирует о ошибках.
Стабилизация показаний после подачи питания (30 сек). Удержание кнопки «Калибровка». | |
Основной режим работы. Дисплей выводит кислотность исследуемой жидкости. | |
Ошибка 0. Провал инициализации чипа АЦП. Попробуйте отключить и вновь подать питание на датчик. | |
Ошибка 1. Ошибка возникает при низком напряжении питания. Проверьте питание и разъём RJ-45. | |
Ошибка 2. На щуп подано напряжение ниже требуемого. Датчик неисправен. | |
Ошибка 3. На щуп подано напряжение выше требуемого. Датчик неисправен. | |
Ошибка 4. Высокая разница потенциалов на выводах щупа pH<0. Возможно щуп не подключён или неисправен. | |
Ошибка 5. Высокая разница потенциалов на выводах щупа pH>14. Возможно щуп не подключён или неисправен. | |
Ошибка 6. Некорректные показания кислотности. Данные "скачут". Неисправен щуп или некорректны калибровочные значения. | |
Ошибка 7. Ошибка чтения данных с чипа АЦП. Датчик неисправен. | |
Ошибка С (Error Calibration). Ошибка калибровки. Выполнена с ошибкой или прервана. |
Зуммер:
Датчик без дисплея позволяет информировать о ошибках подачей звуковых сигналов.
Ошибка 0 | • | Провал инициализации чипа АЦП. Каждую секунду датчик издаёт один короткий звуковой сигнал. |
Ошибка 1 | ─ | Низкое напряжение питания. Каждую секунду датчик издаёт один длинный звуковой сигнал. |
Ошибка 2 | • • | На щуп подано напряжение ниже требуемого. Каждую секунду датчик издаёт два коротких звуковых сигнала. |
Ошибка 3 | ─ ─ | На щуп подано напряжение выше требуемого. Каждую секунду датчик издаёт два длинных звуковых сигнала. |
Ошибка 4 | • ─ | Высокая разница потенциалов на выводах щупа pH<0. Каждую секунду датчик издаёт два сигнала, короткий, потом длинный. |
Ошибка 5 | ─ • | Высокая разница потенциалов на выводах щупа pH>14. Каждую секунду датчик издаёт два сигнала, длинный, потом короткий. |
Ошибка 6 | • • ─ | Некорректные показания кислотности. Данные "скачут". Каждую секунду датчик издаёт три сигнала, 2 коротких и 1 длинный. |
Ошибка 7 | ─ • • | Ошибка чтения данных с чипа АЦП. Каждую секунду датчик издаёт три сигнала, 1 длинный и 2 коротких. |
Ошибка С | ─ ─ ─ | Калибровка выполнена с ошибкой или прервана. Датчик издаёт три очень длинных звуковых сигнала. |
Сигналы о ошибках генерируются на низкой (500Гц) частоте.
Длительность короткого сигнала составляет 0,1 сек, длинного 1 сек, а очень длинного 2 сек.
Калибровка:
Для калибровки потребуются две калибровочные жидкости, с водородными показателями 4,0 pH и 9.18 pH, а так же дистиллированная вода. Все жидкости должны иметь температуру при которой планируется выполнять дальнейшие измерения.
Примечание: Для калибровки датчика можно использовать жидкости с другими водородными показателями если их предварительно указать функцией setKnownPH() библиотеки iarduino_MB_pH.
Водородный показатель первой калибровочной жидкости должен отличаться от второй не менее чем на 2 pH.
Перед калибровкой очистите щуп от жидкости в которой он был ранее. Для этого опустите щуп в стакан с дистиллированной водой, поводите щупом споласкивая его, достаньте щуп и встряхните, избавившись от крупных капель.
Калибровка датчика с дисплеем:
Запуск калибровки. Опустите щуп в первую жидкость (4,0 pH). Удерживайте кнопку «Калибровка» до появления «----». | |
1 стадия калибровки (ожидание). На дисплее появится требуемый pH первой жидкости (4,00). Датчик ждёт стабилизации показаний измерительного щупа. | |
1 стадия калибровки (выполнение). Датчик считывает показания измерительного щупа и выводит на дисплей анимацию кругового включения сегментов. | |
Ожидание смены жидкости. На дисплее мигает требуемый pH второй жидкости (9,18). Достаньте щуп из первой жидкости и опустите во вторую. Датчик сам определит смену жидкости. | |
2 стадия калибровки (ожидание). Требуемый водородный показатель перестанет мигать. Датчик ждёт стабилизации показаний измерительного щупа. | |
2 стадия калибровки (выполнение). Датчик считывает показания измерительного щупа и выводит на дисплей анимацию кругового включения сегментов. | |
Успешное завершение калибровки. Если на дисплее появилась надпись «Good», значит калибровка выполнена успешно и все рассчитанные показания сохранены в энергонезависимую память датчика. | |
Ошибка калибровки. Если на дисплее появилась надпись «Err.C» значит калибровка не выполнена и данные не сохранены. Результат калибровки (Good / Err.C) исчезнет через 2 секунды. |
Калибровка датчика без дисплея:
• | Запуск калибровки. Опустите щуп в первую калибровочную жидкость (4,00 pH). Нажмите и удерживайте кнопку «Калибровка». Датчик издаст короткий звуковой сигнал при нажатии на кнопку и такой же сигнал через секунду её удержания, тогда кнопку можно отпустить. |
• | 1 стадия калибровки. Каждую секунду датчик издаёт один короткий звуковой сигнал. На этой стадии датчик ждёт стабилизации показаний щупа, а потом считывает их. |
─ ─ | Ожидание смены жидкости. Каждую секунду датчик издаёт два длинных звуковых сигнала. Достаньте щуп из первой калибровочной жидкости и опустите во вторую. |
• • | 2 стадия калибровки. Каждую секунду датчик издаёт два коротких звуковых сигнала. На этой стадии датчик ждёт стабилизации показаний щупа, а потом считывает их. |
─ | Успешное завершение калибровки. Если датчик издал один очень длинный звуковой сигнал, значит калибровка выполнена успешно и все рассчитанные показания сохранены в энергонезависимую память. |
─ ─ ─ | Ошибка калибровки. Если датчик издал три очень длинных звуковых сигнала, значит калибровка не выполнена и данные не сохранены. |
Сигналы о стадиях и успехе калибровки генерируются на высокой (3кГц) частоте, а сигнал о ошибке, на низкой (500Гц) частоте.
Длительность короткого сигнала составляет 0,1 сек, длинного 1 сек, а очень длинного 2 сек.
Правила калибровки общие для датчиков с дисплеем и без:
Запустить калибровку можно не только удержанием кнопки «Калибровка», но и обращением к функции setCalibration() библиотеки iarduino_MB_pH.
После запуска калибровки, требуется только сменить первую калибровочную жидкость на вторую. Датчик самостоятельно зафиксирует смену жидкости и перейдёт ко второй стадии.
При смене калибровочных жидкостей рекомендуется сполоснуть щуп в дистиллированной воде, чтоб остатки первой калибровочной жидкости не попали во вторую.
Процесс ожидания стабилизации показаний щупа занимает не менее 10 секунд.
Калибровку можно отменить, в любой момент, повторным нажатием на кнопку «Калибровка». Калибровка автоматически отменяется, если любая из стадий калибровки выполняется дольше 2 минут. Отмена калибровки расценивается как ошибка с соответствующим уведомлением.
Библиотека iarduino_MB_pH позволяет запускать калибровку, определять стадии калибровки, получать результат калибровки, читать и менять данные рассчитанные при калибровке, а так же указывать pH используемых калибровочных жидкостей.
Описание функций библиотеки:
В данном разделе описаны функции библиотеки iarduino_MB_pH для работы с датчиком кислотности жидкости (pH-метр) 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_pH.h> // Подключаем библиотеку для работы с датчиком pH-метра. // ModbusClient modbus(Serial, 2); // Создаём объект для работы по протоколу Modbus указав класс Serial и номер вывода DE конвертера UART-RS485. iarduino_MB_pH sensor(modbus); // Создаём объект для работы с pH-метром указав объект протокола Modbus. // void setup(){ // ... // Serial.begin(9600); // Указываем скорость шины RS485. Она равна скорости шины UART подключённой к конвертеру UART-RS485. while(!Serial); // sensor.begin(4); // Инициируем работу с pH-метром, указав его адрес. ... // Если адрес не указан sensor.begin(), то он будет найден, но это займёт некоторое время. } //
Если используется аппаратная шина UART-1, то вместо класса Serial указываем Serial1, для шины UART2 указываем Serial2 и т.д.
- Если используется программная реализация шины UART:
#include <SoftwareSerial.h> // Подключаем библиотеку для работы с программной шиной UART. #include <iarduino_Modbus.h> // Подключаем библиотеку для работы по протоколу Modbus. #include <iarduino_MB_pH.h> // Подключаем библиотеку для работы с датчиком pH-метра. // SoftwareSerial rs485(8, 9); // Создаём объект для работы с программной шиной UART указывая выводы RX, TX. ModbusClient modbus(rs485, 2); // Создаём объект для работы по протоколу Modbus указав объект программной шины UART и номер вывода DE конвертера UART-RS485. iarduino_MB_pH sensor(modbus); // Создаём объект для работы с pH-метром указав объект протокола Modbus. // void setup(){ // ... // rs485.begin(9600); // Указываем скорость шины RS485. Она равна скорости программной шины UART подключённой к конвертеру UART-RS485. while(!rs485); // sensor.begin(4); // Инициируем работу с pH-метром, указав его адрес. ... // Если адрес не указан sensor.begin(), то он будет найден, но это займёт некоторое время. } //
Для программной реализации шины UART необходимо указать выводы которые будут использоваться как RX и TX, в примере указаны выводы 8, и 9 соответственно. При создании объекта modbus указывается не класс Serial, а объект для работы с программной шиной UART.
Скорость передачи данных по шине Modbus равна скорости шины UART.
Функция begin();
- Назначение: Инициализация работы с датчиком pH-метра.
- Синтаксис: begin( [ АДРЕС_ДАТЧИКА ] );
- Параметр: uint8_t АДРЕС_ДАТЧИКА - значение от 1 до 247.
- Возвращаемое значение: bool - результат инициализации (true или false).
- Примечание:
- Если вызвать функцию без параметра, то адрес pH-метра будет найден автоматически. На это уйдёт некоторое время и на шине долен быть только один датчик pH-метра.
- Функцию достаточно вызвать 1 раз в коде Setup(), до обращения к остальным функциям библиотеки.
- Датчики pH-метров поставляются с адресом 4 на шине, но этот адрес можно изменить.
- Пример:
sensor.begin(4); // Инициируем работу с pH-метром, указав его адрес на шине.
Функция reset();
- Назначение: Программная перезагрузка датчика pH-метра.
- Синтаксис: reset();
- Параметры: Нет.
- Возвращаемое значение: bool - результат перезагрузки (true или false).
- Пример:
sensor.reset(); // Выполняем программную перезагрузку.
Функция changeID();
- Назначение: Установка нового адреса на шине.
- Синтаксис: changeID( АДРЕС_ДАТЧИКА );
- Параметр: uint8_t АДРЕС_ДАТЧИКА - значение от 1 до 247.
- Возвращаемое значение: bool - результат изменения адреса (true или false).
- Примечание:
- Новый адрес сохраняется в энергонезависимую память, а значит остаётся после отключения питания.
- Выполнение функции занимает более 120 миллисекунд.
- Пример:
sensor.changeID(10); // Изменить адрес датчика на значение 10.
Функция setSpeedMB();
- Назначение: Установка новой скорости передачи данных.
- Синтаксис: setSpeedMB( СКОРОСТЬ );
- Параметр: uint32_t СКОРОСТЬ - может принимать одно из значений:
2400 / 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();
- Назначение: Чтение напряжения питания на шине 5V.
- Синтаксис: getPWR();
- Параметры: Нет.
- Возвращаемое значение: float - напряжение (00,000...65,535 В), или -1 при провале чтения.
- Примечание:
- Данная функция позволяет узнать напряжение питания на гальванически развязанной шине питания 5V.
- У других модулей iarduino, не имеющих гальванической развязки по питанию, данная функция возвращает напряжение питания получаемое с разъема RJ45.
- Пример:
i = sensor.getPWR(); // Читаем гальванически развязанное напряжение питания 5V. if(i<0){ Serial.print("ERR"); } // Сообщаем о ошибке. else { Serial.print( i ); } // Выводим напряжение питания шины 5V в вольтах.
Функция getErr();
- Назначение: Чтение флагов ошибок из регистра диагностики.
- Синтаксис: getErr();
- Параметры: Нет.
- Возвращаемое значение: int32_t - регистр диагностики (2 байта), или -1 при провале чтения.
- Примечание:
- Функция возвращает двухбайтное значение из регистра диагностики.
- Каждый бит регистра диагностики информирует о ошибке.
- Датчик постоянно проводит самодиагностику в режиме реального времени.
- Пример:
i = sensor.getErr(); // Получаем значение регистра диагностики. if( i ){ Serial.print( "Есть ошибки: " ); } if( i & ERR_MB_pH_Power ){ Serial.print( "Стабилизация после подачи питания. " ); } if( i & ERR_MB_pH_Data ){ Serial.print( "Ошибка чтения данных из АЦП. " ); } if( i & ERR_MB_pH_Jumps ){ Serial.print( "Значение pH 'скачет'. " ); } if( i & ERR_MB_pH_Vin ){ Serial.print( "Некорректное напряжение на щупе. " ); } if( i & ERR_MB_pH_Vout ){ Serial.print( "Некорректное напряжение от щупа. " ); } if( i & ERR_MB_pH_5V ){ Serial.print( "Низкое напряжение питания 5В шины. " ); } if( i & ERR_MB_pH_Init ){ Serial.print( "Ошибка инициализации АЦП. " ); }
Функция setCalibration();
- Назначение: Запуск калибровки.
- Синтаксис: setCalibration();
- Параметры: Нет.
- Возвращаемое значение: bool - результат запуска калибровки (true или false).
- Примечание:
- Обращение к функции равносильно нажатию на кнопку "Калибровка".
- Перед запуском нужно сполоснуть щуп и опустить его в 1 калибровочную жидкость.
- Узнать текущую стадию калибровки можно функцией getCalibration().
- Пример:
sensor.setCalibration(); // Запускаем калибровку.
Функция getCalibration();
- Назначение: Чтение текущей стадии калибровки.
- Синтаксис: getCalibration();
- Параметры: Нет.
- Возвращаемое значение: int8_t - стадия калибровки (0,1,2,3), или -1 при провале чтения.
- Примечание:
- Подробно о стадиях калибровки написано выше, в разделе "Калибровка".
- Актуальные значения возвращаемые функцией:
- 0 - Калибровка не выполняется.
- 1 - Выполняется первая стадия калибровки.
- 2 - Выполняется вторая стадия калибровки.
- 3 - Датчик ожидает смены первой калибровочной жидкости на вторую.
- Результат калибровки можно узнать функцией getResultCalib().
- Пример:
i = sensor.setCalibration(); // Запускаем калибровку. do{ j = sensor.getCalibration(); delay(1000); // Читаем текущую стадию калибровки. if( j==1 ){ Serial.println("1 стадия..." ); } // Выполняется 1 стадия калибровки. if( j==3 ){ Serial.println("смените жидкость"); } // Датчик ждёт смены жидкости. if( j==2 ){ Serial.println("2 стадия..." ); } // Выполняется 2 стадия калибровки. }while( j ); // Выполняем цикл пока выполняется калибровка. Serial.println("Калибровка завершена"); } // Эта строка выполнится если j==0.
Функция getResultCalib();
- Назначение: Чтение результата последней калибровки.
- Синтаксис: getResultCalib();
- Параметры: Нет.
- Возвращаемое значение: int8_t - результат (true или false), или -1 при провале чтения.
- Примечание:
- Результат калибровки устанавливается в true при запуске калибровки.
- Результат калибровки сбрасывается в false если калибровка выполнена с ошибкой.
- Датчик считает калибровку выполненной с ошибкой,если рассчитанная чувствительность щупа выходит за диапазон 12...75 мВ/pH, или нейтральная кислотность для щупа выходит за диапазон ±3 pH от эталонного значения 7,00 pH. В таком случае результаты калибровки не сохраняются, а функция getResultCalib() возвращает false.
- Пример:
sensor.setCalibration(); // Запускаем калибровку. while( sensor.getCalibration() ) // Выполняем цикл пока выполняется калибровка. { delay(1000); } // Не перегружаем шину. i = sensor.getResultCalib(); // Получаем результат калибровки. if(i<0){ Serial.print("?" ); }else // Датчик не ответил. if( i ){ Serial.print("OK" ); }else // Калибровка завершена успешно. { Serial.print("ERR"); } // Калибровка завершена с ошибкой.
Функция getStability();
- Назначение: Чтение флага нормализации показаний.
- Синтаксис: getStability();
- Параметры: Нет.
- Возвращаемое значение: int8_t - флаг нормализации (true/false), или -1 при провале чтения.
- Примечание:
- Функция возвращает true если показания кислотности стабильны.
- Функция возвращает false если кислотность увеличивается или уменьшается.
- Показания кислотности считаются стабильными если её среднее значение за последние 10 секунд не сместилось за предел допустимой флуктуации.
- Показания кислотности считаются нестабильными (увеличиваются или уменьшаются, если её среднее значение за последние 10 секунд сместилось за предел высокой флуктуации.
- Функции setFluctuation() / getFluctuation() позволяют задавать / получать уровни допустимой и высокой флуктуации.
- Пример:
i = sensor.getStability(); // Читаем флаг нормализации показаний. if(i<0){ Serial.print("ERR"); } // Сообщаем о ошибке. else { Serial.print( i ); } // Выводим флаг.
Функция getPH();
- Назначение: Чтение кислотности исследуемой жидкости.
- Синтаксис: getPH();
- Параметры: Нет.
- Возвращаемое значение: float - кислотность (0...14,000 pH), или -1 при провале чтения.
- Пример:
i = sensor.getPH(); // Читаем кислотность. if(i<0){ Serial.print("ERR"); } // Сообщаем о ошибке. else { Serial.print( i ); } // Выводим кислотность.
Функции настройки датчика:
В данном разделе описаны функции настройки работы датчика. Датчик использует различные коэффициенты и значения для вычислений. По умолчанию они установлены в стандартные значения и не требуют изменений.
Важно: Все значения устанавливаемые функциями настройки датчика сохраняются в энергонезависимую память датчика, а значит действуют и после отключения питания!
Функция setKnownPH();
- Назначение: Установка кислотности калибровочных жидкостей.
- Синтаксис: setKnownPH( СТАДИЯ , КИСЛОТНОСТЬ );
- Параметры:
- uint8_t СТАДИЯ - может принимать значение 1 или 2.
- float КИСЛОТНОСТЬ - может принимать значения от 0,000 до 14,000 pH.
- Возвращаемое значение: bool - результат записи значения (true или false).
- Примечание:
- Калибровка производится с использованием двух калибровочных жидкостей, кислотность которых должна быть равна 4,00 и 9,18 pH (по умолчанию). Данная функция позволяет указать датчику, что для калибровки будут использоваться другие жидкости.
- Первый параметр указывает, кислотность какой жидкости (1 или 2) мы сохраняем.
- Второй параметр указывает, жидкость с какой кислотностью будет использоваться.
- Кислотность первой калибровочной жидкости должна отличатся от кислотности второй калибровочной жидкости не менее чем на 2,00 pH (в любую сторону).
- Указанные кислотности сохраняются в энергонезависимую память.
- Выполнение функции занимает более 50 миллисекунд.
- Пример:
sensor.setKnownPH(1, 5.00); // На 1 стадии калибровки будет жидкость 5.00 pH. sensor.setKnownPH(2, 9.00); // На 2 стадии калибровки будет жидкость 9.00 pH.
Функция getKnownPH();
- Назначение: Чтение кислотности жидкостей требуемых для калибровки.
- Синтаксис: getKnownPH( СТАДИЯ );
- Параметр: uint8_t СТАДИЯ - может принимать значение 1 или 2.
- Возвращаемое значение: float - требуемая кислотность в pH, или -1 при провале чтения.
- Примечание:
- Функция позволяет узнать требуемые кислотности калибровочных жидкостей.
- Параметр функции указывает, кислотность какой жидкости (1 или 2) требуется вернуть.
- По умолчанию, для 1 стадии калибровки, требуется жидкость с кислотностью 4.00 pH.
- По умолчанию, для 2 стадии калибровки, требуется жидкость с кислотностью 9.18 pH.
- Пример:
i = sensor.getKnownPH( 1 ); // Читаем кислотность требуемую на 1 стадии калибровки. j = sensor.getKnownPH( 2 ); // Читаем кислотность требуемую на 2 стадии калибровки. if( i<0 || j<0 ){ Serial.print("Err"); }else{ Serial.print( (String) "1="+i+"pH, 2="+j+"pH." ); }
Функция setFluctuation();
- Назначение: Установка пределов флуктуации кислотности.
- Синтаксис: setFluctuation( ТИП , КИСЛОТНОСТЬ );
- Параметры:
- uint8_t ТИП - может принимать значение STABLE_PH или UNSTABLE_PH.
- float КИСЛОТНОСТЬ - может принимать значения от 0,001 до 14,000 pH.
- Возвращаемое значение: bool - результат записи значения (true или false).
- Примечание:
- Функция позволяет задать пределы допустимой и высокой флуктуации.
- Первый параметр позволяет указать тип устанавливаемого предела:
- STABLE_PH - задать предел допустимой флуктуации.
- UNSTABLE_PH - задать предел высокой флуктуации.
- Второй параметр определяет значение устанавливаемого предела.
- Если среднее значение кислотности за последние 10 секунд не сместилось за предел допустимой флуктуации, то показания кислотности считаются стабильными.
При таких показаниях, функция getStability() возвращает true. - Если среднее значение кислотности за последние 10 секунд сместилось за предел высокой флуктуации, то показания кислотности считаются не стабильными.
При таких показаниях, функция getStability() возвращает false. - Предел допустимой флуктуации должен быть ниже предела высокой флуктуации.
- Во время калибровки датчик проверяет нормализацию показаний кислотности, значит меняя пределы флуктуаций можно ускорить или замедлить процесс калибровки.
- Указанные пределы сохраняются в энергонезависимую память.
- Выполнение функции занимает более 50 миллисекунд.
- Пример:
sensor.setFluctuation(STABLE_PH , 0.002); // Показания будут считаться стабильными, если среднее значение кислотности за последние 10 секунд не смещается более чем на ±0.002 pH. sensor.setFluctuation(UNSTABLE_PH, 0.003); // Показания будут считаться не стабильными, если среднее значение кислотности за последние 10 секунд сместится более чем на ±0.003 pH.
Функция getFluctuation();
- Назначение: Чтение пределов флуктуации кислотности.
- Синтаксис: getFluctuation( ТИП );
- Параметр: uint8_t ТИП - может принимать значение STABLE_PH или UNSTABLE_PH.
- Возвращаемое значение: float - предел флуктуации в pH, или -1 при провале чтения.
- Примечание:
- Функция позволяет получить установленные пределы флуктуации кислотности.
- Параметр позволяет указать тип читаемого предела флуктуаций.
- STABLE_PH - получить предел допустимой флуктуации.
- UNSTABLE_PH - получить предел высокой флуктуации.
- Если среднее значение кислотности за последние 10 секунд не сместилось за предел допустимой флуктуации, то показания кислотности считаются стабильными.
При таких показаниях, функция getStability() возвращает true. - Если среднее значение кислотности за последние 10 секунд сместилось за предел высокой флуктуации, то показания кислотности считаются не стабильными.
При таких показаниях, функция getStability() возвращает false. - По умолчанию, предел допустимой флуктуации кислотности равен 0.002 pH.
- По умолчанию, предел высокой флуктуации кислотности равен 0.003 pH.
- Пример:
i = sensor.getFluctuation( STABLE_PH ); // Читаем предел допустимой флуктуации кислотности. j = sensor.getFluctuation( UNSTABLE_PH ); // Читаем предел высокой флуктуации кислотности.
Функция setVstp();
- Назначение: Установка чувствительности щупа.
- Синтаксис: setVstp( НАПРЯЖЕНИЕ );
- Параметры:
- float НАПРЯЖЕНИЕ чувствительности в мВ/pH, значение от 0,01 до 655,35.
- Возвращаемое значение:
- bool - результат применения нового напряжения (true или false).
- Примечание:
- Значение по умолчанию 30,00 мВ (с учётом шунта входным сопротивлением АЦП датчика).
- Данное значение указывает на сколько изменится напряжение с щупа при изменении водородного показателя жидкости на 1,0 pH.
- Датчик самостоятельно определяет и сохраняет значение Vstp в процессе калибровки.
- Чувствительность щупа сохраняется в энергонезависимую память.
- Выполнение функции занимает более 50 миллисекунд.
- Пример:
sensor.setVstp( 60.0 ); // Указываем датчику новую чувствительность щупа в мВ/pH.
Функция getVstp();
- Назначение: Чтение чувствительности щупа.
- Синтаксис: getVstp();
- Параметры: Нет.
- Возвращаемое значение: float напряжение (0,01...655,35 мВ/pH), или -1 при провале чтения.
- Пример:
i = sensor.getVstp(); // Читаем чувствительность щупа из памяти датчика. if( i<0 ){ Serial.print("Err"); }else{ Serial.print( (String) "Vstp = "+i+" мВ/pH." ); }
Функция getVin();
- Назначение: Чтение напряжения поданного на вход измерительного щупа.
- Синтаксис: getVin();
- Параметры: Нет.
- Возвращаемое значение: float напряжение (0...6,5535 В), или -1 при провале чтения.
- Примечание:
- Напряжение на входе измерительного щупа устанавливается резистивным делителем.
- Эталонное значение: Vin = 0.5Vcc = 0.5*3.3 = 1.65 В.
- Функция возвращает не эталонное, а реальное напряжение на входе щупа.
- Пример:
i = sensor.getVin(); // Читаем напряжение на входе щупа. if( i<0 ){ Serial.print("Err"); }else{ Serial.print( (String) "Vin = "+i+" В." ); }
Функция getVout();
- Назначение: Чтение напряжения на выходе измерительного щупа.
- Синтаксис: getVout();
- Параметры: Нет.
- Возвращаемое значение: float напряжение (0...6,5535 В), или -1 при провале чтения.
- Примечание: Напряжение на выходе щупа измеряется встроенным АЦП CS1237.
- Пример:
i = sensor.getVout(); // Читаем напряжение на выходе щупа. if( i<0 ){ Serial.print("Err"); }else{ Serial.print( (String) "Vout = "+i+" В." ); }
Функция setPHn();
- Назначение: Установка нейтральной кислотности для щупа.
- Синтаксис: setPHn( КИСЛОТНОСТЬ );
- Параметры:
- float КИСЛОТНОСТЬ жидкости от 0 до 14 pH при котором напряжение щупа равно 0.
- Возвращаемое значение:
- bool - результат применения нового нейтрального pH щупа (true или false).
- Примечание:
- Нейтральный водородный показатель жидкости для щупа это pH нулевой точки, такой водородный показатель при котором напряжение щупа равно нулю.
- При погружении щупа в нейтральную среду (pH=7,0), потенциалы на входе и выходе щупа должны быть одинаковыми (напряжение щупа равно 0) - нулевая точка. Но в процессе старения щупа его нулевая точка смещается, и напряжение щупа будет равно нулю при водородном показателе жидкости отличном от 7,0 pH, это значение и является нейтральным водородным показателем для щупа pHn.
- Датчик самостоятельно определяет и сохраняет значение pHn в процессе калибровки.
- Нейтральная кислотность для щупа сохраняется в энергонезависимую память.
- Выполнение функции занимает более 50 миллисекунд.
- Пример:
sensor.setPHn( 7.02 ); // Указываем датчику новую нейтральную кислотность в pH.
Функция getPHn();
- Назначение: Запрос нейтральной кислотности для щупа.
- Синтаксис: getPHn();
- Параметры: Нет.
- Возвращаемое значение: float кислотность (0...14,000 pH), или -1 при провале чтения.
- Пример:
i = sensor.getPHn(); // Читаем нейтральную кислотность для щупа в pH. if( i<0 ){ Serial.print("Err"); }else{ Serial.print( (String) "pHn = "+i+" pH." ); }
Обработка ошибок:
Рассмотренные выше функции библиотеки iarduino_MB_pH возвращают не только результат чтения, но и ошибки при записи или чтении. Причину ошибок можно выяснить функцией 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.getPH(); // Читаем кислотность исследуемой жидкости. if(i>=0){ // Если значение прочитано без ошибок... Serial.print("Кислотность "); // Serial.print( i ); // Выводим прочитанное значение. Serial.println(" pH."); // }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 - ошибка синтаксиса, означает наличие ошибки в коде, например функция вызвавшая данную ошибку была вызвана с некорректными параметрами, или вызвана до инициализации датчика.
Ссылки:
- Датчик кислотности жидкости (pH-метр) RS485 / Modbus с дисплеем.
- Датчик кислотности жидкости (pH-метр) RS485 / Modbus без дисплея.
- Trema конвертер UART-RS485.
- Wiki - Датчик кислотности жидкости (pH-метр) RS485 / Modbus - Datasheet.
- Wiki - Работа с протоколом Modbus RTU/ASCI по шине RS485.
- Библиотека iarduino_Modbus.
- Библиотека iarduino_MB_pH.
- Wiki - Установка библиотек в Arduino IDE.
Обсуждение