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

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

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

Датчик кислотности жидкости (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 - ошибка синтаксиса, означает наличие ошибки в коде, например функция вызвавшая данную ошибку была вызвана с некорректными параметрами, или вызвана до инициализации датчика.

      Ссылки:




      Обсуждение

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