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

Устройство для автоматической нормализации раствора (нормализатор TDS)

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

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

Систему можно будет использовать для нормализации TDS/ЕС для гидропоники, хотя сфера применения этим не ограничивается. Кстати, мы уже собирали устройство, нормализующее pH, о нём можно почитать в этой статье.

Видео

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

Нам понадобится

* Можно использовать любой контроллер серии Piranha, Arduino, или ESP-32.

** Необходим для программирования контроллера Piranha Trema. Однако, можно обойтись без него: контроллер можно запрограммировать при помощи другого контроллера. 

Схема

(картинка кликабельна)

Схема автоматического нормализатора концентрации TDS

Обратите внимание на установку джамперов на силовых ключах и DC-DC преобразователе.

Если насосы не перекачивают жидкость, поменяйте полярность их подключения: от неё зависит направление подачи раствора.

Скетч проекта

Установите библиотеку для работы с TDS-метром и LCD-дисплеем. Если необходима помощь в её установке, читайте статью. Если вы впервые работаете с контроллерами, вам поможет статья.

Загрузите код к контроллер при помощи USB-UART преобразователя. В пункте выбора контроллера Arduino IDE необходимо указать контроллер Arduino Mini.

#include <Wire.h>                     // Подключаем библиотеку для работы с шиной I2C
#include <iarduino_I2C_TDS.h>         // Подключаем библиотеку для работы с TDS/EC-метром I2C-flash.
#include <LiquidCrystal_I2C.h>        //  Подключаем библиотеку для работы с LCD дисплеем по шине I2C

#define pomp1 2                       // Первый насос подключен к выводу 2
#define pomp2 3                       // Второй насос подключен к выводу 3
#define pomp3 4                       // Третий насос подключен к выводу 4
#define resPin A3                     // Вывод, в которому подключен потенциометр

                                      // Создаём объекты, указывая адрес модуля на шине I2C:
LiquidCrystal_I2C lcd(0x27,20,4);     // Дисплей(адрес I2C = 0x27, количество столбцов = 20, количество строк = 4) (для диспления 1602 параметры будут 16 и 2)
iarduino_I2C_TDS TDSsens(0x09);       // TDS/EC-метр

/////////НАСТРОЙКИ//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const uint8_t productivity = 40;       // Производительность насоса (мл/мин)
float valPomp1 = 1.5;                  // Объём порции первого насоса, мл
float valPomp2 = 1.0;                  // Объём порции второго насоса, мл
float valPomp3 = 1.5;                  // Объём порции третьего насоса, мл
const uint32_t timeWait = 10000;       // Время одижания между подачами порции (время на размешивание раствора)
                                       // Настройка TDS:
const uint16_t tdsDown = 500;          // от (минимум)
const uint16_t tdsUp = 1500;           // до (максимум)
const uint32_t lcdPeriod = 500;        // Период обновления значений на дисплее
const uint32_t changeTimeDelay = 3000; // Время задержки после установления значения потенциометром, во время которого не будет производиться корректировка раствора, мс
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint16_t tds;                          // Измеренный уровень TDS
uint16_t tdsOn;                        // Нижний уровень TDS, после которого начнётся долив концентратов (зависит от поворота ручки потенциометра)
uint32_t timeLastPortion;              // Время последнего долива порции
uint32_t timeLastLcdUpdate;            // Время последнего обновления значений на дисплее
uint32_t timeChange;                   // Время изменения заданного значения TDS
int16_t res, lastRes=0;                // Текущее и предыдущее значение c потенциометра

uint8_t symbol[3][8] = {               // Объявляем массив из 3 собственных символов, каждый символ состоит из 8 байт
  {B01110,B10001,B00001,B00010,B00001,B10001,B01110,B00000,}, // Буква "З"
  {B01111,B00101,B00101,B01001,B10001,B11111,B10001,B00000,}, // Буква "Д"
  {B00100,B01110,B10101,B10101,B00100,B00100,B00100,B00100}}; // Стрелка вверх

void setup() {
  delay(500);      
  pinMode(pomp1, OUTPUT);                          // Насос - выход
  pinMode(pomp2, OUTPUT);                          // Насос - выход
  pinMode(pomp3, OUTPUT);                          // Насос - выход
  Serial.begin(9600);                              // Открываем последовательный порт передачи данных
  lcd.init();                                      // Инициируем работу с LCD дисплеем
  lcd.backlight();                                 // Включаем подсветку LCD дисплея
                                                     
  if (!TDSsens.begin()) Serial.println("TDS/EC-метр не инициализирован. Проверьте подключение и I2C-адрес модуля"); // Иниируем работу с TDS/EC-метром. Если не удалось выполнить подклчение, выводим сообщение об ошибке

  lcd.clear();
  lcd.createChar(1, symbol[0]);                    // Загружаем 1 символ "З" в ОЗУ дисплея
  lcd.createChar(2, symbol[1]);                    // Загружаем 2 символ "Д" в ОЗУ дисплея
  lcd.createChar(3, symbol[2]);                    // Загружаем стрелку в ОЗУ дисплея
  lcd.setCursor(0, 0);                             // Устанавливаем курсор в 0 столбец 0 строку дисплея
  lcd.print("PACTBOP: ");                          // Выводим текст на дисплей
  lcd.setCursor(0, 1);                             // Устанавливаем курсор в 0 столбец 1 строку дисплея
  lcd.print("\1A\2AHO: ");                         // Выводим текст на дисплей
  
  delay(2000);                                     // Задержка для завершения переходных процессов (в частности, устновление показаний TDS-метра)
}

void loop() {
  tds = TDSsens.getTDS();                          // Измерение TDS
  Serial.println("TDS: "+ (String)tds);            // Вывод значения TDS в монитор порта

  res = analogRead(resPin);                        // Получение значения с потенциометра
  tdsOn = (map(res, 0, 1023, tdsDown, tdsUp)/10)*10; // Перевод значений потенциометра (АЦП) в значения установки TDS. Делим и умножаем на 10 для округления десятков
  
  if (abs(lastRes-res) > 5){                       // Начали поворачивать ручку потенциометра
    timeChange = millis();                         // Обновляем время изменения значений
  }

  if (timeChange + changeTimeDelay <= millis()){   // Если после ввода значений прошло достаточное время
    if (timeLastPortion + timeWait <= millis()){   // Если с момента добавления предыдущей порции прошло необходимое время
      if (tds < tdsOn) {                           // Если концентрация раствора ниже заданной
        lcd.setCursor(14, 0);                      // Устанавливаем курсор в 14 столбец 0 строку дисплея
        lcd.print("  ");                           // Очищаем
        lcd.setCursor(14, 0);                      // Устанавливаем курсор в 14 столбец 0 строку дисплея
        lcd.print("\3");                           // Выводим стрелку
        lcd.setCursor(9, 0);                       // Устанавливаем курсор в 9 столбец 0 строку дисплея
        lcd.print("    ");                         // Очищаем
        lcd.setCursor(9, 0);                       // Устанавливаем курсор в 9 столбец 0 строку дисплея
        lcd.print(tds);                            // Выводим показания TDS на экран
        correctTDS();                              // TDS снизился, нужно повысить
      }
      else{                                        // Если концентрация раствора больше или равна заданной
        lcd.setCursor(14, 0);                      // Устанавливаем курсор в 14 столбец 0 строку дисплея
        lcd.print("OK");                           // Выводим текст
      }
    }
  }  
  lastRes = res;                                   // Обновляем прежнее значение с потенциометра 
  
  if (timeLastLcdUpdate + lcdPeriod <= millis()){  // Если пора обновить значения на дисплее
    lcd.setCursor(9, 0);                           // Устанавливаем курсор в 9 столбец 0 строку дисплея
    lcd.print("    ");                             // Очищаем
    lcd.setCursor(9, 0);                           // Устанавливаем курсор в 9 столбец 0 строку дисплея
    lcd.print(tds);                                // Выводим показания TDS на экран

    lcd.setCursor(9, 1);                           // Устанавливаем курсор в 9 столбец 1 строку дисплея
    lcd.print("    ");                             // Очищаем
    lcd.setCursor(9, 1);                           // Устанавливаем курсор в 9 столбец 1 строку дисплея
    lcd.print(tdsOn);                              // Выводим показания TDS на экран
        
    timeLastLcdUpdate = millis();                  // Обновляем время
  }
}

void correctTDS (){                                  // Функция дозации компонентов
  digitalWrite(pomp1,HIGH);                          // Включаем первый насос
  delay((float)productivity/60.0*valPomp1*1000.0);   // Выполняем задержку, равную времени работы насоса, треюуемому для подачи нужного количества жидкости
  digitalWrite(pomp1,LOW);
  delay(200);                                        // Пауза для завершения переходных процессов (в частности, по питанию)
                                                     // Повторяем для остальных насосов
  digitalWrite(pomp2,HIGH);                         
  delay((float)productivity/60.0*valPomp2*1000.0);                   
  digitalWrite(pomp2,LOW);
  delay(200); 

  digitalWrite(pomp3,HIGH);                         
  delay((float)productivity/60.0*valPomp3*1000.0);                   
  digitalWrite(pomp3,LOW);
  
  timeLastPortion = millis();                        // Фиксируем время, когда произошел долив компонентов
}

Ссылки




Обсуждение

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