ESP8266 NodeMCU с датчиком TDS (датчик качества воды)

В этом руководстве вы узнаете, как использовать TDS-метр (Total Dissolved Solids – общее количество растворённых веществ) с платой ESP8266 NodeMCU. TDS-метр показывает общее количество растворённых веществ, таких как соли, минералы и металлы, в растворе. Этот параметр можно использовать для оценки качества воды и сравнения воды из разных источников. Одним из основных применений TDS-метра является мониторинг качества воды в аквариумах.

ESP8266 NodeMCU с датчиком TDS датчик качества воды Arduino IDE

Мы будем использовать TDS-метр от keystudio и покажем вам простой пример измерения TDS в единицах ppm с помощью Arduino IDE.

Знакомство с TDS-метром

TDS-метр измеряет количество общих растворённых веществ, таких как соли, минералы и металлы, в воде. По мере увеличения количества растворённых веществ в воде возрастает проводимость воды, и это позволяет нам рассчитать общее количество растворённых веществ в ppm (мг/л).

Датчик TDS метр keystudio

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

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

В этом руководстве мы будем использовать TDS-метр от keystudio, который поставляется с интерфейсным модулем и электродным щупом (см. изображение выше).

Для получения дополнительной информации о TDS-метре рекомендуем ознакомиться с официальной документацией.

Характеристики и спецификации

Данное руководство относится к TDS Meter V1.0 от keystudio. Вот параметры датчика:

TDS-метр:

  • Входное напряжение: DC 3.3 ~ 5.5 В

  • Выходное напряжение: 0 ~ 2.3 В

  • Рабочий ток: 3 ~ 6 мА

  • Диапазон измерения TDS: 0 ~ 1000 ppm

  • Точность измерения TDS: +/- 10% F.S. (25 °C)

  • Интерфейс модуля: XH2.54-3P

  • Интерфейс электрода: XH2.54-2P

Щуп TDS:

  • Количество игл: 2

  • Общая длина: 60 см

  • Интерфейс подключения: XH2.54-2P

  • Цвет: белый

  • Водонепроницаемый щуп

Где купить датчик TDS?

Вы можете найти датчик TDS на Maker Advisor по лучшей цене:

Вы можете воспользоваться ссылкой выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

Подключение TDS-метра к ESP8266

TDS-метр выдаёт аналоговый сигнал, который можно измерить с помощью аналогового пина ESP8266 A0.

Подключите датчик согласно следующей таблице:

Датчик TDS

ESP8266

GND

GND

VCC

3.3V

Data

A0

Чтение TDS (качества воды) с ESP8266 – код

Как мы упоминали ранее, датчик выдаёт аналоговый сигнал, который можно преобразовать в TDS в ppm. Мы используем код, предоставленный в документации датчика, с некоторыми модификациями.

ESP8266 NodeMCU с датчиком TDS качество воды

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

Загрузите следующий код на вашу ESP8266.

// Original source code: https://wiki.keyestudio.com/KS0429_keyestudio_TDS_Meter_V1.0#Test_Code
// Project details: https://RandomNerdTutorials.com/esp8266-nodemcu-tds-water-quality-sensor/

#define TdsSensorPin A0
#define VREF 3.3              // analog reference voltage(Volt) of the ADC
#define SCOUNT  30            // sum of sample point

int analogBuffer[SCOUNT];     // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0;
int copyIndex = 0;

float averageVoltage = 0;
float tdsValue = 0;
float temperature = 23;       // current temperature for compensation

// median filtering algorithm
int getMedianNum(int bArray[], int iFilterLen){
  int bTab[iFilterLen];
  for (byte i = 0; i<iFilterLen; i++)
  bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0){
    bTemp = bTab[(iFilterLen - 1) / 2];
  }
  else {
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  }
  return bTemp;
}

void setup(){
  Serial.begin(115200);
  pinMode(TdsSensorPin,INPUT);
}

void loop(){
  static unsigned long analogSampleTimepoint = millis();
  if(millis()-analogSampleTimepoint > 40U){     //every 40 milliseconds,read the analog value from the ADC
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer
    analogBufferIndex++;
    if(analogBufferIndex == SCOUNT){
      analogBufferIndex = 0;
    }
  }

  static unsigned long printTimepoint = millis();
  if(millis()-printTimepoint > 800U){
    printTimepoint = millis();
    for(copyIndex=0; copyIndex<SCOUNT; copyIndex++){
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];

      // read the analog value more stable by the median filtering algorithm, and convert to voltage value
      averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 1024.0;

      //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
      float compensationCoefficient = 1.0+0.02*(temperature-25.0);
      //temperature compensation
      float compensationVoltage=averageVoltage/compensationCoefficient;

      //convert voltage value to tds value
      tdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5;

      //Serial.print("voltage:");
      //Serial.print(averageVoltage,2);
      //Serial.print("V   ");
      Serial.print("TDS Value:");
      Serial.print(tdsValue,0);
      Serial.println("ppm");
    }
  }
}

Исходный код

Как работает код

Давайте кратко рассмотрим код. Вы также можете сразу перейти к разделу Демонстрация.

Переменная TdsSensorPin сохраняет GPIO, с которого вы хотите получать показания. У ESP8266 есть только один аналоговый пин – A0.

#define TdsSensorPin A0

Затем укажите опорное аналоговое напряжение для АЦП. Для ESP8266 это 3.3 В, для Arduino, например, это 5 В.

#define VREF 3.3              // analog reference voltage(Volt) of the ADC

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

#define SCOUNT  30            // sum of sample point

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

int analogBuffer[SCOUNT];     // store the analog value in the array, read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0;
int copyIndex = 0;

Инициализируем переменные averageVoltage и tdsValue как переменные типа float.

float averageVoltage = 0;
float tdsValue = 0;

Переменная temperature сохраняет текущее значение температуры. Температура влияет на показания, поэтому существует алгоритм, компенсирующий колебания температуры. В этом примере эталонная температура составляет 25 °C, но вы можете изменить её в зависимости от вашей среды. Для более точных результатов вы можете добавить датчик температуры и получать фактическую температуру в момент считывания показаний датчика.

float temperature = 25;       // current temperature for compensation

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

// median filtering algorithm
int getMedianNum(int bArray[], int iFilterLen){
  int bTab[iFilterLen];
  for (byte i = 0; i<iFilterLen; i++)
  bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0){
    bTemp = bTab[(iFilterLen - 1) / 2];
  }
  else {
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  }
  return bTemp;
}

В setup() инициализируем Serial Monitor на скорости 115200 бод.

Serial.begin(115200);

Устанавливаем пин датчика TDS как вход.

pinMode(TdsSensorPin,INPUT);

В loop() каждые 40 миллисекунд получаем новые показания TDS и сохраняем их в буфер:

static unsigned long analogSampleTimepoint = millis();
if(millis()-analogSampleTimepoint > 40U){     //every 40 milliseconds,read the analog value from the ADC
  analogSampleTimepoint = millis();
  analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin);    //read the analog value and store into the buffer
  analogBufferIndex++;
  if(analogBufferIndex == SCOUNT){
    analogBufferIndex = 0;
  }
}

Затем каждые 800 миллисекунд код получает последние показания и вычисляет среднее напряжение с помощью ранее созданного алгоритма фильтрации:

static unsigned long printTimepoint = millis();
if(millis()-printTimepoint > 800U){
  printTimepoint = millis();
  for(copyIndex=0; copyIndex<SCOUNT; copyIndex++){
    analogBufferTemp[copyIndex] = analogBuffer[copyIndex];

    // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 1024.0;

Затем вычисляется коэффициент температурной компенсации и рассчитывается значение TDS с учётом этого значения:

//temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
float compensationCoefficient = 1.0+0.02*(temperature-25.0);
//temperature compensation
float compensationVoltage=averageVoltage/compensationCoefficient;

//convert voltage value to tds value
tdsValue=(133.42*compensationVoltage*compensationVoltage*compensationVoltage - 255.86*compensationVoltage*compensationVoltage + 857.39*compensationVoltage)*0.5;

Наконец, выводится значение TDS в ppm:

Serial.print("TDS Value:");
Serial.print(tdsValue,0);
Serial.println("ppm");

Демонстрация

После копирования кода в Arduino IDE загрузите код на вашу плату. Не забудьте выбрать правильную плату в Tools > Board и правильный COM-порт в Tools > Port.

После загрузки откройте Serial Monitor на скорости 115200 бод и нажмите кнопку RST на ESP8266, чтобы код начал работать.

Тестирование TDS метра ESP32 ESP8266 Arduino

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

Датчик TDS Arduino IDE Serial Monitor демонстрация

Я измерил значение TDS водопроводной воды у себя дома и получил значение около 100 ppm, что является хорошим значением для питьевой воды.

Я также проверил чай, и значение TDS увеличилось примерно до 230 ppm, что выглядит как разумное значение.

Наконец, я также измерил значение TDS бутилированной воды и получил значение около 25 ppm. У вас есть один из этих датчиков? Какие значения вы получили для бутилированной воды?

Также делюсь здесь результатами одного из наших читателей, чтобы вы могли сравнить:

  • водопроводная вода на ранчо: 125 ppm

  • пиво Corona: 384 ppm

  • уксус: 610 ppm

  • джин с тоником: 43 ppm

  • очищенная вода: 0 ppm

Заключение

TDS-метр может измерять общее количество растворённых веществ в растворе. Он может использоваться как индикатор качества воды и позволяет характеризовать воду. Метр возвращает значение TDS в ppm (частей на миллион – мг/л). Значение TDS имеет множество применений, но само по себе не может быть использовано для определения того, является ли вода пригодной для питья или нет.

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

Интересует ли вас монитор качества воды для аквариума? Я думал о создании веб-приложения для мониторинга и контроля температуры воды в аквариуме и качества воды, а также о возможности управления насосом через выходной пин ESP8266. Что думаете?

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

Узнайте больше о ESP8266 с помощью наших ресурсов: